commit 8d078dfec14e89bfe88b64b3b97729a0f4e14c30 Author: chahine Date: Thu Aug 15 17:21:53 2024 +0000 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9357415 --- /dev/null +++ b/.gitignore @@ -0,0 +1,20 @@ +/node_modules/ +/dist/ +/package-lock.json +build +bin +.gradle/ +src/auto/ +.settings/ +.classpath +.project +src/main/resources/static +gradlew +gradlew.bat +.idea/ +gradle/wrapper/gradle-wrapper.jar +gradle/wrapper/gradle-wrapper.properties +dependencies.gradle +package.json +wsl-deploy.sh +cygwin-deploy.sh \ No newline at end of file diff --git a/src/main/css/collapsible.css b/src/main/css/collapsible.css new file mode 100644 index 0000000..05ccdae --- /dev/null +++ b/src/main/css/collapsible.css @@ -0,0 +1,3 @@ +.css-1ebavjp-MuiPaper-root-MuiAccordion-root { + background-color: #ECECEC!important; +} \ No newline at end of file diff --git a/src/main/js/CliOptions.jsx b/src/main/js/CliOptions.jsx new file mode 100644 index 0000000..22bb6f7 --- /dev/null +++ b/src/main/js/CliOptions.jsx @@ -0,0 +1,32 @@ +import React from 'react'; + +import { loadFormData } from "../../auto/js/forms/CivilRecordForm"; +import { createFormComponent } from "../../auto/js/widgets"; +import { civilRecordFormfields } from "./forms/CivilRecordFormCommon"; +import { loadHistoryFormData } from './forms/CivilRecordHistoryCommon'; + +const viewVitalRecord = (args) => { + let CivilRecordForm = createFormComponent(civilRecordFormfields); + return loadFormData(args.id)} readOnly buttons={() => null}/> + +} + +const viewVitalRecordHistory = (args) => { + let CivilRecordForm = createFormComponent(civilRecordFormfields); + return loadHistoryFormData(args.id)} readOnly buttons={() => null}/> + +} + +export const subcommandOptions = { + viewvr: { + id: 'number' + }, + viewvrh: { + id: 'number' + } +}; + +export const commandHooks = { + viewvr: viewVitalRecord, + viewvrh: viewVitalRecordHistory +} diff --git a/src/main/js/GeneralStatistics.jsx b/src/main/js/GeneralStatistics.jsx new file mode 100644 index 0000000..4a799af --- /dev/null +++ b/src/main/js/GeneralStatistics.jsx @@ -0,0 +1,139 @@ +import * as React from 'react'; +import {v4 as uuidv4} from 'uuid'; +import LoadingOverlay from 'react-loading-overlay-ts'; + +import { OPEN_VIEW_EVENT, PRINT_EVENT } from '../../auto/js/events/Gui'; +import { getServiceUri } from '../../auto/js/metadata'; +import { rest, t } from '../../auto/js/services'; +import { Welcome } from './pages/Welcome'; +import { showNotification } from '../../auto/js/utils'; + +const groupingNumber = (number) => { + if (number != null) + return number.toLocaleString('en', {useGrouping:true}) + return null; +} + +const getProvinceStatisticsItems = (list) => { + let items = []; + list.forEach(element => { + items.push() + }); + return items; +} + +const GeneralStatisticsWrapper = () => { + const [ready, setReady] = React.useState(false); + + if (!ready) + rest.request(getServiceUri() + 'reports/general-statistics', 'GET').then(response => { + setReady(true) + const printable = { + content:, + copyParentStyle:true + } + PRINT_EVENT.publish(printable) + }) + + return ( + + + ) +} +export default class GeneralStatistics extends React.Component { + constructor(props) { + super(props); + this.data = props.data; + } + + render() { + + var currentdate = new Date(); + var datetime = currentdate.getDate() + "/" + + (currentdate.getMonth() + 1) + "/" + + currentdate.getFullYear() + let provinceStatisticsItems = getProvinceStatisticsItems(this.data.provinceGeneralStatisticsList); + return ( +
+
+
As of {this.props.timestamp}:
+
- A total of {groupingNumber(this.data.issuedIdCardsNumber)} ID cards are recorded to have been issued overtime.
+
- Of these, {groupingNumber(this.data.notExpiredIdCardsNumber)} have not expired yet
+
- Of these, {groupingNumber(this.data.notCancelledIdCardsNumber)} have not been canceled
+
- Of these, {groupingNumber(this.data.activatedIdCardsNumber)} have been activated
+
- Of these, {groupingNumber(this.data.distinctIndividualsIdCardsNumber)} belong to distinct individuals – in other words, some of the cards above most probably have been reissued without canceling the previous one, while the previous card is still active and not expired.
+
+

Those {groupingNumber(this.data.distinctIndividualsIdCardsNumber)} will be the reference for the statistics below, only considering the latest card issued for anyone who has more than one.

+

In parallel, there are {groupingNumber(this.data.authorizedBirthRecordsNumber)} “authorized birth records”. Please note that in CRIM terminology, the line between “authorized birth records”, “checked birth records” and “persons records” is not always clear cut. “checked birth records” for example, are sometimes issued legal documents, + and “persons records” can be changed into birth records. It also may create minor discrepancies depending on how the database is queried. For example, some records previously marked as “authorized” have been reverted to “checked”. +

+
+
Since records being marked as “authorized birth records” are the most authoritative source of legal identity in RV4, they will be the basis for the statistics below.
+
- Of these, {groupingNumber(this.data.livingAuthorizedBirthRecordsNumber)} have not been marked one way or another as deceased.
+
Overall, in Vanuatu:
+
- Below 18: {groupingNumber(this.data.livingMalesAgedUnder18Number)} males, {groupingNumber(this.data.livingFemalesAgedUnder18Number)} females
+
- 18 and above, below 30: {groupingNumber(this.data.livingMalesAged18To29Number)} males, {groupingNumber(this.data.livingFemalesAged18To29Number)} females
+
- 30 or above, below 50: {groupingNumber(this.data.livingMalesAged30To49Number)} males, {groupingNumber(this.data.livingFemalesAged30To49Number)} females
+
- 50 or above: {groupingNumber(this.data.livingMalesAgedOver49Number)} males, {groupingNumber(this.data.livingFemalesAgedOver49Number)} females
+
Crossing the data between ID cards and living people, we get:
+
- {groupingNumber(this.data.livingPeopleWithCardsNumber)} people recorded as living have at least one non-expired, non-canceled, activated, ID card. I’ll call those “living people with cards”. The others, recorded as living, without a card, will be called “living people without cards”.
+
Age or Sex information is missing in a small number of cases. These cases are excluded those from calculations. For “living people with cards”:
+
- Below 18: {groupingNumber(this.data.livingMalesAgedUnder18WithCardsNumber)} males, {groupingNumber(this.data.livingFemalesAgedUnder18WithCardsNumber)} females
+
- 18 or above, below 30: {groupingNumber(this.data.livingMalesAged18To29WithCardsNumber)} males, {groupingNumber(this.data.livingFemalesAged18To29WithCardsNumber)} females
+
- 30 or above, below 50: {groupingNumber(this.data.livingMalesAged30To49WithCardsNumber)} males, {groupingNumber(this.data.livingFemalesAged30To49WithCardsNumber)} females
+
- Above 50: {groupingNumber(this.data.livingMalesAgedOver49WithCardsNumber)} males, {groupingNumber(this.data.livingFemalesAgedOver49WithCardsNumber)} females
+
+ {provinceStatisticsItems} +
+ ) + } +} + +class ProvinceGeneralStatistics extends React.Component { + constructor(props) { + super(props); + this.data = props.data; + } + + render() { + + return ( + <> +

{this.data.provinceName}

+ +

In this province there are {groupingNumber(this.data.authorizedBirthRecordsNumber)} “authorized birth records”

+
+
Since records being marked as “authorized birth records” are the most authoritative source of legal identity in RV4, they will be the basis for the statistics below.
+
- Of these, {groupingNumber(this.data.livingAuthorizedBirthRecordsNumber)} have not been marked one way or another as deceased.
+
Overall, in {this.data.provinceName}:
+
- Below 18: {groupingNumber(this.data.livingMalesAgedUnder18Number)} males, {groupingNumber(this.data.livingFemalesAgedUnder18Number)} females
+
- 18 and above, below 30: {groupingNumber(this.data.livingMalesAged18To29Number)} males, {groupingNumber(this.data.livingFemalesAged18To29Number)} females
+
- 30 or above, below 50: {groupingNumber(this.data.livingMalesAged30To49Number)} males, {groupingNumber(this.data.livingFemalesAged30To49Number)} females
+
- 50 or above: {groupingNumber(this.data.livingMalesAgedOver49Number)} males, {groupingNumber(this.data.livingFemalesAgedOver49Number)} females
+
Crossing the data between ID cards and living people, we get:
+
- {groupingNumber(this.data.livingPeopleWithCardsNumber)} people recorded as living have at least one non-expired, non-canceled, activated, ID card. I’ll call those “living people with cards”. The others, recorded as living, without a card, will be called “living people without cards”.
+
Age or Sex information is missing in a small number of cases. These cases are excluded those from calculations. For “living people with cards”:
+
- Below 18: {groupingNumber(this.data.livingMalesAgedUnder18WithCardsNumber)} males, {groupingNumber(this.data.livingFemalesAgedUnder18WithCardsNumber)} females
+
- 18 or above, below 30: {groupingNumber(this.data.livingMalesAged18To29WithCardsNumber)} males, {groupingNumber(this.data.livingFemalesAged18To29WithCardsNumber)} females
+
- 30 or above, below 50: {groupingNumber(this.data.livingMalesAged30To49WithCardsNumber)} males, {groupingNumber(this.data.livingFemalesAged30To49WithCardsNumber)} females
+
- Above 50: {groupingNumber(this.data.livingMalesAgedOver49WithCardsNumber)} males, {groupingNumber(this.data.livingFemalesAgedOver49WithCardsNumber)} females
+
+ + ) + } +} + +export const applyForGeneralStatisticsReport = (gui) => { + let dto = {} + dto.name = "" + rest.request(getServiceUri() + 'reports/new-document', 'POST', dto).then(response => { + if (response.status) + showNotification(response.message.split('Detail: ')[1], "error") + else + showNotification(t`Applyed for new General Statistics Report`, "success"); + }) +} \ No newline at end of file diff --git a/src/main/js/GetReady.jsx b/src/main/js/GetReady.jsx new file mode 100644 index 0000000..0b05b48 --- /dev/null +++ b/src/main/js/GetReady.jsx @@ -0,0 +1,23 @@ +import { metadataLoader } from "../../auto/js/metadata" +import { geoMetadataLoader } from "../../auto/js/metadata/GeoMetadataLoader" +import { geoDataMetadataLoader } from "../../auto/js/metadata/GeoDataMetadataLoader" + + +export const loadCountries = async () => { + return metadataLoader.load("country") +} + +export const loadProvinces = async () => { + return metadataLoader.load("province") +} + +export const loadPollingStations = async () => { + return metadataLoader.load("polling-stations") +} + +export const loadLocations = async () => { + return geoMetadataLoader.load(); +} +export const loadGeoData = async () => { + return geoDataMetadataLoader.load(); +} \ No newline at end of file diff --git a/src/main/js/GlobalState.jsx b/src/main/js/GlobalState.jsx new file mode 100644 index 0000000..270d632 --- /dev/null +++ b/src/main/js/GlobalState.jsx @@ -0,0 +1,20 @@ +import { CachedImageLoader } from "../../auto/js/events/CachedImageLoader"; + +class GlobalState { + constructor() { + if (!!GlobalState.instance) { + return GlobalState.instance; + } + + GlobalState.instance = this; + this.avatarImage = new CachedImageLoader("/public/avatar.png"); + return this; + } + + getAvatarImage () { + return this.avatarImage; + } + +} + +export const globalState = new GlobalState(); diff --git a/src/main/js/forms/BirthCertificate.jsx b/src/main/js/forms/BirthCertificate.jsx new file mode 100644 index 0000000..1b73b93 --- /dev/null +++ b/src/main/js/forms/BirthCertificate.jsx @@ -0,0 +1,335 @@ +import * as React from 'react'; +import QRCode from "react-qr-code"; +import {t} from "../../../auto/js/services"; +import {birthCertificateContent} from "../../../main/js/forms/CivilRecordFormCommon"; +import { geoDataMetadataLoader } from '../../../auto/js/metadata/GeoDataMetadataLoader'; + +const formatDate = (date) => { + let d = new Date(date[0], date[1]-1, date[2]); + return d.toLocaleDateString('en-us', { weekday:"long", year:"numeric", month:"short", day:"numeric"}) +} + +const formatTime = (time) => { + if (time !== null) { + let h = (time[0] < 0)? "0" + time[0] : time[0]; + let m = (time[0] < 0)? "0" + time[1] : time[1]; + return h + ":" + m; + } else + return t`Unkown Time` +} + +const formatLocation = (location) => { + let birthPlace = []; + if (location != null) { + let birthPlaceComponents = location.split("."); + let place = location; + birthPlace.push( + (geoDataMetadataLoader.getArea(place))?t(geoDataMetadataLoader.getArea(place).name + " "):t("INVALID DATA ") + ) + for (let i = 0; i < birthPlaceComponents.length - 1 ; i ++) { + let parentAreaId = place.substring(0, place.lastIndexOf(".")); + place = parentAreaId; + birthPlace.push( + (geoDataMetadataLoader.getArea(parentAreaId))?t(geoDataMetadataLoader.getArea(parentAreaId).name + " "):t("INVALID DATA ") + ) + } + } + else + birthPlace.push(

{t`Unknown Birth Place`}

) + return birthPlace; +} + +export class BirthCertificate extends React.Component { + constructor(props) { + super(props); + this.data = props.data; + } + + // @ts-ignore + render() { + let birthdate = this.data.birthdate? formatDate(this.data.birthdate):'Unknown'; + let motherBirthdate = this.data.motherBirthdate? formatDate(this.data.motherBirthdate):'Unknown'; + let fatherBirthdate = this.data.fatherBirthdate? formatDate(this.data.fatherBirthdate):'Unknown'; + let declarantDate = (this.data.timestamp && this.data.timestamp !== null)? formatDate(this.data.timestamp):'Unknown'; + var currentdate = new Date(); + var datetime = currentdate.getDate() + "/" + + (currentdate.getMonth() + 1) + "/" + + currentdate.getFullYear() + " @ " + + currentdate.getHours() + ":" + + currentdate.getMinutes() + ":" + + currentdate.getSeconds(); + let fullname = ''; + fullname += this.data.firstname ? this.data.firstname + ' ' : ''; + fullname += this.data.secondname ? this.data.secondname + ' ' : ''; + fullname += this.data.fourthname ? this.data.fourthname + ' ' : ''; + let declarantFullName = ''; + if (this.data.declarantId != null) { + declarantFullName += this.data.declarantFirstname ? this.data.declarantFirstname + ' ' : ''; + declarantFullName += this.data.declarantSecondname ? this.data.declarantSecondname + ' ' : ''; + declarantFullName += this.data.declarantFourthname ? this.data.declarantFourthname + ' ' : ''; + } + let witness1FullName = ''; + if (this.data.witness1Id != null) { + witness1FullName += this.data.witness1Firstname ? this.data.witness1Firstname + ' ' : ''; + witness1FullName += this.data.witness1Secondname ? this.data.witness1Secondname + ' ' : ''; + witness1FullName += this.data.witness1Fourthname ? this.data.witness1Fourthname + ' ' : ''; + } + let witness2FullName = ''; + if (this.data.witness2Id != null) { + witness2FullName += this.data.witness2Firstname ? this.data.witness2Firstname + ' ' : ''; + witness2FullName += this.data.witness2Secondname ? this.data.witness2Secondname + ' ' : ''; + witness2FullName += this.data.witness2Fourthname ? this.data.witness2Fourthname + ' ' : ''; + } + let childGender = (this.data.gender == 1)?'MALE':'FEMALE'; + if (this.data.motherId == null) { + if (this.data.reportedMotherName != null) { + var names = this.data.reportedMotherName.split(" ") + this.data.motherFirstname = names[0]; + if (names[2]) { + this.data.motherThirdname = names[1]; + this.data.motherFourthname = names[2]; + } + else if (names[1]) + this.data.motherFourthname = names[1] + } + } + if (this.data.fatherId == null) { + if (this.data.reportedFatherName != null) { + var names = this.data.reportedFatherName.split(" ") + this.data.fatherFirstname = names[0]; + if (names[2]) { + this.data.fatherThirdname = names[1]; + this.data.fatherFourthname = names[2]; + } + else if (names[1]) + this.data.fatherFourthname = names[1] + } + } + return ( + +
+
+
+

{birthCertificateContent.leftTitle1}
+ {birthCertificateContent.leftTitle2}

+
+ +
+
+

{birthCertificateContent.rightTitle1}
{birthCertificateContent.rightTitle2}

+
+
+ +
+
+

{birthCertificateContent.mainTitle}

+

{birthCertificateContent.mainSubTitle}

+
+
+

{t`National ID Number`}: {this.data.id}

+
+
+
+
+

{t`Child`}

+
+

{t`Surname`}
+ {t`First Name(s)`}
+ {t`Melanesian Name`}
+ {t`Sex`}
+ {t`National ID Number`}
+

+

+ {t`Date of birth`}
+ {t`Time of birth`}
+ {t`Birth Location`}
+

+ +
+
+

{this.data.fourthname}
+ {this.data.firstname}
+ {this.data.thirdname}
+ {childGender}
+ {this.data.id}
+

+

+ {birthdate}
+ {formatTime(this.data.birthTime)}
+ {formatLocation(this.data.birthPlace)}
+

+

+

+
+
+ +
+

{t`Mother`}

+
+ {(this.data.motherId != null)? + <> +

{t`Surname`}
+ {t`First Name(s)`}
+ {t`Melanesian Name`}
+ {t`National ID Number`}
+

+

+ {t`Date of birth`}
+ {t`Birth Location`}
+ {t`Citizenship`}
+ {t`Parents of mother`}
+

+

+ {t`Occupation`} +

: + <> +

+ {t`Reported Name(s)`}
+

+ } +
+
+ {(this.data.motherId != null)? + <> +

{this.data.motherFourthname}
+ {this.data.motherFirstname}
+ {this.data.motherThirdname}
+ {this.data.motherId}
+

+

+ {motherBirthdate}
+ {formatLocation(this.data.motherBirthPlace)}
+
+ {this.data.grandFatherMotherFirstname} ,{this.data.grandMotherMotherFirstname}
+
+

+

+ +

: + <> +

{this.data.reportedMotherName}
+

+

+ +

} +
+
+
+

{t`Father`}

+
+ {(this.data.fatherId != null)? + <> +

{t`Surname`}
+ {t`First Name(s)`}
+ {t`Melanesian Name`}
+ {t`National ID Number`}
+

+

+ {t`Date of birth`}
+ {t`Birth Location`}
+ {t`Citizenship`}
+ {t`Parents of mother`}
+

+

+ {t`Occupation`} +

: + <> +

+ {t`Reported Name(s)`}
+

+ } +
+
+ {(this.data.fatherId != null)? + <> +

{this.data.fatherFourthname}
+ {this.data.fatherFirstname}
+ {this.data.fatherThirdname}
+ {this.data.fatherId}
+

+

+ {fatherBirthdate}
+ {formatLocation(this.data.fatherBirthPlace)}
+
+ {this.data.grandFatherFatherFirstname} ,{this.data.grandMotherFatherFirstname}
+
+

+

+ +

: + <> +

{this.data.reportedFatherName}
+

+

+ +

} +
+
+
+

{t`Witnesses`}

+
+

{t`Witness 1`}

+

{t`Full Name`}
+ {t`National ID Number`} +

+

{t`Witness 2`}

+

{t`Full Name`}
+ {t`National ID Number`} +

+
+
+

 

+

{witness1FullName}
+ {this.data.witness1Id} +

+

 

+

{witness2FullName}
+ {this.data.witness2Id} +

+
+
+
+

{t`Declaration`}

+ {(this.data.declarantId != null)? + <> +
+

{t`Full Name`}
+ {t`National ID Number`}
+ {t`Date`}
+ {t`Place`}
+

+
+
+

{declarantFullName}
+ {this.data.declarantId}
+ {declarantDate}
+ {formatLocation(this.data.registrationLocation)}
+
+

+

+
+
+

+
+ : +

{t`No Declarant Found`}

} +
+
+
+
+ +
+ {/*
*/} +
+
+

Certified to be a true copy issued without alteration + at

{birthCertificateContent.signedBy}
Registrar General

+ +
+ +
+
+ + ) + } +} \ No newline at end of file diff --git a/src/main/js/forms/CertificateStyleObj.jsx b/src/main/js/forms/CertificateStyleObj.jsx new file mode 100644 index 0000000..cbead50 --- /dev/null +++ b/src/main/js/forms/CertificateStyleObj.jsx @@ -0,0 +1,333 @@ +export const certificateStyle = ` +@charset "UTF-8"; +@import url(https://fonts.cdnfonts.com/css/montserrat); +:root { +--bleed: 0.5cm; +--margin: 1cm; +} + +@page { +size: A4 ; +margin: 0; +} +* { +box-sizing: border-box; +} +* { +-webkit-print-color-adjust: exact !important; /* Chrome, Safari 6 – 15.3, Edge */ +color-adjust: exact !important; /* Firefox 48 – 96 */ +print-color-adjust: exact !important; /* Firefox 97+, Safari 15.4+ */ +} + +body { +margin: 0 auto !important; +padding: 0 !important; +background: rgb(204, 204, 204); +--bleed: 0mm; +--margin: 10mm; + +} +.page { +display: inline-block; +position: relative; +height: 206mm; +width: 297mm; +font-size: 12pt; +margin: 10mm auto; +padding: calc(var(--bleed) + var(--margin)); +box-shadow: 0 0 0.5cm rgba(0, 0, 0, 0.5); +background: white; +font-family: montserrat; +} +h1 { +font-size: 15pt !important; +font-weight: bold !important; +text-align: center; +margin: 0mm; +position: relative; +bottom: 4mm; +} +h2 { +font-size:9pt !important; +font-weight:bold !important; +} +.header h1 { + color:#fff; +} +h2 { + /*color:#04a6e1; */ + color:#fff; +} +h2.idnumber1 { + color:#fff; +} +.headercol5 h2 { + color:#fff; +} + +.header { + background-color: #004a98; +} +.headercol5 h2 { +text-align: center; +margin-top: 0mm; +position: relative; +top:-4mm; +} +.headercol5 h1 { +text-align: center; +padding-bottom: 0mm !important; +} +h3 { +font-size:0.95em !important; +font-weight:bold !important; +margin: 0 !important; +} + +p { +font-size:8pt; +font-weight:normal; +line-height: 13pt; +} +p.bottom { +margin-top: 0mm !important; +} +.lefttext { +text-align: left; +} +.righttext { +text-align: right; +} +.idnumber1 { +margin: 0mm; +position: relative; +bottom: -2mm; +font-size:8pt; +font-weight:normal; +line-height: 13pt; +} + +.pattern { +margin: 10mm calc(-1mm - var(--margin)); +} + +.header { +margin: calc(0mm - var(--margin))!important; +/*position: relative; +top: -6mm !important;*/ +padding: 4mm 10mm; +border-bottom: 0.75mm solid #000000; +display: flex; +flex-direction:row; +flex-wrap: wrap; +height:65mm; +} +.header::after { +position: absolute; +content: ''; +top: 65mm; +left: 0; +width: 100%; +height: 10mm; +margin: 0; +pointer-events: none; +z-index: 9999; +background-image: url(https://rv5.gov.vu/public/birth-certificate-pattern.svg); +background-repeat: no-repeat; +} +.headercol1 { +height:90%; +margin:0mm 10mm 0mm 0mm; +flex-basis: 75mm; +} + +.headercol2 { +margin:0mm; +flex-basis: 107mm; +} +.headercol3 { +margin:0mm 0mm 0mm 10mm ; +height:90%; +flex-basis: 75mm; +} +.headercol4 { +height:10%; +margin:0mm 10mm 0mm 0mm; +flex-basis: 75mm; +} +.headercol5 { +margin:0mm; +flex-basis: 107mm; +height:10%; +} +.headercol6 { +margin:0mm 0mm 0mm 10mm ; +height:10%; +flex-basis: 75mm; +} + +.logos { +background-image: url(https://rv5.gov.vu/public/logos.png); +background-repeat: no-repeat; +background-size: contain; +margin:-2mm auto; +text-aligh:center; +background-position:bottom 50%; +height:49mm !important; +} +.clear {clear:both;} +.bodycontent { +margin-top: 25mm; +display: flex; +flex-wrap: wrap; +} +.bodycol1 { +height:80mm; +margin:0mm 10mm 0mm 0mm; +flex-basis: 87.333mm; +} + +.bodycol2 { +height:80mm; +margin:0mm; +flex-basis: 87.333mm; +} +.bodycol3 { +height:80mm; +margin:0mm 0mm 0mm 10mm ; +flex-basis: 82.333mm; +} +.bodycol4 { +height:41mm; +margin:0mm 10mm 0mm 0mm; +flex-basis: 87.333mm; +} +.bodycol5 { +height:41mm; +margin:0mm; +flex-basis: 87.333mm; +} +.bodycol6 { +height:41mm; +margin:0mm 0mm 0mm 10mm ; +flex-basis: 82.333mm; +} +.nestedcol1 { +width:36%; +height:85%; +margin: 0 2% 10mm 0; +/*background-color: #999999;*/ +float:left; +font-weight: bold; +} +.nestedcol1 p{ +font-weight: bold; +font-size:8pt; +line-height: 13pt; +} +.nestedcol2 p{ +font-weight: normal; +font-size:8pt; +line-height: 13pt; +} +.nestedcol1 p:first-child, .nestedcol2 p:first-child{ +margin-top:0mm !important; +} +.nestedcol2 { +width:62%; +height:85%; +margin: 0 0 10mm 0; +/*background-color: #313131;*/ +float:left; +} +.official { +/*postion: relative;*/ +display: flex; +height:25mm; +} +.qr-code { +postion: relative; +top:0mm; +left:0mm; +width: 22mm; +height:22mm; +margin-bottom:2mm; +} +.stamp { +position: relative; +top:-8mm; +left:20mm; +width: 32mm; +height:32mm; +margin-bottom:2mm; +background-image:url(https://rv5.gov.vu/public/offical-approved-stamp.svg); +background-size: contain; +} +.signature { +position: absolute; +z-index:9999; +bottom:30mm; +right:30mm; +width: 32mm; +height:15mm; +margin-bottom:2mm; +background-image:url(https://rv5.gov.vu/public/signature-temp.png); +background-size: contain; +background-repeat: no-repeat; +} +.strongstyle{ +margin-top:1.5mm !important; +line-height:10pt; +font-size: 8pt; +font-weight: normal; +} + +@media screen { + .page::after { + position: absolute; + content: ''; + top: 0; + left: 0; + width: calc(100% - var(--bleed) * 2); + height: calc(100% - var(--bleed) * 2); + margin: var(--bleed); + outline: thin dashed black; + pointer-events: none; + z-index: 9999; + } + } + + @media print { + .page { + margin: 0; + overflow: hidden; + size: A4 landscape; + box-shadow: 0 0 0cm rgba(0, 0, 0, 0); + } + @page { + size: A4 landscape; + margin: 0; + } + html, body { + height: 100vh; + overflow: hidden; + } + body { + /*transform: rotate(90deg);*/ + margin: 0; + } + + html { + margin: 0; + } + + * { + -webkit-print-color-adjust: exact !important; /* Chrome, Safari 6 – 15.3, Edge */ + color-adjust: exact !important; /* Firefox 48 – 96 */ + print-color-adjust: exact !important; /* Firefox 97+, Safari 15.4+ */ + /*overflow: hidden!important;*/ + } + +}`; + + diff --git a/src/main/js/forms/CivilRecordAdminInfo.jsx b/src/main/js/forms/CivilRecordAdminInfo.jsx new file mode 100644 index 0000000..be7af47 --- /dev/null +++ b/src/main/js/forms/CivilRecordAdminInfo.jsx @@ -0,0 +1,234 @@ +import React from "react"; +import {v4 as uuidv4} from 'uuid'; +import { createFormComponent } from '../../../auto/js/widgets/FormComponent'; +import { CAN_I_SWITCH } from '../../../auto/js/events/Gui'; +import { rest } from "../../../auto/js/services/RestClient"; +import { t } from "../../../auto/js/services/i18ndb"; +import { AlertDialog } from "../../../auto/js/widgets"; +import { pojoMetadata } from "../../../auto/js/metadata"; +import { Accordion, AccordionDetails, AccordionSummary, Typography } from "@mui/material"; +import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; +import { createTableComponent } from "../../../auto/js/widgets/TableComponent"; + +import { addressFields, countAddressData, filterData, form2Dto, getAddressData, loadGeoData } from "../../../auto/js/lists/AddressList"; +import { emailFields, getEmailData, countEmailData } from "../../../auto/js/lists/EmailList"; +import { phoneNumberFields, getPhoneData, countPhoneData } from "../../../auto/js/lists/PhoneNumberList"; +import { EMAIL_ORDER_BY_EMAIL } from "../../../auto/js/metadata/EmailOrderBy"; +import { PHONE_NUMBER_ORDER_BY_PHONE_NUMBER } from "../../../auto/js/metadata/PhoneNumberOrderBy"; + +export class AdministrativeUpdateApplicationFormComponent extends React.Component { + constructor(props) { + super(props); + } + + render() { + let AddressList = createTableComponent(addressFields); + let EmailList = createTableComponent(emailFields); + let PhoneNumberList = createTableComponent(phoneNumberFields); + + return ( + <> + {(this.props.onFinish) && } + + } + aria-controls="panel1a-content" + id="panel1a-header" + > + {t`Address`} + + + buildAddressData(query, this.props.id)} editable={getAddressEditables(this.props.id)}/> + + + + } + aria-controls="panel1a-content" + id="panel1a-header" + > + {t`Email`} + + + buildEmailData(query, this.props.id)} editable={getEmailEditables(this.props.id)}/> + + + + } + aria-controls="panel1a-content" + id="panel1a-header" + > + {t`PhoneNumber`} + + + buildPhoneNumberData(query, this.props.id)} editable={getPhoneNumberEditables(this.props.id)}/> + + + + ) + } + +} + + +export const readCivilRecordAdminInfo = (onFinish) => (id) => { + let uuid = uuidv4(); + return { + uuid, view: () => + } +} + +export const displayCivilRecordAdminInfo = (gui, id) => { + gui.goTo(readCivilRecordAdminInfo(), id) +} + +const buildAddressData = async (query, id) => { + let filter = query; + let data; + filter["address"] = {vitalRecordId: id}; + filter["orderBy"] = null; + filter.orderDirection = null; + filter.offset = query.page * query.pageSize; + if (query.search && query.search!='') { + pojoMetadata["address"].columns.forEach(element => { + if(element.type=='text'){ + filter["address"][element.key]= query.search; + } + }); + filter["and"] = false; + } + return await getAddressData(filter).then(response => { + data = filterData(response); + data.forEach(element => { + loadGeoData(element); + }); + return countAddressData(filter).then((count) => {return {data: data, totalCount: count, page: query.page}}) + }); +} + +const getAddressEditables = (id) => { + let editables = {} + editables.onRowAdd = newData => + new Promise((resolve, reject) => { + + let dto = pojoMetadata['address'].form2dto(newData); + dto["vitalRecordId"] = id; + form2Dto(dto, newData); + try { + return rest.create('address', dto).then(() => resolve()); + } catch (err) { + alert(err); + } + }), + editables.onRowUpdate = (newData, oldData) => + new Promise((resolve, reject) => { + let dto = pojoMetadata['address'].form2dto(newData); + newData.id = oldData.id; + form2Dto(dto, newData); + try { + return rest.update('address', dto).then(() => { + resolve()}).catch((e) => console.table(e)) + + } catch (err) { + alert(err); + } + }), + editables.onRowDelete = oldData => + new Promise((resolve, reject) => { + try { + return rest.purge('address', oldData.id).then(() => resolve()); + } catch (err) { + alert(err); + } + }) + return editables; +} + +export const buildEmailData = async (query, id) => { + let filter = query; + let data; + filter["email"] = {vitalRecordId: id}; + filter["orderBy"] = EMAIL_ORDER_BY_EMAIL; + filter.orderDirection = null; + filter.offset = query.page * query.pageSize; + if (query.search && query.search!='') { + pojoMetadata["email"].columns.forEach(element => { + if(element.type=='text'){ + filter["email"][element.key]= query.search; + } + }); + filter["and"] = false; + } + return await getEmailData(filter).then(response => { + data = response; + return countEmailData(filter).then((count) => {return {data: data, totalCount: count, page: query.page}}) + }); +} + +const buildPhoneNumberData = async (query, id) => { + let filter = query; + let data; + filter["phone-number"] = {vitalRecordId: id}; + filter["orderBy"] = PHONE_NUMBER_ORDER_BY_PHONE_NUMBER; + filter.orderDirection = null; + filter.offset = query.page * query.pageSize; + if (query.search && query.search!='') { + pojoMetadata["phone-number"].columns.forEach(element => { + if(element.type=='text'){ + filter["phone-number"][element.key]= query.search; + } + }); + filter["and"] = false; + } + return await getPhoneData(filter).then(response => { + data = response; + return countPhoneData(filter).then((count) => {return {data: data, totalCount: count, page: query.page}}) + }); +} + +const getEmailEditables = (id) => { + let editables = {} + editables.onRowAdd = newData => + new Promise((resolve, reject) => { + let dto = pojoMetadata['email'].form2dto(newData); + dto["vitalRecordId"] = id; + try { + return rest.create('email', dto).then(() => resolve()); + } catch (err) { + alert(err); + } + }) + editables.onRowDelete = oldData => + new Promise((resolve, reject) => { + try { + return rest.purge('email', oldData.id).then(() => resolve()); + } catch (err) { + alert(err); + } + }) + return editables; +} + +const getPhoneNumberEditables = (id) => { + let editables = {} + editables.onRowAdd = newData => + new Promise((resolve, reject) => { + let dto = pojoMetadata['phone-number'].form2dto(newData); + dto["vitalRecordId"] = id; + try { + return rest.create('phone-number', dto).then(() => resolve()); + } catch (err) { + alert(err); + } + }) + editables.onRowDelete = oldData => + new Promise((resolve, reject) => { + try { + return rest.purge('phone-number', oldData.id).then(() => resolve()); + } catch (err) { + alert(err); + } + }) + return editables; +} \ No newline at end of file diff --git a/src/main/js/forms/CivilRecordAdvancedSearch.jsx b/src/main/js/forms/CivilRecordAdvancedSearch.jsx new file mode 100644 index 0000000..b3ac203 --- /dev/null +++ b/src/main/js/forms/CivilRecordAdvancedSearch.jsx @@ -0,0 +1,40 @@ +/* import React, { useState } from "react" +import {v4 as uuidv4} from 'uuid'; +import { SearchComponent } from "../../../auto/js/widgets" +import { t } from "../../../auto/js/services" +import { displayCivilRecordsList } from "../../../auto/js/lists/CivilRecordList" +import { OPEN_VIEW_EVENT } from "../../../auto/js/events/Gui"; +import { FormLabel } from "@mui/material"; +import SearchBar from "material-ui-search-bar"; + +const SearchPage = () => { + const [id, setId] = useState(""); + + const onChange = (id) => { + setId(id); + } + const onRequestSearch = () => { + if (id != null && id != "") { + let filter = {}; + filter['vital-record'] = {id: id}; + displayCivilRecordsList(filter); + } + } + + return ( + <> + {t`Search By ID`} + + + ) +} + +export const displayCivilRecordAdvancedSearch = () => { + let uuid = uuidv4(); + OPEN_VIEW_EVENT.publish({ + uuid, view: () => + }); +} */ diff --git a/src/main/js/forms/CivilRecordBiometricData.jsx b/src/main/js/forms/CivilRecordBiometricData.jsx new file mode 100644 index 0000000..f495979 --- /dev/null +++ b/src/main/js/forms/CivilRecordBiometricData.jsx @@ -0,0 +1,96 @@ +import React from "react"; +import {v4 as uuidv4} from 'uuid'; +import { createFormComponent } from '../../../auto/js/widgets/FormComponent'; +import { rest } from "../../../auto/js/services/RestClient"; +import { getServiceUri, pojoMetadata } from "../../../auto/js/metadata"; + + + +const fingerprintsFields = [ + {name: "leftThumbImage", type:"view", x:1, y:1, layout:"col-md-6"}, + {name: "leftIndexFingerImage", type:"view", x:2, y:1, layout:"col-md-6"}, + {name: "leftMiddleFingerImage", type:"view", x:1, y:2, layout:"col-md-6"}, + {name: "leftRingFingerImage", type:"view", x:2, y:2, layout:"col-md-6"}, + {name: "leftPinkyImage", type:"view", x:1, y:19, layout:"col-md-6"}, + {name: "rightThumbImage", type:"view", x:2, y:19, layout:"col-md-6"}, + {name: "rightIndexFingerImage", type:"view", x:1, y:20, layout:"col-md-6"}, + {name: "rightMiddleFingerImage", type:"view", x:2, y:20, layout:"col-md-6"}, + {name: "rightRingFingerImage", type:"view", x:1, y:21, layout:"col-md-6"}, + {name: "rightPinkyImage", type:"view", x:2, y:21, layout:"col-md-6"} +]; + +export class BiometricDataComponent extends React.Component { + constructor(props) { + super(props); + } + render() { + let CivilRecordFingerprintsForm = createFormComponent(fingerprintsFields); + return ( + <> + loadFormData(this.props.id)} buttons={() => null}/> + + ) + } + +} + + +export const displayCivilRecordBiometricData = (gui, id) => { + const readCivilRecordBiometricData = (onFinish) => (id) => { + let uuid = uuidv4(); + return { + uuid, view: () => + } + } + gui.goTo(readCivilRecordBiometricData(), id) +} + +const loadFormData = async (id) => { + let filter = {}; + let data; + filter["fingerprints"] = {vitalRecordId: id}; + filter["orderBy"] = null; + filter.orderDirection = null; + filter.offset = null; + return await getData(filter).then(response => { + if (response.length) + return loadFingerprint(response[response.length - 1].id) + else + return loadEmptyFingerprint(); + }); +} + +const getData = async (filter) => { + return rest.search('fingerprints', filter) +} + +const loadFingerprint = async (id) => { + let token = await rest.getToken(getServiceUri() + 'token/get-auth-code'); + let form = {}; + form['leftThumbImage'] = {x: 0.5, y:0.5, scale: 1, rotate: 0, url: getServiceUri() + 'fingerprints/' + 'left-thumb/' + id + '/' + token, isEmpty: true, width:70, height:70} + form['leftIndexFingerImage'] = {x: 0.5, y:0.5, scale: 1, rotate: 0, url: getServiceUri() + 'fingerprints/' + 'left-index-finger/' + id + '/' + token, isEmpty: true, width:70, height:70} + form['leftMiddleFingerImage'] = {x: 0.5, y:0.5, scale: 1, rotate: 0, url: getServiceUri() + 'fingerprints/' + 'left-middle-finger/' + id + '/' + token, isEmpty: true, width:70, height:70} + form['leftRingFingerImage'] = {x: 0.5, y:0.5, scale: 1, rotate: 0, url: getServiceUri() + 'fingerprints/' + 'left-ring-finger/' + id + '/' + token, isEmpty: true, width:70, height:70} + form['leftPinkyImage'] = {x: 0.5, y:0.5, scale: 1, rotate: 0, url: getServiceUri() + 'fingerprints/' + 'left-pinky/' + id + '/' + token, isEmpty: true, width:70, height:70} + form['rightThumbImage'] = {x: 0.5, y:0.5, scale: 1, rotate: 0, url: getServiceUri() + 'fingerprints/' + 'right-thumb/' + id + '/' + token, isEmpty: true, width:70, height:70} + form['rightIndexFingerImage'] = {x: 0.5, y:0.5, scale: 1, rotate: 0, url: getServiceUri() + 'fingerprints/' + 'right-index-finger/' + id + '/' + token, isEmpty: true, width:70, height:70} + form['rightMiddleFingerImage'] = {x: 0.5, y:0.5, scale: 1, rotate: 0, url: getServiceUri() + 'fingerprints/' + 'right-middle-finger/' + id + '/' + token, isEmpty: true, width:70, height:70} + form['rightRingFingerImage'] = {x: 0.5, y:0.5, scale: 1, rotate: 0, url: getServiceUri() + 'fingerprints/' + 'right-ring-finger/' + id + '/' + token, isEmpty: true, width:70, height:70} + form['rightPinkyImage'] = {x: 0.5, y:0.5, scale: 1, rotate: 0, url: getServiceUri() + 'fingerprints/' + 'right-pinky/' + id + '/' + token, isEmpty: true, width:70, height:70} + return form; +} + +const loadEmptyFingerprint = async () => { + let form = {}; + form['leftThumbImage'] = {x: 0.5, y:0.5, scale: 1, rotate: 0, url: 'public/finger-not-found.png', isEmpty: true, width:70, height:70} + form['leftIndexFingerImage'] = {x: 0.5, y:0.5, scale: 1, rotate: 0, url: 'public/finger-not-found.png', isEmpty: true, width:70, height:70} + form['leftMiddleFingerImage'] = {x: 0.5, y:0.5, scale: 1, rotate: 0, url: 'public/finger-not-found.png', isEmpty: true, width:70, height:70} + form['leftRingFingerImage'] = {x: 0.5, y:0.5, scale: 1, rotate: 0, url: 'public/finger-not-found.png', isEmpty: true, width:70, height:70} + form['leftPinkyImage'] = {x: 0.5, y:0.5, scale: 1, rotate: 0, url: 'public/finger-not-found.png', isEmpty: true, width:70, height:70} + form['rightThumbImage'] = {x: 0.5, y:0.5, scale: 1, rotate: 0, url: 'public/finger-not-found.png', isEmpty: true, width:70, height:70} + form['rightIndexFingerImage'] = {x: 0.5, y:0.5, scale: 1, rotate: 0, url: 'public/finger-not-found.png', isEmpty: true, width:70, height:70} + form['rightMiddleFingerImage'] = {x: 0.5, y:0.5, scale: 1, rotate: 0, url: 'public/finger-not-found.png', isEmpty: true, width:70, height:70} + form['rightRingFingerImage'] = {x: 0.5, y:0.5, scale: 1, rotate: 0, url: 'public/finger-not-found.png', isEmpty: true, width:70, height:70} + form['rightPinkyImage'] = {x: 0.5, y:0.5, scale: 1, rotate: 0, url: 'public/finger-not-found.png', isEmpty: true, width:70, height:70} + return form; +} diff --git a/src/main/js/forms/CivilRecordFormCommon.jsx b/src/main/js/forms/CivilRecordFormCommon.jsx new file mode 100644 index 0000000..b831782 --- /dev/null +++ b/src/main/js/forms/CivilRecordFormCommon.jsx @@ -0,0 +1,274 @@ +import React from "react"; + +import * as Yup from 'yup'; + +import '../pages/printable.css'; +import { AddressComponent } from "../../../auto/js/widgets/AddressComponent"; +import { Section } from "../widgets/Section"; +import { PersonComponent } from "../../../auto/js/widgets/PersonComponent"; +import { loadPersonData } from "../utils"; +import { MentionsGrid } from "../../../auto/js/widgets/MentionsGrid"; +import { GeoDataComponent } from "../../../auto/js/widgets/GeoDataComponent"; +import { CountryAutoCompleteInput } from "../widgets/CountryAutoCompleteInput"; +import { geoDataMetadataLoader } from "../../../auto/js/metadata/GeoDataMetadataLoader"; +import AutocompleteListSelector from "../widgets/AutocompleteListSelector"; +import { rest, t } from "../../../auto/js/services"; +import { swapObject } from "../../../auto/js/utils"; +import { TypeOfAcquisition } from "../../../auto/js/metadata/TypeOfAcquisition"; +import { AdvancedSearchPersonComponent } from "../widgets/AdvancedSearchPersonComponent"; +import { getServiceUri } from "../../../auto/js/metadata"; +import { DELETE_ATTACHMENT_EVENT } from "../../../auto/js/events/Gui"; + +const gender = { 1: "MALE", 2: "FEMALE" }; +const maritalStatus = { 1: "SINGLE", 2: "MARRIED", 3: "DIVORCED", 4: "WIDOWED" }; + +export const civilRecordFormfields = [ + + { name: "image", type: "image", x: 1, y: 2, layout: "col-md-12" }, + { name: "tags", type: "tags", x: 1, y: 1, layout: "col-md-12" }, + { name: "id", type: "number", x: 1, y: 3, layout: "col-md-12" }, + { name: "firstname", type: "text", x: 2, y: 5, layout: "col-md-6"}, + { name: "secondname", type: "text", x: 2, y: 4, layout: "col-md-6" }, + { name: "thirdname", type: "text", x: 1, y: 5, layout: "col-md-6" }, + { name: "fourthname", type: "text", x: 1, y: 4, layout: "col-md-6"}, + {name: "fifthname", type: "text", x:1, y: 6, layout:"col-md-12"}, + { name: "gender", type: "select", x: 1, y: 7, layout: "col-md-6", metadata: () => gender }, + { name: "maritalStatus", type: "select", x: 2, y: 7, layout: "col-md-6", metadata: () => maritalStatus }, + {name:"citizenshipBox", label: "Citizenship", components: [ + {name: "primaryCitizenship", type:"custom", x:1, y:1, layout:"col-md-6", component: (name, disabled) => }, + {name: "typeOfAcquisition", type:"select", x:2, y:1, layout:"col-md-6", metadata: () => swapObject(TypeOfAcquisition)}, + {name: "otherCitizenshipCsv", type: "custom", x:1, y:3, layout: "col-md-6", component: (name, disabled) => }, + ], type: "box", x:2, y:8, layout:"col-md-11 ms-2 mt-2 pt-1 pb-2"}, + { name: "birthdate", type: "date", x: 1, y: 11, layout: "col-md-6"}, + {name: "birthTime", type: "time", x:2, y:11, layout:"col-md-6"}, + {name:"birthBox", label: "Birth Place", components: [ + {name: "birthPlace", type: "custom", x:1, y:1, layout:"col-md-12", component: (name, disabled) => } + ], type: "box", x:2, y:12, layout:"col-md-11 ms-2 mt-2 pt-1 pb-2"}, + {name:"originBox", label: "Village Of Origin", components: [ + {name: "villageOfOrigin", type: "custom", x:1, y:1, layout:"col-md-12", component: (name, disabled) => }, + ], type: "box", x:1, y:12, layout:"col-md-11 ms-2 mt-2 pt-1 pb-2"}, + {name: "motherDetails", type: "custom", x:1, y:16, layout:"col-md-12", component: (name, disabled) =>
}, + {name:"motherInfo", options: [ + {"name":"motherWithBirthRecord","label":"motherWithBirthRecord"}, + {"name":"motherWithoutBirthRecord","label":"motherWithoutBirthRecord"}, + {"name":"unknownMother","label":"unknownMother"}, + ], type: "radio", x:1, y:17, layout:"col-md-12 pt-4"}, + {name: "motherId", label: "Search Mother", type: "custom", x:1, y:17, layout:"col-md-12", + component: (name, disabled) => , + display: (data) => {return (data.motherInfo === "motherWithBirthRecord" || data.motherId != null)?true: false;}}, + {name: "reportedMotherName", type: "text", x:2, y:17, layout:"col-md-12", + display: (data) => {return data.motherInfo === "motherWithoutBirthRecord"?true: false;} + }, + {name: "fatherDetails", type: "custom", x:1, y:18, layout:"col-md-12", component: (name, disabled) =>
}, + {name:"fatherInfo", options: [ + {"name":"fatherWithBirthRecord","label":"fatherWithBirthRecord"}, + {"name":"fatherWithoutBirthRecord","label":"fatherWithoutBirthRecord"}, + {"name":"unknownFather","label":"unknownFather"}, + ], type: "radio", x:1, y:20, layout:"col-md-12 pt-4"}, + {name: "fatherId", label: "Search Father", type: "custom", x:1, y:21, layout:"col-md-12", + component: (name, disabled) => , + display: (data) => {return (data.fatherInfo === "fatherWithBirthRecord" || data.fatherId != null)?true: false;}}, + {name: "reportedFatherName", type: "text", x:2, y:22, layout:"col-md-12", + display: (data) => {return data.fatherInfo === "fatherWithoutBirthRecord"?true: false;} + }, + {name: "adoptionDetails", type: "custom", x:1, y:23, layout:"col-md-12", component: (name, disabled) =>
, + display: (data) => {return (data.adoptiveMotherId !== null || data.adoptiveFatherId !== null)} + }, + {name: "adoptiveMotherId", label: "Search Adoptive Mother", type: "custom", x:1, y:24, layout:"col-md-12", + component: (name, disabled) => , + display: (data) => {return data.adoptiveMotherId !== null} + }, + {name: "adoptiveFatherId", label: "Search Adoptive Father", type: "custom", x:1, y:25, layout:"col-md-12", + component: (name, disabled) => , + display: (data) => {return data.adoptiveFatherId !== null} + }, + {name: "medicalNotificationFile", label:"Medical Notification", type: "file", x:1, y:25, layout:"col-md-12", + uploadUrl: (id) => getUploadUrl(id), + previewUrl: (id) => getPreviewUrl(id), + loadData: async (id) => loadMedicalNotificationAttachment(id), + handleDelete:(id) => handleMedicalNotificationDelete(id), + handleClick: (id) => handleMedicalNotificationClick(id), + updateFileData: (data) => updateFileData(data) + }, + {name: "Mentions", type: "custom", x:1, y:28, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "mentions", type: "text", x:1, y:29, layout:"col-md-12"}, + {name: "Extras", type: "custom", x:1, y:33, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "notes", type: "text", x:1, y:34, layout:"col-md-12"} +]; + +const getUploadUrl = (id) => { + return getServiceUri() + 'vital-record/medical-notification-file' + '/' + id; +} + +const getPreviewUrl = (id) => { + return getServiceUri() + 'vital-record/medical-notification-file' + '/preview/' + id; +} + +const updateFileData = (data) => { + let filter = {name: data.fileName, description: data.description}; + rest.request(getServiceUri() + 'vital-record/medical-notification-file' + '/' + data.id, "PUT", filter); +} + +const handleMedicalNotificationClick = async (id) => { + const token = await rest.getToken(getServiceUri() + 'token/get-auth-code'); + window.location = getServiceUri() + 'vital-record/medical-notification-file' + '/' + id + '/' + token; +}; + +const handleMedicalNotificationDelete = (id) => { + rest.delete('vital-record/medical-notification-file', id).then(() => { + DELETE_ATTACHMENT_EVENT.publish(id) + }); +}; + +const loadMedicalNotificationAttachment = async (id) => { + let filter = {and: true}; + filter['vital-record-medical-notification-file'] = {}; + filter['vital-record-medical-notification-file']['vitalRecordId'] = id; + return rest.search('vital-record/medical-notification-file', filter) +} + + +export const birthCertificateContent = + + { leftTitle1: "Gouvernement de République de Vanuatu", + leftTitle2: "Enrégistrement Civil et Gestion d’Identité", + rightTitle1: "Government of the Republic of Vanuatu", + rightTitle2: "Civil Registration and Identity Management", + mainTitle: "Vanuatu Birth Registration Certificate", + mainSubTitle: "(Civil Registration and Identity Management Act - 28/2021)", + signedBy: "Jeffrey Tila Langati Trief" }; + +export const parentsSearchFormfields = [ + {name: "exactId", type: "number", x:1, y: 1, layout:"col-md-4"}, + {name: "idSeparator", type: "custom", x:1, y:2, layout:"col-md-12", component: (name, disabled) => }, + { name: "caseSensitiveSearch", label: "Case Sensitive Search", type: "checkbox", x: 1, y: 3, layout: "col-md-3" }, + + {name: "firstname", type: "text", x:1, y:7, layout:"col-md-6"}, + {name:"firstnameCondition", options: [ + {"name":"fuzzy","label":"Fuzzy"}, + {"name":"exact","label":"Exact"}, + {"name":"startsWith","label":"Startswith"}, + ], type: "radio", x:2, y:7, layout:"col-md-6 pt-5", defaultValue:"startsWith"}, + + {name: "secondname", type: "text", x:1, y:5, layout:"col-md-6"}, + {name:"secondnameCondition", options: [ + {"name":"fuzzy","label":"Fuzzy"}, + {"name":"exact","label":"Exact"}, + {"name":"startsWith","label":"Startswith"}, + ], type: "radio", x:2, y:5, layout:"col-md-6 pt-5", defaultValue:"startsWith"}, + + {name: "thirdname", type: "text", x:1, y: 6, layout:"col-md-6"}, + {name:"thirdnameCondition", options: [ + {"name":"fuzzy","label":"Fuzzy"}, + {"name":"exact","label":"Exact"}, + {"name":"startsWith","label":"Startswith"}, + ], type: "radio", x:2, y:6, layout:"col-md-6 pt-5",defaultValue:"startsWith"}, + + {name: "fourthname", type: "text", x:1, y: 4, layout:"col-md-6",defaultValue:"startsWith"}, + {name:"fourthnameCondition", options: [ + {"name":"fuzzy","label":"Fuzzy"}, + {"name":"exact","label":"Exact"}, + {"name":"startsWith","label":"Startswith"}, + ], type: "radio", x:2, y:4, layout:"col-md-6 pt-5",defaultValue:"startsWith"}, + + {name:"genderBox", label: "Gender", components: [ + {name: "male",label:"Male", type: "checkbox", x:1, y:1, layout:"col-md-3"}, + {name: "female",label:"Female", type: "checkbox", x:2, y:1, layout:"col-md-3"}, + ], type: "box", x:3, y:8, layout:"col-md-11 ms-2 mt-2"},//mx-auto + {name:"birthBox", label: "Birth Date", components: [ + {name: "rangeBirthdate",label:"exactbirthdate", type: "checkbox", x:1, y:1, layout:"col-md-12"}, + {name: "exactBirthdate", type: "date", x:1, y: 2, layout:"col-md-6", display: (data)=>{ + return !data.rangeBirthdate; + }}, + + {name: "birthdateStart", type: "date", x:1, y: 3, layout:"col-md-6",display: (data)=>{ + return data.rangeBirthdate; + }}, + {name: "birthdateEnd", type: "date", x:2, y: 3, layout:"col-md-6", display: (data)=>{ + return data.rangeBirthdate; + }}, + ], type: "box", x:1, y:9, layout:"col-md-11 ms-2 mt-2 pt-1 pb-2"}, + + {name:"birthBox", label: "Birth Place", components: [ + {name: "anyBornOutsideCountry", label:"anyBornOutsideCountry", type: "checkbox", x:1, y:1, layout:"col-md-12"}, + {name: "birthPlace", type: "custom", x:1, y:2, layout:"col-md-6", + component: (name, disabled) => , + display: (data) => {return !data.anyBornOutsideCountry} + }, + ], type: "box", x:2, y:10, layout:"col-md-11 ms-2 mt-2 pt-1 pb-2"} +]; + +export const birthRecordColumns = [ + {title:"image", field:"image", render: rowData => {e.target.onerror = null; e.target.src="/public/avatar.png"}} style={{width: 40, borderRadius: '50%', height: 40}}/>}, + {title: "id", field: "id"}, + {title: "fourthname", field: "fourthname"}, + {title: "secondname", field: "secondname"}, + {title: "thirdname", field: "thirdname"}, + {title: "firstname", field: "firstname"}, + {title: "birthdate", field: "birthdate"}, + ]; + + export const Separator = () => { + return ( + <> +
+
+
+ + ); + }; +export const LabelSeparator = ({name}) => { +return ( + <> +

{name}

+ +); +}; + +export const transformFormData = (formData) => { + const columns = []; + + const addColumn = (name, type, value, condition) => { + columns.push({ + name, + type, + [type === 'date' ? 'dateValue' : (type === 'text' ? 'textValue' : 'longValue')]: value, + searchType: condition ? condition : null, + }); + }; + (formData.firstname !== "") && addColumn('firstname', 'text', formData.firstname, formData.firstnameCondition); + + (formData.secondname !== "") && addColumn('secondname', 'text', formData.secondname, formData.secondnameCondition); + + (formData.thirdname !== "") && addColumn('thirdname', 'text', formData.thirdname, formData.thirdnameCondition); + + (formData.fourthname !== "") && addColumn('fourthname', 'text', formData.fourthname, formData.fourthnameCondition); + + (formData.exactId !== "") && addColumn('id', 'number', formData.exactId, null); + if (formData.anyBornOutsideCountry) + addColumn('birthPlace', 'text', '191', 'notStartsWith'); + else + (formData.birthPlace) && addColumn('birthPlace', 'text', formData.birthPlace,formData.birthPlace? "startsWith" : null); + const birthdateRange = formData.birthdateStart && formData.birthdateEnd + ? { + min: formData.birthdateStart ? formData.birthdateStart : null, + max: formData.birthdateEnd ? formData.birthdateEnd : null, + } + : null; + + (birthdateRange != null || formData.exactBirthdate != null) && addColumn('birthdate', 'date', formData.exactBirthdate, null); + if ((birthdateRange != null || formData.exactBirthdate != null)) + columns[columns.length - 1].dateRange = birthdateRange; + + const gender = []; + formData.male ? gender.push("1") : null; + formData.female ? gender.push("2") : null; + if (gender.length) + columns.push({ + name: 'gender', + type: 'enum', + enumValues: gender, + }); + + return { columns, caseSensitiveSearch: formData.caseSensitiveSearch }; +}; diff --git a/src/main/js/forms/CivilRecordHistoryCommon.jsx b/src/main/js/forms/CivilRecordHistoryCommon.jsx new file mode 100644 index 0000000..9a31213 --- /dev/null +++ b/src/main/js/forms/CivilRecordHistoryCommon.jsx @@ -0,0 +1,57 @@ +import React from "react"; + +import { rest } from "../../../auto/js/services"; +import { showNotification, swapObject } from "../../../auto/js/utils"; +import { TypeOfAcquisition } from "../../../auto/js/metadata/TypeOfAcquisition"; +import { getServiceUri } from "../../../auto/js/metadata"; + +export const loadHistoryFormData = async (id) => { + let token = await rest.getToken(getServiceUri() + 'token/get-auth-code'); + return await rest.read('vital-record-history', id).then(async response => { + let form = response; + if (response.faceId != null) { + const imageUrl = getServiceUri() + 'face/image/' + response.faceId + "/" + token; + form['image'] = { x: 0.5, y: 0.5, scale: 1, rotate: 0, url: (imageUrl != null) ? imageUrl : '/public/avatar.png', isEmpty: false }; + } else + form['image'] = { x: 0.5, y: 0.5, scale: 1, rotate: 0, url: '/public/avatar.png', isEmpty: true }; + + if (response.otherCitizenshipCsv == null || response.otherCitizenshipCsv === "") + form.otherCitizenshipCsv = [] + else { + let values = []; + let components = response.otherCitizenshipCsv.split(","); + components.forEach(element => { + values.push(parseInt(element)) + }); + form.otherCitizenshipCsv = values; + } + if (response.typeOfAcquisition != null) + form.typeOfAcquisition = TypeOfAcquisition[response.typeOfAcquisition] + if (response.motherId == null) { + if (response.reportedMotherName != null) + form.motherInfo = "motherWithoutBirthRecord" + else if (response.unknownMother != null && response.unknownMother) + form.motherInfo = "unknownMother" + else + form.motherInfo = "motherWithoutBirthRecord" + } else + form.motherInfo = "motherWithBirthRecord" + + if (response.fatherId == null) { + if (response.reportedFatherName != null) + form.fatherInfo = "fatherWithoutBirthRecord" + else if (response.unknownFather != null && response.unknownFather) + form.fatherInfo = "unknownFather" + else + form.fatherInfo = "fatherWithoutBirthRecord" + } else + form.fatherInfo = "fatherWithBirthRecord" + let tagFilter = { and: true }; + tagFilter['vital-record-tag-history'] = { vitalRecordId: response.id }; + return rest.search('vital-record-tag-history', tagFilter).then(tags => { + form['tags'] = tags + + return form; + }) + }) +} \ No newline at end of file diff --git a/src/main/js/forms/CivilRecordTabsView.jsx b/src/main/js/forms/CivilRecordTabsView.jsx new file mode 100644 index 0000000..b5b5608 --- /dev/null +++ b/src/main/js/forms/CivilRecordTabsView.jsx @@ -0,0 +1,43 @@ +import React, { useState } from 'react'; + +import { v4 as uuidv4 } from 'uuid'; +import { TabBrowser } from '../../../auto/js/browsers/TabBrowser'; +import { t } from '../../../auto/js/services'; +import { displayReadCivilRecordForm } from '../../../auto/js/forms/CivilRecordForm'; +import { displayCivilRecordAdminInfo } from './CivilRecordAdminInfo'; +import { displayCivilRecordBiometricData } from './CivilRecordBiometricData'; + +export const displayCivilRecordTabsView = (gui, id) => { + + class TabsViewComponent extends TabBrowser { + constructor(props) { + super(props) + this.tabs = { + "civilRecordForm" : { + title: t`Civil Record`, + description: t`Civil Record Form`, + do: () => displayReadCivilRecordForm(id, this) + }, + "civilRecordAdminInfo" : { + title: t`Aministrative Information`, + description: t`Civil Record Aministrative Information`, + do: () => displayCivilRecordAdminInfo(this, id) + }, + "civilRecordBiometricData" : { + title: t`Biometric Data`, + description: t`Civil Record Biometric Data`, + do: () => displayCivilRecordBiometricData(this, id) + } + } + displayReadCivilRecordForm(id, this) + } + } + + const createRetornadosTabView = () => { + let uuid = uuidv4(); + return { + uuid, view: () => <>} /> + } + } + gui.goTo(createRetornadosTabView, null, null); +} \ No newline at end of file diff --git a/src/main/js/forms/DeathCertificate.jsx b/src/main/js/forms/DeathCertificate.jsx new file mode 100644 index 0000000..1e274f7 --- /dev/null +++ b/src/main/js/forms/DeathCertificate.jsx @@ -0,0 +1,255 @@ +import * as React from 'react'; +import QRCode from "react-qr-code"; +import {deathCertificateContent} from "./DeathRecordFormCommon.jsx"; +import { geoDataMetadataLoader } from '../../../auto/js/metadata/GeoDataMetadataLoader'; +import { t } from '../../../auto/js/services'; + +const formatDate = (date) => { + if (date != null) { + let d = new Date(date[0], date[1]-1, date[2]); + return d.toLocaleDateString('en-us', { weekday:"long", year:"numeric", month:"short", day:"numeric"}); + } else + return t`Unknown`; +} + +const formatTime = (time) => { + if (time !== null) { + let h = (time[0] < 0)? "0" + time[0] : time[0]; + let m = (time[0] < 0)? "0" + time[1] : time[1]; + return h + ":" + m; + } else + return t`Unkown Time` +} + +const formatLocation = (location) => { + let birthPlace = []; + if (location != null) { + let birthPlaceComponents = location.split("."); + let place = location; + birthPlace.push( + (geoDataMetadataLoader.getArea(place))?t(geoDataMetadataLoader.getArea(place).name + " "):t("INVALID DATA ") + ) + for (let i = 0; i < birthPlaceComponents.length - 1 ; i ++) { + let parentAreaId = place.substring(0, place.lastIndexOf(".")); + place = parentAreaId; + birthPlace.push( + (geoDataMetadataLoader.getArea(parentAreaId))?t(geoDataMetadataLoader.getArea(parentAreaId).name + " "):t("INVALID DATA ") + ) + } + } + else + birthPlace.push(t`Unknown Place`) + return birthPlace; +} + +export class DeathCertificate extends React.Component { + constructor(props) { + super(props); + this.data = props.data; + } + + // @ts-ignore + render() { + let dateOfDeath = this.data.dateOfDeath? formatDate(this.data.dateOfDeath):'Unknown'; + let declarantDate = (this.data.timestamp && this.data.timestamp !== null)? formatDate(this.data.timestamp):'Unknown'; + var currentdate = new Date(); + var datetime = currentdate.getDate() + "/" + + (currentdate.getMonth() + 1) + "/" + + currentdate.getFullYear() + " @ " + + currentdate.getHours() + ":" + + currentdate.getMinutes() + ":" + + currentdate.getSeconds(); + let fullname = ''; + fullname += this.data.firstname ? this.data.firstname + ' ' : ''; + fullname += this.data.secondname ? this.data.secondname + ' ' : ''; + fullname += this.data.fourthname ? this.data.fourthname + ' ' : ''; + let declarantFullName = ''; + if (this.data.declarantId != null) { + declarantFullName += this.data.declarantFirstname ? this.data.declarantFirstname + ' ' : ''; + declarantFullName += this.data.declarantSecondname ? this.data.declarantSecondname + ' ' : ''; + declarantFullName += this.data.declarantFourthname ? this.data.declarantFourthname + ' ' : ''; + } + let childGender = (this.data.gender == 1)?'MALE':(this.data.gender == 2)?'FEMALE': t`Unknown`; + let children = []; + if (this.data.children != null) + this.data.children.forEach(child => { + children.push( + <>{child.name} {child.gender} {child.age}
+ ) + }); + return ( + +
+
+
+

{deathCertificateContent.leftTitle1}
+ {deathCertificateContent.leftTitle2}

+
+ +
+
+

{deathCertificateContent.rightTitle1}
{deathCertificateContent.rightTitle2}

+
+
+ +
+
+

{deathCertificateContent.mainTitle}

+

{deathCertificateContent.mainSubTitle}

+
+ {/*
+

{t`Death ID Number`}: {this.data.id}

+
*/} +
+
+
+

{t`Death details`}:

+

{t`Date`}: {dateOfDeath} Time: {formatTime(this.data.timeOfDeath)} Place: {formatLocation(this.data.deathPlace)}Certificate Number: {this.data.id}

+
+
+

{(this.data.reportedRecord)?t`Reported`+ ' ':null}{t`Deceased`}

+
+

Family Name
+ {t`First Name(s)`}
+ {t`Melanesian Name`}
+ {t`Sex`}
+ {t`National ID Number`} +

+ +

+ {t`Date of birth`}
+ {t`Location of Birth`}
+  
+  
+ {t`Occupation`}
+

+

+ {t`Usual Residence`}
+  
+  
+

+

+ {t`Mother's Name`}
+ {t`Father's Name`}
+

+
+
+

{this.data.fourthname}
+ {this.data.firstname}
+ {(this.data.thirdname !== null)?this.data.thirdname: " "}
+ {childGender}
+ {this.data.vitalRecordId} +

+ +

+ {formatDate(this.data.birthdate)}
+ {formatLocation(this.data.birthPlace)}
+ + {(formatLocation(this.data.birthPlace).length < 3) && (<> +  
+ + ) } +  
+ {(this.data.occupation != null)?this.data.occupation:" "}
+

+

+ {formatLocation(this.data.address)}
+ {(formatLocation(this.data.address).length < 3) && (<> +  
+ ) } +  
+

+

+ {(this.data.motherName !== null)?this.data.motherName: " "}
+ {(this.data.fatherName !== null)?this.data.fatherName: " "}
+

+
+
+ +
+

Family of deceased

+
+

Name of Spouse
+ National ID Number +

+

Date of Marriage
+

+

+ Location of Marriage
+  
+  
+

+

+ Surviving Children +

+ +
+
+

{(this.data.spouseName !== null)?this.data.spouseName: " "}
+ {(this.data.spouseId !== null)?this.data.spouseId: " "}
+

+

+ {formatDate(this.data.marriageDate)}
+

+

+ {(this.data.marriageLocation !== null)?this.data.marriageLocation: " "}
+  
+  
+

+

+ {children} +

+ +
+
+
+

Declaration

+ {(this.data.declarantId)? + <> +
+

{t`Full Name`}
+ {t`National ID Number`}
+ {t`Date`}
+ {t`Place`}
+

+

+ {t`Officer`}
+ {t`Position`}
+

+
+
+

{declarantFullName}
+ {this.data.declarantId}
+ {declarantDate}
+
+

+

+
+
+

+
+ : +

{t`No Declarant Found`}

} + +
+
+ +

Remarks

+

+

+
+ +
+
+
+
+
+

Certified to be a true copy issued without alteration at {"Vanuatu"} on {datetime}

Jeffrey Langati Trief
Registrar General

+ +
+
+
+ + ) + } +} \ No newline at end of file diff --git a/src/main/js/forms/DeathCertificateStyleObj.jsx b/src/main/js/forms/DeathCertificateStyleObj.jsx new file mode 100644 index 0000000..2a64a1e --- /dev/null +++ b/src/main/js/forms/DeathCertificateStyleObj.jsx @@ -0,0 +1,346 @@ +export const certificateStyle = ` +@charset "UTF-8"; +@import url('https://fonts.cdnfonts.com/css/montserrat'); +:root { + --bleed: 0.5cm; + --margin: 1cm; +} + +@page { + size: A4 landscape; + margin: 0; +} + + +* { + box-sizing: border-box; +} +* { + -webkit-print-color-adjust: exact !important; /* Chrome, Safari 6 – 15.3, Edge */ + color-adjust: exact !important; /* Firefox 48 – 96 */ + print-color-adjust: exact !important; /* Firefox 97+, Safari 15.4+ */ +} + +.header h1 { + color:#fff; +} +h2 { + /*color:#04a6e1; */ + color:#fff; +} +h2.idnumber1 { + color:#fff; +} +.headercol5 h2 { + color:#fff; +} + +.header { + background-color: #004a98; +} + +.logos { + background-image: url(https://rv5.gov.vu/public/logos.png); + background-repeat: no-repeat; + background-size: contain; + margin:-2mm auto; + text-align:center; + height:49mm !important; + box-shadow: inset 0 0 0 10px #004a98; +} + +body { + --bleed: 0mm; + --margin: 10mm; + margin: 0 auto; + padding: 0; + background: rgb(204, 204, 204); + display: flex; + flex-direction: column; +} + +.page { + display: inline-block; + position: relative; + height: 210mm; + width: 297mm; + font-size: 12pt; + margin: 10mm auto; + padding: calc(var(--bleed) + var(--margin)); + box-shadow: 0 0 0.5cm rgba(0, 0, 0, 0.5); + background: white; + font-family: montserrat; +} +h1 { + font-size: 15pt; + font-weight: bold !important; + text-align: left; + margin: 0mm; + position: relative; + bottom: 1mm; +} +.headercol5 h1 { + bottom: 4mm; + text-align: center; +} +h2 { + font-size:9pt; + font-weight:bold !important; +} +h2.marriageinfo { + font-size:10pt; + font-weight:normal !important; + text-align: center; + margin:5mm 0mm 5mm 0mm; +} +.headercol5 h2 { + text-align: center; + margin-top: 0mm; + position: relative; + top:-4mm; +} +.headercol5 h1 { + text-align: center; + padding-bottom: 0mm !important; +} +h3 { + font-size:0.95em; + font-weight:bold !important; + margin: 0 !important; +} + +p { + font-size:8pt; + font-weight:normal; + line-height: 13pt; +} +p.bottom { +margin-top: 0mm !important; +} +.lefttext { + text-align: left; +} +.righttext { + text-align: right; +} +.idnumber1 { + margin: 0mm; + position: relative; + bottom: -2mm; +} +.pattern { + margin: 10mm calc(-1mm - var(--margin)); +} +.logos { + background-repeat: no-repeat; + background-size: contain; + margin:-2mm auto; + text-aligh:center; + background-position:bottom 50%; + height:49mm !important; +} +.header { + margin: calc(0mm - var(--margin))!important; + padding: 4mm 10mm; + border-bottom: 0.75mm solid #000000; + display: flex; + flex-direction:row; + flex-wrap: wrap; + height:65mm; +} +.header::after { + position: absolute; + content: ''; + top: 65mm; + left: 0; + width: 100%; + height: 10mm; + margin: 0; + pointer-events: none; + z-index: 9999; + background-image: url(https://rv5.gov.vu/public/birth-certificate-pattern.svg); + background-repeat: no-repeat; +} +.headercol1 { + height:90%; +margin:0mm 10mm 0mm 0mm; + flex-basis: 75mm; +} + +.headercol2 { + margin:0mm; + flex-basis: 107mm; +} +.headercol3 { + margin:0mm 0mm 0mm 10mm ; + height:90%; + flex-basis: 75mm; +} +.headercol4 { + height:10%; +margin:0mm 10mm 0mm 0mm; + flex-basis: 45mm; +} +.headercol5 { + margin:0mm; + flex-basis: 167mm; + height:10%; +} +.headercol6 { + margin:0mm 0mm 0mm 10mm ; + height:10%; + flex-basis: 45mm; +} + +.clear {clear:both;} +.bodycontent { + margin-top: 18mm; + display: flex; + flex-wrap: wrap; +} +.bodyrow { + margin:2mm 0mm 0mm 0mm; + flex-basis: 277mm; +} +.bodycol1 { + +margin:4mm 10mm 0mm 0mm; + flex-basis: 92.333mm; +} + +.bodycol2 { + height:65mm; + margin:4mm 0mm 0mm 0mm; + flex-basis: 92.333mm; +} +.bodycol3 { + height:50mm; + margin:4mm 0mm 0mm 10mm ; + flex-basis: 72.333mm; +} +.bodycol4 { + height:12mm; + margin:1mm 10mm 0mm 0mm; + flex-basis: 174.333mm; +} +.bodycol4 h3 { + margin-top:0px !important; + padding-top:0px !important; +} +.bodycol5 { + height:25mm; + margin:8mm 0mm 0mm 0mm; + flex-basis: 87.333mm; +} +.bodycol6 { + height: 52mm; + margin: -33mm 0mm 0mm 10mm; + flex-basis: 82.333mm; +} +.nestedcol1 { + width:46%; + margin: 0 2% 2mm 0; + /*background-color: #999999;*/ + float:left; + font-weight: bold; +} +.nestedcol1 p{ + font-weight: bold; +} +.nestedcol1 p:first-child, .nestedcol2 p:first-child{ + margin-top:0mm !important; +} +.nestedcol2 { + width:52%; + margin: 0 0 1mm 0; + /*background-color: #313131;*/ + float:left; +} +.official { + /*postion: relative;*/ + display: flex; + height:25mm; +} +.qr-code { + position: relative; + top:0mm; + left:0mm; + width: 22mm; + height:22mm; + margin-bottom:2mm; +} +.stamp { + position: relative; + top:-8mm; + left:20mm; + width: 32mm; + height:32mm; + margin-bottom:2mm; + background-image:url(https://rv5.gov.vu/public/offical-approved-stamp.svg); + background-size: contain; + z-index:9999; +} +.signature { + position: absolute; + z-index:9999; + bottom:26mm; + right:35mm; + width: 32mm; + height:32mm; + margin-bottom:2mm; + background-image:url(https://rv5.gov.vu/public/signature-temp.png); + background-size: contain; + background-repeat: no-repeat; +} +.details { + margin: 0 8mm 0 0; +} + +@media screen { + .page::after { + position: absolute; + content: ''; + top: 0; + left: 0; + width: calc(100% - var(--bleed) * 2); + height: calc(100% - var(--bleed) * 2); + margin: var(--bleed); + outline: thin dashed black; + pointer-events: none; + z-index: 9999; + } +} + +@media print { + .page { + margin: 0; + overflow: hidden; + size: A4 landscape; + box-shadow: 0 0 0cm rgba(0, 0, 0, 0); + } + @page { + size: A4 landscape; + margin: 0; +} + html, body { + height: 100vh; + overflow: hidden; + } + body { + /*transform: rotate(90deg);*/ + margin: 0; +} + + html { + margin: 0; + } + + * { + -webkit-print-color-adjust: exact !important; /* Chrome, Safari 6 – 15.3, Edge */ + color-adjust: exact !important; /* Firefox 48 – 96 */ + print-color-adjust: exact !important; /* Firefox 97+, Safari 15.4+ */ + /*overflow: hidden!important;*/ +} + +} +`; diff --git a/src/main/js/forms/DeathRecordFormCommon.jsx b/src/main/js/forms/DeathRecordFormCommon.jsx new file mode 100644 index 0000000..64c71e0 --- /dev/null +++ b/src/main/js/forms/DeathRecordFormCommon.jsx @@ -0,0 +1,148 @@ +import React from "react"; + +import { GeoDataComponent } from "../../../auto/js/widgets/GeoDataComponent"; +import { AdvancedSearchPersonComponent } from "../widgets/AdvancedSearchPersonComponent"; +import { Section } from "../widgets/Section"; +import { rest } from "../../../auto/js/services"; +import { setContextualOptions } from "../../../auto/js/widgets"; +import { certificateStyle } from "./DeathCertificateStyleObj"; +import { DeathCertificate } from "./DeathCertificate"; +import { getServiceUri } from "../../../auto/js/metadata"; +import { loadPersonData } from "../utils"; +import { PRINT_EVENT } from "../../../auto/js/events/Gui"; +import { displayNewAmendmentDeathApplicationForm } from "../../../auto/js/forms/amendmentDeathApplication/NewAmendmentDeathApplicationForm"; +import { DELETE_ATTACHMENT_EVENT } from "../../../auto/js/events/Gui"; +export const deathRecordFields = [ + { name: "tags", type: "tags", x: 1, y: 1, layout: "col-md-12" }, + {name: "deceasedDetails", type: "custom", x:1, y:2, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "vitalRecordId", type: "custom", x:1, y: 3, layout:"col-md-12", component: (name, disabled) => }, + {name: "deathDetails", type: "custom", x:1, y:4, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "dateOfDeath", type: "date", x:1, y: 5, layout:"col-md-6"}, + {name: "timeOfDeath", type: "time", x:2, y: 5, layout:"col-md-6"}, + {name:"deathPlaceBox", label: "Death Place", components: [ + {name: "deathLocation", type: "custom", x:1, y:7, layout:"col-md-12", component: (name, disabled) => }, + ], type: "box", x:1, y:7, layout:"col-md-11 ms-2 mt-2 pt-1 pb-2"}, + {name:"burialPlaceBox", label: "Burial Place", components: [ + {name: "burialPlace", type: "custom", x:1, y:7, layout:"col-md-12", component: (name, disabled) => }, + ], type: "box", x:1, y:8, layout:"col-md-11 ms-2 mt-2 pt-1 pb-2"}, + {name: "deathNotificationFile", type: "file", x:1, y:10, layout:"col-md-12", + uploadUrl: (id) => getUploadUrl(id), + previewUrl: (id) => getPreviewUrl(id), + loadData: async (id) => loadDeathNotificationAttachment(id), + handleDelete:(id) => handleDeathNotificationDelete(id), + handleClick: (id) => handleDeathNotificationClick(id), + updateFileData: (data) => updateFileData(data) + }, + {name: "declarantDetails", type: "custom", x:1, y:11, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "declarantId", type: "custom", x:1, y:12, layout:"col-md-12", component: (name, disabled) => }, + {name: "extras", type: "custom", x:1, y:13, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "notes", type: "text", x:1, y: 14, layout:"col-md-12"} +]; + +const getUploadUrl = (id) => { + return getServiceUri() + 'death-record/death-notification-file' + '/' + id; +} + +const updateFileData = (data) => { + let filter = {name: data.fileName, description: data.description}; + rest.request(getServiceUri() + 'death-record/death-notification-file' + '/' + data.id, "PUT", filter); +} + +const getPreviewUrl = (id) => { + return getServiceUri() + 'death-record/death-notification-file' + '/preview/' + id; +} + +const handleDeathNotificationClick = async (id) => { + const token = await rest.getToken(getServiceUri() + 'token/get-auth-code'); + window.location = getServiceUri() + 'death-record/death-notification-file' + '/' + id + '/' + token; +}; + +const handleDeathNotificationDelete = (id) => { + rest.delete('death-record/death-notification-file', id).then(() => { + DELETE_ATTACHMENT_EVENT.publish(id) + }); +}; + +const loadDeathNotificationAttachment = async (id) => { + let filter = {and: true}; + filter['death-record-death-notification-file'] = {}; + filter['death-record-death-notification-file']['deathRecordId'] = id; + return rest.search('death-record/death-notification-file', filter) +} + +export const deathCertificateContent = { + leftTitle1: "Gouvernement de République de Vanuatu", + leftTitle2: "Enrégistrement Civil et Gestion d’Identité", + rightTitle1: "Government of the Republic of Vanuatu", + rightTitle2: "Civil Registration and Identity Management", + mainTitle: "Vanuatu Death Certificate", + mainSubTitle: "(Civil Registration and Identity Management Act - 28/2021)", + signedBy: "Jeffrey Tila Langati Trief" +}; + +const printDeathCertificate = (data) => () => { + const printable = { + content:, + style:{certificateStyle}.certificateStyle, + copyParentStyle:false + } + PRINT_EVENT.publish(printable); +} + +export const loadFormData = async (id) => { + return await rest.read('death-record', id).then(async (response) => { + let token = await rest.getToken(getServiceUri() + 'token/get-auth-code'); + let form = response; + let faceUrl = null; + if (response.faceId != null) { + const imageUrl = getServiceUri() + 'face/image/' + response.faceId + "/" + token; + form['image'] = { x: 0.5, y: 0.5, scale: 1, rotate: 0, url: (imageUrl != null) ? imageUrl : '/public/avatar.png', isEmpty: false }; + } else + form['image'] = { x: 0.5, y: 0.5, scale: 1, rotate: 0, url: '/public/avatar.png', isEmpty: true }; + if (response.timeOfDeath !== null) { + form.timeOfDeath = new Date().setHours(response.timeOfDeath[0], response.timeOfDeath[1]); + } + let tagFilter = {and: true}; + tagFilter['death-record-tag'] = {deathRecordId: id}; + + return rest.search('death-record-tag', tagFilter).then(tags => { + form['tags'] = tags + if (tags.status) + showNotification(response.message.split('Detail: ')[1], "error"); + rest.read('death-certificate/read/', id).then(async data => { + setContextualOptions({ + "death-records": { + submenu: { + "actions": { + options: { + "amend-death": { + label: "Amend", do: (gui) => displayNewAmendmentDeathApplicationForm(gui, form) + }, + "death-certificate": { + label: "Print Death Certificate", do: printDeathCertificate(data) + } + }, + label: "Actions" + } + } + }, + "civil-records": { + submenu: { + "actions": { + options: { + "amend-death": { + label: "Amend", do: (gui) => displayNewAmendmentDeathApplicationForm(gui, data) + }, + "print-death-certificate": { + label: "Print Death Certificate", do: printDeathCertificate(data) + } + }, + label: "Actions" + } + } + } + })}); + return form; + }) + }) +} \ No newline at end of file diff --git a/src/main/js/forms/DivorceCerificateCommon.jsx b/src/main/js/forms/DivorceCerificateCommon.jsx new file mode 100644 index 0000000..e4e76f4 --- /dev/null +++ b/src/main/js/forms/DivorceCerificateCommon.jsx @@ -0,0 +1,10 @@ + +export const divorceCertificateContent = + + { leftTitle1: "Gouvernement de République de Vanuatu", + leftTitle2: "Enrégistrement Civil et Gestion d’Identité", + rightTitle1: "Government of the Republic of Vanuatu", + rightTitle2: "Civil Registration and Identity Management", + mainTitle: "Vanuatu Divorce Certificate", + mainSubTitle: "(Civil Registration and Identity Management Act - 28/2021)", + signedBy: "Jeffrey Tila Langati Trief" }; \ No newline at end of file diff --git a/src/main/js/forms/DivorceCertificate.jsx b/src/main/js/forms/DivorceCertificate.jsx new file mode 100644 index 0000000..67e8cd8 --- /dev/null +++ b/src/main/js/forms/DivorceCertificate.jsx @@ -0,0 +1,113 @@ +import * as React from 'react'; +import QRCode from "react-qr-code"; + +import {divorceCertificateContent} from "./DivorceCerificateCommon.jsx"; +import { geoDataMetadataLoader } from '../../../auto/js/metadata/GeoDataMetadataLoader'; +import { t } from '../../../auto/js/services'; + + +const formatDate = (date) => { + if (date != null) { + let d = new Date(date[0], date[1]-1, date[2]); + return d.toLocaleDateString('en-us', { weekday:"long", year:"numeric", month:"short", day:"numeric"}); + } else + return t`Unknown`; +} + +const formatTime = (time) => { + if (time !== null) { + let h = (time[0] < 0)? "0" + time[0] : time[0]; + let m = (time[0] < 0)? "0" + time[1] : time[1]; + return h + ":" + m; + } else + return t`Unkown Time` +} + +const formatLocation = (location) => { + let marriagePlace = []; + if (location != null) { + let marriagePlaceComponents = location.split("."); + let place = location; + marriagePlace.push( + (geoDataMetadataLoader.getArea(place))?t(geoDataMetadataLoader.getArea(place).name + " "):t("INVALID DATA ") + ) + for (let i = 0; i < marriagePlaceComponents.length - 1 ; i ++) { + let parentAreaId = place.substring(0, place.lastIndexOf(".")); + place = parentAreaId; + marriagePlace.push( + (geoDataMetadataLoader.getArea(parentAreaId))?t(geoDataMetadataLoader.getArea(parentAreaId).name + " "):t("INVALID DATA ") + ) + } + } + else + marriagePlace.push(

{t`Unknown Place`}

) + return marriagePlace; +} + +export class DivorceCertificate extends React.Component { + constructor(props) { + super(props); + this.data = props.data; + } + + // @ts-ignore + render() { + let marriagedate = this.data.marriagedate? formatDate(this.data.marriagedate):'Unknown'; + var currentdate = new Date(); + var datetime = currentdate.getDate() + "/" + + (currentdate.getMonth() + 1) + "/" + + currentdate.getFullYear() + " @ " + + currentdate.getHours() + ":" + + currentdate.getMinutes() + ":" + + currentdate.getSeconds(); + + let declarationDate = this.data.declarationDate? formatDate(this.data.declarationDate):'Unknown'; + + return ( + +
+
+
+

{divorceCertificateContent.leftTitle1}
+ {divorceCertificateContent.leftTitle2}

+
+ +
+
+

{divorceCertificateContent.rightTitle1}
{divorceCertificateContent.rightTitle2}

+
+
+ +
+
+

{divorceCertificateContent.mainTitle}

+

{divorceCertificateContent.mainSubTitle}

+
+ {/*
+

{t`National ID Number`}: {this.data.id}

+
*/} +
+
+
+

This divorce decree offically certifies that the marriage of {this.data.partner2Name} and {this.data.partner1Name}, which occured on the {declarationDate} at {formatTime(this.data.timeOfMarriage)} in {(this.data.declarationPlace !== null)? this.data.declarationPlace: t`Unknown Place`} with the marriage certificate number {this.data.unionRecordId} has now ended.

+ +

This divorce is under the order of {this.data.annulmentOrder} dated {formatDate(this.data.dateOfOrder)}.

+

This divorce is effective from the {formatDate(this.data.dateOfEffect)}.

+
+ + +
+ + +
+
+ +

Certified at {"Vanuatu"} on {datetime} by

Jeffrey Langati Trief
Registrar General

+ +
+
+
+ + ) + } +} \ No newline at end of file diff --git a/src/main/js/forms/DivorceCertificateStyleObj.jsx b/src/main/js/forms/DivorceCertificateStyleObj.jsx new file mode 100644 index 0000000..7f6d4df --- /dev/null +++ b/src/main/js/forms/DivorceCertificateStyleObj.jsx @@ -0,0 +1,327 @@ +export const divorceCertificateStyle = ` +@charset "UTF-8"; +@import url('https://fonts.cdnfonts.com/css/montserrat'); +:root { + --bleed: 0.5cm; + --margin: 1cm; +} + +@page { + size: A4; + margin: 0; +} + +* { + box-sizing: border-box; +} +* { + -webkit-print-color-adjust: exact !important; /* Chrome, Safari 6 – 15.3, Edge */ + color-adjust: exact !important; /* Firefox 48 – 96 */ + print-color-adjust: exact !important; /* Firefox 97+, Safari 15.4+ */ +} + +.header { + background-color: #ffffff; +} +.logos { + background-image: url(https://rv5.gov.vu/public/logos.png); +} + +body { + --bleed: 0mm; + --margin: 10mm; + margin: 0 auto; + padding: 0; + background: rgb(204, 204, 204); + display: flex; + flex-direction: column; +} + +.page { + display: inline-block; + position: relative; + width: 210mm; + height: 297mm; + font-size: 15pt; + margin: 10mm auto; + padding: calc(var(--bleed) + var(--margin)); + box-shadow: 0 0 0.5cm rgba(0, 0, 0, 0.5); + background: white; + font-family: montserrat; +} +h1 { + font-size: 15pt; + font-weight: bold !important; + text-align: left; + margin: 0mm; + position: relative; + bottom: 1mm; +} +.headercol5 h1 { + bottom: 4mm; + text-align: center; +} +h2 { + font-size:8pt; + font-weight:bold !important; +} +h2.marriageinfo { + font-size:10pt; + font-weight:normal !important; + text-align: center; + margin:5mm 0mm 5mm 0mm; +} +.headercol5 h2 { + text-align: center; + margin-top: 0mm; + position: relative; + top:-4mm; +} +.headercol5 h1 { + text-align: center; + padding-bottom: 0mm !important; +} +h3 { + font-size:0.95em; + font-weight:bold !important; + margin: 0 !important; +} + +p { + font-size:10pt; + font-weight:normal; + line-height: 13pt; +} +p.bottom { +margin-top: 0mm !important; +font-size:11pt; +line-height:16pt; +} +.lefttext { + text-align: left; +} +.righttext { + text-align: right; +} +.idnumber1 { + margin: 0mm; + position: relative; + bottom: -2mm; +} +.pattern { + margin: 10mm calc(-1mm - var(--margin)); +} +.logos { + background-repeat: no-repeat; + background-size: contain; + margin:-2mm 0; + text-align:center; + background-position:bottom 50%; + height:49mm !important; +} +.header { + margin: calc(0mm - var(--margin))!important; + padding: 4mm 10mm; + border-bottom: 0.75mm solid #000000; + width:210mm; + height:65mm; + display: flex; + flex-direction:row; + flex-wrap: wrap; +} +.header::after { + position: absolute; + content: ''; + top: 65mm; + left: 0; + width: 100%; + height: 10mm; + margin: 0; + pointer-events: none; + z-index: 9999; + background-image: url(https://rv5.gov.vu/public/birth-certificate-pattern.svg); + background-repeat: no-repeat; +} +.headercol1 { + height: 90%; + margin:0mm 0mm 0mm 0mm; + flex-basis: 50mm; +} + +.headercol2 { + margin:0mm; + flex-basis: 90mm; +} +.headercol3 { + margin: 0mm 0mm 0mm 0mm; + height: 90%; + flex-basis: 50mm; +} +.headercol4 { + margin: 5mm 0mm 0mm 0mm; + height: 10%; + flex-basis: 50mm; +} +.headercol5 { + margin: 2mm 0 0 0; + flex-basis: 90mm; + height: 10%; +} +.headercol6 { + margin: 0mm 0mm 0mm 0mm; + height: 10%; + flex-basis: 50mm; +} + +.clear {clear:both;} +.bodycontent { + margin-top: 18mm; + display: flex; + flex-wrap: wrap; +} +.bodyrow { + margin:15mm 0mm 0mm 0mm; + flex-basis: 190mm; +} +.bodycol1 { + +margin:4mm 10mm 0mm 0mm; + flex-basis: 87.333mm; +} + +.bodycol2 { + height:65mm; + margin:4mm 0mm 0mm 0mm; + flex-basis: 87.333mm; +} +.bodycol3 { + height:50mm; + margin:4mm 0mm 0mm 10mm ; + flex-basis: 82.333mm; +} +.bodycol4 { + height:20mm; + margin:2mm 10mm 0mm 0mm; + flex-basis: 174.333mm; +} +.bodycol5 { + height:25mm; + margin:8mm 0mm 0mm 0mm; + flex-basis: 87.333mm; +} +.bodycol6 { + height:41mm; + margin:-28mm 0mm 0mm 10mm ; + flex-basis: 82.333mm; +} +.nestedcol1 { + width:36%; + margin: 0 2% 2mm 0; + /*background-color: #999999;*/ + float:left; + font-weight: bold; +} +.nestedcol1 p{ + font-weight: bold; +} +.nestedcol1 p:first-child, .nestedcol2 p:first-child{ + margin-top:0mm !important; +} +.nestedcol2 { + width:62%; + margin: 0 0 2mm 0; + /*background-color: #313131;*/ + float:left; +} +.bodyrowbottom { + position: absolute; + bottom: 2mm; + left: 15mm; + height: 30mm; + width: 100mm; +} + +.official { + height: 25mm; + width: 85mm; +} +.qr-code { + position: absolute; + top: -26mm; + left: 0mm; + width: 22mm; + height: 22mm; + margin-bottom: 2mm; +} +.stamp { + position: relative; + top:-8mm; + left:20mm; + width: 32mm; + height:32mm; + margin-bottom:2mm; + background-image:url(https://rv5.gov.vu/public/offical-approved-stamp.svg); + background-size: contain; + z-index:9999; +} +.signature { + position: absolute; + z-index: 9999; + top: -32mm; + left: 29mm; + width: 32mm; + height: 32mm; + margin-bottom: 2mm; + background-image: url(https://rv5.gov.vu/public/signature-temp.png); + background-size: contain; + background-repeat: no-repeat; +} +.details { + margin: 0 8mm 0 0; +} + +@media screen { + .page::after { + position: absolute; + content: ''; + top: 0; + left: 0; + width: calc(100% - var(--bleed) * 2); + height: calc(100% - var(--bleed) * 2); + margin: var(--bleed); + outline: thin dashed black; + pointer-events: none; + z-index: 9999; + } +} + +@media print { + .page { + margin: 0; + overflow: hidden; + } + html, body { + height: 100vh; + overflow: hidden; + } + @page { + size: A4; + margin: 0; +} + body { + margin: 0; +} + html { + margin: 0; + } + + + + * { + -webkit-print-color-adjust: exact !important; /* Chrome, Safari 6 – 15.3, Edge */ + color-adjust: exact !important; /* Firefox 48 – 96 */ + print-color-adjust: exact !important; /* Firefox 97+, Safari 15.4+ */ +} +} + +`; diff --git a/src/main/js/forms/IssuedDocumentsFormCommon.jsx b/src/main/js/forms/IssuedDocumentsFormCommon.jsx new file mode 100644 index 0000000..a6d1a35 --- /dev/null +++ b/src/main/js/forms/IssuedDocumentsFormCommon.jsx @@ -0,0 +1,49 @@ +import React from "react"; +import {v4 as uuidv4} from 'uuid'; + +import { OPEN_VIEW_EVENT } from "../../../auto/js/events/Gui"; +import { createFormComponent } from "../../../auto/js/widgets" +import { rest } from "../../../auto/js/services"; +import { showNotification } from "../../../auto/js/utils"; +import { PersonComponent } from "../../../auto/js/widgets/PersonComponent"; +import { loadPersonData } from "../utils"; + +const issuedDocumentsFields = [ + {name: "tags", type:"tags", x:1, y:1, layout:"col-md-12"}, + {name:"image", type:"image", x:1, y:2, layout:"col-md-12"}, + {name: "documentId", type:"text", x:1, y:3, layout:"col-md-6"}, + {name: "vitalRecordId", type:"custom", x:1, y:3, layout:"col-md-12", component: (name, disabled) => }, + {name: "issuedDate", type:"date", x:1, y:4, layout:"col-md-6"}, + {name: "expires", type:"date", x:1, y:4, layout:"col-md-6"}, + {name: "cancelledDate", type:"date", x:1, y:5, layout:"col-md-6"}, + {name: "cancelledReason", type:"text", x:1, y:6, layout:"col-md-12"}, +] + +export const displayReadIssuedDocumentsForm = (onFinish) => (id) => { + let IssuedDocumentsFormComponent = createFormComponent(issuedDocumentsFields) + + let uuid = uuidv4(); + return { + uuid, view: () => loadFormData(id)} buttons={() => null} readOnly={true} /> + }; +} + +const loadFormData = async (id) => { + return await rest.read('issued-documents', id).then(response => { + let form = response; + let face = null; + if (response.face != null) { + let mimeType = "image/png"; + face = "data:".concat(mimeType, ";base64,", response.face) + } + form['image'] = {x: 0.5, y:0.5, scale: 1, rotate: 0, url: (face != null)?face: '/public/avatar.png', isEmpty: true}; + + let tagFilter = {and: true}; + tagFilter['issued-documents-tag'] = {issuedDocumentsId: id}; + return rest.search('issued-documents-tag', tagFilter).then(tags => { + form['tags'] = tags + + return form; + }) + }) +} \ No newline at end of file diff --git a/src/main/js/forms/MarriageCerificateCommon.jsx b/src/main/js/forms/MarriageCerificateCommon.jsx new file mode 100644 index 0000000..fc9a9b4 --- /dev/null +++ b/src/main/js/forms/MarriageCerificateCommon.jsx @@ -0,0 +1,10 @@ + +export const marriageCertificateContent = + + { leftTitle1: "Gouvernement de République de Vanuatu", + leftTitle2: "Enrégistrement Civil et Gestion d’Identité", + rightTitle1: "Government of the Republic of Vanuatu", + rightTitle2: "Civil Registration and Identity Management", + mainTitle: "Vanuatu Marriage Certificate", + mainSubTitle: "(Civil Registration and Identity Management Act - 28/2021)", + signedBy: "Jeffrey Tila Langati Trief" }; \ No newline at end of file diff --git a/src/main/js/forms/MarriageCertificate.jsx b/src/main/js/forms/MarriageCertificate.jsx new file mode 100644 index 0000000..31afe4a --- /dev/null +++ b/src/main/js/forms/MarriageCertificate.jsx @@ -0,0 +1,273 @@ +import * as React from 'react'; +import QRCode from "react-qr-code"; + +import {marriageCertificateContent} from "./MarriageCerificateCommon.jsx"; +import { geoDataMetadataLoader } from '../../../auto/js/metadata/GeoDataMetadataLoader'; +import { t } from '../../../auto/js/services'; + + +const formatDate = (date) => { + let d = new Date(date[0], date[1]-1, date[2]); + return d.toLocaleDateString('en-us', { weekday:"long", year:"numeric", month:"short", day:"numeric"}) +} + +const regime = {1:"Civil Marriage", 2:"Religious Marriage", 3: "Custom Marriage"}; + +const formatTime = (time) => { + let formattedTime = "Unknown Time" + if (time !== null) { + let h = (time[0] < 10)?'0'+ time[0]:time[0]; + let m = (time[1] < 10)?'0'+ time[1]:time[1]; + formattedTime = h + ':' + m + } + return formattedTime; +} + +const formatLocation = (location) => { + let marriagePlace = []; + if (location != null) { + let marriagePlaceComponents = location.split("."); + let place = location; + marriagePlace.push( + (geoDataMetadataLoader.getArea(place))?t(geoDataMetadataLoader.getArea(place).name + " "):t("INVALID DATA ") + ) + for (let i = 0; i < marriagePlaceComponents.length - 1 ; i ++) { + let parentAreaId = place.substring(0, place.lastIndexOf(".")); + place = parentAreaId; + marriagePlace.push( + (geoDataMetadataLoader.getArea(parentAreaId))?t(geoDataMetadataLoader.getArea(parentAreaId).name + " "):t("INVALID DATA ") + ) + } + } + else + marriagePlace.push(t`Unknown Place`) + return marriagePlace; +} + +export class MarriageCertificate extends React.Component { + constructor(props) { + super(props); + this.data = props.data; + } + + // @ts-ignore + render() { + let marriagedate = this.data.marriagedate? formatDate(this.data.marriagedate):'Unknown'; + var currentdate = new Date(); + + let partner1DateOfBirth = this.data.partner1DateOfBirth? formatDate(this.data.partner1DateOfBirth):'Unknown'; + let partner2DateOfBirth = this.data.partner2DateOfBirth? formatDate(this.data.partner2DateOfBirth):'Unknown'; + let declarationDate = this.data.declarationDate? formatDate(this.data.declarationDate):'Unknown'; + + let fullname = ''; + fullname += this.data.firstname ? this.data.firstname + ' ' : ''; + fullname += this.data.secondname ? this.data.secondname + ' ' : ''; + fullname += this.data.fourthname ? this.data.fourthname + ' ' : ''; + let marriagePlace = []; + let place = formatLocation(this.data.declarationPlace); + if (place.length > 3) { + marriagePlace.push(place[place.length - 3]) + marriagePlace.push(place[place.length - 2]) + marriagePlace.push(place[place.length - 1]) + } else + marriagePlace = place; + + return ( + +
+
+
+

{marriageCertificateContent.leftTitle1}
+ {marriageCertificateContent.leftTitle2}

+
+ +
+
+

{marriageCertificateContent.rightTitle1}
{marriageCertificateContent.rightTitle2}

+
+
+ +
+
+

{marriageCertificateContent.mainTitle}

+

{marriageCertificateContent.mainSubTitle}

+
+ {/*
+

{t`National ID Number`}: {this.data.id}

+
*/} +
+
+
+

{t`Marriage Details`}

+

{t`Date`}: {declarationDate} {t`Time`}: {formatTime(this.data.timeOfMarriage)} {t`Place`}: {marriagePlace}{t`Celebrant`}: {this.data.celebrant}{t`Type of Marriage`}: {(this.data.marriageType !== null)?regime[this.data.marriageType]:null}.

+
+
+

{(this.data.partner2reported)?t`Reported` + ' ':null}{t`Wife`}

+
+

Family Name
+ {t`First Name(s)`}
+ {t`Melanesian Name`}
+ {t`National ID Number`} +

+ +

+ {t`Date of birth`}
+ {t`Location of Birth`}
+  
+  
+

+

+ {t`Usual Residence`}
+  
+  
+

+

+ {t`Mother's Name`}
+ {t`Father's Name`}
+

+
+
+

+ {(this.data.partner2Surname !== null)?this.data.partner2Surname: " "}
+ {(this.data.partner2FirstNames !== null)?this.data.partner2FirstNames: " "}
+ {(this.data.partner2MelanesianName !== null)?this.data.partner2MelanesianName:" "}
+ {(this.data.partner2VitalRecordId !== null)?this.data.partner2VitalRecordId: " "} +

+ +

+ {partner2DateOfBirth}
+ {formatLocation(this.data.partner2BirthLocation)}
+ {(formatLocation(this.data.partner2BirthLocation).length < 3) && (<> +  
+ ) } +  
+

+

+ {formatLocation(this.data.partner2UsualResidence)}
+  
+

+

+ {this.data.partner2MotherName}
+ {this.data.partner2FatherName} +

+
+
+
+

{(this.data.partner1reported)?t`Reported` + ' ':null}{t`Husband`}

+
+

Family Name
+ {t`First Name(s)`}
+ {t`Melanesian Name`}
+ {t`National ID Number`} +

+ +

+ {t`Date of birth`}
+ {t`Location of Birth`}
+  
+  
+

+

+ {t`Usual Residence`}
+  
+  
+

+

+ {t`Mother's Name`}
+ {t`Father's Name`}
+

+
+
+

+ {(this.data.partner1Surname !== null)?this.data.partner1Surname: " "}
+ {(this.data.partner1FirstNames !== null)?this.data.partner1FirstNames: " "}
+ {(this.data.partner1MelanesianName !== null)?this.data.partner1MelanesianName:" "}
+ {(this.data.partner1VitalRecordId !== null)?this.data.partner1VitalRecordId: " "} +

+ +

+ {partner1DateOfBirth}
+ {formatLocation(this.data.partner1BirthLocation)}
+ {(formatLocation(this.data.partner1BirthLocation).length < 3) && (<> +  
+ ) } +  
+

+

+ {formatLocation(this.data.partner1UsualResidence)}
+  
+

+

+ {this.data.partner1MotherName}
+ {this.data.partner1FatherName} +

+
+
+
+

{t`Declaration`}

+
+

{t`Officer`}
+ {t`declarant`}
+ {t`Date`}
+ {t`Place`}
+

+
+
+

{this.data.officer}
+ {this.data.declarationFullName}
+ {declarationDate}
+ {formatLocation(this.data.registrationLocation)}
+

+
+
+
+

{t`Witnesses`}

+
+

{t`Witness 1`}

+

{t`Full Name`}
+ {t`National ID Number`} +

+ +
+
+

 

+

{(this.data.firstWitnessName !== null)?this.data.firstWitnessName: " "}
+ {(this.data.firstWitnessId !== null)?this.data.firstWitnessId:" "} +

+ +
+
+
+

 

+
+

{t`Witness 2`}

+

{t`Full Name`}
+ {t`National ID Number`} +

+ +
+
+

 

+

{(this.data.secondWitnessName !== null)?this.data.secondWitnessName: " "}
+ {(this.data.secondWitnessId !== null)?this.data.secondWitnessId: " "} +

+ +
+
+ +
+
+
+ +
+
+
+

Certified to be a true copy issued without alteration + at

{marriageCertificateContent.signedBy}
Registrar General

+
+
+
+ + ) + } +} \ No newline at end of file diff --git a/src/main/js/forms/MarriageCertificateStyleObj.jsx b/src/main/js/forms/MarriageCertificateStyleObj.jsx new file mode 100644 index 0000000..a85e933 --- /dev/null +++ b/src/main/js/forms/MarriageCertificateStyleObj.jsx @@ -0,0 +1,339 @@ +export const certificateStyle = ` +@charset "UTF-8"; +@import url('https://fonts.cdnfonts.com/css/montserrat'); +:root { + --bleed: 0.5cm; + --margin: 1cm; +} + +@page { + size: A4 landscape; + margin: 0; +} + +* { + box-sizing: border-box; +} +* { + -webkit-print-color-adjust: exact !important; /* Chrome, Safari 6 – 15.3, Edge */ + color-adjust: exact !important; /* Firefox 48 – 96 */ + print-color-adjust: exact !important; /* Firefox 97+, Safari 15.4+ */ +} + +body { + --bleed: 0mm; +--margin: 10mm; + margin: 0 auto; + padding: 0; + background: rgb(204, 204, 204); + display: flex; + flex-direction: column; +} + +.page { + display: inline-block; + position: relative; + height: 210mm; + width: 297mm; + font-size: 12pt; + margin: 10mm auto; + padding: calc(var(--bleed) + var(--margin)); + box-shadow: 0 0 0.5cm rgba(0, 0, 0, 0.5); + background: white; + font-family: montserrat; +} +h1 { + font-size: 15pt; + font-weight: bold !important; + text-align: left; + margin: 0mm; + position: relative; + bottom: 1mm; +} +.headercol5 h1 { + bottom: 4mm; + text-align: center; +} +h2 { + font-size:9pt; + font-weight:bold !important; +} +h2.marriageinfo { + font-size:10pt; + font-weight:normal !important; + text-align: center; + margin:5mm 0mm 5mm 0mm; +} +.headercol5 h2 { + text-align: center; + margin-top: 0mm; + position: relative; + top:-4mm; +} +.headercol5 h1 { + text-align: center; + padding-bottom: 0mm !important; +} +h3 { + font-size:0.95em; + font-weight:bold !important; + margin: 0 !important; +} + +p { + font-size:8pt; + font-weight:normal; + line-height: 13pt; +} +p.bottom { +margin-top: 0mm !important; +} +.lefttext { + text-align: left; +} +.righttext { + text-align: right; +} +.idnumber1 { + margin: 0mm; + position: relative; + bottom: -2mm; +} +.pattern { + margin: 10mm calc(-1mm - var(--margin)); +} +.logos { + background-repeat: no-repeat; + background-size: contain; + margin:-2mm auto; + text-aligh:center; + background-position:bottom 50%; + height:49mm !important; +} +.header h1 { + color:#fff; +} +h2 { + /*color:#04a6e1; */ + color:#fff; +} +h2.idnumber1 { + color:#fff; +} +.headercol5 h2 { + color:#fff; +} + +.header { + background-color: #004a98; +} + +.logos { + background-image: url(https://rv5.gov.vu/public/logos.png); + background-repeat: no-repeat; + background-size: contain; + margin:-2mm auto; + text-align:center; + height:49mm !important; + box-shadow: inset 0 0 0 10px #004a98; +} +.header { + margin: calc(0mm - var(--margin))!important; + padding: 4mm 10mm; + border-bottom: 0.75mm solid #000000; + display: flex; + flex-direction:row; + flex-wrap: wrap; + height:65mm; +} +.header::after { + position: absolute; + content: ''; + top: 65mm; + left: 0; + width: 100%; + height: 10mm; + margin: 0; + pointer-events: none; + z-index: 9999; + background-image: url(https://rv5.gov.vu/public/birth-certificate-pattern.svg); + background-repeat: no-repeat; +} +.headercol1 { + height:90%; +margin:0mm 10mm 0mm 0mm; + flex-basis: 75mm; +} + +.headercol2 { + margin:0mm; + flex-basis: 107mm; +} +.headercol3 { + margin:0mm 0mm 0mm 10mm ; + height:90%; + flex-basis: 75mm; +} +.headercol4 { + height:10%; +margin:0mm 10mm 0mm 0mm; + flex-basis: 45mm; +} +.headercol5 { + margin:0mm; + flex-basis: 167mm; + height:10%; +} +.headercol6 { + margin:0mm 0mm 0mm 10mm ; + height:10%; + flex-basis: 45mm; +} + +.clear {clear:both;} +.bodycontent { + margin-top: 18mm; + display: flex; + flex-wrap: wrap; +} +.bodyrow { + margin:2mm 0mm 0mm 0mm; + flex-basis: 277mm; +} +.bodycol1 { + +margin:4mm 10mm 0mm 0mm; + flex-basis: 99.333mm; +} + +.bodycol2 { + height:65mm; + margin:4mm 0mm 0mm 0mm; + flex-basis: 99.333mm; +} +.bodycol3 { + height:50mm; + margin:4mm 0mm 0mm 10mm ; + flex-basis: 58.333mm; +} +.bodycol4 { + height:25mm; + margin:8mm 10mm 0mm 0mm; + flex-basis: 87.333mm; +} +.bodycol5 { + height:25mm; + margin:8mm 0mm 0mm 0mm; + flex-basis: 87.333mm; +} +.bodycol6 { + height:41mm; + margin:-12mm 0mm 0mm 10mm ; + flex-basis: 82.333mm; +} +.nestedcol1 { + width:36%; + margin: 0 2% 2mm 0; + /*background-color: #999999;*/ + float:left; + font-weight: bold; +} +.nestedcol1 p{ + font-weight: bold; +} +.nestedcol1 p:first-child, .nestedcol2 p:first-child{ + margin-top:0mm !important; +} +.nestedcol2 { + width:62%; + margin: 0 0 2mm 0; + /*background-color: #313131;*/ + float:left; +} +.official { + /*postion: relative;*/ + display: flex; + height:25mm; +} +.qr-code { + position: relative; + top:0mm; + left:0mm; + width: 22mm; + height:22mm; + margin-bottom:2mm; +} +.stamp { + position: relative; + top:-8mm; + left:20mm; + width: 32mm; + height:32mm; + margin-bottom:2mm; + background-image:url(https://rv5.gov.vu/public/offical-approved-stamp.svg); + background-size: contain; + z-index:9999; +} +.signature { + position: absolute; + z-index:9999; + bottom:26mm; + right:35mm; + width: 32mm; + height:32mm; + margin-bottom:2mm; + background-image:url(https://rv5.gov.vu/public/signature-temp.png); + background-size: contain; + background-repeat: no-repeat; +} +.details { + margin: 0 4mm 0 0; +} + +@media screen { + .page::after { + position: absolute; + content: ''; + top: 0; + left: 0; + width: calc(100% - var(--bleed) * 2); + height: calc(100% - var(--bleed) * 2); + margin: var(--bleed); + outline: thin dashed black; + pointer-events: none; + z-index: 9999; + } +} + +@media print { + .page { + margin: 0; + overflow: hidden; + size: A4 landscape; + box-shadow: 0 0 0cm rgba(0, 0, 0, 0); + } + @page { + size: A4 landscape; + margin: 0; +} + html, body { + height: 100vh; + overflow: hidden; + } + body { + /*transform: rotate(90deg);*/ + margin: 0; +} + + html { + margin: 0; + } + + * { + -webkit-print-color-adjust: exact !important; /* Chrome, Safari 6 – 15.3, Edge */ + color-adjust: exact !important; /* Firefox 48 – 96 */ + print-color-adjust: exact !important; /* Firefox 97+, Safari 15.4+ */ + /*overflow: hidden!important;*/ +} + +}`; \ No newline at end of file diff --git a/src/main/js/forms/TemporaryCertificateManager.jsx b/src/main/js/forms/TemporaryCertificateManager.jsx new file mode 100644 index 0000000..9faebb3 --- /dev/null +++ b/src/main/js/forms/TemporaryCertificateManager.jsx @@ -0,0 +1,41 @@ +import React from "react"; +import { v4 as uuidv4 } from 'uuid'; +import { t } from "../../../auto/js/services"; +import { StepperBrowser } from "../../../auto/js/browsers/StepperBrowser"; +import { BirthApplicationTask } from "../tasks/BirthApplicationTask"; +import { ServerApprovalTask } from "../tasks/ServerApprovalTask"; +import { ApproveApplicationTask } from "../tasks/ApproveApplicationTask"; +import { RecordRegistrationTask } from "../tasks/RecordRegistrationTask"; +import { PrintCertificateTask } from "../tasks/PrintCertificateTask"; + +export const displayTemporaryCertificateWorkflow = (gui) => { + let steps = [ + t`Birth Application`, + t`Server Approval`, + t`Approve Application`, + t`Record Registration`, + t`Print Cerificate`, + ]; + + class TemporaryCertificateStepperBrowser extends StepperBrowser { + constructor(props) { + super(props) + this.tasks.push(new BirthApplicationTask(0, steps[0], this)); + this.tasks.push(new ServerApprovalTask(1, steps[1], this)); + this.tasks.push(new ApproveApplicationTask(2, steps[2], this)); + this.tasks.push(new RecordRegistrationTask(3, steps[3], this)); + this.tasks.push(new PrintCertificateTask(4, steps[4], this)); + this.start(); + } + + } + + const createTemporaryCertificateFlowBrowser = (gui) => { + let uuid = uuidv4(); + return { + uuid, + view: () => <>}/> + } + } + gui.goTo(createTemporaryCertificateFlowBrowser, null, null); +} \ No newline at end of file diff --git a/src/main/js/forms/UnionRecordForm.jsx b/src/main/js/forms/UnionRecordForm.jsx new file mode 100644 index 0000000..c3b51f0 --- /dev/null +++ b/src/main/js/forms/UnionRecordForm.jsx @@ -0,0 +1,262 @@ +import React from "react"; +import {v4 as uuidv4} from 'uuid'; +import { createFormComponent } from '../../../auto/js/widgets/FormComponent'; +import { rest, t } from "../../../auto/js/services"; +import { showNotification } from "../../../auto/js/utils"; +import { certificateStyle } from "./MarriageCertificateStyleObj"; +import { divorceCertificateStyle } from "./DivorceCertificateStyleObj"; + +import { Section } from "../widgets/Section"; +import { PersonComponent } from "../../../auto/js/widgets/PersonComponent"; +import { loadPersonData } from "../utils"; +import { GeoDataComponent } from "../../../auto/js/widgets/GeoDataComponent"; +import { AttachmentsArea, setContextualOptions } from "../../../auto/js/widgets"; +import { MarriageCertificate } from "./MarriageCertificate"; +import { PRINT_EVENT } from "../../../auto/js/events/Gui"; +import { DivorceCertificate } from "./DivorceCertificate"; +import { displayNewDivorceRegistrationForm } from "../../../auto/js/forms/divorceRegistration/NewDivorceRegistrationForm"; +import { AdvancedSearchPersonComponent } from "../widgets/AdvancedSearchPersonComponent"; +import { displayAmendmentUnionApplicationList } from "../../../auto/js/lists/amendmentUnionApplication/AmendmentUnionApplicationList"; +import { displayNewAmendmentUnionApplicationForm } from "../../../auto/js/forms/amendmentUnionApplication/NewAmendmentUnionApplicationForm"; +import { getServiceUri } from "../../../auto/js/metadata"; + +const gender = {1:"MALE", 2:"FEMALE"}; +const maritalStatus = {1:"SINGLE", 2:"MARRIED", 3:"DIVORCED", 4:"WIDOWED"}; +const regime = {1:"Civil Marriage", 2:"Religious Marriage", 3: "Custom Marriage"}; + +/* const fields = [ + {name: "tags", type:"tags", x:1, y:1, layout:"col-md-12"}, + {name: "id", type: "number", x:1, y:2, layout:"col-md-12"}, + {name: "celebrant", type: "text", x:1, y:20, layout:"col-md-4"}, + {name: "marriageDetails", type: "custom", x:1, y:3, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "dateOfMarriage", type: "date", x:1, y: 4, layout:"col-md-6"}, + {name: "timeOfMarriage", type: "time", x:2, y:4, layout:"col-md-6"}, + {name: "unionRegime", type: "select", x:1, y: 5, layout:"col-md-6", metadata: () => regime}, + {name:"addressBox", label: "Place", components: [ + {name: "address", type: "custom", x:1, y:1, layout:"col-md-12", component: (name, disabled) => }, + ], type: "box", x:2, y:6, layout:"col-md-11 ms-2 mt-2 pt-1 pb-2"}, {name: "wifeDetails", type: "custom", x:1, y:7, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "partner2VitalRecordId", type: "custom", x:1, y:8, layout:"col-md-12", component: (name, disabled) => }, + {name: "husbandDetails", type: "custom", x:1, y:10, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "partner1VitalRecordId", type: "custom", x:1, y:11, layout:"col-md-12", component: (name, disabled) => }, + {name: "witnessDetails", type: "custom", x:1, y:13, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "firstWitnessId", type: "custom", x:1, y:14, layout:"col-md-12", component: (name, disabled) => }, + {name: "secondWitnessId", type: "custom", x:1, y:16, layout:"col-md-12", component: (name, disabled) => }, + {name: "divorceDetails", type: "custom", x:1, y:17, layout:"col-md-12", component: (name, disabled) =>
, display: (data) => {return data.dateOfEffect !== null }}, + {name: "dateOfEffect", type: "date", x:1, y:18, layout:"col-md-6", display: (data) => {return data.dateOfEffect !== null }}, + {name: "dateOfOrder", type: "date", x:2, y:18, layout:"col-md-6", display: (data) => {return data.dateOfEffect !== null }}, + {name: "declarationDetails", type: "custom", x:1, y:19, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "officer", type: "text", x:1, y:21, layout:"col-md-4"}, + {name: "position", type: "text", x:2, y:21, layout:"col-md-4"}, + {name: "Extras", type: "custom", x:1, y:22, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "notes", type: "text", x:1, y:23, layout:"col-md-12"} +]; */ + +const fields = [ + {name: "tags", type:"tags", x:1, y:1, layout:"col-md-12"}, + {name: "marriageDetails", type: "custom", x:1, y:2, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "id", type: "number", x:1, y:3, layout:"col-md-6", disabled: true}, + { + name: "celebrantId", label: "Search Celebrant", type: "custom", x: 1, y: 5, layout: "col-md-12", + component: (name, disabled) => , + }, + { + name: "reportedCelebrant", type: "text", x: 2, y: 6, layout: "col-md-12", + display: (data) => { return data.reportedCelebrant !== null && data.celebrantId === null ? true : false; } + }, + {name: "dateOfMarriage", type: "date", x:1, y: 7, layout:"col-md-6"}, + {name: "timeOfMarriage", type: "time", x:2, y:7, layout:"col-md-6"}, + {name: "unionRegime", type: "select", x:1, y: 8, layout:"col-md-6", metadata: () => regime}, + {name:"addressBox", label: "Place", components: [ + {name: "address", type: "custom", x:1, y:1, layout:"col-md-12", component: (name, disabled) => }, + ], type: "box", x:2, y:9, layout:"col-md-11 ms-2 mt-2 pt-1 pb-2"}, + {name: "wifeDetails", type: "custom", x:1, y:10, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "partner2VitalRecordId", type: "custom", x:1, y:11, layout:"col-md-12", component: (name, disabled) => }, + {name: "husbandDetails", type: "custom", x:1, y:12, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "partner1VitalRecordId", type: "custom", x:1, y:13, layout:"col-md-12", component: (name, disabled) => }, + {name: "witnessDetails", type: "custom", x:1, y:14, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "firstWitnessId", type: "custom", x:1, y:15, layout:"col-md-12", component: (name, disabled) => }, + {name: "secondWitnessId", type: "custom", x:1, y:16, layout:"col-md-12", component: (name, disabled) => }, + + { name: "declarationDetails", type: "custom", x: 1, y: 17, layout: "col-md-12", component: (name, disabled) =>
}, + { + name: "declarantId", label: "Search Declarant", type: "custom", x: 1, y: 19, layout: "col-md-12", + component: (name, disabled) => , + }, + { + name: "reportedDeclarant", type: "text", x: 2, y: 20, layout: "col-md-12", + display: (data) => { return data.reportedDeclarant !== null && data.declarantId === null ? true : false; } + }, + {name:"registrationBox", label: "Registration Location", components: [ + {name: "registrationLocation", type: "custom", x:1, y:1, layout:"col-md-12", component: (name, disabled) => } + ], type: "box", x:2, y:22, layout:"col-md-11 ms-2 mt-2 pt-1 pb-2"}, + { + name: "officerId", label: "Search officer", type: "custom", x: 1, y: 23, layout: "col-md-12", + component: (name, disabled) => , + }, + { + name: "reportedOfficer", type: "text", x: 2, y: 24, layout: "col-md-12", + display: (data) => { return data.reportedOfficer !== null && data.officerId ===null ? true : false; } + }, + {name: "divorceDetails", type: "custom", x:1, y:25, layout:"col-md-12", component: (name, disabled) =>
, display: (data) => {return data.dateOfEffect !== null }}, + {name: "dateOfEffect", type: "date", x:1, y:26, layout:"col-md-6", display: (data) => {return data.dateOfEffect !== null }}, + {name: "dateOfOrder", type: "date", x:2, y:26, layout:"col-md-6", display: (data) => {return data.dateOfEffect !== null }}, + {name: "courtOrderFile", label:"Court Order", type: "file", x:1, y:27, layout:"col-md-12", + uploadUrl: (id) => getCourtOrderUploadUrl(id), + previewUrl: async (id) => getCourtOrderPreviewUrl(id), + loadData: async (id) => loadCourtOrder(id), + handleDelete:(id) => handleCourtOrderDelete(id), + handleClick: (id) => handleCourtOrderClick(id), + updateFileData: (data) => updateCourtOrderFileData(data), + display: (data) => {return data.dateOfEffect !== null } + }, + {name: "Mentions", type: "custom", x:1, y:34, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "mentions", type: "text", x:1, y:35, layout:"col-md-12"}, + {name: "Extras", type: "custom", x:1, y:36, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "notes", type: "text", x:1, y:37, layout:"col-md-12"} +]; + +const getCourtOrderUploadUrl = (id) => { + return getServiceUri() + 'union-record/court-order-file' + '/' + id; +} + +const getCourtOrderPreviewUrl = async (id) => { + const token = await rest.getToken(getServiceUri() + 'token/get-auth-code'); + return getServiceUri() + 'union-record/court-order-file' + '/preview/' + id + '/' + token; +} + +const updateCourtOrderFileData = (data) => { + let filter = {name: data.fileName, description: data.description}; + rest.request(getServiceUri() + 'union-record/court-order-file' + '/' + data.id, "PUT", filter); +} + +const handleCourtOrderClick = async (id) => { + const token = await rest.getToken(getServiceUri() + 'token/get-auth-code'); + window.location = getServiceUri() + 'union-record/court-order-file' + '/' + id + '/' + token; +}; +const handleCourtOrderDelete = (id) => { + rest.delete('union-record/court-order-file', id).then(() => { + DELETE_ATTACHMENT_EVENT.publish(id) + }); +}; +const loadCourtOrder = async (id) => { + let filter = {and: true}; + filter['union-record-court-order-file'] = {}; + filter['union-record-court-order-file']['unionRecordId'] = id; + return rest.search('union-record/court-order-file', filter) +} + + +export const displayUnionRecordForm = (gui, id) => { + const readUnionRecordForm = (onFinish) => (id) => { + let UnionRecordForm = createFormComponent(fields); + let uuid = uuidv4(); + return { + uuid, view: () => { + return ( + <> + loadFormData(id, gui)} readOnly={true} buttons={() => null}/> + getPreviewUrl(id)} loadData={async () => loadUnionRecordAttachment(id)} handleClick={(fileId) => handleUnionRecordAttachmentClick(fileId)} readOnly/> + + ) + } + }; + } + + gui.goTo(readUnionRecordForm(), id); +} + +const handleUnionRecordAttachmentClick = async (id) => { + const token = await rest.getToken(getServiceUri() + 'token/get-auth-code'); + window.location = getServiceUri() + 'union-record-attachment' + '/' + id + '/' + token; +}; + +const getPreviewUrl = (id) => { + return getServiceUri() + 'union-record-attachment' + '/preview/' + id; +} + +const loadUnionRecordAttachment = async (id) => { + let filter = {and: true}; + filter['union-record-attachment'] = {}; + filter['union-record-attachment']['unionRecordId'] = id; + return rest.search('union-record-attachment', filter) +} + +const loadFormData = async (id, gui) => { + return await rest.read('union-record', id).then(response => { + let form = response; + if (form.timeOfMarriage !== null) + form.timeOfMarriage = new Date().setHours(form.timeOfMarriage[0], form.timeOfMarriage[1]); + + let tagFilter = {and: true}; + tagFilter['union-record-tag'] = {unionRecordId: id}; + if (response.dateOfEffect != null) { + rest.read('divorce-certificate/read', id).then(async data => { + setContextualOptions({ + "marriage-records": { + submenu: { + "actions": { + options: { + "amend": { + label: "Amend", do: (gui) => displayNewAmendmentUnionApplicationForm(gui, form) + }, + "marriage-certificate": { + label: "Certificate", do: printDivorceCertificate(data) + }, + }, + label: "Actions" + } + } + } + })}); + } + else + rest.read('marriage-certificate/read', id).then(async data => { + setContextualOptions({ + "marriage-records": { + submenu: { + "actions": { + options: { + "amend": { + label: "Amend", do: (gui) => displayNewAmendmentUnionApplicationForm(gui, form) + }, + "marriage-certificate": { + label: "Certificate", do: printMarriageCertificate(data) + }, + "apply-divorce": { + label: "Apply For Divorce", do: () => applyForDivorce(form, gui) + }, + }, + label: "Actions" + } + } + } + })}); + return rest.search('union-record-tag', tagFilter).then(tags => { + form['tags'] = tags + + return form; + }) + }) +} + +const printMarriageCertificate = (data) => () => { + const printable = { + content:, + style:{certificateStyle}.certificateStyle, + copyParentStyle:false + } + PRINT_EVENT.publish(printable); +} + +const printDivorceCertificate = (data) => () => { + const printable = { + content:, + style:{divorceCertificateStyle}.divorceCertificateStyle, + copyParentStyle:false + } + PRINT_EVENT.publish(printable); +} + +const applyForDivorce = (form, gui) => { + displayNewDivorceRegistrationForm(gui, form); +} diff --git a/src/main/js/forms/administrativeUpdateApplication/AdministrativeUpdateApplicationFormCommon.jsx b/src/main/js/forms/administrativeUpdateApplication/AdministrativeUpdateApplicationFormCommon.jsx new file mode 100644 index 0000000..ab4ab5e --- /dev/null +++ b/src/main/js/forms/administrativeUpdateApplication/AdministrativeUpdateApplicationFormCommon.jsx @@ -0,0 +1,12 @@ + +export const administrativeUpdateApplicationFields = [ + {name: "vitalRecordId", type: "number", x: 1, y: 1, layout: "col-md-12" } +]; + +export const newAdministrativeUpdateApplicationFormForm2Dto = (form, dto) => { + +} + +export const form2dto = (form, dto) => { + +} \ No newline at end of file diff --git a/src/main/js/forms/adoptionApplication/AdoptionApplicationFormCommon.jsx b/src/main/js/forms/adoptionApplication/AdoptionApplicationFormCommon.jsx new file mode 100644 index 0000000..4d6cd5b --- /dev/null +++ b/src/main/js/forms/adoptionApplication/AdoptionApplicationFormCommon.jsx @@ -0,0 +1,394 @@ +import React from "react"; +import _ from 'lodash'; +import { buildEmptyObject } from "../../../../auto/js/widgets/FormComponent"; +import { getServiceUri, metadataLoader, pojoMetadata } from "../../../../auto/js/metadata"; +import { MTLB_TYPE_ADOPTION } from "../../../../auto/js/metadata/MtlbType"; +import { rest } from "../../../../auto/js/services/RestClient"; +import { t } from '../../../../auto/js/services/i18ndb'; +import { showNotification, swapObject } from "../../../../auto/js/utils"; +import * as Yup from 'yup'; +import { Section } from "../../widgets/Section"; +import { AddressComponent } from "../../../../auto/js/widgets/AddressComponent"; +import { PersonComponent } from "../../../../auto/js/widgets/PersonComponent"; +import { loadPersonData } from "../../utils"; +import { GeoDataComponent } from "../../../../auto/js/widgets/GeoDataComponent"; +import { AdvancedSearchPersonComponent } from "../../widgets/AdvancedSearchPersonComponent"; +import { CountryAutoCompleteInput } from "../../widgets/CountryAutoCompleteInput"; +import AutocompleteListSelector from "../../widgets/AutocompleteListSelector"; +import { geoDataMetadataLoader } from "../../../../auto/js/metadata/GeoDataMetadataLoader"; +import { TypeOfAcquisition } from "../../../../auto/js/metadata/TypeOfAcquisition"; +import { DELETE_ATTACHMENT_EVENT } from "../../../../auto/js/events/Gui"; + +const gender = {1:"MALE", 2:"FEMALE"}; +const maritalStatus = {1:"SINGLE", 2:"MARRIED", 3:"DIVORCED", 4:"WIDOWED"}; + +export const adoptionApplicationFields = [ + {name: "tags", type:"tags", x:1, y:1, layout:"col-md-12"}, + {name: "citizenDetails", type: "custom", x:1, y:2, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "image", type: "image", x: 1, y: 3, layout: "col-md-12" }, + {name: "vitalRecordId", type:"number", x: 1, y: 4, layout: "col-md-6" }, + {name: "firstname", type: "text", x:2, y:6, layout:"col-md-6", + "validation": Yup.string().nullable().default(undefined).min(2, t`First name must be at least two characters long`).max(14, t`First name must be less than fifteen characters long`).required(t`First name is required`).matches(/[\p{Letter}\p{Mark}\s]+$/u, t`Only alphabets are allowed for this field `).matches(/^\p{Lu}.*$/u, t`First letter need to be Upper Case`)}, + {name: "secondname", type: "text", x:2, y:5, layout:"col-md-6", + "validation": Yup.string().nullable().default(undefined).min(2, t`Middle name must be at least four characters long`).max(28, t`Middle name must be less than twenty eight characters long`).matches(/^\p{Lu}.*$/u, t`First letter need to be Upper Case`)}, + {name: "thirdname", type: "text", x:1, y: 6, layout:"col-md-6", + "validation": Yup.string().nullable().default(undefined).min(2, t`Melanisian name must be at least four characters long`).max(14, t`Melanisian name must be less than fifteen characters long`).matches(/[\p{Letter}\p{Mark}\s]+$/u, t`Only alphabets are allowed for this field `).matches(/^\p{Lu}.*$/u, t`First letter need to be Upper Case`)}, + {name: "fourthname", type: "text", x:1, y: 5, layout:"col-md-6", + "validation": Yup.string().nullable().default(undefined).min(2, t`Family name must be at least four characters long`).max(14, t`Family name must be less than fifteen characters long`).required(t`Family name is required`).matches(/[\p{Letter}\p{Mark}\s]+$/u, t`Only alphabets are allowed for this field `).matches(/^\p{Lu}.*$/u, t`First letter need to be Upper Case`)}, + {name: "fifthname", type: "text", x:1, y: 7, layout:"col-md-6", + "validation": Yup.string().nullable().default(undefined).min(2, t`Marriage name must be at least four characters long`).max(14, t`Marriage name must be less than fifteen characters long`).matches(/[\p{Letter}\p{Mark}\s]+$/u, t`Only alphabets are allowed for this field `).matches(/^\p{Lu}.*$/u, t`First letter need to be Upper Case`)}, + {name: "gender", type: "select", x:1, y: 8, layout:"col-md-6", metadata: () => gender, + "validation": Yup.string().nullable().default(undefined).required(t`Gender is required`)}, + {name: "maritalStatus", type: "select", x:2, y:8, layout:"col-md-6", metadata: () => maritalStatus}, + {name: "birthdate", type: "date", x:1, y: 9, layout:"col-md-6", + "validation": Yup.date().nullable().default(undefined).required('A date of birth is required') + }, + {name: "birthTime", type: "time", x:2, y:9, layout:"col-md-6"}, + {name: "birthDayUnknown", type: "checkbox", x:1, y:10, layout:"col-md-4"}, + {name: "birthMonthUnknown", type: "checkbox", x:2, y:10, layout:"col-md-4"}, + {name: "birthYearUnknown", type: "checkbox", x:3, y:10, layout:"col-md-4"}, + {name: "disability", type: "checkbox", x:1, y:11, layout:"col-md-6"}, + {name:"citizenshipBox", label: "Citizenship", components: [ + {name: "primaryCitizenship", type:"custom", x:1, y:1, layout:"col-md-6", component: (name, disabled) => }, + {name: "typeOfAcquisition", type:"select", x:2, y:1, layout:"col-md-6", metadata: () => swapObject(TypeOfAcquisition)}, + {name: "otherCitizenshipCsv", type: "custom", x:1, y:3, layout: "col-md-6", component: (name, disabled) => }, + ], type: "box", x:2, y:12, layout:"col-md-11 ms-2 mt-2 pt-1 pb-2"}, + {name:"birthBox", label: "Birth Place", components: [ + {name: "birthPlace", type: "custom", x:1, y:1, layout:"col-md-12", component: (name, disabled) => } + ], type: "box", x:2, y:13, layout:"col-md-11 ms-2 mt-2 pt-1 pb-2"}, + {name:"originBox", label: "Village Of Origin", components: [ + {name: "villageOfOrigin", type: "custom", x:1, y:1, layout:"col-md-12", component: (name, disabled) => }, + ], type: "box", x:1, y:14, layout:"col-md-6 ms-2 mt-2 pt-1 pb-2"}, + {name: "birthMotherDetails", type: "custom", x:1, y:16, layout:"col-md-12", component: (name, disabled) =>
}, + {name:"motherInfo", options: [ + {"name":"motherWithBirthRecord","label":"Birth Mother With Record"}, + {"name":"motherWithoutBirthRecord","label":"Birth Mother Without Record"}, + {"name":"unknownMother","label":"Unknown Birth Mother"}, + ], type: "radio", x:1, y:17, layout:"col-md-12 pt-4"}, + {name: "motherId", label: "Search Birth Mother", type: "custom", x:1, y:17, layout:"col-md-12", + component: (name, disabled) => , + display: (data) => {return (data.motherInfo === "motherWithBirthRecord" || data.motherId != null)?true: false;}}, + {name: "reportedMotherName", type: "text", x:2, y:17, layout:"col-md-12", + display: (data) => {return data.motherInfo === "motherWithoutBirthRecord"?true: false;} + }, + {name: "birthFatherDetails", type: "custom", x:1, y:18, layout:"col-md-12", component: (name, disabled) =>
}, + {name:"fatherInfo", options: [ + {"name":"fatherWithBirthRecord","label":"Birth Father With Record"}, + {"name":"fatherWithoutBirthRecord","label":"Birth Father Without Record"}, + {"name":"unknownFather","label":"Unknown Birth Father"}, + ], type: "radio", x:1, y:20, layout:"col-md-12 pt-4"}, + {name: "fatherId", label: "Search Birth Father", type: "custom", x:1, y:21, layout:"col-md-12", + component: (name, disabled) => , + display: (data) => {return (data.fatherInfo === "fatherWithBirthRecord" || data.fatherId != null)?true: false;}}, + {name: "reportedFatherName", type: "text", x:2, y:22, layout:"col-md-12", + display: (data) => {return data.fatherInfo === "fatherWithoutBirthRecord"?true: false;} + }, + {name: "newAdoptionDetails", type: "custom", x:1, y:23, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "notChangingMother", type: "checkbox", x:1, y: 24, layout:"col-md-12"}, + {name: "adoptiveMotherId", label: "Search Adoptive Mother", type: "custom", x:1, y:25, layout:"col-md-12", + component: (name, disabled) => , + display: (data) => {return !data.notChangingMother} + }, + {name: "motherAdoptionDate", type: "date", x:1, y: 26, layout:"col-md-6", display: (data) => {return !data.notChangingMother}}, + {name: "notChangingFather", type: "checkbox", x:1, y: 27, layout:"col-md-12"}, + {name: "adoptiveFatherId", label: "Search Adoptive Father", type: "custom", x:1, y:28, layout:"col-md-12", + component: (name, disabled) => , + display: (data) => {return !data.notChangingFather} + }, + {name: "fatherAdoptionDate", type: "date", x:1, y: 29, layout:"col-md-6", display: (data) => {return !data.notChangingFather}}, + {name: "courtAdoptionNumber", type: "text", x:1, y: 30, layout:"col-md-12"}, + {name: "previousAdoptiveFatherDetails", type: "custom", x:1, y:31, layout:"col-md-12", component: (name, disabled) =>
, + display: (data) => {return data.prevFatherId} + }, + {name: "prevFatherId", label: "", type: "custom", x:1, y:32, layout:"col-md-12", + component: (name, disabled) => , + display: (data) => {return data.prevFatherId} + }, + {name: "fatherEndAdoptionDate", type: "date", x:1, y: 33, layout:"col-md-6", display: (data) => {return data.prevFatherId}}, + {name: "previousAdoptiveMotherDetails", type: "custom", x:1, y:34, layout:"col-md-12", component: (name, disabled) =>
, + display: (data) => {return data.prevMotherId} + }, + {name: "prevMotherId", label: "", type: "custom", x:1, y:35, layout:"col-md-12", + component: (name, disabled) => , + display: (data) => {return data.prevMotherId} + }, + {name: "motherEndAdoptionDate", type: "date", x:1, y: 36, layout:"col-md-6", display: (data) => {return data.prevMotherId}}, + + {name: "medicalNotificationFile", label:"Medical Notification", type: "file", x:1, y:37, layout:"col-md-12", + uploadUrl: (id) => getUploadUrl(id), + previewUrl: (id) => getPreviewUrl(id), + loadData: async (id) => loadMedicalNotificationAttachment(id), + handleDelete:(id) => handleMedicalNotificationDelete(id), + handleClick: (id) => handleMedicalNotificationClick(id), + updateFileData: (data) => updateFileData(data) + }, + {name: "Mentions", type: "custom", x:1, y:38, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "mentions", type: "text", x:1, y:39, layout:"col-md-12"}, + {name: "Extras", type: "custom", x:1, y:40, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "notes", type: "text", x:1, y:41, layout:"col-md-12"} +]; + +const getUploadUrl = (id) => { + return getServiceUri() + 'civil-status-mtlb/medical-notification-file' + '/' + id; +} + +const getPreviewUrl = (id) => { + return getServiceUri() + 'civil-status-mtlb/medical-notification-file' + '/preview/' + id; +} + +const updateFileData = (data) => { + let filter = {name: data.fileName, description: data.description}; + rest.request(getServiceUri() + 'civil-status-mtlb/medical-notification-file' + '/' + data.id, "PUT", filter); +} + +const handleMedicalNotificationClick = async (id) => { + const token = await rest.getToken(getServiceUri() + 'token/get-auth-code'); + window.location = getServiceUri() + 'civil-status-mtlb/medical-notification-file' + '/' + id + '/' + token; +}; +const handleMedicalNotificationDelete = (id) => { + rest.delete('civil-status-mtlb/medical-notification-file', id).then(() => { + DELETE_ATTACHMENT_EVENT.publish(id) + }); +}; + +const loadMedicalNotificationAttachment = async (id) => { + let filter = {and: true}; + filter['civil-status-mtlb-medical-notification-file'] = {}; + filter['civil-status-mtlb-medical-notification-file']['civilStatusMtlbId'] = id; + return rest.search('civil-status-mtlb/medical-notification-file', filter) +} + +export const saveAdoptionApplicationForm = async (formData) => { + let data = _.clone(formData); + let dto = pojoMetadata['civil-status-mtlb'].form2dto(data); + dto.mtlbType = MTLB_TYPE_ADOPTION; + dto.vitalRecordId = formData.id; + dto.id = null; + if (formData.faceId && formData.faceId != null) { + return rest.read('face', formData.faceId).then(faceObject => { + dto.face = faceObject.image; + dto.faceMimeType = faceObject.faceMimeType; + if (formData.birthCountry) + dto.birthCountry = formData.birthCountry.key; + try { + return rest.request(getServiceUri() + 'apply/create-civil-status-mtlb', 'POST', dto) + } catch (err) { + alert(err); + } + }) + } + else { + if (!formData.image.isEmpty) { + let base64Image = formData.image.url; + let faceMimeType = base64Image.substring(base64Image.indexOf(':') + 1, base64Image.indexOf(';')) + let base64 = base64Image.substr(base64Image.indexOf(',') + 1); + dto.face = base64; + dto.faceMimeType = faceMimeType; + } + if (formData.birthCountry) + dto.birthCountry = formData.birthCountry.key; + try { + return rest.request(getServiceUri() + 'apply/create-civil-status-mtlb', 'POST', dto) + } catch (err) { + alert(err); + } + } +} + +export const loadAdoptionApplicationFormData = async (id) => { + return await rest.read('civil-status-mtlb', id).then(response => { + let form = response; + let face = null; + if (response.face != null) { + let mimeType = response['faceMimeType']; + face = "data:".concat(mimeType, ";base64,", response.face) + } + if (response.birthCountry != null) { + let countryMetadata = metadataLoader.get('country'); + form.birthCountry = {key: response.birthCountry, value: countryMetadata[response.birthCountry]} + } + if (response.secondname != null) { + form['middlename'] = response.secondname; + if (response.thirdname != null) + form['middlename'] = form['middlename'] + " " + response.thirdname; + } + if (response.birthTime !== null) + response.birthTime = new Date().setHours(response.birthTime[0], response.birthTime[1]); + form['image'] = {x: 0.5, y:0.5, scale: 1, rotate: 0, url: (face != null)?face: '/public/avatar.png', isEmpty: true}; + + + let tagFilter = {and: true}; + tagFilter['civil-status-mtlb-tag'] = {civilStatusMtlbId: id}; + + return rest.search('civil-status-mtlb-tag', tagFilter).then(tags => { + form['tags'] = tags + + return form; + }) + }) +} + +export const updatePendingAdoptionApplicationForm = async (formData) => { + let dto = pojoMetadata['civil-status-mtlb'].form2dto(formData); + form2dto(formData, dto); + try { + return rest.request(getServiceUri() + 'civil-status-mtlb/pending/update', 'POST', dto); + } catch (err) { + alert(err); + } +} + +export const updateAdoptionApplicationForm = async (formData) => { + let dto = pojoMetadata['civil-status-mtlb'].form2dto(formData); + form2dto(formData, dto); + try { + return rest.update('civil-status-mtlb', dto); + } catch (err) { + alert(err); + } +} + +export const deleteAdoptionApplicationForm = async (id) => { + try { + return rest.delete('civil-status-mtlb', id); + } catch (err) { + alert(err); + } +} + +export const updateRejectedAdoptionApplicationForm = async (formData) => { + //TODO: Move form2dto from pojo metadata + let dto = pojoMetadata['civil-status-mtlb'].form2dto(formData); + form2dto(formData, dto); + try { + return rest.request(getServiceUri() + 'civil-status-mtlb/rejected/update', 'POST', dto); + } catch (err) { + alert(err); + } +} + +export const rejectAdoptionApplicationForm = async (id) => { + try { + return rest.request(getServiceUri() + 'civil-status-mtlb/pending/reject', 'POST', id); + } catch (err) { + alert(err); + } +} + +export const rejectReadyAdoptionApplicationForm = async (id) => { + try { + return rest.request(getServiceUri() + 'civil-status-mtlb/ready/reject', 'POST', id); + } catch (err) { + alert(err); + } +} + +export const approveReadyAdoptionApplicationForm = async (id) => { + try { + return rest.request(getServiceUri() + 'civil-status-mtlb/ready/approve', 'POST', id); + } catch (err) { + alert(err); + } +} + +export const buildNewAdoptionApplicationForm = () => { + const empty = buildEmptyObject(adoptionApplicationFields); + empty['image'] = {x: 0.5, y:0.5, scale: 1, rotate: 0, url:'/public/avatar.png', isEmpty: true}; + empty['birthCountry'] = {key: 191, value: 'Vanuatu'} + return empty; +} + +export const loadCivilStatusMtlbAttachment = async (id) => { + let filter = {and: true}; + filter['civil-status-mtlb-attachment'] = {}; + filter['civil-status-mtlb-attachment']['civilStatusMtlbId'] = id; + return rest.search('civil-status-mtlb/attachment', filter) +} + +export const form2dto = (formData, dto) => { + dto.mtlbType = MTLB_TYPE_ADOPTION; + if (!formData.image.isEmpty) { + let base64Image = formData.image.url; + let faceMimeType = base64Image.substring(base64Image.indexOf(':') + 1, base64Image.indexOf(';')) + let base64 = base64Image.substr(base64Image.indexOf(',') + 1); + dto.face = base64; + dto.faceMimeType = faceMimeType; + } + if (formData.middlename != null) { + let names = formData.middlename.split(" "); + dto.secondname = names[0] + if (names.length > 1) + dto.thirdname = names[1]; + } + if (formData.birthCountry) + dto.birthCountry = formData.birthCountry.key; + if (formData.birthTime != null && typeof(formData.birthTime) != 'string') { + const date = new Date(formData.birthTime) + let birthHour = date.getHours() < 10 ? '0' + date.getHours() : date.getHours(); + let birthMinute = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes(); + dto.birthTime = birthHour + ":" + birthMinute; + } + if (formData.otherCitizenshipCsv !== null && formData.otherCitizenshipCsv && Array.isArray(formData.otherCitizenshipCsv)) { + let otherCitizenshipCsv = formData.otherCitizenshipCsv.join(','); + dto.otherCitizenshipCsv = otherCitizenshipCsv; + } + if (formData.typeOfAcquisition != null) + dto.typeOfAcquisition = swapObject(TypeOfAcquisition)[formData.typeOfAcquisition] +} + + +export const dto2form = (response) => { + let form = response; + let face = null; + if (response.face != null) { + let mimeType = response['faceMimeType']; + face = "data:".concat(mimeType, ";base64,", response.face) + } + if (response.otherCitizenshipCsv == null || response.otherCitizenshipCsv === "") + response.otherCitizenshipCsv = [] + else { + let values = []; + let components = response.otherCitizenshipCsv.split(","); + components.forEach(element => { + values.push(parseInt(element)) + }); + response.otherCitizenshipCsv = values; + } + if (response.birthTime !== null) { + response.birthTime = new Date().setHours(response.birthTime[0], response.birthTime[1]); + } + form['image'] = {x: 0.5, y:0.5, scale: 1, rotate: 0, url: (face != null)?face: '/public/avatar.png', isEmpty: (face == null)}; + if (response.motherId == null) { + if (response.reportedMotherName != null) + form.motherInfo = "motherWithoutBirthRecord" + else if (response.unknownMother != null && response.unknownMother) + form.motherInfo = "unknownMother" + else + form.motherInfo = "motherWithoutBirthRecord" + } else + form.motherInfo = "motherWithBirthRecord" + + if (response.fatherId == null) { + if (response.reportedFatherName != null) + form.fatherInfo = "fatherWithoutBirthRecord" + else if (response.unknownFather != null && response.unknownFather) + form.fatherInfo = "unknownFather" + else + form.fatherInfo = "fatherWithoutBirthRecord" + } else + form.fatherInfo = "fatherWithBirthRecord" + if (response.typeOfAcquisition != null) + form.typeOfAcquisition = TypeOfAcquisition[response.typeOfAcquisition] + return form; +} + +export const newAdoptionApplicationFormForm2Dto = (formData, dto) => { + dto.vitalRecordId = formData.id; + dto.id = null; + if (formData.otherCitizenshipCsv !== null && formData.otherCitizenshipCsv) { + let otherCitizenshipCsv = formData.otherCitizenshipCsv.join(','); + dto.otherCitizenshipCsv = otherCitizenshipCsv; + } + dto.adoptiveFatherId = null; + dto.adoptiveMotherId = null; +} \ No newline at end of file diff --git a/src/main/js/forms/amendmentApplication/AmendmentApplicationFormCommon.jsx b/src/main/js/forms/amendmentApplication/AmendmentApplicationFormCommon.jsx new file mode 100644 index 0000000..a68dbd2 --- /dev/null +++ b/src/main/js/forms/amendmentApplication/AmendmentApplicationFormCommon.jsx @@ -0,0 +1,383 @@ +import React from "react"; +import _ from 'lodash'; +import { buildEmptyObject } from "../../../../auto/js/widgets/FormComponent"; +import { getServiceUri, metadataLoader, pojoMetadata } from "../../../../auto/js/metadata"; +import { MTLB_TYPE_CIVIL_STATUS_CHANGE } from "../../../../auto/js/metadata/MtlbType"; +import { rest } from "../../../../auto/js/services/RestClient"; +import { t } from '../../../../auto/js/services/i18ndb'; +import { showNotification, swapObject } from "../../../../auto/js/utils"; +import * as Yup from 'yup'; +import { Section } from "../../widgets/Section"; +import { AddressComponent } from "../../../../auto/js/widgets/AddressComponent"; +import { PersonComponent } from "../../../../auto/js/widgets/PersonComponent"; +import { loadPersonData } from "../../utils"; +import { GeoDataComponent } from "../../../../auto/js/widgets/GeoDataComponent"; +import { AdvancedSearchPersonComponent } from "../../widgets/AdvancedSearchPersonComponent"; +import { CountryAutoCompleteInput } from "../../widgets/CountryAutoCompleteInput"; +import AutocompleteListSelector from "../../widgets/AutocompleteListSelector"; +import { geoDataMetadataLoader } from "../../../../auto/js/metadata/GeoDataMetadataLoader"; +import { TypeOfAcquisition } from "../../../../auto/js/metadata/TypeOfAcquisition"; +import { DELETE_ATTACHMENT_EVENT } from "../../../../auto/js/events/Gui"; +import { buildFemaleEmptyObject, buildMaleEmptyObject } from "../birthRegistration/BirthRegistrationFormCommon"; +import { formState } from "../../../../auto/js/forms/FormState"; +import { ContactComponent } from "../../widgets/ContactComponent"; + +const gender = {1:"MALE", 2:"FEMALE"}; +const maritalStatus = {1:"SINGLE", 2:"MARRIED", 3:"DIVORCED", 4:"WIDOWED"}; + +export const amendmentApplicationFields = [ + {name: "tags", type:"tags", x:1, y:1, layout:"col-md-12"}, + {name: "citizenDetails", type: "custom", x:1, y:2, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "image", type: "image", x: 1, y: 3, layout: "col-md-12" }, + {name: "vitalRecordId", type:"number", x: 1, y: 4, layout: "col-md-6", disabled: true }, + {name: "firstname", type: "text", x:2, y:6, layout:"col-md-6", + "validation": Yup.string().nullable().default(undefined).min(2, t`First name must be at least two characters long`).max(14, t`First name must be less than fifteen characters long`).required(t`First name is required`).matches(/[\p{Letter}\p{Mark}\s]+$/u, t`Only alphabets are allowed for this field `).matches(/^\p{Lu}.*$/u, t`First letter need to be Upper Case`)}, + {name: "secondname", type: "text", x:2, y:5, layout:"col-md-6", + "validation": Yup.string().nullable().default(undefined).min(2, t`Middle name must be at least four characters long`).max(28, t`Middle name must be less than twenty eight characters long`).matches(/^\p{Lu}.*$/u, t`First letter need to be Upper Case`)}, + {name: "thirdname", type: "text", x:1, y: 6, layout:"col-md-6", + "validation": Yup.string().nullable().default(undefined).min(2, t`Melanisian name must be at least four characters long`).max(14, t`Melanisian name must be less than fifteen characters long`).matches(/[\p{Letter}\p{Mark}\s]+$/u, t`Only alphabets are allowed for this field `).matches(/^\p{Lu}.*$/u, t`First letter need to be Upper Case`)}, + {name: "fourthname", type: "text", x:1, y: 5, layout:"col-md-6", + "validation": Yup.string().nullable().default(undefined).min(2, t`Family name must be at least four characters long`).max(14, t`Family name must be less than fifteen characters long`).required(t`Family name is required`).matches(/[\p{Letter}\p{Mark}\s]+$/u, t`Only alphabets are allowed for this field `).matches(/^\p{Lu}.*$/u, t`First letter need to be Upper Case`)}, + {name: "fifthname", type: "text", x:1, y: 7, layout:"col-md-6", + "validation": Yup.string().nullable().default(undefined).min(2, t`Marriage name must be at least four characters long`).max(14, t`Marriage name must be less than fifteen characters long`).matches(/[\p{Letter}\p{Mark}\s]+$/u, t`Only alphabets are allowed for this field `).matches(/^\p{Lu}.*$/u, t`First letter need to be Upper Case`)}, + {name: "gender", type: "select", x:1, y: 8, layout:"col-md-6", metadata: () => gender, + "validation": Yup.string().nullable().default(undefined).required(t`Gender is required`)}, + {name: "maritalStatus", type: "select", x:2, y:8, layout:"col-md-6", metadata: () => maritalStatus}, + {name: "birthdate", type: "date", x:1, y: 9, layout:"col-md-6", + "validation": Yup.date().nullable().default(undefined).required('A date of birth is required') + }, + {name: "birthTime", type: "time", x:2, y:9, layout:"col-md-6"}, + {name: "birthDayUnknown", type: "checkbox", x:1, y:10, layout:"col-md-4"}, + {name: "birthMonthUnknown", type: "checkbox", x:2, y:10, layout:"col-md-4"}, + {name: "birthYearUnknown", type: "checkbox", x:3, y:10, layout:"col-md-4"}, + {name: "disability", type: "checkbox", x:1, y:11, layout:"col-md-6"}, + {name:"citizenshipBox", label: "Citizenship", components: [ + {name: "primaryCitizenship", type:"custom", x:1, y:1, layout:"col-md-6", component: (name, disabled) => }, + {name: "typeOfAcquisition", type:"select", x:2, y:1, layout:"col-md-6", metadata: () => swapObject(TypeOfAcquisition)}, + {name: "otherCitizenshipCsv", type: "custom", x:1, y:3, layout: "col-md-6", component: (name, disabled) => }, + ], type: "box", x:2, y:12, layout:"col-md-11 ms-2 mt-2 pt-1 pb-2"}, + {name:"birthBox", label: "Birth Place", components: [ + {name: "birthPlace", type: "custom", x:1, y:1, layout:"col-md-12", component: (name, disabled) => } + ], type: "box", x:2, y:13, layout:"col-md-11 ms-2 mt-2 pt-1 pb-2"}, + {name:"originBox", label: "Village Of Origin", components: [ + {name: "villageOfOrigin", type: "custom", x:1, y:1, layout:"col-md-12", component: (name, disabled) => }, + ], type: "box", x:1, y:14, layout:"col-md-6 ms-2 mt-2 pt-1 pb-2"}, + {name: "motherDetails", type: "custom", x:1, y:16, layout:"col-md-12", component: (name, disabled) =>
}, + {name:"motherInfo", options: [ + {"name":"motherWithBirthRecord","label":"motherWithBirthRecord"}, + {"name":"motherWithoutBirthRecord","label":"motherWithoutBirthRecord"}, + {"name":"unknownMother","label":"unknownMother"}, + ], type: "radio", x:1, y:17, layout:"col-md-12 pt-4"}, + {name: "motherId", label: "Search Mother", type: "custom", x:1, y:17, layout:"col-md-12", + component: (name, disabled) => , + display: (data) => {return (data.motherInfo === "motherWithBirthRecord" || data.motherId != null)?true: false;}}, + { + name: "motherGenderValidation", type: "validation", x: 1, y: 18, layout: "col-md-6", + "validation": Yup.boolean().test("motherGenderValidation", "Mother need to be female", function () { + return (formState.getState()["motherId-gender"])? formState.getState()["motherId-gender"] === "FEMALE": true; + }) + }, + {name: "reportedMotherName", type: "text", x:2, y:19, layout:"col-md-12", + display: (data) => {return data.motherInfo === "motherWithoutBirthRecord"?true: false;} + }, + {name: "fatherDetails", type: "custom", x:1, y:20, layout:"col-md-12", component: (name, disabled) =>
}, + {name:"fatherInfo", options: [ + {"name":"fatherWithBirthRecord","label":"fatherWithBirthRecord"}, + {"name":"fatherWithoutBirthRecord","label":"fatherWithoutBirthRecord"}, + {"name":"unknownFather","label":"unknownFather"}, + ], type: "radio", x:1, y:21, layout:"col-md-12 pt-4"}, + {name: "fatherId", label: "Search Father", type: "custom", x:1, y:22, layout:"col-md-12", + component: (name, disabled) => , + display: (data) => {return (data.fatherInfo === "fatherWithBirthRecord" || data.fatherId != null)?true: false;}}, + { + name: "fatherGenderValidation", type: "validation", x: 1, y: 23, layout: "col-md-6", + "validation": Yup.boolean().test("fatherGenderValidation", "Father need to be male", function () { + return (formState.getState()["fatherId-gender"])? formState.getState()["fatherId-gender"] === "MALE": true; + }) + }, + {name: "reportedFatherName", type: "text", x:2, y:24, layout:"col-md-12", + display: (data) => {return data.fatherInfo === "fatherWithoutBirthRecord"?true: false;} + }, + {name: "medicalNotificationFile", label:"Medical Notification", type: "file", x:1, y:25, layout:"col-md-12", + uploadUrl: (id) => getUploadUrl(id), + previewUrl: (id) => getPreviewUrl(id), + loadData: async (id) => loadMedicalNotificationAttachment(id), + handleDelete:(id) => handleMedicalNotificationDelete(id), + handleClick: (id) => handleMedicalNotificationClick(id), + updateFileData: (data) => updateFileData(data) + }, + {name: "declarantDetails", type: "custom", x:1, y:26, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "declarantId", type: "custom", x:1, y:27, layout:"col-md-12", component: (name, disabled) => }, + {name:"registrationBox", label: "Registration Location", components: [ + {name: "registrationLocation", type: "custom", x:1, y:1, layout:"col-md-12", component: (name, disabled) => } + ], type: "box", x:2, y:28, layout:"col-md-11 ms-2 mt-2 pt-1 pb-2"}, + + {name: "Mentions", type: "custom", x:1, y:30, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "mentions", type: "text", x:1, y:31, layout:"col-md-12"}, + {name: "Extras", type: "custom", x:1, y:32, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "notes", type: "text", x:1, y:33, layout:"col-md-12"} + +]; + +const getUploadUrl = (id) => { + return getServiceUri() + 'civil-status-mtlb/medical-notification-file' + '/' + id; +} + +const getPreviewUrl = (id) => { + return getServiceUri() + 'civil-status-mtlb/medical-notification-file' + '/preview/' + id; +} + +const updateFileData = (data) => { + let filter = {name: data.fileName, description: data.description}; + rest.request(getServiceUri() + 'civil-status-mtlb/medical-notification-file' + '/' + data.id, "PUT", filter); +} + +const handleMedicalNotificationClick = async (id) => { + const token = await rest.getToken(getServiceUri() + 'token/get-auth-code'); + window.location = getServiceUri() + 'civil-status-mtlb/medical-notification-file' + '/' + id + '/' + token; +}; +const handleMedicalNotificationDelete = (id) => { + rest.delete('civil-status-mtlb/medical-notification-file', id).then(() => { + DELETE_ATTACHMENT_EVENT.publish(id) + }); +}; + +const loadMedicalNotificationAttachment = async (id) => { + let filter = {and: true}; + filter['civil-status-mtlb-medical-notification-file'] = {}; + filter['civil-status-mtlb-medical-notification-file']['civilStatusMtlbId'] = id; + return rest.search('civil-status-mtlb/medical-notification-file', filter) +} + +export const saveAmendmentApplicationForm = async (formData) => { + let data = _.clone(formData); + let dto = pojoMetadata['civil-status-mtlb'].form2dto(data); + dto.mtlbType = MTLB_TYPE_CIVIL_STATUS_CHANGE; + dto.vitalRecordId = formData.id; + dto.id = null; + if (formData.faceId && formData.faceId != null) { + return rest.read('face', formData.faceId).then(faceObject => { + dto.face = faceObject.image; + dto.faceMimeType = faceObject.faceMimeType; + if (formData.birthCountry) + dto.birthCountry = formData.birthCountry.key; + try { + return rest.request(getServiceUri() + 'apply/create-civil-status-mtlb', 'POST', dto) + } catch (err) { + alert(err); + } + }) + } + else { + if (!formData.image.isEmpty) { + let base64Image = formData.image.url; + let faceMimeType = base64Image.substring(base64Image.indexOf(':') + 1, base64Image.indexOf(';')) + let base64 = base64Image.substr(base64Image.indexOf(',') + 1); + dto.face = base64; + dto.faceMimeType = faceMimeType; + } + if (formData.birthCountry) + dto.birthCountry = formData.birthCountry.key; + try { + return rest.request(getServiceUri() + 'apply/create-civil-status-mtlb', 'POST', dto) + } catch (err) { + alert(err); + } + } +} + +export const loadAmendmentApplicationFormData = async (id) => { + return await rest.read('civil-status-mtlb', id).then(response => { + let form = response; + let face = null; + if (response.face != null) { + let mimeType = response['faceMimeType']; + face = "data:".concat(mimeType, ";base64,", response.face) + } + if (response.birthCountry != null) { + let countryMetadata = metadataLoader.get('country'); + form.birthCountry = {key: response.birthCountry, value: countryMetadata[response.birthCountry]} + } + if (response.secondname != null) { + form['middlename'] = response.secondname; + if (response.thirdname != null) + form['middlename'] = form['middlename'] + " " + response.thirdname; + } + if (response.birthTime !== null) + response.birthTime = new Date().setHours(response.birthTime[0], response.birthTime[1]); + form['image'] = {x: 0.5, y:0.5, scale: 1, rotate: 0, url: (face != null)?face: '/public/avatar.png', isEmpty: true}; + + + let tagFilter = {and: true}; + tagFilter['civil-status-mtlb-tag'] = {civilStatusMtlbId: id}; + + return rest.search('civil-status-mtlb-tag', tagFilter).then(tags => { + form['tags'] = tags + + return form; + }) + }) +} + +export const updatePendingAmendmentApplicationForm = async (formData) => { + let dto = pojoMetadata['civil-status-mtlb'].form2dto(formData); + form2dto(formData, dto); + try { + return rest.request(getServiceUri() + 'civil-status-mtlb/pending/update', 'POST', dto); + } catch (err) { + alert(err); + } +} + +export const updateAmendmentApplicationForm = async (formData) => { + let dto = pojoMetadata['civil-status-mtlb'].form2dto(formData); + form2dto(formData, dto); + try { + return rest.update('civil-status-mtlb', dto); + } catch (err) { + alert(err); + } +} + +export const deleteAmendmentApplicationForm = async (id) => { + try { + return rest.delete('civil-status-mtlb', id); + } catch (err) { + alert(err); + } +} + +export const updateRejectedAmendmentApplicationForm = async (formData) => { + //TODO: Move form2dto from pojo metadata + let dto = pojoMetadata['civil-status-mtlb'].form2dto(formData); + form2dto(formData, dto); + try { + return rest.request(getServiceUri() + 'civil-status-mtlb/rejected/update', 'POST', dto); + } catch (err) { + alert(err); + } +} + +export const rejectAmendmentApplicationForm = async (id) => { + try { + return rest.request(getServiceUri() + 'civil-status-mtlb/pending/reject', 'POST', id); + } catch (err) { + alert(err); + } +} + +export const rejectReadyAmendmentApplicationForm = async (id) => { + try { + return rest.request(getServiceUri() + 'civil-status-mtlb/ready/reject', 'POST', id); + } catch (err) { + alert(err); + } +} + +export const approveReadyAmendmentApplicationForm = async (id) => { + try { + return rest.request(getServiceUri() + 'civil-status-mtlb/ready/approve', 'POST', id); + } catch (err) { + alert(err); + } +} + +export const buildNewAmendmentApplicationForm = () => { + const empty = buildEmptyObject(amendmentApplicationFields); + empty['image'] = {x: 0.5, y:0.5, scale: 1, rotate: 0, url:'/public/avatar.png', isEmpty: true}; + empty['birthCountry'] = {key: 191, value: 'Vanuatu'} + return empty; +} + +export const loadCivilStatusMtlbAttachment = async (id) => { + let filter = {and: true}; + filter['civil-status-mtlb-attachment'] = {}; + filter['civil-status-mtlb-attachment']['civilStatusMtlbId'] = id; + return rest.search('civil-status-mtlb/attachment', filter) +} + +export const form2dto = (formData, dto) => { + dto.mtlbType = MTLB_TYPE_CIVIL_STATUS_CHANGE; + if (!formData.image.isEmpty) { + let base64Image = formData.image.url; + let faceMimeType = base64Image.substring(base64Image.indexOf(':') + 1, base64Image.indexOf(';')) + let base64 = base64Image.substr(base64Image.indexOf(',') + 1); + dto.face = base64; + dto.faceMimeType = faceMimeType; + } + if (formData.middlename != null) { + let names = formData.middlename.split(" "); + dto.secondname = names[0] + if (names.length > 1) + dto.thirdname = names[1]; + } + if (formData.birthCountry) + dto.birthCountry = formData.birthCountry.key; + if (formData.birthTime != null && typeof(formData.birthTime) != 'string') { + const date = new Date(formData.birthTime) + let birthHour = date.getHours() < 10 ? '0' + date.getHours() : date.getHours(); + let birthMinute = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes(); + dto.birthTime = birthHour + ":" + birthMinute; + } + if (formData.otherCitizenshipCsv !== null && formData.otherCitizenshipCsv && Array.isArray(formData.otherCitizenshipCsv)) { + let otherCitizenshipCsv = formData.otherCitizenshipCsv.join(','); + dto.otherCitizenshipCsv = otherCitizenshipCsv; + } + if (formData.typeOfAcquisition != null) + dto.typeOfAcquisition = swapObject(TypeOfAcquisition)[formData.typeOfAcquisition] +} + + +export const dto2form = (response) => { + let form = response; + let face = null; + if (response.face != null) { + let mimeType = response['faceMimeType']; + face = "data:".concat(mimeType, ";base64,", response.face) + } + if (response.otherCitizenshipCsv == null || response.otherCitizenshipCsv === "") + response.otherCitizenshipCsv = [] + else { + let values = []; + let components = response.otherCitizenshipCsv.split(","); + components.forEach(element => { + values.push(parseInt(element)) + }); + response.otherCitizenshipCsv = values; + } + if (response.birthTime !== null) { + response.birthTime = new Date().setHours(response.birthTime[0], response.birthTime[1]); + } + form['image'] = {x: 0.5, y:0.5, scale: 1, rotate: 0, url: (face != null)?face: '/public/avatar.png', isEmpty: (face == null)}; + if (response.motherId == null) { + if (response.reportedMotherName != null) + form.motherInfo = "motherWithoutBirthRecord" + else if (response.unknownMother != null && response.unknownMother) + form.motherInfo = "unknownMother" + else + form.motherInfo = "motherWithoutBirthRecord" + } else + form.motherInfo = "motherWithBirthRecord" + + if (response.fatherId == null) { + if (response.reportedFatherName != null) + form.fatherInfo = "fatherWithoutBirthRecord" + else if (response.unknownFather != null && response.unknownFather) + form.fatherInfo = "unknownFather" + else + form.fatherInfo = "fatherWithoutBirthRecord" + } else + form.fatherInfo = "fatherWithBirthRecord" + if (response.typeOfAcquisition != null) + form.typeOfAcquisition = TypeOfAcquisition[response.typeOfAcquisition] + return form; +} + +export const newAmendmentApplicationFormForm2Dto = (formData, dto) => { + dto.vitalRecordId = formData.id; + dto.id = null; + if (formData.otherCitizenshipCsv !== null && formData.otherCitizenshipCsv) { + let otherCitizenshipCsv = formData.otherCitizenshipCsv.join(','); + dto.otherCitizenshipCsv = otherCitizenshipCsv; + } +} \ No newline at end of file diff --git a/src/main/js/forms/amendmentDeathApplication/AmendmentDeathApplicationFormCommon.jsx b/src/main/js/forms/amendmentDeathApplication/AmendmentDeathApplicationFormCommon.jsx new file mode 100644 index 0000000..fc5f81e --- /dev/null +++ b/src/main/js/forms/amendmentDeathApplication/AmendmentDeathApplicationFormCommon.jsx @@ -0,0 +1,141 @@ +import React from "react"; +import _ from 'lodash'; +import { buildEmptyObject } from "../../../../auto/js/widgets/FormComponent"; +import { getServiceUri } from "../../../../auto/js/metadata"; +import { MTLB_TYPE_DEATH_RECORD_CHANGE } from "../../../../auto/js/metadata/MtlbType"; +import { rest } from "../../../../auto/js/services/RestClient"; +import * as Yup from 'yup'; +import { Section } from "../../widgets/Section"; +import { loadPersonData } from "../../utils"; +import { GeoDataComponent } from "../../../../auto/js/widgets/GeoDataComponent"; +import { AdvancedSearchPersonComponent } from "../../widgets/AdvancedSearchPersonComponent"; +import { formState } from "../../../../auto/js/forms/FormState"; +import { DELETE_ATTACHMENT_EVENT } from "../../../../auto/js/events/Gui"; + +export const amendmentDeathApplicationFields = [ + { name: "tags", type: "tags", x: 1, y: 1, layout: "col-md-12" }, + {name: "deceasedDetails", type: "custom", x:1, y:2, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "vitalRecordId", type: "custom", x:1, y: 3, layout:"col-md-12", component: (name, disabled) => }, + {name: "deathDetails", type: "custom", x:1, y:4, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "dateOfDeath", type: "date", x:1, y: 5, layout:"col-md-6", "validation": Yup.date().test( + 'is-after-birthdate', + 'Date of death must be after birthdate', + function (dateOfDeath) { + const birthdate = new Date(formState.getState().birthdate[0], formState.getState().birthdate[1]-1, formState.getState().birthdate[2]); + return dateOfDeath > birthdate; + })}, + {name: "timeOfDeath", type: "time", x:2, y: 5, layout:"col-md-6"}, + {name:"deathPlaceBox", label: "Death Place", components: [ + {name: "deathPlace", type: "custom", x:1, y:7, layout:"col-md-12", component: (name, disabled) => }, + ], type: "box", x:1, y:7, layout:"col-md-11 ms-2 mt-2 pt-1 pb-2"}, + {name:"burialPlaceBox", label: "Burial Place", components: [ + {name: "burialPlace", type: "custom", x:1, y:7, layout:"col-md-12", component: (name, disabled) => }, + ], type: "box", x:1, y:8, layout:"col-md-11 ms-2 mt-2 pt-1 pb-2"}, + {name: "deathNotification", type: "checkbox", x:1, y:9, layout:"col-md-12"}, + {name: "deathNotificationFile", type: "file", x:1, y:10, layout:"col-md-12", + uploadUrl: (id) => getUploadUrl(id), + previewUrl: (id) => getPreviewUrl(id), + loadData: async (id) => loadDeathNotificationAttachment(id), + handleDelete:(id) => handleDeathNotificationDelete(id), + handleClick: (id) => handleDeathNotificationClick(id), + display: (data) => {return data.deathNotification}, + updateFileData: (data) => updateFileData(data) + }, + {name: "declarantDetails", type: "custom", x:1, y:11, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "declarantId", type: "custom", x:1, y:12, layout:"col-md-12", component: (name, disabled) => }, + {name:"registrationBox", label: "Registration Location", components: [ + {name: "registrationLocation", type: "custom", x:1, y:1, layout:"col-md-12", component: (name, disabled) => } + ], type: "box", x:2, y:28, layout:"col-md-11 ms-2 mt-2 pt-1 pb-2"}, + + {name: "Mentions", type: "custom", x:1, y:30, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "mentions", type: "text", x:1, y:31, layout:"col-md-12"}, + {name: "Extras", type: "custom", x:1, y:32, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "notes", type: "text", x:1, y:33, layout:"col-md-12"} + +]; + +const getUploadUrl = (id) => { + return getServiceUri() + 'civil-status-mtlb/death-notification-file' + '/' + id; +} + +const getPreviewUrl = (id) => { + return getServiceUri() + 'civil-status-mtlb/death-notification-file' + '/preview/' + id; +} + +const updateFileData = (data) => { + let filter = {name: data.fileName, description: data.description}; + rest.request(getServiceUri() + 'civil-status-mtlb/death-notification-file' + '/' + data.id, "PUT", filter); +} + +const handleDeathNotificationClick = async (id) => { + const token = await rest.getToken(getServiceUri() + 'token/get-auth-code'); + window.location = getServiceUri() + 'civil-status-mtlb/death-notification-file' + '/' + id + '/' + token; +}; + +const handleDeathNotificationDelete = (id) => { + rest.delete('civil-status-mtlb/death-notification-file', id).then(() => { + DELETE_ATTACHMENT_EVENT.publish(id) + }); +}; + +const loadDeathNotificationAttachment = async (id) => { + let filter = {and: true}; + filter['civil-status-mtlb-death-notification-file'] = {}; + filter['civil-status-mtlb-death-notification-file']['civilStatusMtlbId'] = id; + return rest.search('civil-status-mtlb/death-notification-file', filter) +} + +export const buildNewAmendmentApplicationForm = () => { + const empty = buildEmptyObject(amendmentApplicationFields); + empty['image'] = {x: 0.5, y:0.5, scale: 1, rotate: 0, url:'/public/avatar.png', isEmpty: true}; + return empty; +} + +export const loadCivilStatusMtlbAttachment = async (id) => { + let filter = {and: true}; + filter['civil-status-mtlb-attachment'] = {}; + filter['civil-status-mtlb-attachment']['civilStatusMtlbId'] = id; + return rest.search('civil-status-mtlb/attachment', filter) +} + +export const form2dto = (formData, dto) => { + dto.mtlbType = MTLB_TYPE_DEATH_RECORD_CHANGE; + if(formData.dateOfDeath != null && typeof(formData.dateOfDeath) != 'string') { + let dateOfDeathAsDate = new Date(formData.dateOfDeath); + dto.dateOfDeath = dateOfDeathAsDate.getFullYear() + "-" + ('0' + (dateOfDeathAsDate.getMonth() + 1)).slice(-2) + "-" + ('0' + dateOfDeathAsDate.getDate()).slice(-2); + } + if (formData.timeOfDeath != null && typeof(formData.timeOfDeath) != 'string') { + const date = new Date(formData.timeOfDeath) + let birthHour = date.getHours() < 10 ? '0' + date.getHours() : date.getHours(); + let birthMinute = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes(); + dto.timeOfDeath = birthHour + ":" + birthMinute; + } + if (formData.image) + if (!formData.image.isEmpty) { + let base64Image = formData.image.url; + let faceMimeType = base64Image.substring(base64Image.indexOf(':') + 1, base64Image.indexOf(';')) + let base64 = base64Image.substr(base64Image.indexOf(',') + 1); + dto.face = base64; + dto.faceMimeType = faceMimeType; + } +} + + +export const dto2form = (dto) => { + if (dto.timeOfDeath !== null) { + dto.timeOfDeath = new Date().setHours(dto.timeOfDeath[0], dto.timeOfDeath[1]); + } + return dto; +} + +export const newAmendmentDeathApplicationFormForm2Dto = (formData, dto) => { + dto.id = null; + dto.mtlbType = MTLB_TYPE_DEATH_RECORD_CHANGE; + dto.birthTime = null; + dto.typeOfAcquisition = null; + if (dto.otherCitizenshipCsv !== null && dto.otherCitizenshipCsv) { + dto.otherCitizenshipCsv = null; + } + dto.deathPlace = formData.deathLocation; + dto.tags = null; +} \ No newline at end of file diff --git a/src/main/js/forms/amendmentUnionApplication/AmendmentUnionApplicationFormCommon.jsx b/src/main/js/forms/amendmentUnionApplication/AmendmentUnionApplicationFormCommon.jsx new file mode 100644 index 0000000..c7aa757 --- /dev/null +++ b/src/main/js/forms/amendmentUnionApplication/AmendmentUnionApplicationFormCommon.jsx @@ -0,0 +1,149 @@ +import React from "react"; +import _ from 'lodash'; +import { buildEmptyObject } from "../../../../auto/js/widgets/FormComponent"; +import { getServiceUri } from "../../../../auto/js/metadata"; +import { MTLB_TYPE_UNION_RECORD_CHANGE } from "../../../../auto/js/metadata/MtlbType"; +import { rest } from "../../../../auto/js/services/RestClient"; +import * as Yup from 'yup'; +import { Section } from "../../widgets/Section"; +import { loadPersonData } from "../../utils"; +import { GeoDataComponent } from "../../../../auto/js/widgets/GeoDataComponent"; +import { AdvancedSearchPersonComponent } from "../../widgets/AdvancedSearchPersonComponent"; +import { buildFemaleEmptyObject, buildMaleEmptyObject } from "../birthRegistration/BirthRegistrationFormCommon"; +import { verifyAge } from "../marriageRegistration/MarriageRegistrationFormCommon"; +import { formState } from "../../../../auto/js/forms/FormState"; + +const regime = {1:"Civil Marriage", 2:"Religious Marriage", 3: "Custom Marriage"}; + +export const amendmentUnionApplicationFields = [ + {name: "tags", type:"tags", x:1, y:1, layout:"col-md-12"}, + {name: "marriageDetails", type: "custom", x:1, y:2, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "unionRecordId", type: "number", x:1, y:3, layout:"col-md-6", disabled: true}, + { + name: "celebrantId", label: "Search Celebrant", type: "custom", x: 1, y: 5, layout: "col-md-12", + component: (name, disabled) => + }, + { + name: "reportedCelebrant", type: "text", x: 2, y: 6, layout: "col-md-12", + display: (data) => { return data.reportedCelebrant !== null && data.celebrantId === null ? true : false; } + }, + {name: "declaredDate", type: "date", x:1, y: 7, layout:"col-md-6"}, + {name: "timeOfMarriage", type: "time", x:2, y:7, layout:"col-md-6"}, + {name: "unionRegime", type: "select", x:1, y: 8, layout:"col-md-6", metadata: () => regime}, + {name:"addressBox", label: "Place", components: [ + {name: "address", type: "custom", x:1, y:1, layout:"col-md-12", component: (name, disabled) => }, + ], type: "box", x:2, y:9, layout:"col-md-11 ms-2 mt-2 pt-1 pb-2"}, + {name: "wifeDetails", type: "custom", x:1, y:10, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "partner2VitalRecordId", type: "custom", x:1, y:11, layout:"col-md-12", component: (name, disabled) => }, + { + name: "wifeGenderValidation", type: "validation", x: 1, y: 12, layout: "col-md-6", + "validation": Yup.boolean().test("wifeGenderValidation", "Bride need to be female", function () { + return (formState.getState()["partner2VitalRecordId-gender"])? formState.getState()["partner2VitalRecordId-gender"] === "FEMALE": true; + }) + }, + { + name: "wifeAgeValidation", type: "validation", x: 2, y: 12, layout: "col-md-6", + "validation": Yup.boolean().test("wifeAgeValidation", "Bride must be at least 16 years old", function () { + return (formState.getState()["partner2VitalRecordId-birthdate"])? verifyAge(formState.getState()["partner2VitalRecordId-birthdate"], 16) : true; + }) + }, + {name: "husbandDetails", type: "custom", x:1, y:13, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "partner1VitalRecordId", type: "custom", x:1, y:14, layout:"col-md-12", component: (name, disabled) => }, + { + name: "husbandGenderValidation", type: "validation", x: 1, y: 15, layout: "col-md-6", + "validation": Yup.boolean().test("husbandGenderValidation", "Groom need to be male", function () { + return (formState.getState()["partner1VitalRecordId-gender"])? formState.getState()["partner1VitalRecordId-gender"] === "MALE": true; + }) + }, + { + name: "husbandAgeValidation", type: "validation", x: 2, y: 15, layout: "col-md-6", + "validation": Yup.boolean().test("husbandAgeValidation", "Groom must be at least 18 years old", function () { + return (formState.getState()["partner1VitalRecordId-birthdate"])? verifyAge(formState.getState()["partner1VitalRecordId-birthdate"], 18) : true; + }) + }, + {name: "witnessDetails", type: "custom", x:1, y:17, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "witness1VitalRecordId", type: "custom", x:1, y:18, layout:"col-md-12", component: (name, disabled) => }, + {name: "witness2VitalRecordId", type: "custom", x:1, y:19, layout:"col-md-12", component: (name, disabled) => }, + + { name: "declarationDetails", type: "custom", x: 1, y: 20, layout: "col-md-12", component: (name, disabled) =>
}, + { + name: "declarantId", label: "Search Declarant", type: "custom", x: 1, y: 21, layout: "col-md-12", + component: (name, disabled) => + }, + { + name: "reportedDeclarant", type: "text", x: 2, y: 22, layout: "col-md-12", + display: (data) => { return data.reportedDeclarant !== null && data.declarantId === null ? true : false; } + }, + {name:"registrationBox", label: "Registration Location", components: [ + {name: "registrationLocation", type: "custom", x:1, y:1, layout:"col-md-12", component: (name, disabled) => } + ], type: "box", x:2, y:23, layout:"col-md-11 ms-2 mt-2 pt-1 pb-2"}, { + name: "officerId", label: "Search officer", type: "custom", x: 1, y: 24, layout: "col-md-12", + component: (name, disabled) => + }, + { + name: "reportedOfficer", type: "text", x: 2, y: 25, layout: "col-md-12", + display: (data) => { return data.reportedOfficer !== null && data.officerId ===null ? true : false; } + }, + {name: "divorceDetails", type: "custom", x:1, y:26, layout:"col-md-12", component: (name, disabled) =>
, display: (data) => {return data.dateOfEffect !== null }}, + {name: "dateOfEffect", type: "date", x:1, y:27, layout:"col-md-6", display: (data) => {return data.dateOfEffect !== null }}, + {name: "dateOfOrder", type: "date", x:2, y:28, layout:"col-md-6", display: (data) => {return data.dateOfEffect !== null }}, + {name: "Mentions", type: "custom", x:1, y:29, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "mentions", type: "text", x:1, y:30, layout:"col-md-12"}, + {name: "Extras", type: "custom", x:1, y:31, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "notes", type: "text", x:1, y:32, layout:"col-md-12"} +]; + + +export const buildNewAmendmentUnionApplicationForm = () => { + const empty = buildEmptyObject(amendmentUnionApplicationFields); + return empty; +} + +export const loadUnionMtlbAttachment = async (id) => { + let filter = {and: true}; + filter['union-mtlb-attachment'] = {}; + filter['union-mtlb-attachment']['unionMtlbId'] = id; + return rest.search('union-mtlb/attachment', filter) +} + +export const form2dto = (formData, dto) => { + dto.mtlbType = MTLB_TYPE_UNION_RECORD_CHANGE; + if(formData.dateOfEffect != null && typeof(formData.dateOfEffect) != 'string') { + let dateOfEffectAsDate = new Date(formData.dateOfEffect); + dto.dateOfEffect = dateOfEffectAsDate.getFullYear() + "-" + ('0' + (dateOfEffectAsDate.getMonth() + 1)).slice(-2) + "-" + ('0' + dateOfEffectAsDate.getDate()).slice(-2); + } + if(formData.dateOfOrder != null && typeof(formData.dateOfOrder) != 'string') { + let dateOfOrderAsDate = new Date(formData.dateOfOrder); + dto.dateOfOrder = dateOfOrderAsDate.getFullYear() + "-" + ('0' + (dateOfOrderAsDate.getMonth() + 1)).slice(-2) + "-" + ('0' + dateOfOrderAsDate.getDate()).slice(-2); + } + if (formData.partner1VitalRecordId != null) + dto.partner1VitalRecordId = parseInt(formData.partner1VitalRecordId) + if (formData.partner2VitalRecordId != null) + dto.partner2VitalRecordId = parseInt(formData.partner2VitalRecordId) + if (formData.witness1VitalRecordId != null) + dto.witness1VitalRecordId = parseInt(formData.witness1VitalRecordId) + if (formData.witness2VitalRecordId != null) + dto.witness2VitalRecordId = parseInt(formData.witness2VitalRecordId) + if (formData.timeOfMarriage != null && typeof(formData.timeOfMarriage) != 'string') { + const date = new Date(formData.timeOfMarriage) + let birthHour = date.getHours() < 10 ? '0' + date.getHours() : date.getHours(); + let birthMinute = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes(); + dto.timeOfMarriage = birthHour + ":" + birthMinute; + } +} + + +export const dto2form = (dto) => { + if (dto.timeOfMarriage !== null) { + dto.timeOfMarriage = new Date().setHours(dto.timeOfMarriage[0], dto.timeOfMarriage[1]); + } + return dto; +} + +export const newAmendmentUnionApplicationFormForm2Dto = (formData, dto) => { + dto.unionRecordId = formData.id; + dto.id = null; + dto.mtlbType = MTLB_TYPE_UNION_RECORD_CHANGE; + dto.declaredDate = formData.dateOfMarriage; + dto.tags = null; +} \ No newline at end of file diff --git a/src/main/js/forms/birthRegistration/AdjudicationFormCommon.jsx b/src/main/js/forms/birthRegistration/AdjudicationFormCommon.jsx new file mode 100644 index 0000000..24a4d9a --- /dev/null +++ b/src/main/js/forms/birthRegistration/AdjudicationFormCommon.jsx @@ -0,0 +1,36 @@ + +const gender = {1:"MALE", 2:"FEMALE"}; + +export const adjudicationFields = [ + {name: "image", type: "image", x: 1, y: 3, layout: "col-md-12" }, + {name: "firstname", type: "text", x:1, y:5, layout:"col-md-6"}, + {name: "secondname", type: "text", x:2, y:4, layout:"col-md-6"}, + {name: "thirdname", type: "text", x:1, y: 5, layout:"col-md-6"}, + {name: "fourthname", type: "text", x:1, y: 4, layout:"col-md-6"}, + {name: "fifthname", type: "text", x:2, y: 6, layout:"col-md-6"}, + {name: "gender", type: "select", x:1, y: 7, layout:"col-md-6", metadata: () => gender}, + {name: "birthdate", type: "date", x:1, y: 8, layout:"col-md-6"}, + {name: "birthTime", type: "time", x:2, y:8, layout:"col-md-6"}, + {name: "leftThumbImage", type:"view", x:1, y:17, layout:"col-md-6"}, + {name: "leftIndexFingerImage", type:"view", x:2, y:17, layout:"col-md-6"}, + {name: "leftMiddleFingerImage", type:"view", x:1, y:18, layout:"col-md-6"}, + {name: "leftRingFingerImage", type:"view", x:2, y:18, layout:"col-md-6"}, + {name: "leftPinkyImage", type:"view", x:1, y:19, layout:"col-md-6"}, + {name: "rightThumbImage", type:"view", x:2, y:19, layout:"col-md-6"}, + {name: "rightIndexFingerImage", type:"view", x:1, y:20, layout:"col-md-6"}, + {name: "rightMiddleFingerImage", type:"view", x:2, y:20, layout:"col-md-6"}, + {name: "rightRingFingerImage", type:"view", x:1, y:21, layout:"col-md-6"}, + {name: "rightPinkyImage", type:"view", x:2, y:21, layout:"col-md-6"} +]; + +export const adjudicationMatchFields = [ + {name: "image", type: "image", x: 1, y: 3, layout: "col-md-12" }, + {name: "firstname", type: "text", x:1, y:5, layout:"col-md-6"}, + {name: "secondname", type: "text", x:2, y:4, layout:"col-md-6"}, + {name: "thirdname", type: "text", x:1, y: 5, layout:"col-md-6"}, + {name: "fourthname", type: "text", x:1, y: 4, layout:"col-md-6"}, + {name: "fifthname", type: "text", x:2, y: 6, layout:"col-md-6"}, + {name: "gender", type: "select", x:1, y: 7, layout:"col-md-6", metadata: () => gender}, + {name: "birthdate", type: "date", x:1, y: 8, layout:"col-md-6"}, + {name: "birthTime", type: "time", x:2, y:8, layout:"col-md-6"}, +]; \ No newline at end of file diff --git a/src/main/js/forms/birthRegistration/BirthRegistrationFormCommon.jsx b/src/main/js/forms/birthRegistration/BirthRegistrationFormCommon.jsx new file mode 100644 index 0000000..f8ca96f --- /dev/null +++ b/src/main/js/forms/birthRegistration/BirthRegistrationFormCommon.jsx @@ -0,0 +1,564 @@ +import React from "react"; + +import { buildEmptyObject } from "../../../../auto/js/widgets/FormComponent"; +import { getServiceUri, metadataLoader, pojoMetadata } from "../../../../auto/js/metadata"; +import { MTLB_TYPE_BIRTH_REGISTRATION } from "../../../../auto/js/metadata/MtlbType"; +import { rest } from "../../../../auto/js/services/RestClient"; +import { t } from '../../../../auto/js/services/i18ndb'; +import { showNotification, swapObject } from "../../../../auto/js/utils"; +import * as Yup from 'yup'; +import { formState } from "../../../../auto/js/forms/FormState"; +import { AddressComponent } from "../../../../auto/js/widgets/AddressComponent"; +import { PersonComponent } from "../../../../auto/js/widgets/PersonComponent"; +import { loadPersonData } from "../../utils"; +import { GeoDataComponent } from "../../../../auto/js/widgets/GeoDataComponent"; +import { geoDataMetadataLoader } from "../../../../auto/js/metadata/GeoDataMetadataLoader"; +import { CountryAutoCompleteInput } from "../../widgets/CountryAutoCompleteInput"; +// import { FileInput } from "../../widgets/FileInput"; +import { DELETE_ATTACHMENT_EVENT, FILE_UPLOADED_EVENT } from "../../../../auto/js/events/Gui"; +import { FILE_TYPE_MEDICAL_NOTIFICATION, FILE_TYPE_OTHER } from "../../../../auto/js/metadata/FileType"; +import { AdvancedSearchPersonComponent } from "../../widgets/AdvancedSearchPersonComponent"; +import AutocompleteListSelector from "../../widgets/AutocompleteListSelector"; +import { TypeOfAcquisition } from "../../../../auto/js/metadata/TypeOfAcquisition"; +import { ContactComponent } from "../../widgets/ContactComponent"; +const gender = { 1: "MALE", 2: "FEMALE" }; +const maritalStatus = { 1: "SINGLE", 2: "MARRIED", 3: "DIVORCED", 4: "WIDOWED" }; + +export const birthRegistrationFields = [ + { name: "tags", type: "tags", x: 1, y: 1, layout: "col-md-12" }, + { name: "childDetails", type: "custom", x: 1, y: 2, layout: "col-md-12", component: (name, disabled) =>
}, + { name: "image", type: "image", x: 1, y: 3, layout: "col-md-12" }, + { + name: "firstname", type: "text", x: 2, y: 5, layout: "col-md-6", + "validation": Yup.string().nullable().default(undefined).min(2, t`First name must be at least two characters long`).max(14, t`First name must be less than fifteen characters long`).required(t`First name is required`).matches(/[\p{Letter}\p{Mark}\s]+$/u, t`Only alphabets are allowed for this field `).matches(/^\p{Lu}.*$/u, t`First letter need to be Upper Case`) + }, + { + name: "secondname", type: "text", x: 2, y: 4, layout: "col-md-6", + "validation": Yup.string().nullable().default(undefined).min(2, t`Middle name must be at least four characters long`).max(28, t`Middle name must be less than twenty eight characters long`).matches(/^\p{Lu}.*$/u, t`First letter need to be Upper Case`) + }, + { + name: "thirdname", type: "text", x: 1, y: 5, layout: "col-md-6", + "validation": Yup.string().nullable().default(undefined).min(2, t`Melanisian name must be at least four characters long`).max(14, t`Melanisian name must be less than fifteen characters long`).matches(/[\p{Letter}\p{Mark}\s]+$/u, t`Only alphabets are allowed for this field `).matches(/^\p{Lu}.*$/u, t`First letter need to be Upper Case`) + }, + { + name: "fourthname", type: "text", x: 1, y: 4, layout: "col-md-6", + "validation": Yup.string().nullable().default(undefined).min(2, t`Family name must be at least four characters long`).max(14, t`Family name must be less than fifteen characters long`).required(t`Family name is required`).matches(/[\p{Letter}\p{Mark}\s]+$/u, t`Only alphabets are allowed for this field `).matches(/^\p{Lu}.*$/u, t`First letter need to be Upper Case`) + }, + { + name: "fifthname", type: "text", x: 2, y: 6, layout: "col-md-6", + "validation": Yup.string().nullable().default(undefined).min(2, t`Melanesian name must be at least four characters long`).max(14, t`Marriage name must be less than fifteen characters long`).matches(/[\p{Letter}\p{Mark}\s]+$/u, t`Only alphabets are allowed for this field `).matches(/^\p{Lu}.*$/u, t`First letter need to be Upper Case`) + }, + { + name: "gender", type: "select", x: 1, y: 7, layout: "col-md-6", metadata: () => gender, + "validation": Yup.string().nullable().default(undefined).required(t`Gender is required`) + }, + { + name: "birthdate", type: "date", x: 1, y: 8, layout: "col-md-6", + "validation": Yup.date().nullable().default(undefined).required('A date of birth is required') + }, + { name: "birthTime", type: "time", x: 2, y: 8, layout: "col-md-6" }, + { name: "birthDayUnknown", type: "checkbox", x: 1, y: 9, layout: "col-md-4" }, + { name: "birthMonthUnknown", type: "checkbox", x: 2, y: 9, layout: "col-md-4" }, + { name: "birthYearUnknown", type: "checkbox", x: 3, y: 9, layout: "col-md-4" }, + { name: "disability", type: "checkbox", x: 1, y: 10, layout: "col-md-6" }, + { + name: "citizenshipBox", label: "Citizenship", components: [ + { name: "primaryCitizenship", type: "custom", x: 1, y: 1, layout: "col-md-6", component: (name, disabled) => }, + { name: "typeOfAcquisition", type: "select", x: 2, y: 1, layout: "col-md-6", metadata: () => swapObject(TypeOfAcquisition) }, + { name: "otherCitizenshipCsv", type: "custom", x: 1, y: 3, layout: "col-md-6", component: (name, disabled) => }, + ], type: "box", x: 2, y: 11, layout: "col-md-11 ms-2 mt-2 pt-1 pb-2" + }, + { + name: "birthBox", label: "Birth Place", components: [ + { name: "birthPlace", type: "custom", x: 1, y: 1, layout: "col-md-12", component: (name, disabled) => } + ], type: "box", x: 2, y: 12, layout: "col-md-11 ms-2 mt-2 pt-1 pb-2" + }, + { + name: "originBox", label: "Village Of Origin", components: [ + { name: "villageOfOrigin", type: "custom", x: 1, y: 1, layout: "col-md-12", component: (name, disabled) => }, + ], type: "box", x: 1, y: 13, layout: "col-md-11 ms-2 mt-2 pt-1 pb-2" + }, + { name: "motherDetails", type: "custom", x: 1, y: 15, layout: "col-md-12", component: (name, disabled) =>
}, + { + name: "motherInfo", options: [ + { "name": "motherWithBirthRecord", "label": t`motherWithBirthRecord` }, + { "name": "motherWithoutBirthRecord", "label": t`motherWithoutBirthRecord` }, + { "name": "unknownMother", "label": t`unknownMother` }, + ], type: "radio", x: 1, y: 16, layout: "col-md-12 pt-4" + }, + { + name: "motherId", label: "Search Mother", type: "custom", x: 1, y: 17, layout: "col-md-12", + component: (name, disabled) => , + display: (data) => { return (data.motherInfo === "motherWithBirthRecord" || data.motherId != null) ? true : false; } + }, + { + name: "motherGenderValidation", type: "validation", x: 1, y: 18, layout: "col-md-6", + "validation": Yup.boolean().test("motherGenderValidation", "Mother need to be female", function () { + return (formState.getState()["motherId-gender"])? formState.getState()["motherId-gender"] === "FEMALE": true; + }) + }, + { + name: "reportedMotherName", type: "text", x: 2, y: 19, layout: "col-md-12", + display: (data) => { return data.motherInfo === "motherWithoutBirthRecord" ? true : false; } + }, + { name: "fatherDetails", type: "custom", x: 1, y: 20, layout: "col-md-12", component: (name, disabled) =>
}, + { + name: "fatherInfo", options: [ + { "name": "fatherWithBirthRecord", "label": t`fatherWithBirthRecord` }, + { "name": "fatherWithoutBirthRecord", "label": t`fatherWithoutBirthRecord` }, + { "name": "unknownFather", "label": t`unknownFather` }, + ], type: "radio", x: 1, y: 20, layout: "col-md-12 pt-4" + }, + { + name: "fatherId", label: "Search Father", type: "custom", x: 1, y: 21, layout: "col-md-12", + component: (name, disabled) => , + display: (data) => { return (data.fatherInfo === "fatherWithBirthRecord" || data.fatherId != null) ? true : false; } + }, + { + name: "fatherGenderValidation", type: "validation", x: 1, y: 22, layout: "col-md-6", + "validation": Yup.boolean().test("fatherGenderValidation", "Father need to be male", function () { + return (formState.getState()["fatherId-gender"])? formState.getState()["fatherId-gender"] === "MALE": true; + }) + }, + { + name: "reportedFatherName", type: "text", x: 2, y: 23, layout: "col-md-12", + display: (data) => { return data.fatherInfo === "fatherWithoutBirthRecord" ? true : false; } + }, + { name: "medicalNotification", type: "checkbox", x: 1, y: 24, layout: "col-md-12" }, + { + name: "medicalNotificationFile", type: "file", x: 1, y: 25, layout: "col-md-12", + uploadUrl: (id) => getUploadUrl(id), + previewUrl: (id) => getPreviewUrl(id), + loadData: async (id) => loadMedicalNotificationAttachment(id), + handleDelete: (id) => handleMedicalNotificationDelete(id), + handleClick: (id) => handleMedicalNotificationClick(id), + display: (data) => { return data.medicalNotification }, + updateFileData: (data) => updateFileData(data) + }, + { + name: "witness1Id", type: "custom", x: 1, y: 26, layout: "col-md-12", + "validation": Yup.string().nullable().default(undefined).when(["medicalNotification"], + (medicalNotification) => { + if (!medicalNotification) { + return Yup.string().nullable().default(undefined).required('If no medical notification exists witness is required') + } + } + ), component: (name, disabled) => , + display: (data) => { return !data.medicalNotification } + }, + { + name: "witness2Id", type: "custom", x: 2, y: 27, layout: "col-md-12", + "validation": Yup.string().nullable().default(undefined).when(["medicalNotification"], + (medicalNotification) => { + if (!medicalNotification) { + return Yup.string().nullable().default(undefined).required('If no medical notification exists witness is required') + } + } + ), component: (name, disabled) => , + display: (data) => { return !data.medicalNotification } + }, + {name: "AdministrativeDetails", type: "custom", x:1, y:28, layout:"col-md-12", component: (name, disabled) =>
}, + { name: "contact", type: "custom", x: 1, y: 29, layout: "col-md-12", component: (name, disabled, data) => }, + { + name: "addressValidation", type: "validation", x: 1, y: 30, layout: "col-md-12", + "validation": Yup.boolean().test("addressValidation", "Address is required", function () { + return formState.getAddressList().length; + }) + }, + { name: "declarantDetails", type: "custom", x: 1, y: 31, layout: "col-md-12", component: (name, disabled) =>
}, + { name: "declarantId", type: "custom", x: 1, y: 32, layout: "col-md-12", component: (name, disabled) => }, + {name:"registrationBox", label: "Registration Location", components: [ + {name: "registrationLocation", type: "custom", x:1, y:1, layout:"col-md-12", component: (name, disabled) => } + ], type: "box", x:2, y:33, layout:"col-md-11 ms-2 mt-2 pt-1 pb-2"}, + + {name: "Mentions", type: "custom", x:1, y:34, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "mentions", type: "text", x:1, y:35, layout:"col-md-12"}, + {name: "Extras", type: "custom", x:1, y:36, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "notes", type: "text", x:1, y:37, layout:"col-md-12"} + + +]; + +const getUploadUrl = (id) => { + return getServiceUri() + 'civil-status-mtlb/medical-notification-file' + '/' + id; +} + +const getPreviewUrl = (id) => { + return getServiceUri() + 'civil-status-mtlb/medical-notification-file' + '/preview/' + id; +} + +const updateFileData = (data) => { + let filter = { name: data.fileName, description: data.description }; + rest.request(getServiceUri() + 'civil-status-mtlb/medical-notification-file' + '/' + data.id, "PUT", filter); +} + +const handleMedicalNotificationClick = async (id) => { + const token = await rest.getToken(getServiceUri() + 'token/get-auth-code'); + window.location = getServiceUri() + 'civil-status-mtlb/medical-notification-file' + '/' + id + '/' + token; +}; +const handleMedicalNotificationDelete = (id) => { + rest.delete('civil-status-mtlb/medical-notification-file', id).then(() => { + DELETE_ATTACHMENT_EVENT.publish(id) + }); +}; + +const loadMedicalNotificationAttachment = async (id) => { + let filter = { and: true }; + filter['civil-status-mtlb-medical-notification-file'] = {}; + filter['civil-status-mtlb-medical-notification-file']['civilStatusMtlbId'] = id; + return rest.search('civil-status-mtlb/medical-notification-file', filter) +} + +export const loadCivilStatusMtlbAttachment = async (id) => { + let filter = { and: true }; + filter['civil-status-mtlb-attachment'] = {}; + filter['civil-status-mtlb-attachment']['civilStatusMtlbId'] = id; + return rest.search('civil-status-mtlb/attachment', filter) +} + +export const saveBirthRegistrationForm = async (formData) => { + let dto = pojoMetadata['civil-status-mtlb'].form2dto(formData); + dto.mtlbType = MTLB_TYPE_BIRTH_REGISTRATION; + if (!formData.image.isEmpty) { + let base64Image = formData.image.url; + let faceMimeType = base64Image.substring(base64Image.indexOf(':') + 1, base64Image.indexOf(';')) + let base64 = base64Image.substr(base64Image.indexOf(',') + 1); + dto.face = base64; + dto.faceMimeType = faceMimeType; + } + if (formData.middlename != null) { + let names = formData.middlename.split(" "); + dto.secondname = names[0] + if (names.length > 1) + dto.thirdname = names[1]; + } + if (formData.birthCountry) + dto.birthCountry = formData.birthCountry.key; + try { + return rest.request(getServiceUri() + 'apply/create-civil-status-mtlb', 'POST', dto) + } catch (err) { + alert(err); + } +} + +export const loadBirthRegistrationFormData = async (id) => { + return await rest.read('civil-status-mtlb', id).then(response => { + let form = response; + let face = null; + if (response.face != null) { + let mimeType = response['faceMimeType']; + face = "data:".concat(mimeType, ";base64,", response.face) + } + if (response.birthCountry != null) { + let countryMetadata = metadataLoader.get('country'); + form.birthCountry = { key: response.birthCountry, value: countryMetadata[response.birthCountry] } + } + if (response.birthTime !== null) + response.birthTime = new Date().setHours(response.birthTime[0], response.birthTime[1]); + if (response.birthPlace == null) + form.birthPlace = "191"; + form['image'] = { x: 0.5, y: 0.5, scale: 1, rotate: 0, url: (face != null) ? face : '/public/avatar.png', isEmpty: true }; + + let tagFilter = { and: true }; + tagFilter['civil-status-mtlb-tag'] = { civilStatusMtlbId: id }; + + return rest.search('civil-status-mtlb-tag', tagFilter).then(tags => { + form['tags'] = tags + + return form; + }) + }) +} + +export const updatePendingBirthRegistrationForm = async (formData) => { + let dto = pojoMetadata['civil-status-mtlb'].form2dto(formData); + form2dto(formData, dto); + try { + return rest.request(getServiceUri() + 'civil-status-mtlb/pending/update', 'POST', dto); + } catch (err) { + alert(err); + } +} + +export const updateBirthRegistrationForm = async (formData) => { + let dto = pojoMetadata['civil-status-mtlb'].form2dto(formData); + form2dto(formData, dto); + try { + return rest.update('civil-status-mtlb', dto); + } catch (err) { + alert(err); + } +} + +export const deleteBirthRegistrationForm = async (id) => { + try { + return rest.delete('civil-status-mtlb', id); + } catch (err) { + alert(err); + } +} + +export const updateRejectedBirthRegistrationForm = async (formData) => { + //TODO: Move form2dto from pojo metadata + let dto = pojoMetadata['civil-status-mtlb'].form2dto(formData); + form2dto(formData, dto); + try { + return rest.request(getServiceUri() + 'civil-status-mtlb/rejected/update', 'POST', dto); + } catch (err) { + alert(err); + } +} + +export const rejectBirthRegistrationForm = async (id) => { + try { + return rest.request(getServiceUri() + 'civil-status-mtlb/pending/reject', 'POST', id); + } catch (err) { + alert(err); + } +} + +export const rejectReadyBirthRegistrationForm = async (id) => { + try { + return rest.request(getServiceUri() + 'civil-status-mtlb/ready/reject', 'POST', id); + } catch (err) { + alert(err); + } +} + +export const approveReadyBirthRegistrationForm = async (id) => { + try { + return rest.request(getServiceUri() + 'civil-status-mtlb/ready/approve', 'POST', id); + } catch (err) { + alert(err); + } +} + +export const buildBirthRegistrationFormEmptyObject = () => { + const empty = buildEmptyObject(birthRegistrationFields); + empty['image'] = { x: 0.5, y: 0.5, scale: 1, rotate: 0, url: '/public/avatar.png', isEmpty: true }; + empty['birthPlace'] = "191"; + return empty; +} +export const form2dto = (formData, dto) => { + if (dto.mtlbType === null || !dto.mtlbType) + dto.mtlbType = MTLB_TYPE_BIRTH_REGISTRATION; + if (!formData.image.isEmpty) { + let base64Image = formData.image.url; + let faceMimeType = base64Image.substring(base64Image.indexOf(':') + 1, base64Image.indexOf(';')) + let base64 = base64Image.substr(base64Image.indexOf(',') + 1); + dto.face = base64; + dto.faceMimeType = faceMimeType; + } + if (formData.birthCountry) + dto.birthCountry = formData.birthCountry.key; + if (formData.birthTime != null && typeof (formData.birthTime) != 'string') { + const date = new Date(formData.birthTime) + let birthHour = date.getHours() < 10 ? '0' + date.getHours() : date.getHours(); + let birthMinute = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes(); + dto.birthTime = birthHour + ":" + birthMinute; + } + if (formData.middlename != null) { + let names = formData.middlename.split(" "); + dto.secondname = names[0] + if (names.length > 1) + dto.thirdname = names[1]; + } + if (formData.otherCitizenshipCsv !== null && formData.otherCitizenshipCsv) { + let otherCitizenshipCsv = formData.otherCitizenshipCsv.join(','); + dto.otherCitizenshipCsv = otherCitizenshipCsv; + } + if (formData.motherInfo == "unknownMother") + dto.unknownMother = true; + if (formData.fatherInfo == "unknownFather") + dto.unknownFather = true; + + if (formData.typeOfAcquisition != null) + dto.typeOfAcquisition = swapObject(TypeOfAcquisition)[formData.typeOfAcquisition] +} + +export const dto2form = (dto) => { + let form = dto; + let face = null; + if (dto.face != null) { + let mimeType = dto['faceMimeType']; + face = "data:".concat(mimeType, ";base64,", dto.face) + } + if (dto.birthTime !== null) { + dto.birthTime = new Date().setHours(dto.birthTime[0], dto.birthTime[1]); + } + + if (dto.otherCitizenshipCsv == null || dto.otherCitizenshipCsv === "") + dto.otherCitizenshipCsv = [] + else { + let values = []; + let components = dto.otherCitizenshipCsv.split(","); + components.forEach(element => { + values.push(parseInt(element)) + }); + dto.otherCitizenshipCsv = values; + } + + form['image'] = { x: 0.5, y: 0.5, scale: 1, rotate: 0, url: (face != null) ? face : '/public/avatar.png', isEmpty: (face == null) }; + + if (dto.motherId == null) { + if (dto.reportedMotherName != null) + dto.motherInfo = "motherWithoutBirthRecord" + else if (dto.unknownMother != null && dto.unknownMother) + dto.motherInfo = "unknownMother" + else + dto.motherInfo = "motherWithoutBirthRecord" + } else + dto.motherInfo = "motherWithBirthRecord" + + if (dto.fatherId == null) { + if (dto.reportedFatherName != null) + dto.fatherInfo = "fatherWithoutBirthRecord" + else if (dto.unknownFather != null && dto.unknownFather) + dto.fatherInfo = "unknownFather" + else + dto.fatherInfo = "fatherWithoutBirthRecord" + } else + dto.fatherInfo = "fatherWithBirthRecord" + + if (dto.typeOfAcquisition != null) + form.typeOfAcquisition = TypeOfAcquisition[dto.typeOfAcquisition] + else + form.typeOfAcquisition = 9; + + form['leftThumbImage'] = { x: 0.5, y: 0.5, scale: 1, rotate: 0, url: (getFormFinger(dto.leftThumb) != null) ? getFormFinger(dto.leftThumb) : '/public/finger-not-found.png', isEmpty: true, width: 70, height: 70 } + form['leftIndexFingerImage'] = { x: 0.5, y: 0.5, scale: 1, rotate: 0, url: (getFormFinger(dto.leftIndexFinger) != null) ? getFormFinger(dto.leftIndexFinger) : '/public/finger-not-found.png', isEmpty: true, width: 70, height: 70 } + form['leftMiddleFingerImage'] = { x: 0.5, y: 0.5, scale: 1, rotate: 0, url: (getFormFinger(dto.leftMiddleFinger) != null) ? getFormFinger(dto.leftMiddleFinger) : '/public/finger-not-found.png', isEmpty: true, width: 70, height: 70 } + form['leftRingFingerImage'] = { x: 0.5, y: 0.5, scale: 1, rotate: 0, url: (getFormFinger(dto.leftRingFinger) != null) ? getFormFinger(dto.leftRingFinger) : '/public/finger-not-found.png', isEmpty: true, width: 70, height: 70 } + form['leftPinkyImage'] = { x: 0.5, y: 0.5, scale: 1, rotate: 0, url: (getFormFinger(dto.leftPinky) != null) ? getFormFinger(dto.leftPinky) : '/public/finger-not-found.png', isEmpty: true, width: 70, height: 70 } + form['rightThumbImage'] = { x: 0.5, y: 0.5, scale: 1, rotate: 0, url: (getFormFinger(dto.rightThumb) != null) ? getFormFinger(dto.rightThumb) : '/public/finger-not-found.png', isEmpty: true, width: 70, height: 70 } + form['rightIndexFingerImage'] = { x: 0.5, y: 0.5, scale: 1, rotate: 0, url: (getFormFinger(dto.rightIndexFinger) != null) ? getFormFinger(dto.rightIndexFinger) : '/public/finger-not-found.png', isEmpty: true, width: 70, height: 70 } + form['rightMiddleFingerImage'] = { x: 0.5, y: 0.5, scale: 1, rotate: 0, url: (getFormFinger(dto.rightMiddleFinger) != null) ? getFormFinger(dto.rightMiddleFinger) : '/public/finger-not-found.png', isEmpty: true, width: 70, height: 70 } + form['rightRingFingerImage'] = { x: 0.5, y: 0.5, scale: 1, rotate: 0, url: (getFormFinger(dto.rightRingFinger) != null) ? getFormFinger(dto.rightRingFinger) : '/public/finger-not-found.png', isEmpty: true, width: 70, height: 70 } + form['rightPinkyImage'] = { x: 0.5, y: 0.5, scale: 1, rotate: 0, url: (getFormFinger(dto.rightPinky) != null) ? getFormFinger(dto.rightPinky) : '/public/finger-not-found.png', isEmpty: true, width: 70, height: 70 } + return form; +} + +const getFormFinger = (fingerData) => { + let finger = null; + if (fingerData !== null) { + let mimeType = "image/png" + finger = "data:".concat(mimeType, ";base64,", fingerData) + } + return finger; +} + +const Section = ({ name }) => { + return ( + <> +
+

{t(name)}

+
+ + ) +} + +export const newBirthRegistrationFormForm2Dto = (form, dto) => { + +} + +export const buildFemaleEmptyObject = (fields) => { + const empty = {}; + for (let i = 0; i < fields.length; i++) { + let field = fields[i]; + switch (field.type) { + case ("text"): + empty[field.name] = ""; + break; + case ("number"): + empty[field.name] = ""; + break; + case ("checkbox"): + switch (field.name) { + case "male": + empty[field.name] = false; + break + case "female": + empty[field.name] = true; + break; + default: + empty[field.name] = false; + break; + } + break; + case ("timestampz"): + empty[field.name] = ''; + break; + case ("date"): + empty[field.name] = null; + break; + case ("time"): + empty[field.name] = null; + break; + case ("select"): // dynamic lists, loaded from the backend + empty[field.name] = ''; + break; + case ("list"): // static lists, hardcoded + empty[field.name] = ''; + break; + case ("password"): + empty[field.name] = ''; + break; + case ("box"): + Object.assign(empty, buildFemaleEmptyObject(field.components)); + break + } + } + + return empty; +} + +export const buildMaleEmptyObject = (fields) => { + const empty = {}; + for (let i = 0; i < fields.length; i++) { + let field = fields[i]; + switch (field.type) { + case ("text"): + empty[field.name] = ""; + break; + case ("number"): + empty[field.name] = ""; + break; + case ("checkbox"): + switch (field.name) { + case "male": + empty[field.name] = true; + break + case "female": + empty[field.name] = false; + break; + default: + empty[field.name] = false; + break; + } + break; + case ("timestampz"): + empty[field.name] = ''; + break; + case ("date"): + empty[field.name] = null; + break; + case ("time"): + empty[field.name] = null; + break; + case ("select"): // dynamic lists, loaded from the backend + empty[field.name] = ''; + break; + case ("list"): // static lists, hardcoded + empty[field.name] = ''; + break; + case ("password"): + empty[field.name] = ''; + break; + case ("box"): + Object.assign(empty, buildMaleEmptyObject(field.components)); + break + } + } + + return empty; +} \ No newline at end of file diff --git a/src/main/js/forms/deathRegistration/DeathRegistrationFormCommon.jsx b/src/main/js/forms/deathRegistration/DeathRegistrationFormCommon.jsx new file mode 100644 index 0000000..49c1594 --- /dev/null +++ b/src/main/js/forms/deathRegistration/DeathRegistrationFormCommon.jsx @@ -0,0 +1,274 @@ +import React from "react"; + +import { buildEmptyObject } from "../../../../auto/js/widgets/FormComponent"; +import { getServiceUri, pojoMetadata } from "../../../../auto/js/metadata"; +import { MTLB_TYPE_DEATH_REGISTRATION } from "../../../../auto/js/metadata/MtlbType"; +import { rest, t } from "../../../../auto/js/services"; +import * as Yup from 'yup'; +import { formatDate, showNotification } from "../../../../auto/js/utils"; +import { Section } from "../../widgets/Section"; +import { PersonComponent } from "../../../../auto/js/widgets/PersonComponent"; +import { loadPersonData } from "../../utils"; +import { formState } from "../../../../auto/js/forms/FormState"; +import { GeoDataComponent } from "../../../../auto/js/widgets/GeoDataComponent"; +import { AdvancedSearchPersonComponent } from "../../widgets/AdvancedSearchPersonComponent"; +import { DELETE_ATTACHMENT_EVENT } from "../../../../auto/js/events/Gui"; +export const deathRegistrationFields = [ + { name: "tags", type: "tags", x: 1, y: 1, layout: "col-md-12" }, + {name: "deceasedDetails", type: "custom", x:1, y:2, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "vitalRecordId", type: "custom", x:1, y: 3, layout:"col-md-12", component: (name, disabled) => }, + {name: "deathDetails", type: "custom", x:1, y:4, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "dateOfDeath", type: "date", x:1, y: 5, layout:"col-md-6", "validation": Yup.date().test( + 'is-after-birthdate', + 'Date of death must be after birthdate', + function (dateOfDeath) { + const birthdate = new Date(formState.getState().birthdate[0], formState.getState().birthdate[1]-1, formState.getState().birthdate[2]); + return dateOfDeath > birthdate; + })}, + {name: "timeOfDeath", type: "time", x:2, y: 5, layout:"col-md-6"}, + {name:"deathPlaceBox", label: "Death Place", components: [ + {name: "deathPlace", type: "custom", x:1, y:7, layout:"col-md-12", component: (name, disabled) => }, + ], type: "box", x:1, y:7, layout:"col-md-11 ms-2 mt-2 pt-1 pb-2"}, + {name:"burialPlaceBox", label: "Burial Place", components: [ + {name: "burialPlace", type: "custom", x:1, y:7, layout:"col-md-12", component: (name, disabled) => }, + ], type: "box", x:1, y:8, layout:"col-md-11 ms-2 mt-2 pt-1 pb-2"}, + {name: "deathNotification", type: "checkbox", x:1, y:9, layout:"col-md-12"}, + {name: "deathNotificationFile", type: "file", x:1, y:10, layout:"col-md-12", + uploadUrl: (id) => getUploadUrl(id), + previewUrl: (id) => getPreviewUrl(id), + loadData: async (id) => loadDeathNotificationAttachment(id), + handleDelete:(id) => handleDeathNotificationDelete(id), + handleClick: (id) => handleDeathNotificationClick(id), + display: (data) => {return data.deathNotification}, + updateFileData: (data) => updateFileData(data) + }, + {name: "declarantDetails", type: "custom", x:1, y:11, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "declarantId", type: "custom", x:1, y:12, layout:"col-md-12", component: (name, disabled) => }, + {name:"registrationBox", label: "Registration Location", components: [ + {name: "registrationLocation", type: "custom", x:1, y:1, layout:"col-md-12", component: (name, disabled) => } + ], type: "box", x:2, y:28, layout:"col-md-11 ms-2 mt-2 pt-1 pb-2"}, + + {name: "Mentions", type: "custom", x:1, y:30, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "mentions", type: "text", x:1, y:31, layout:"col-md-12"}, + {name: "Extras", type: "custom", x:1, y:32, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "notes", type: "text", x:1, y:33, layout:"col-md-12"} + +]; + +const getUploadUrl = (id) => { + return getServiceUri() + 'civil-status-mtlb/death-notification-file' + '/' + id; +} + +const getPreviewUrl = (id) => { + return getServiceUri() + 'civil-status-mtlb/death-notification-file' + '/preview/' + id; +} + +const updateFileData = (data) => { + let filter = {name: data.fileName, description: data.description}; + rest.request(getServiceUri() + 'civil-status-mtlb/death-notification-file' + '/' + data.id, "PUT", filter); +} + +const handleDeathNotificationClick = async (id) => { + const token = await rest.getToken(getServiceUri() + 'token/get-auth-code'); + window.location = getServiceUri() + 'civil-status-mtlb/death-notification-file' + '/' + id + '/' + token; +}; + +const handleDeathNotificationDelete = (id) => { + rest.delete('civil-status-mtlb/death-notification-file', id).then(() => { + DELETE_ATTACHMENT_EVENT.publish(id) + }); +}; + +const loadDeathNotificationAttachment = async (id) => { + let filter = {and: true}; + filter['civil-status-mtlb-death-notification-file'] = {}; + filter['civil-status-mtlb-death-notification-file']['civilStatusMtlbId'] = id; + return rest.search('civil-status-mtlb/death-notification-file', filter) +} + +export const loadCivilStatusMtlbAttachment = async (id) => { + let filter = {and: true}; + filter['civil-status-mtlb-attachment'] = {}; + filter['civil-status-mtlb-attachment']['civilStatusMtlbId'] = id; + return rest.search('civil-status-mtlb/attachment', filter) +} + +export const saveDeathRegistrationForm = async (formData) => { + let dto = pojoMetadata['civil-status-mtlb'].form2dto(formData); + dto.mtlbType = MTLB_TYPE_DEATH_REGISTRATION; + try { + return rest.request(getServiceUri() + 'apply/create-civil-status-mtlb', 'POST', dto) + } catch (err) { + alert(err); + } +} + +export const loadDeathRegistrationFormData = async (id) => { + return await rest.read('civil-status-mtlb', id).then(response => { + let form = response; + let face = null; + if (response.face != null) { + let mimeType = response['faceMimeType']; + face = "data:".concat(mimeType, ";base64,", response.face) + } + if (response.timeOfDeath !== null) + response.timeOfDeath = new Date().setHours(response.timeOfDeath[0], response.timeOfDeath[1]); + form['image'] = {x: 0.5, y:0.5, scale: 1, rotate: 0, url: (face != null)?face: '/public/avatar.png', isEmpty: true}; + let tagFilter = {and: true}; + tagFilter['civil-status-mtlb-tag'] = {civilStatusMtlbId: id}; + + return rest.search('civil-status-mtlb-tag', tagFilter).then(tags => { + form['tags'] = tags + + return form; + }) + }) +} + +export const updatePendingDeathRegistrationForm = async (formData) => { + let dto = pojoMetadata['civil-status-mtlb'].form2dto(formData); + if (!formData.image.isEmpty) { + let base64Image = formData.image.url; + let faceMimeType = base64Image.substring(base64Image.indexOf(':') + 1, base64Image.indexOf(';')) + let base64 = base64Image.substr(base64Image.indexOf(',') + 1); + dto.face = base64; + dto.faceMimeType = faceMimeType; + } + if (formData.timeOfDeath != null && typeof(formData.timeOfDeath) != 'string') { + const date = new Date(formData.timeOfDeath) + let birthHour = date.getHours() < 10 ? '0' + date.getHours() : date.getHours(); + let birthMinute = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes(); + dto.timeOfDeath = birthHour + ":" + birthMinute; + } + try { + return rest.request(getServiceUri() + 'civil-status-mtlb/pending/update', 'POST', dto);; + } catch (err) { + alert(err); + } +} + +export const newDeathRegistrationFormForm2Dto = (form, dto) => { + dto.vitalRecordId = form.id; + dto.id = null; + dto.mtlbType = MTLB_TYPE_DEATH_REGISTRATION; + dto.birthTime = null; + dto.typeOfAcquisition = null; + if (dto.otherCitizenshipCsv !== null && dto.otherCitizenshipCsv) { + dto.otherCitizenshipCsv = null; + } + dto.declarantId = null; +} + +export const updateRejectedDeathRegistrationForm = async (formData) => { + let dto = pojoMetadata['civil-status-mtlb'].form2dto(formData); + if (!formData.image.isEmpty) { + let base64Image = formData.image.url; + let faceMimeType = base64Image.substring(base64Image.indexOf(':') + 1, base64Image.indexOf(';')) + let base64 = base64Image.substr(base64Image.indexOf(',') + 1); + dto.face = base64; + dto.faceMimeType = faceMimeType; + } + if (formData.timeOfDeath != null && typeof(formData.timeOfDeath) != 'string') { + const date = new Date(formData.timeOfDeath) + let birthHour = date.getHours() < 10 ? '0' + date.getHours() : date.getHours(); + let birthMinute = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes(); + dto.timeOfDeath = birthHour + ":" + birthMinute; + } + try { + return rest.request(getServiceUri() + 'civil-status-mtlb/rejected/update', 'POST', dto); + } catch (err) { + alert(err); + } +} + +export const rejectDeathRegistrationForm = async (id) => { + try { + return rest.request(getServiceUri() + 'civil-status-mtlb/pending/reject', 'POST', id); + } catch (err) { + alert(err); + } +} + +export const approveReadyDeathRegistrationForm = async (id) => { + try { + return rest.request(getServiceUri() + 'civil-status-mtlb/ready/approve', 'POST', id); + } catch (err) { + alert(err); + } +} + +export const rejectReadyDeathRegistrationForm = async (id) => { + try { + return rest.request(getServiceUri() + 'civil-status-mtlb/ready/reject', 'POST', id); + } catch (err) { + alert(err); + } +} + +export const buildDeathRegistrationFormEmptyObject = () => { + const empty = buildEmptyObject(deathRegistrationFields); + empty['image'] = {x: 0.5, y:0.5, scale: 1, rotate: 0, url:'/public/avatar.png', isEmpty: true}; + return empty; +} + +export const updateDeathRegistrationForm = async (formData) => { + let dto = pojoMetadata['civil-status-mtlb'].form2dto(formData); + if (!formData.image.isEmpty) { + let base64Image = formData.image.url; + let faceMimeType = base64Image.substring(base64Image.indexOf(':') + 1, base64Image.indexOf(';')) + let base64 = base64Image.substr(base64Image.indexOf(',') + 1); + dto.face = base64; + dto.faceMimeType = faceMimeType; + } + if (formData.birthCountry) + dto.birthCountry = formData.birthCountry.key; + if (formData.timeOfDeath != null && typeof(formData.timeOfDeath) != 'string') { + const date = new Date(formData.timeOfDeath) + let birthHour = date.getHours() < 10 ? '0' + date.getHours() : date.getHours(); + let birthMinute = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes(); + dto.timeOfDeath = birthHour + ":" + birthMinute; + } + dto.draft = false; + try { + return rest.update('civil-status-mtlb', dto); + } catch (err) { + alert(err); + } +} + +export const deleteDeathRegistrationForm = async (id) => { + try { + return rest.delete('civil-status-mtlb', id); + } catch (err) { + alert(err); + } +} + +export const form2dto = (formData, dto) => { + dto.mtlbType = MTLB_TYPE_DEATH_REGISTRATION; + if(formData.dateOfDeath != null && typeof(formData.dateOfDeath) != 'string') { + let dateOfDeathAsDate = new Date(formData.dateOfDeath); + dto.dateOfDeath = dateOfDeathAsDate.getFullYear() + "-" + ('0' + (dateOfDeathAsDate.getMonth() + 1)).slice(-2) + "-" + ('0' + dateOfDeathAsDate.getDate()).slice(-2); + } + if (formData.timeOfDeath != null && typeof(formData.timeOfDeath) != 'string') { + const date = new Date(formData.timeOfDeath) + let birthHour = date.getHours() < 10 ? '0' + date.getHours() : date.getHours(); + let birthMinute = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes(); + dto.timeOfDeath = birthHour + ":" + birthMinute; + } + if (formData.image) + if (!formData.image.isEmpty) { + let base64Image = formData.image.url; + let faceMimeType = base64Image.substring(base64Image.indexOf(':') + 1, base64Image.indexOf(';')) + let base64 = base64Image.substr(base64Image.indexOf(',') + 1); + dto.face = base64; + dto.faceMimeType = faceMimeType; + } +} + +export const dto2form = (dto) => { + if (dto.timeOfDeath !== null) { + dto.timeOfDeath = new Date().setHours(dto.timeOfDeath[0], dto.timeOfDeath[1]); + } + return dto; +} \ No newline at end of file diff --git a/src/main/js/forms/digitalization/DigitalizationFormCommon.jsx b/src/main/js/forms/digitalization/DigitalizationFormCommon.jsx new file mode 100644 index 0000000..d281c72 --- /dev/null +++ b/src/main/js/forms/digitalization/DigitalizationFormCommon.jsx @@ -0,0 +1,321 @@ +import React from "react"; + +import { buildEmptyObject } from "../../../../auto/js/widgets/FormComponent"; +import { getServiceUri, metadataLoader, pojoMetadata } from "../../../../auto/js/metadata"; +import { MTLB_TYPE_BIRTH_REGISTRATION, MTLB_TYPE_DIGITALIZATION } from "../../../../auto/js/metadata/MtlbType"; +import { rest } from "../../../../auto/js/services/RestClient"; +import { t } from '../../../../auto/js/services/i18ndb'; +import { showNotification, swapObject } from "../../../../auto/js/utils"; +import * as Yup from 'yup'; +import { formState } from "../../../../auto/js/forms/FormState"; +import { AddressComponent } from "../../../../auto/js/widgets/AddressComponent"; +import { PersonComponent } from "../../../../auto/js/widgets/PersonComponent"; +import { loadPersonData } from "../../utils"; +import { GeoDataComponent } from "../../../../auto/js/widgets/GeoDataComponent"; +import { geoDataMetadataLoader } from "../../../../auto/js/metadata/GeoDataMetadataLoader"; +import { CountryAutoCompleteInput } from "../../widgets/CountryAutoCompleteInput"; +// import { FileInput } from "../../widgets/FileInput"; +import { DELETE_ATTACHMENT_EVENT, FILE_UPLOADED_EVENT } from "../../../../auto/js/events/Gui"; +import { FILE_TYPE_MEDICAL_NOTIFICATION, FILE_TYPE_OTHER } from "../../../../auto/js/metadata/FileType"; +import { AdvancedSearchPersonComponent } from "../../widgets/AdvancedSearchPersonComponent"; +import AutocompleteListSelector from "../../widgets/AutocompleteListSelector"; +import { TypeOfAcquisition } from "../../../../auto/js/metadata/TypeOfAcquisition"; +import { ContactComponent } from "../../widgets/ContactComponent"; + +const gender = {1:"MALE", 2:"FEMALE"}; +const maritalStatus = {1:"SINGLE", 2:"MARRIED", 3:"DIVORCED", 4:"WIDOWED"}; + +export const digitalizationFields = [ + { name: "tags", type: "tags", x: 1, y: 1, layout: "col-md-12" }, + { name: "childDetails", type: "custom", x: 1, y: 2, layout: "col-md-12", component: (name, disabled) =>
}, + { name: "image", type: "image", x: 1, y: 3, layout: "col-md-12" }, + { + name: "firstname", type: "text", x: 2, y: 5, layout: "col-md-6", + "validation": Yup.string().nullable().default(undefined).min(2, t`First name must be at least two characters long`).max(14, t`First name must be less than fifteen characters long`).required(t`First name is required`).matches(/[\p{Letter}\p{Mark}\s]+$/u, t`Only alphabets are allowed for this field `).matches(/^\p{Lu}.*$/u, t`First letter need to be Upper Case`) + }, + { + name: "secondname", type: "text", x: 2, y: 4, layout: "col-md-6", + "validation": Yup.string().nullable().default(undefined).min(2, t`Middle name must be at least four characters long`).max(28, t`Middle name must be less than twenty eight characters long`).matches(/^\p{Lu}.*$/u, t`First letter need to be Upper Case`) + }, + { + name: "thirdname", type: "text", x: 1, y: 5, layout: "col-md-6", + "validation": Yup.string().nullable().default(undefined).min(2, t`Melanisian name must be at least four characters long`).max(14, t`Melanisian name must be less than fifteen characters long`).matches(/[\p{Letter}\p{Mark}\s]+$/u, t`Only alphabets are allowed for this field `).matches(/^\p{Lu}.*$/u, t`First letter need to be Upper Case`) + }, + { + name: "fourthname", type: "text", x: 1, y: 4, layout: "col-md-6", + "validation": Yup.string().nullable().default(undefined).min(2, t`Family name must be at least four characters long`).max(14, t`Family name must be less than fifteen characters long`).required(t`Family name is required`).matches(/[\p{Letter}\p{Mark}\s]+$/u, t`Only alphabets are allowed for this field `).matches(/^\p{Lu}.*$/u, t`First letter need to be Upper Case`) + }, + { + name: "fifthname", type: "text", x: 2, y: 6, layout: "col-md-6", + "validation": Yup.string().nullable().default(undefined).min(2, t`Melanesian name must be at least four characters long`).max(14, t`Marriage name must be less than fifteen characters long`).matches(/[\p{Letter}\p{Mark}\s]+$/u, t`Only alphabets are allowed for this field `).matches(/^\p{Lu}.*$/u, t`First letter need to be Upper Case`) + }, + { + name: "gender", type: "select", x: 1, y: 7, layout: "col-md-6", metadata: () => gender, + "validation": Yup.string().nullable().default(undefined).required(t`Gender is required`) + }, + { + name: "birthdate", type: "date", x: 1, y: 8, layout: "col-md-6", + "validation": Yup.date().nullable().default(undefined).required('A date of birth is required') + }, + { name: "birthTime", type: "time", x: 2, y: 8, layout: "col-md-6" }, + { name: "birthDayUnknown", type: "checkbox", x: 1, y: 9, layout: "col-md-4" }, + { name: "birthMonthUnknown", type: "checkbox", x: 2, y: 9, layout: "col-md-4" }, + { name: "birthYearUnknown", type: "checkbox", x: 3, y: 9, layout: "col-md-4" }, + { name: "disability", type: "checkbox", x: 1, y: 10, layout: "col-md-6" }, + { + name: "citizenshipBox", label: "Citizenship", components: [ + { name: "primaryCitizenship", type: "custom", x: 1, y: 1, layout: "col-md-6", component: (name, disabled) => }, + { name: "typeOfAcquisition", type: "select", x: 2, y: 1, layout: "col-md-6", metadata: () => swapObject(TypeOfAcquisition) }, + { name: "otherCitizenshipCsv", type: "custom", x: 1, y: 3, layout: "col-md-6", component: (name, disabled) => }, + ], type: "box", x: 2, y: 11, layout: "col-md-11 ms-2 mt-2 pt-1 pb-2" + }, + { + name: "birthBox", label: "Birth Place", components: [ + { name: "birthPlace", type: "custom", x: 1, y: 1, layout: "col-md-12", component: (name, disabled) => } + ], type: "box", x: 2, y: 12, layout: "col-md-11 ms-2 mt-2 pt-1 pb-2" + }, + { + name: "originBox", label: "Village Of Origin", components: [ + { name: "villageOfOrigin", type: "custom", x: 1, y: 1, layout: "col-md-12", component: (name, disabled) => }, + ], type: "box", x: 1, y: 13, layout: "col-md-11 ms-2 mt-2 pt-1 pb-2" + }, + { name: "motherDetails", type: "custom", x: 1, y: 15, layout: "col-md-12", component: (name, disabled) =>
}, + { + name: "motherInfo", options: [ + { "name": "motherWithBirthRecord", "label": t`motherWithBirthRecord` }, + { "name": "motherWithoutBirthRecord", "label": t`motherWithoutBirthRecord` }, + { "name": "unknownMother", "label": t`unknownMother` }, + ], type: "radio", x: 1, y: 16, layout: "col-md-12 pt-4" + }, + { + name: "motherId", label: "Search Mother", type: "custom", x: 1, y: 17, layout: "col-md-12", + component: (name, disabled) => , + display: (data) => { return (data.motherInfo === "motherWithBirthRecord" || data.motherId != null) ? true : false; } + }, + { + name: "motherGenderValidation", type: "validation", x: 1, y: 18, layout: "col-md-6", + "validation": Yup.boolean().test("motherGenderValidation", "Mother need to be female", function () { + return (formState.getState()["motherId-gender"])? formState.getState()["motherId-gender"] === "FEMALE": true; + }) + }, + { + name: "reportedMotherName", type: "text", x: 2, y: 19, layout: "col-md-12", + display: (data) => { return data.motherInfo === "motherWithoutBirthRecord" ? true : false; } + }, + { name: "fatherDetails", type: "custom", x: 1, y: 20, layout: "col-md-12", component: (name, disabled) =>
}, + { + name: "fatherInfo", options: [ + { "name": "fatherWithBirthRecord", "label": t`fatherWithBirthRecord` }, + { "name": "fatherWithoutBirthRecord", "label": t`fatherWithoutBirthRecord` }, + { "name": "unknownFather", "label": t`unknownFather` }, + ], type: "radio", x: 1, y: 20, layout: "col-md-12 pt-4" + }, + { + name: "fatherId", label: "Search Father", type: "custom", x: 1, y: 21, layout: "col-md-12", + component: (name, disabled) => , + display: (data) => { return (data.fatherInfo === "fatherWithBirthRecord" || data.fatherId != null) ? true : false; } + }, + { + name: "fatherGenderValidation", type: "validation", x: 1, y: 22, layout: "col-md-6", + "validation": Yup.boolean().test("fatherGenderValidation", "Father need to be male", function () { + return (formState.getState()["fatherId-gender"])? formState.getState()["fatherId-gender"] === "MALE": true; + }) + }, + { + name: "reportedFatherName", type: "text", x: 2, y: 23, layout: "col-md-12", + display: (data) => { return data.fatherInfo === "fatherWithoutBirthRecord" ? true : false; } + }, + { name: "medicalNotification", type: "checkbox", x: 1, y: 24, layout: "col-md-12" }, + { + name: "medicalNotificationFile", type: "file", x: 1, y: 25, layout: "col-md-12", + uploadUrl: (id) => getUploadUrl(id), + previewUrl: (id) => getPreviewUrl(id), + loadData: async (id) => loadMedicalNotificationAttachment(id), + handleDelete: (id) => handleMedicalNotificationDelete(id), + handleClick: (id) => handleMedicalNotificationClick(id), + display: (data) => { return data.medicalNotification }, + updateFileData: (data) => updateFileData(data) + }, + { + name: "witness1Id", type: "custom", x: 1, y: 26, layout: "col-md-12", + "validation": Yup.string().nullable().default(undefined).when(["medicalNotification"], + (medicalNotification) => { + if (!medicalNotification) { + return Yup.string().nullable().default(undefined).required('If no medical notification exists witness is required') + } + } + ), component: (name, disabled) => , + display: (data) => { return !data.medicalNotification } + }, + { + name: "witness2Id", type: "custom", x: 2, y: 27, layout: "col-md-12", + "validation": Yup.string().nullable().default(undefined).when(["medicalNotification"], + (medicalNotification) => { + if (!medicalNotification) { + return Yup.string().nullable().default(undefined).required('If no medical notification exists witness is required') + } + } + ), component: (name, disabled) => , + display: (data) => { return !data.medicalNotification } + }, + {name: "AdministrativeDetails", type: "custom", x:1, y:28, layout:"col-md-12", component: (name, disabled) =>
}, + { name: "contact", type: "custom", x: 1, y: 29, layout: "col-md-12", component: (name, disabled, data) => }, + { + name: "addressValidation", type: "validation", x: 1, y: 30, layout: "col-md-12", + "validation": Yup.boolean().test("addressValidation", "Address is required", function () { + return formState.getAddressList().length; + }) + }, + { name: "declarantDetails", type: "custom", x: 1, y: 31, layout: "col-md-12", component: (name, disabled) =>
}, + { name: "declarantId", type: "custom", x: 1, y: 32, layout: "col-md-12", component: (name, disabled) => }, + {name:"registrationBox", label: "Registration Location", components: [ + {name: "registrationLocation", type: "custom", x:1, y:1, layout:"col-md-12", component: (name, disabled) => } + ], type: "box", x:2, y:33, layout:"col-md-11 ms-2 mt-2 pt-1 pb-2"}, + + {name: "Mentions", type: "custom", x:1, y:34, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "mentions", type: "text", x:1, y:35, layout:"col-md-12"}, + {name: "Extras", type: "custom", x:1, y:36, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "notes", type: "text", x:1, y:37, layout:"col-md-12"} + + +]; + +const getUploadUrl = (id) => { + return getServiceUri() + 'civil-status-mtlb/medical-notification-file' + '/' + id; +} + +const getPreviewUrl = (id) => { + return getServiceUri() + 'civil-status-mtlb/medical-notification-file' + '/preview/' + id; +} + +const updateFileData = (data) => { + let filter = { name: data.fileName, description: data.description }; + rest.request(getServiceUri() + 'civil-status-mtlb/medical-notification-file' + '/' + data.id, "PUT", filter); +} + +const handleMedicalNotificationClick = async (id) => { + const token = await rest.getToken(getServiceUri() + 'token/get-auth-code'); + window.location = getServiceUri() + 'civil-status-mtlb/medical-notification-file' + '/' + id + '/' + token; +}; +const handleMedicalNotificationDelete = (id) => { + rest.delete('civil-status-mtlb/medical-notification-file', id).then(() => { + DELETE_ATTACHMENT_EVENT.publish(id) + }); +}; + +const loadMedicalNotificationAttachment = async (id) => { + let filter = { and: true }; + filter['civil-status-mtlb-medical-notification-file'] = {}; + filter['civil-status-mtlb-medical-notification-file']['civilStatusMtlbId'] = id; + return rest.search('civil-status-mtlb/medical-notification-file', filter) +} + +export const loadCivilStatusMtlbAttachment = async (id) => { + let filter = { and: true }; + filter['civil-status-mtlb-attachment'] = {}; + filter['civil-status-mtlb-attachment']['civilStatusMtlbId'] = id; + return rest.search('civil-status-mtlb/attachment', filter) +} + +const Section = ({name}) => { + return ( + <> +
+

{t(name)}

+
+ + ) +} + +export const form2dto = (formData, dto) => { + if (dto.mtlbType === null || !dto.mtlbType) + dto.mtlbType = MTLB_TYPE_DIGITALIZATION; + if (!formData.image.isEmpty) { + let base64Image = formData.image.url; + let faceMimeType = base64Image.substring(base64Image.indexOf(':') + 1, base64Image.indexOf(';')) + let base64 = base64Image.substr(base64Image.indexOf(',') + 1); + dto.face = base64; + dto.faceMimeType = faceMimeType; + } + if (formData.birthCountry) + dto.birthCountry = formData.birthCountry.key; + if (formData.birthTime != null && typeof (formData.birthTime) != 'string') { + const date = new Date(formData.birthTime) + let birthHour = date.getHours() < 10 ? '0' + date.getHours() : date.getHours(); + let birthMinute = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes(); + dto.birthTime = birthHour + ":" + birthMinute; + } + if (formData.middlename != null) { + let names = formData.middlename.split(" "); + dto.secondname = names[0] + if (names.length > 1) + dto.thirdname = names[1]; + } + if (formData.otherCitizenshipCsv !== null && formData.otherCitizenshipCsv) { + let otherCitizenshipCsv = formData.otherCitizenshipCsv.join(','); + dto.otherCitizenshipCsv = otherCitizenshipCsv; + } + if (formData.motherInfo == "unknownMother") + dto.unknownMother = true; + if (formData.fatherInfo == "unknownFather") + dto.unknownFather = true; + + if (formData.typeOfAcquisition != null) + dto.typeOfAcquisition = swapObject(TypeOfAcquisition)[formData.typeOfAcquisition] +} + +export const dto2form = (dto) => { + let form = dto; + let face = null; + if (dto.face != null) { + let mimeType = dto['faceMimeType']; + face = "data:".concat(mimeType, ";base64,", dto.face) + } + if (dto.birthTime !== null) { + dto.birthTime = new Date().setHours(dto.birthTime[0], dto.birthTime[1]); + } + + if (dto.otherCitizenshipCsv == null || dto.otherCitizenshipCsv === "") + dto.otherCitizenshipCsv = [] + else { + let values = []; + let components = dto.otherCitizenshipCsv.split(","); + components.forEach(element => { + values.push(parseInt(element)) + }); + dto.otherCitizenshipCsv = values; + } + + form['image'] = { x: 0.5, y: 0.5, scale: 1, rotate: 0, url: (face != null) ? face : '/public/avatar.png', isEmpty: (face == null) }; + + if (dto.motherId == null) { + if (dto.reportedMotherName != null) + dto.motherInfo = "motherWithoutBirthRecord" + else if (dto.unknownMother != null && dto.unknownMother) + dto.motherInfo = "unknownMother" + else + dto.motherInfo = "motherWithoutBirthRecord" + } else + dto.motherInfo = "motherWithBirthRecord" + + if (dto.fatherId == null) { + if (dto.reportedFatherName != null) + dto.fatherInfo = "fatherWithoutBirthRecord" + else if (dto.unknownFather != null && dto.unknownFather) + dto.fatherInfo = "unknownFather" + else + dto.fatherInfo = "fatherWithoutBirthRecord" + } else + dto.fatherInfo = "fatherWithBirthRecord" + + if (dto.typeOfAcquisition != null) + form.typeOfAcquisition = TypeOfAcquisition[dto.typeOfAcquisition] + else + form.typeOfAcquisition = 9; + + return form; +} + +export const newBirthRegistrationFormForm2Dto = (form, dto) => { + +} \ No newline at end of file diff --git a/src/main/js/forms/divorceRegistration/DivorceRegistrationFormCommon.jsx b/src/main/js/forms/divorceRegistration/DivorceRegistrationFormCommon.jsx new file mode 100644 index 0000000..7837d35 --- /dev/null +++ b/src/main/js/forms/divorceRegistration/DivorceRegistrationFormCommon.jsx @@ -0,0 +1,160 @@ +import React from "react"; + +import { buildEmptyObject } from "../../../../auto/js/widgets/FormComponent"; +import { getServiceUri, pojoMetadata } from "../../../../auto/js/metadata"; +import { MTLB_TYPE_DIVORCE } from "../../../../auto/js/metadata/MtlbType"; +import { rest, t } from "../../../../auto/js/services"; +import { showNotification } from "../../../../auto/js/utils"; +import { MTLB_STATUS_SUBMITTED } from "../../../../auto/js/metadata/MtlbStatus"; +import { DELETE_ATTACHMENT_EVENT } from "../../../../auto/js/events/Gui"; +import { Section } from "../../../../auto/js/widgets/Section"; + +export const divorceRegistrationFields = [ + {name: "tags", type:"tags", x:1, y:1, layout:"col-md-12"}, + {name: "unionRecordId", type: "number", x:1, y:2, layout:"col-md-12", disabled: true}, + {name: "dateOfEffect", type: "date", x:1, y:3, layout:"col-md-6"}, + {name: "dateOfOrder", type: "date", x:2, y:3, layout:"col-md-6"}, + {name: "courtOrderFile", label:"Court Order", type: "file", x:1, y:25, layout:"col-md-12", + uploadUrl: (id) => getUploadUrl(id), + previewUrl: async (id) => getPreviewUrl(id), + loadData: async (id) => loadCourtOrder(id), + handleDelete:(id) => handleCourtOrderDelete(id), + handleClick: (id) => handleCourtOrderClick(id), + updateFileData: (data) => updateFileData(data) + }, + {name: "Mentions", type: "custom", x:1, y:29, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "mentions", type: "text", x:1, y:30, layout:"col-md-12"}, + {name: "Extras", type: "custom", x:1, y:31, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "notes", type: "text", x:1, y:32, layout:"col-md-12"} +]; + +const getUploadUrl = (id) => { + return getServiceUri() + 'union-mtlb/court-order-file' + '/' + id; +} + +const getPreviewUrl = async (id) => { + const token = await rest.getToken(getServiceUri() + 'token/get-auth-code'); + return getServiceUri() + 'union-mtlb/court-order-file' + '/preview/' + id + '/' + token; +} + +const updateFileData = (data) => { + let filter = {name: data.fileName, description: data.description}; + rest.request(getServiceUri() + 'union-mtlb/court-order-file' + '/' + data.id, "PUT", filter); +} + +const handleCourtOrderClick = async (id) => { + const token = await rest.getToken(getServiceUri() + 'token/get-auth-code'); + window.location = getServiceUri() + 'union-mtlb/court-order-file' + '/' + id + '/' + token; +}; +const handleCourtOrderDelete = (id) => { + rest.delete('union-mtlb/court-order-file', id).then(() => { + DELETE_ATTACHMENT_EVENT.publish(id) + }); +}; + +const loadCourtOrder = async (id) => { + let filter = {and: true}; + filter['union-mtlb-court-order-file'] = {}; + filter['union-mtlb-court-order-file']['unionMtlbId'] = id; + return rest.search('union-mtlb/court-order-file', filter) +} + +export const saveDivorceRegistrationForm = async (formData) => { + let dto = pojoMetadata['union-mtlb'].form2dto(formData); + dto.mtlbType = MTLB_TYPE_DIVORCE; + try { + return rest.request(getServiceUri() + 'union-mtlb', 'POST', dto) + } catch (err) { + alert(err); + } +} + +export const loadDivorceRegistrationFormData = async (id) => { + return await rest.read('union-mtlb', id).then(response => { + let form = response; + let tagFilter = {and: true}; + tagFilter['union-mtlb-tag'] = {unionMtlbId: id}; + if (response.status) + showNotification(response.message.split('Detail: ')[1], "error") + + return rest.search('union-mtlb-tag', tagFilter).then(tags => { + form['tags'] = tags + + return form; + }) + }) +} + +export const updatePendingDivorceRegistrationForm = async (formData) => { + let dto = pojoMetadata['union-mtlb'].form2dto(formData); + try { + return rest.request(getServiceUri() + 'union-mtlb/pending/update', 'POST', dto); + } catch (err) { + alert(err); + } +} + +export const updateRejectedDivorceRegistrationForm = async (formData) => { + let dto = pojoMetadata['union-mtlb'].form2dto(formData); + try { + return rest.request(getServiceUri() + 'union-mtlb/rejected/update', 'POST', dto); + } catch (err) { + alert(err); + } +} + +export const rejectDivorceRegistrationForm = async (id) => { + try { + return rest.request(getServiceUri() + 'union-mtlb/pending/reject', 'POST', id); + } catch (err) { + alert(err); + } +} + +export const buildDivorceRegistrationFormEmptyObject = () => { + const empty = buildEmptyObject(divorceRegistrationFields); + return empty; +} + +export const updateDivorceRegistrationForm = async (formData) => { + let dto = pojoMetadata['union-mtlb'].form2dto(formData); + dto.mtlbStatus = MTLB_STATUS_SUBMITTED; + dto.draft = false; + try { + return rest.update('union-mtlb', dto); + } catch (err) { + alert(err); + } +} + +export const deleteDivorceRegistrationForm = async (id) => { + try { + return rest.delete('union-mtlb', id); + } catch (err) { + alert(err); + } +} + +export const form2dto = (formData, dto) => { + dto.mtlbType = MTLB_TYPE_DIVORCE; + if(formData.dateOfEffect != null && typeof(formData.dateOfEffect) != 'string') { + let dateOfEffectAsDate = new Date(formData.dateOfEffect); + dto.dateOfEffect = dateOfEffectAsDate.getFullYear() + "-" + ('0' + (dateOfEffectAsDate.getMonth() + 1)).slice(-2) + "-" + ('0' + dateOfEffectAsDate.getDate()).slice(-2); + } + if(formData.dateOfOrder != null && typeof(formData.dateOfOrder) != 'string') { + let dateOfOrderAsDate = new Date(formData.dateOfOrder); + dto.dateOfOrder = dateOfOrderAsDate.getFullYear() + "-" + ('0' + (dateOfOrderAsDate.getMonth() + 1)).slice(-2) + "-" + ('0' + dateOfOrderAsDate.getDate()).slice(-2); + } +} + +export const dto2form = (response) => { + return response; + +} + +export const newDivorceRegistrationFormForm2Dto = (form, dto) => { + dto.mtlbType = MTLB_TYPE_DIVORCE; + dto.unionRecordId = form.id; + dto.id = null; + dto.timeOfMarriage = null; +} \ No newline at end of file diff --git a/src/main/js/forms/familyTreeRegistration/FamilyTreeRegistrationFormCommon.jsx b/src/main/js/forms/familyTreeRegistration/FamilyTreeRegistrationFormCommon.jsx new file mode 100644 index 0000000..8bcf1ff --- /dev/null +++ b/src/main/js/forms/familyTreeRegistration/FamilyTreeRegistrationFormCommon.jsx @@ -0,0 +1,250 @@ +import React from "react"; + +import { buildEmptyObject } from "../../../../auto/js/widgets/FormComponent"; +import { getServiceUri, metadataLoader, pojoMetadata } from "../../../../auto/js/metadata"; +import { MTLB_TYPE_RV4_BIRTH_FAMILY_TREE_RECORD, MTLB_TYPE_RV4_BIRTH_VITAL_RECORD } from "../../../../auto/js/metadata/MtlbType"; +import { rest } from "../../../../auto/js/services/RestClient"; +import { t } from '../../../../auto/js/services/i18ndb'; +import { showNotification } from "../../../../auto/js/utils"; +import * as Yup from 'yup'; +import { formState } from "../../../../auto/js/forms/FormState"; +import { AddressComponent } from "../../../../auto/js/widgets/AddressComponent"; +import { PersonComponent } from "../../../../auto/js/widgets/PersonComponent"; +import { loadPersonData } from "../../utils"; + +const gender = {1:"MALE", 2:"FEMALE"}; +const maritalStatus = {1:"SINGLE", 2:"MARRIED", 3:"DIVORCED", 4:"WIDOWED"}; + +export const familyTreeRegistrationFields = [ + {name: "tags", type:"tags", x:1, y:1, layout:"col-md-12"}, + {name: "childDetails", type: "custom", x:1, y:2, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "image", type: "image", x: 1, y: 3, layout: "col-md-12" }, + {name: "vitalRecordId", type:"number", x: 1, y: 4, layout: "col-md-12"}, + {name: "firstname", type: "text", x:1, y:6, layout:"col-md-6", + "validation": Yup.string().nullable().default(undefined).min(2, t`First name must be at least two characters long`).max(14, t`First name must be less than fifteen characters long`).required(t`First name is required`).matches(/[\p{Letter}\p{Mark}\s]+$/u, t`Only alphabets are allowed for this field `)}, + {name: "middlename", type: "text", x:2, y:5, layout:"col-md-6", + "validation": Yup.string().nullable().default(undefined).min(2, t`Middle name must be at least four characters long`).max(28, t`Middle name must be less than twenty eight characters long`)}, + {name: "fourthname", type: "text", x:1, y: 5, layout:"col-md-6", + "validation": Yup.string().nullable().default(undefined).min(2, t`Family name must be at least four characters long`).max(14, t`Family name must be less than fifteen characters long`).required(t`Family name is required`).matches(/[\p{Letter}\p{Mark}\s]+$/u, t`Only alphabets are allowed for this field `)}, + {name: "fifthname", type: "text", x:2, y: 6, layout:"col-md-6", + "validation": Yup.string().nullable().default(undefined).min(2, t`Melanesian name must be at least four characters long`).max(14, t`Marriage name must be less than fifteen characters long`).matches(/[\p{Letter}\p{Mark}\s]+$/u, t`Only alphabets are allowed for this field `)}, + {name: "gender", type: "select", x:1, y: 7, layout:"col-md-6", metadata: () => gender, + "validation": Yup.string().nullable().default(undefined).required(t`Gender is required`)}, + {name: "birthdate", type: "date", x:1, y: 8, layout:"col-md-6", + "validation": Yup.date().nullable().default(undefined).required('A date of birth is required') + }, + {name: "birthTime", type: "time", x:2, y:8, layout:"col-md-6"}, + {name: "birthDayUnknown", type: "checkbox", x:1, y:9, layout:"col-md-4"}, + {name: "birthMonthUnknown", type: "checkbox", x:2, y:9, layout:"col-md-4"}, + {name: "birthYearUnknown", type: "checkbox", x:3, y:9, layout:"col-md-4"}, + {name: "disability", type: "checkbox", x:1, y:10, layout:"col-md-6"}, +// {name: "birthPlace", type: "custom", x:1, y:12, layout:"col-md-12", component: (name, disabled) =>
}, +// {name: "birthPlace", type: "custom", x:1, y:13, layout:"col-md-12", component: (name, disabled) => }, + {name: "motherDetails", type: "custom", x:1, y:14, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "unknownMother", type: "checkbox", x:1, y:15, layout:"col-md-12"}, + {name: "motherId", type: "custom", x:1, y:16, layout:"col-md-12", component: (name, disabled) => }, + {name: "reportedMotherName", type: "text", x:2, y:17, layout:"col-md-12"}, + {name: "fatherDetails", type: "custom", x:1, y:18, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "unknownFather", type: "checkbox", x:1, y:19, layout:"col-md-12"}, + {name: "fatherId", type: "custom", x:1, y:20, layout:"col-md-12", component: (name, disabled) => }, + {name: "reportedFatherName", type: "text", x:1, y:21, layout:"col-md-12"}, + {name: "extras", type: "custom", x:1, y:28, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "notes", type: "text", x:1, y:29, layout:"col-md-12"}, + +]; + +const checkAttachment = () => { + var attachments = formState.getAttachmentList(); + return attachments.length; +} + +export const saveFamilyTreeRegistrationForm = async (formData) => { + let dto = pojoMetadata['rvfour-birth-mtlb'].form2dto(formData); + dto.mtlbType = MTLB_TYPE_RV4_BIRTH_FAMILY_TREE_RECORD; + if (!formData.image.isEmpty) { + let base64Image = formData.image.url; + let faceMimeType = base64Image.substring(base64Image.indexOf(':') + 1, base64Image.indexOf(';')) + let base64 = base64Image.substr(base64Image.indexOf(',') + 1); + dto.face = base64; + dto.faceMimeType = faceMimeType; + } + if (formData.middlename != null) { + let names = formData.middlename.split(" "); + dto.secondname = names[0] + if (names.length > 1) + dto.thirdname = names[1]; + } + if (formData.birthCountry) + dto.birthCountry = formData.birthCountry.key; + try { + return rest.request(getServiceUri() + 'apply/create-rv-four-birth-mtlb', 'POST', dto) + } catch (err) { + alert(err); + } +} + +export const loadFamilyTreeRegistrationFormData = async (id) => { + return await rest.read('rvfour-birth-mtlb', id).then(response => { + let form = response; + let face = null; + if (response.face != null) { + let mimeType = response['faceMimeType']; + face = "data:".concat(mimeType, ";base64,", response.face) + } + if (response.birthCountry != null) { + let countryMetadata = metadataLoader.get('country'); + form.birthCountry = {key: response.birthCountry, value: countryMetadata[response.birthCountry]} + } + if (response.secondename != null) { + form['middlename'] = response.secondename; + if (response.thirdname != null) + form['middlename'] = form['middlename'] + " " + response.thirdname; + } + if (response.birthtime !== null) + response.birthtime = new Date().setHours(response.birthtime[0], response.birthtime[1]); + if (response.birthPlace == null) + form.birthPlace = "191"; + form['image'] = {x: 0.5, y:0.5, scale: 1, rotate: 0, url: (face != null)?face: '/public/avatar.png', isEmpty: true}; + + let tagFilter = {and: true}; + tagFilter['rvfour-birth-mtlb-tag'] = {rvfourBirthMtlbId: id}; + + return rest.search('rvfour-birth-mtlb-tag', tagFilter).then(tags => { + form['tags'] = tags + + return form; + }) + }) +} + +export const updatePendingFamilyTreeRegistrationForm = async (formData) => { + let dto = pojoMetadata['rvfour-birth-mtlb'].form2dto(formData); + form2dto(formData, dto); + try { + return rest.request(getServiceUri() + 'rvfour-birth-mtlb/pending/update', 'POST', dto); + } catch (err) { + alert(err); + } +} + +export const updateFamilyTreeRegistrationForm = async (formData) => { + let dto = pojoMetadata['rvfour-birth-mtlb'].form2dto(formData); + form2dto(formData, dto); + try { + return rest.update('rvfour-birth-mtlb', dto); + } catch (err) { + alert(err); + } +} + +export const deleteFamilyTreeRegistrationForm = async (id) => { + try { + return rest.delete('rvfour-birth-mtlb', id); + } catch (err) { + alert(err); + } +} + +export const updateRejectedFamilyTreeRegistrationForm = async (formData) => { + //TODO: Move form2dto from pojo metadata + let dto = pojoMetadata['rvfour-birth-mtlb'].form2dto(formData); + form2dto(formData, dto); + try { + return rest.request(getServiceUri() + 'rvfour-birth-mtlb/rejected/update', 'POST', dto); + } catch (err) { + alert(err); + } +} + +export const rejectFamilyTreeRegistrationForm = async (id) => { + try { + return rest.request(getServiceUri() + 'rvfour-birth-mtlb/pending/reject', 'POST', id); + } catch (err) { + alert(err); + } +} + +export const rejectReadyFamilyTreeRegistrationForm = async (id) => { + try { + return rest.request(getServiceUri() + 'rvfour-birth-mtlb/ready/reject', 'POST', id); + } catch (err) { + alert(err); + } +} + +export const approveReadyFamilyTreeRegistrationForm = async (id) => { + try { + return rest.request(getServiceUri() + 'rvfour-birth-mtlb/ready/approve', 'POST', id); + } catch (err) { + alert(err); + } +} + +export const buildFamilyTreeRegistrationFormEmptyObject = () => { + const empty = buildEmptyObject(familyTreeRegistrationFields); + empty['image'] = {x: 0.5, y:0.5, scale: 1, rotate: 0, url:'/public/avatar.png', isEmpty: true}; + empty['birthCountry'] = {key: 179, value: 'Trinidad and Tobago'} + return empty; +} + +export const loadCivilStatusMtlbAttachment = async (id) => { + let filter = {and: true}; + filter['rvfour-birth-mtlb-attachment'] = {}; + filter['rvfour-birth-mtlb-attachment']['civilStatusMtlbId'] = id; + return rest.search('rvfour-birth-mtlb-attachment', filter) +} + +const form2dto = (formData, dto) => { + if (!formData.image.isEmpty) { + let base64Image = formData.image.url; + let faceMimeType = base64Image.substring(base64Image.indexOf(':') + 1, base64Image.indexOf(';')) + let base64 = base64Image.substr(base64Image.indexOf(',') + 1); + dto.face = base64; + dto.faceMimeType = faceMimeType; + } + if (formData.birthCountry) + dto.birthCountry = formData.birthCountry.key; + if (formData.birthtime != null && typeof(formData.birthtime) != 'string') { + const date = new Date(formData.birthTime) + let birthHour = date.getHours() < 10 ? '0' + date.getHours() : date.getHours(); + let birthMinute = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes(); + dto.birthtime = birthHour + ":" + birthMinute; + } + if (formData.middlename != null) { + let names = formData.middlename.split(" "); + dto.secondname = names[0] + if (names.length > 1) + dto.thirdname = names[1]; + } +} + +export const dto2form = (response) => { + let form = response; + let face = null; + if (response.face != null) { + let mimeType = response['faceMimeType']; + face = "data:".concat(mimeType, ";base64,", response.face) + } + if (response.secondename != null) { + form['middlename'] = response.secondename; + if (response.thirdname != null) + form['middlename'] = form['middlename'] + " " + response.thirdname; + } + if (response.birthtime !== null) + response.birthtime = new Date().setHours(response.birthtime[0], response.birthtime[1]); + if (response.birthPlace == null) + form.birthPlace = "191"; + form['image'] = {x: 0.5, y:0.5, scale: 1, rotate: 0, url: (face != null)?face: '/public/avatar.png', isEmpty: (face == null)}; + + return form; +} + +const Section = ({name}) => { + return ( + <> +
+

{t(name)}

+
+ + ) +} \ No newline at end of file diff --git a/src/main/js/forms/idCardApplication/AdjudicationFormCommon.jsx b/src/main/js/forms/idCardApplication/AdjudicationFormCommon.jsx new file mode 100644 index 0000000..59f4afe --- /dev/null +++ b/src/main/js/forms/idCardApplication/AdjudicationFormCommon.jsx @@ -0,0 +1,33 @@ +import React from "react"; +import { loadPersonData } from "../../utils"; +import { AdvancedSearchPersonComponent } from "../../widgets/AdvancedSearchPersonComponent"; + +const gender = {1:"MALE", 2:"FEMALE"}; + + export const adjudicationFields = [ + {name:"image", type:"image", x:1, y:2, layout:"col-md-12"}, + {name: "vitalRecordId", type: "custom", x:1, y: 5, layout:"col-md-12", component: (name, disabled) => }, + {name: "leftThumbImage", type:"view", x:1, y:17, layout:"col-md-6"}, + {name: "leftIndexFingerImage", type:"view", x:2, y:17, layout:"col-md-6"}, + {name: "leftMiddleFingerImage", type:"view", x:1, y:18, layout:"col-md-6"}, + {name: "leftRingFingerImage", type:"view", x:2, y:18, layout:"col-md-6"}, + {name: "leftPinkyImage", type:"view", x:1, y:19, layout:"col-md-6"}, + {name: "rightThumbImage", type:"view", x:2, y:19, layout:"col-md-6"}, + {name: "rightIndexFingerImage", type:"view", x:1, y:20, layout:"col-md-6"}, + {name: "rightMiddleFingerImage", type:"view", x:2, y:20, layout:"col-md-6"}, + {name: "rightRingFingerImage", type:"view", x:1, y:21, layout:"col-md-6"}, + {name: "rightPinkyImage", type:"view", x:2, y:21, layout:"col-md-6"} +]; + +export const adjudicationMatchFields = [ + {name: "image", type: "image", x: 1, y: 2, layout: "col-md-12" }, + {name: "id", type: "number", x:1, y:3, layout:"col-md-6"}, + {name: "firstname", type: "text", x:1, y:5, layout:"col-md-6"}, + {name: "secondname", type: "text", x:2, y:4, layout:"col-md-6"}, + {name: "thirdname", type: "text", x:1, y: 5, layout:"col-md-6"}, + {name: "fourthname", type: "text", x:1, y: 4, layout:"col-md-6"}, + {name: "fifthname", type: "text", x:2, y: 6, layout:"col-md-6"}, + {name: "gender", type: "select", x:1, y: 7, layout:"col-md-6", metadata: () => gender}, + {name: "birthdate", type: "date", x:1, y: 8, layout:"col-md-6"}, + {name: "birthTime", type: "time", x:2, y:8, layout:"col-md-6"}, +]; \ No newline at end of file diff --git a/src/main/js/forms/idCardApplication/IdCardApplicationFormCommon.jsx b/src/main/js/forms/idCardApplication/IdCardApplicationFormCommon.jsx new file mode 100644 index 0000000..4c4aaaa --- /dev/null +++ b/src/main/js/forms/idCardApplication/IdCardApplicationFormCommon.jsx @@ -0,0 +1,355 @@ +import React from "react"; +import * as Yup from 'yup'; +import { buildEmptyObject } from "../../../../auto/js/widgets/FormComponent"; +import { getServiceUri, pojoMetadata } from "../../../../auto/js/metadata"; +import { MTLB_TYPE_ID_CARD } from "../../../../auto/js/metadata/MtlbType"; +import { rest, t } from "../../../../auto/js/services"; +import { showNotification } from "../../../../auto/js/utils"; + +import { PRINT_EVENT } from './../../../../auto/js/events/Gui'; +import { MTLB_STATUS_ARCHIVED } from "../../../../auto/js/metadata/MtlbStatus"; +import { IdCard } from './../../../../auto/js/forms/IdCard'; +import { style } from './../../../../auto/js/forms/IdCardStyleObj'; +import { setContextualOptions } from '../../../../auto/js/widgets/RibbonTab'; +import { ADDRESS_ORDER_BY_PROVINCE_NAME } from "../../../../auto/js/metadata/AddressOrderBy"; +import { PersonComponent } from "../../../../auto/js/widgets/PersonComponent"; +import { buildAddressData, loadPersonData } from "../../utils"; +import { DOCUMENT_TYPE_ID_CARD } from "../../../../auto/js/metadata/DocumentType"; +import { AdvancedSearchPersonComponent } from "../../widgets/AdvancedSearchPersonComponent"; +import { Section } from "../../../../auto/js/widgets/Section"; + +export const idCardApplicationFields = [ + { name: "tags", type: "tags", x: 1, y: 1, layout: "col-md-12", }, + { name: "image", type: "image", x: 1, y: 2, layout: "col-md-12" }, + { + name: "photo", type: "validation", x: 1, y: 3, layout: "col-md-12", + "validation": Yup.string().nullable().default(undefined).when(["image"], + (image) => { + if (image.isEmpty) + return Yup.string().nullable().default(undefined).required('Photo is Required') + }) + }, + { name: "vitalRecordId", type: "custom", x: 1, y: 5, layout: "col-md-12", component: (name, disabled) => }, + {name: "Extras", type: "custom", x:1, y:6, layout:"col-md-12", component: (name, disabled) =>
}, + { name: "notes", type: "text", x: 1, y: 7, layout: "col-md-12" } +]; + +export const saveIdCardApplicationForm = async (formData) => { + let data = _.clone(formData); + let dto = pojoMetadata['id-mtlb'].form2dto(data); + dto.mtlbType = MTLB_TYPE_ID_CARD; + dto.vitalRecordId = formData.id; + dto.id = null; + if (!formData.image.isEmpty) { + let base64Image = formData.image.url; + let faceMimeType = base64Image.substring(base64Image.indexOf(':') + 1, base64Image.indexOf(';')) + let base64 = base64Image.substr(base64Image.indexOf(',') + 1); + dto.face = base64; + dto.faceMimeType = faceMimeType; + } + try { + return rest.request(getServiceUri() + 'apply/create-id-mtlb', 'POST', dto) + } catch (err) { + alert(err); + } +} + +const printIdCard = (data) => () => { + console.log(data); + let dto = {}; + dto.vitalRecordId = data.id; + dto.face = data.image; + dto.documentType = DOCUMENT_TYPE_ID_CARD; + dto.idMtlbId = data.idMtlbId; + rest.stringResponseRequest(getServiceUri() + 'apply/issue-document', 'POST', dto).then((response) => { + data.documentId = response; + const printable = { + content: , + style: { style }.style, + copyParentStyle: false + } + PRINT_EVENT.publish(printable); + }) +} +const filterData = (DefaultRows) => { + const newRows = []; + for (let i in DefaultRows) { + let row = DefaultRows[i]; + let fromDate = row.fromDate + if (fromDate !== null) { + let date = new Date(fromDate[0] + "/" + fromDate[1] + "/" + fromDate[2]); + date.setTime(date.getTime() + 60 * 60 * 1000) + row.fromDate = date; + } + let toDate = row.toDate + if (toDate !== null) { + let date = new Date(toDate[0] + "/" + toDate[1] + "/" + toDate[2]); + date.setTime(date.getTime() + 60 * 60 * 1000) + row.toDate = date; + } + newRows.push(row); + } + return newRows; +} +/* const buildAddressData = async (query, id) => { + let filter = query; + let data; + filter["address"] = {vitalRecordId: id}; + filter["orderBy"] = ADDRESS_ORDER_BY_PROVINCE_NAME; + filter.orderDirection = null; + filter.offset = query.page * query.pageSize; + if (query.search && query.search!='') { + pojoMetadata["address"].columns.forEach(element => { + if(element.type=='text'){ + filter["address"][element.key]= query.search; + } + }); + filter["and"] = false; + } + return await getData(filter).then(response => { + if (response.length) { + let areaId = response[response.length - 1].areaId; + return areaId; + } + else + return "" + }); +} */ + +const getData = async (filter) => { + return await rest.search('address', filter) +} + +export const loadIdCardApplicationFormData = async (id) => { + return await rest.read('id-mtlb', id).then(response => { + let form = response; + let face = null; + if (response.face != null) { + let mimeType = response['faceMimeType']; + face = "data:".concat(mimeType, ";base64,", response.face) + } + form['image'] = { x: 0.5, y: 0.5, scale: 1, rotate: 0, url: (face != null) ? face : '/public/avatar.png', isEmpty: true }; + let tagFilter = { and: true }; + tagFilter['id-mtlb-tag'] = { idMtlbId: id }; + if (response.status) + showNotification(response.message.split('Detail: ')[1], "error") + + return rest.search('id-mtlb-tag', tagFilter).then(async tags => { + form['tags'] = tags + + + if (form['mtlbStatus'] == MTLB_STATUS_ARCHIVED) { + + let vitalRecordId = form['vitalRecordId']; + rest.read('vital-record', vitalRecordId).then(async print => { + print['image'] = form['face']; + let address = null; + try { + address = await buildAddressData({}, vitalRecordId); + } + catch (error) { + } + print['address'] = address; + setContextualOptions({ + "id-database": { + submenu: { + "cr-form": { + options: { + "print-id": { + label: response.printed ? "Reprint" : "Print", do: printIdCard(print) + }, + } + } + } + } + }) + }) + } + return form; + }) + }) +} + +export const updatePendingIdCardApplicationForm = async (formData) => { + let dto = pojoMetadata['id-mtlb'].form2dto(formData); + if (!formData.image.isEmpty) { + let base64Image = formData.image.url; + let faceMimeType = base64Image.substring(base64Image.indexOf(':') + 1, base64Image.indexOf(';')) + let base64 = base64Image.substr(base64Image.indexOf(',') + 1); + dto.face = base64; + dto.faceMimeType = faceMimeType; + } + try { + return rest.request(getServiceUri() + 'id-mtlb/pending/update', 'POST', dto); + } catch (err) { + alert(err); + } +} + +export const updateRejectedIdCardApplicationForm = async (formData) => { + let dto = pojoMetadata['id-mtlb'].form2dto(formData); + if (!formData.image.isEmpty) { + let base64Image = formData.image.url; + let faceMimeType = base64Image.substring(base64Image.indexOf(':') + 1, base64Image.indexOf(';')) + let base64 = base64Image.substr(base64Image.indexOf(',') + 1); + dto.face = base64; + dto.faceMimeType = faceMimeType; + } + try { + return rest.request(getServiceUri() + 'id-mtlb/rejected/update', 'POST', dto); + } catch (err) { + alert(err); + } +} + +export const rejectIdCardApplicationForm = async (id) => { + try { + return rest.request(getServiceUri() + 'id-mtlb/pending/reject', 'POST', id); + } catch (err) { + alert(err); + } +} + +export const buildIdCardApplicationFormEmptyObject = () => { + const empty = buildEmptyObject(idCardApplicationFields); + empty['image'] = { x: 0.5, y: 0.5, scale: 1, rotate: 0, url: '/public/avatar.png', isEmpty: true }; + return empty; +} + +export const updateIdCardApplicationForm = async (formData) => { + let dto = pojoMetadata['id-mtlb'].form2dto(formData); + if (!formData.image.isEmpty) { + let base64Image = formData.image.url; + let faceMimeType = base64Image.substring(base64Image.indexOf(':') + 1, base64Image.indexOf(';')) + let base64 = base64Image.substr(base64Image.indexOf(',') + 1); + dto.face = base64; + dto.faceMimeType = faceMimeType; + } + dto.draft = false; + try { + return rest.update('id-mtlb', dto); + } catch (err) { + alert(err); + } +} + +export const rejectReadyIdCardApplicationForm = async (id) => { + try { + return rest.request(getServiceUri() + 'id-mtlb/ready/reject', 'POST', id); + } catch (err) { + alert(err); + } +} + +export const approveReadyIdCardApplicationForm = async (id) => { + try { + return rest.request(getServiceUri() + 'id-mtlb/ready/approve', 'POST', id); + } catch (err) { + alert(err); + } +} + +export const deleteIdCardApplicationForm = async (id) => { + try { + return rest.delete('id-mtlb', id); + } catch (err) { + alert(err); + } +} +export const idCardContent = +{ + mainTitle: "Vanuatu National ID Card", + mainSubTitle: "Carte d'identité nationale de Vanuatu", +}; + +export const form2dto = (formData, dto) => { + if (!formData.image.isEmpty) { + let base64Image = formData.image.url; + let faceMimeType = base64Image.substring(base64Image.indexOf(':') + 1, base64Image.indexOf(';')) + let base64 = base64Image.substr(base64Image.indexOf(',') + 1); + dto.face = base64; + dto.faceMimeType = faceMimeType; + } +} + +export const dto2form = (dto) => { + let form = dto; + let face = null; + if (dto.face != null) { + let mimeType = dto['faceMimeType']; + face = "data:".concat(mimeType, ";base64,", dto.face) + } + form['image'] = { x: 0.5, y: 0.5, scale: 1, rotate: 0, url: (face != null) ? face : '/public/avatar.png', isEmpty: (face == null) }; + + + if (form['mtlbStatus'] == MTLB_STATUS_ARCHIVED) { + + let vitalRecordId = form['vitalRecordId']; + rest.read('vital-record', vitalRecordId).then(async print => { + print['image'] = form['face']; + print['idMtlbId'] = dto.id + let address = null; + try { + address = await buildAddressData({}, vitalRecordId); + } + catch (error) { + } + print['address'] = address; + setContextualOptions({ + "id-database": { + submenu: { + "cr-form": { + options: { + "print-id": { + label: dto.printed ? "Reprint ID Card" : "Print ID Card", do: printIdCard(print) + }, + }, + label: "Actions" + } + } + }, + "civil-records": { + submenu: { + "actions": { + options: { + "print-id": { + label: dto.printed ? "Reprint ID Card" : "Print ID Card", do: printIdCard(print) + } + }, + label: "Actions" + } + } + } + }) + }) + } + form['leftThumbImage'] = { x: 0.5, y: 0.5, scale: 1, rotate: 0, url: (getFormFinger(dto.leftThumb) != null) ? getFormFinger(dto.leftThumb) : '/public/finger-not-found.png', isEmpty: true, width: 70, height: 70 } + form['leftIndexFingerImage'] = { x: 0.5, y: 0.5, scale: 1, rotate: 0, url: (getFormFinger(dto.leftIndexFinger) != null) ? getFormFinger(dto.leftIndexFinger) : '/public/finger-not-found.png', isEmpty: true, width: 70, height: 70 } + form['leftMiddleFingerImage'] = { x: 0.5, y: 0.5, scale: 1, rotate: 0, url: (getFormFinger(dto.leftMiddleFinger) != null) ? getFormFinger(dto.leftMiddleFinger) : '/public/finger-not-found.png', isEmpty: true, width: 70, height: 70 } + form['leftRingFingerImage'] = { x: 0.5, y: 0.5, scale: 1, rotate: 0, url: (getFormFinger(dto.leftRingFinger) != null) ? getFormFinger(dto.leftRingFinger) : '/public/finger-not-found.png', isEmpty: true, width: 70, height: 70 } + form['leftPinkyImage'] = { x: 0.5, y: 0.5, scale: 1, rotate: 0, url: (getFormFinger(dto.leftPinky) != null) ? getFormFinger(dto.leftPinky) : '/public/finger-not-found.png', isEmpty: true, width: 70, height: 70 } + form['rightThumbImage'] = { x: 0.5, y: 0.5, scale: 1, rotate: 0, url: (getFormFinger(dto.rightThumb) != null) ? getFormFinger(dto.rightThumb) : '/public/finger-not-found.png', isEmpty: true, width: 70, height: 70 } + form['rightIndexFingerImage'] = { x: 0.5, y: 0.5, scale: 1, rotate: 0, url: (getFormFinger(dto.rightIndexFinger) != null) ? getFormFinger(dto.rightIndexFinger) : '/public/finger-not-found.png', isEmpty: true, width: 70, height: 70 } + form['rightMiddleFingerImage'] = { x: 0.5, y: 0.5, scale: 1, rotate: 0, url: (getFormFinger(dto.rightMiddleFinger) != null) ? getFormFinger(dto.rightMiddleFinger) : '/public/finger-not-found.png', isEmpty: true, width: 70, height: 70 } + form['rightRingFingerImage'] = { x: 0.5, y: 0.5, scale: 1, rotate: 0, url: (getFormFinger(dto.rightRingFinger) != null) ? getFormFinger(dto.rightRingFinger) : '/public/finger-not-found.png', isEmpty: true, width: 70, height: 70 } + form['rightPinkyImage'] = { x: 0.5, y: 0.5, scale: 1, rotate: 0, url: (getFormFinger(dto.rightPinky) != null) ? getFormFinger(dto.rightPinky) : '/public/finger-not-found.png', isEmpty: true, width: 70, height: 70 } + return form; +} + +export const newIdCardApplicationFormForm2Dto = (formData, dto) => { + dto.mtlbType = MTLB_TYPE_ID_CARD; + dto.vitalRecordId = formData.id; + dto.id = null; + dto.face = null; + dto.faceMimeType = null; + formData.image.isEmpty = true; +} + +const getFormFinger = (fingerData) => { + let finger = null; + if (fingerData !== null) { + let mimeType = "image/png" + finger = "data:".concat(mimeType, ";base64,", fingerData) + } + return finger; +} \ No newline at end of file diff --git a/src/main/js/forms/marriageRegistration/MarriageRegistrationFormCommon.jsx b/src/main/js/forms/marriageRegistration/MarriageRegistrationFormCommon.jsx new file mode 100644 index 0000000..c1676f3 --- /dev/null +++ b/src/main/js/forms/marriageRegistration/MarriageRegistrationFormCommon.jsx @@ -0,0 +1,254 @@ +import React from "react"; +import * as Yup from 'yup'; + +import { buildEmptyObject } from "../../../../auto/js/widgets/FormComponent"; +import { getServiceUri, pojoMetadata } from "../../../../auto/js/metadata"; +import { MTLB_TYPE_MARRIAGE } from "../../../../auto/js/metadata/MtlbType"; +import { rest, t } from "../../../../auto/js/services"; +import { formatDate, showNotification } from "../../../../auto/js/utils"; +import { MTLB_STATUS_SUBMITTED } from "../../../../auto/js/metadata/MtlbStatus"; +import { Section } from "../../widgets/Section"; +import { PersonComponent } from "../../../../auto/js/widgets/PersonComponent"; +import { loadPersonData } from "../../utils"; +import { GeoDataComponent } from "../../../../auto/js/widgets/GeoDataComponent"; +import { AdvancedSearchPersonComponent } from "../../widgets/AdvancedSearchPersonComponent"; +import { buildFemaleEmptyObject, buildMaleEmptyObject } from "../birthRegistration/BirthRegistrationFormCommon"; +import { Separator } from "../CivilRecordFormCommon"; +import { formState } from "../../../../auto/js/forms/FormState"; + +const regime = {1:"Civil Marriage", 2:"Religious Marriage", 3: "Custom Marriage"}; + +/* export const marriageRegistrationFields = [ + {name: "tags", type:"tags", x:1, y:1, layout:"col-md-12"}, + {name: "marriageDetails", type: "custom", x:1, y:2, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "declaredDate", type: "date", x:1, y: 3, layout:"col-md-6"}, + {name: "timeOfMarriage", type: "time", x:2, y:3, layout:"col-md-6"}, + {name: "unionRegime", type: "select", x:1, y: 4, layout:"col-md-6", metadata: () => regime}, + {name:"addressBox", label: "Place", components: [ + {name: "address", type: "custom", x:1, y:1, layout:"col-md-12", component: (name, disabled) => }, + ], type: "box", x:2, y:5, layout:"col-md-11 ms-2 mt-2 pt-1 pb-2"}, + {name: "wifeDetails", type: "custom", x:1, y:7, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "partner2VitalRecordId", type: "custom", x:1, y:8, layout:"col-md-12", component: (name, disabled) => }, + {name: "husbandDetails", type: "custom", x:1, y:10, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "partner1VitalRecordId", type: "custom", x:1, y:11, layout:"col-md-12", component: (name, disabled) => }, + {name: "witnessDetails", type: "custom", x:1, y:13, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "witness1VitalRecordId", type: "custom", x:1, y:14, layout:"col-md-12", component: (name, disabled) => }, + {name: "witness2VitalRecordId", type: "custom", x:1, y:16, layout:"col-md-12", component: (name, disabled) => }, + {name: "declarationDetails", type: "custom", x:1, y:17, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "celebrant", type: "text", x:1, y:18, layout:"col-md-4"}, + {name: "officer", type: "text", x:1, y:19, layout:"col-md-4"}, + {name: "position", type: "text", x:2, y:19, layout:"col-md-4"}, + {name: "Extras", type: "custom", x:1, y:20, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "notes", type: "text", x:1, y:21, layout:"col-md-12"} +]; */ + + +export const marriageRegistrationFields = [ + {name: "tags", type:"tags", x:1, y:1, layout:"col-md-12"}, + {name: "marriageDetails", type: "custom", x:1, y:2, layout:"col-md-12", component: (name, disabled) =>
}, + { + name: "celebrantId", label: "Search Celebrant", type: "custom", x: 1, y: 5, layout: "col-md-12", + component: (name, disabled) => + }, + { + name: "reportedCelebrant", type: "text", x: 2, y: 6, layout: "col-md-12", + display: (data) => { return data.reportedCelebrant !== null && data.celebrantId === null ? true : false; } + }, + {name: "declaredDate", type: "date", x:1, y: 7, layout:"col-md-6"}, + {name: "timeOfMarriage", type: "time", x:2, y:7, layout:"col-md-6"}, + {name: "unionRegime", type: "select", x:1, y: 8, layout:"col-md-6", metadata: () => regime}, + {name:"addressBox", label: "Place", components: [ + {name: "address", type: "custom", x:1, y:1, layout:"col-md-12", component: (name, disabled) => }, + ], type: "box", x:2, y:9, layout:"col-md-11 ms-2 mt-2 pt-1 pb-2"}, + {name: "wifeDetails", type: "custom", x:1, y:10, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "partner2VitalRecordId", type: "custom", x:1, y:11, layout:"col-md-12", component: (name, disabled) => }, + { + name: "wifeGenderValidation", type: "validation", x: 1, y: 12, layout: "col-md-6", + "validation": Yup.boolean().test("wifeGenderValidation", "Bride need to be female", function () { + return (formState.getState()["partner2VitalRecordId-gender"])? formState.getState()["partner2VitalRecordId-gender"] === "FEMALE": true; + }) + }, + { + name: "wifeAgeValidation", type: "validation", x: 2, y: 12, layout: "col-md-6", + "validation": Yup.boolean().test("wifeAgeValidation", "Bride must be at least 16 years old", function () { + return (formState.getState()["partner2VitalRecordId-birthdate"])? verifyAge(formState.getState()["partner2VitalRecordId-birthdate"], 16) : true; + }) + }, + {name: "husbandDetails", type: "custom", x:1, y:13, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "partner1VitalRecordId", type: "custom", x:1, y:14, layout:"col-md-12", component: (name, disabled) => }, + { + name: "husbandGenderValidation", type: "validation", x: 1, y: 15, layout: "col-md-6", + "validation": Yup.boolean().test("husbandGenderValidation", "Groom need to be male", function () { + return (formState.getState()["partner1VitalRecordId-gender"])? formState.getState()["partner1VitalRecordId-gender"] === "MALE": true; + }) + }, + { + name: "husbandAgeValidation", type: "validation", x: 2, y: 15, layout: "col-md-6", + "validation": Yup.boolean().test("husbandAgeValidation", "Groom must be at least 18 years old", function () { + return (formState.getState()["partner1VitalRecordId-birthdate"])? verifyAge(formState.getState()["partner1VitalRecordId-birthdate"], 18) : true; + }) + }, + {name: "witnessDetails", type: "custom", x:1, y:17, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "witness1VitalRecordId", type: "custom", x:1, y:18, layout:"col-md-12", component: (name, disabled) => }, + {name: "witness2VitalRecordId", type: "custom", x:1, y:19, layout:"col-md-12", component: (name, disabled) => }, + + { name: "declarationDetails", type: "custom", x: 1, y: 20, layout: "col-md-12", component: (name, disabled) =>
}, + { + name: "declarantId", label: "Search Declarant", type: "custom", x: 1, y: 21, layout: "col-md-12", + component: (name, disabled) => + }, + { + name: "reportedDeclarant", type: "text", x: 2, y: 22, layout: "col-md-12", + display: (data) => { return data.reportedDeclarant !== null && data.declarantId === null ? true : false; } + }, + {name:"registrationBox", label: "Registration Location", components: [ + {name: "registrationLocation", type: "custom", x:1, y:1, layout:"col-md-12", component: (name, disabled) => } + ], type: "box", x:2, y:23, layout:"col-md-11 ms-2 mt-2 pt-1 pb-2"}, + { + name: "officerId", label: "Search officer", type: "custom", x: 1, y: 24, layout: "col-md-12", + component: (name, disabled) => + }, + { + name: "reportedOfficer", type: "text", x: 2, y: 25, layout: "col-md-12", + display: (data) => { return data.reportedOfficer !== null && data.officerId ===null ? true : false; } + }, + {name: "Mentions", type: "custom", x:1, y:34, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "mentions", type: "text", x:1, y:35, layout:"col-md-12"}, + {name: "Extras", type: "custom", x:1, y:36, layout:"col-md-12", component: (name, disabled) =>
}, + {name: "notes", type: "text", x:1, y:37, layout:"col-md-12"} +]; + +export const verifyAge = (date, maxAge) => { + let formattedDate = new Date(date[0], date[1] - 1, date[2]);; + // Get the current date + let currentDate = new Date(); + + // Calculate the age + let age = currentDate.getFullYear() - formattedDate.getFullYear(); + let monthDifference = currentDate.getMonth() - formattedDate.getMonth(); + + // Adjust age if the birth month/day has not been reached yet + if (monthDifference < 0 || (monthDifference === 0 && currentDate.getDate() < formattedDate.getDate())) { + age--; + } + + // Check if the age is at least 16 + return age >= maxAge; +} + +export const saveMarriageRegistrationForm = async (formData) => { + let dto = pojoMetadata['union-mtlb'].form2dto(formData); + dto.mtlbType = MTLB_TYPE_MARRIAGE; + form2dto(formData, dto); + try { + return rest.request(getServiceUri() + 'union-mtlb', 'POST', dto) + } catch (err) { + alert(err); + } +} + +export const loadUnionMtlbAttachment = async (id) => { + let filter = {and: true}; + filter['union-mtlb-attachment'] = {}; + filter['union-mtlb-attachment']['unionMtlbId'] = id; + return rest.search('union-mtlb/attachment', filter) +} + +export const loadMarriageRegistrationFormData = async (id) => { + return await rest.read('union-mtlb/read', id).then(response => { + let form = response; + let tagFilter = {and: true}; + dto2form(response, form); + tagFilter['union-mtlb-tag'] = {unionMtlbId: id}; + if (response.status) + showNotification(response.message.split('Detail: ')[1], "error") + + return rest.search('union-mtlb-tag', tagFilter).then(tags => { + form['tags'] = tags + + return form; + }) + }) +} + +export const updatePendingMarriageRegistrationForm = async (formData) => { + let dto = pojoMetadata['union-mtlb'].form2dto(formData); + form2dto(formData, dto); + try { + return rest.request(getServiceUri() + 'union-mtlb/pending/update', 'POST', dto); + } catch (err) { + alert(err); + } +} + +export const updateRejectedMarriageRegistrationForm = async (formData) => { + let dto = pojoMetadata['union-mtlb'].form2dto(formData); + form2dto(formData, dto); + try { + return rest.request(getServiceUri() + 'union-mtlb/rejected/update', 'POST', dto); + } catch (err) { + alert(err); + } +} + +export const rejectMarriageRegistrationForm = async (id) => { + try { + return rest.request(getServiceUri() + 'union-mtlb/pending/reject', 'POST', id); + } catch (err) { + alert(err); + } +} + +export const buildMarriageRegistrationFormEmptyObject = () => { + const empty = buildEmptyObject(marriageRegistrationFields); + return empty; +} + +export const updateMarriageRegistrationForm = async (formData) => { + let dto = pojoMetadata['union-mtlb'].form2dto(formData); + dto.mtlbStatus = MTLB_STATUS_SUBMITTED; + dto.draft = false; + form2dto(formData, dto); + try { + return rest.update('union-mtlb', dto); + } catch (err) { + alert(err); + } +} + +export const deleteMarriageRegistrationForm = async (id) => { + try { + return rest.delete('union-mtlb', id); + } catch (err) { + alert(err); + } +} + +export const form2dto = (formData, dto) => { + dto.mtlbType = MTLB_TYPE_MARRIAGE; + if (formData.partner1VitalRecordId != null) + dto.partner1VitalRecordId = parseInt(formData.partner1VitalRecordId) + if (formData.partner2VitalRecordId != null) + dto.partner2VitalRecordId = parseInt(formData.partner2VitalRecordId) + if (formData.witness1VitalRecordId != null) + dto.witness1VitalRecordId = parseInt(formData.witness1VitalRecordId) + if (formData.witness2VitalRecordId != null) + dto.witness2VitalRecordId = parseInt(formData.witness2VitalRecordId) + if (formData.timeOfMarriage != null && typeof(formData.timeOfMarriage) != 'string') { + const date = new Date(formData.timeOfMarriage) + let birthHour = date.getHours() < 10 ? '0' + date.getHours() : date.getHours(); + let birthMinute = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes(); + dto.timeOfMarriage = birthHour + ":" + birthMinute; + } +} + +export const dto2form = (dto) => { + if (dto.timeOfMarriage !== null) { + dto.timeOfMarriage = new Date().setHours(dto.timeOfMarriage[0], dto.timeOfMarriage[1]); + } + return dto; +} + +export const newMarriageRegistrationFormForm2Dto = (form, dto) => { + +} \ No newline at end of file diff --git a/src/main/js/lists/AddressList.jsx b/src/main/js/lists/AddressList.jsx new file mode 100644 index 0000000..61f657e --- /dev/null +++ b/src/main/js/lists/AddressList.jsx @@ -0,0 +1,242 @@ +import React, { useState } from "react"; + +import { ADDRESS_ORDER_BY_PROVINCE_NAME } from "../../../auto/js/metadata/AddressOrderBy"; +import { pojoMetadata } from "../../../auto/js/metadata"; +import { rest, t } from "../../../auto/js/services"; +import { geoMetadataLoader } from "../../../auto/js/metadata/GeoMetadataLoader"; +import { Autocomplete } from "@mui/material"; +import { TextField } from "@material-ui/core"; +import { Observable } from "../../../auto/js/events/Observable"; +import { formState } from "../../../auto/js/forms/FormState"; + +let provinceObservable = new Observable(); +let zoneObservable = new Observable(); +let districtObservable = new Observable(); +let islandObservable = new Observable(); +export const addressFields = [ + {title: "provinceName", field: "provinceName", + editComponent: props => { + let [options, setOptions] = useState(undefined); + let [value, setValue] = useState(props.value); + if (!options) { + setOptions(geoMetadataLoader.getProvinces()) + return + } + return ( + { + props.onChange(value); + setValue(value); + provinceObservable.publish(options[value])} + } + value={value} + options={Object.keys(options)} + renderInput={(params) => ( + + )} + />) + } + }, + {title: "zoneName", field: "zoneName", + editComponent: props => { + let [options, setOptions] = useState([]); + let [value, setValue] = useState(props.value); + let callback = (event) => { + if (event) + setOptions(event); + else + setOptions([]) + setValue(''); + zoneObservable.publish(undefined); + } + provinceObservable.subscribe(callback); + return ( + { + props.onChange(value) + setValue(value); + zoneObservable.publish(options[value]); + }} + value={value} + options={Object.keys(options)} + renderInput={(params) => ( + + )} + />) + } + }, + {title: "districtName", field: "districtName", + editComponent: props => { + let [options, setOptions] = useState([]); + let [value, setValue] = useState(props.value); + let callback = (event) => { + if (event) + setOptions(event); + else + setOptions([]) + setValue(''); + districtObservable.publish(undefined); + } + zoneObservable.subscribe(callback); + return ( + { + props.onChange(value) + setValue(value); + districtObservable.publish(options[value]); + }} + value={value} + options={Object.keys(options)} + renderInput={(params) => ( + + )} + />) + } + }, + {title: "islandName", field: "islandName", + editComponent: props => { + let [options, setOptions] = useState([]); + let [value, setValue] = useState(props.value); + let callback = (event) => { + if (event) + setOptions(event); + else + setOptions([]) + setValue(''); + islandObservable.publish(undefined); + } + districtObservable.subscribe(callback); + return ( + { + props.onChange(value) + setValue(value); + islandObservable.publish(options[value]); + }} + value={value} + options={Object.keys(options)} + renderInput={(params) => ( + + )} + />) + } + }, + {title: "locationName", field: "locationName", + editComponent: props => { + let [options, setOptions] = useState([]); + let [value, setValue] = useState(props.value); + let callback = (event) => { + if (event) + setOptions(event); + else + setOptions([]) + setValue(''); + } + islandObservable.subscribe(callback); + return ( + { + props.onChange(value) + setValue(value); + }} + value={value} + options={Object.keys(options)} + renderInput={(params) => ( + + )} + />) + } + }, + {title: "fromDate", field: "fromDate", type:"date"}, + {title: "toDate", field: "toDate", type:"date"}, +] + +export const buildAddressData = async (query, id) => { + let filter = query; + let data; + filter["address"] = {civilStatusMtlbId: id}; + filter["orderBy"] = ADDRESS_ORDER_BY_PROVINCE_NAME; + filter.orderDirection = null; + filter.offset = query.page * query.pageSize; + if (query.search && query.search!='') { + pojoMetadata["address"].columns.forEach(element => { + if(element.type=='text'){ + filter["address"][element.key]= query.search; + } + }); + filter["and"] = false; + } + return await getData(filter).then(response => { + data = filterData(response) + formState.setAddressList(data) + return countData(filter).then((count) => {return {data: data, totalCount: count, page: query.page}}) + }); +} + +const getData = async (filter) => { + return await rest.search('address', filter) +} + +const countData = async (filter) => { + return await rest.count('address', filter); +} + +const filterData = (DefaultRows) => { + const newRows = []; + for (let i in DefaultRows) { + let row = DefaultRows[i]; + let fromDate = row.fromDate + if ( fromDate !== null) { + let date = new Date(fromDate[0]+ "/" +fromDate[1] + "/" + fromDate[2]); + date.setTime(date.getTime() + 60 * 60 * 1000) + row.fromDate = date; + } + let toDate = row.toDate + if ( toDate !== null) { + let date = new Date(toDate[0]+ "/" +toDate[1] + "/" + toDate[2]); + date.setTime(date.getTime() + 60 * 60 * 1000) + row.toDate = date; + } + newRows.push(row); + } + return newRows; +} + +export const getAddressEditables = (id) => { + let editables = {} + editables.onRowAdd = newData => + new Promise((resolve, reject) => { + let dto = pojoMetadata['address'].form2dto(newData); + dto["civilStatusMtlbId"] = id; + try { + return rest.create('address', dto).then(() => resolve()); + } catch (err) { + alert(err); + } + }), + editables.onRowUpdate = (newData, oldData) => + new Promise((resolve, reject) => { + let dto = pojoMetadata['address'].form2dto(newData); + try { + return rest.update('address', dto).then(() => { + formState.addToAddressList(newData) + resolve()}) + } catch (err) { + alert(err); + } + }), + editables.onRowDelete = oldData => + new Promise((resolve, reject) => { + try { + return rest.purge('address', oldData.id).then(() => resolve()); + } catch (err) { + alert(err); + } + }) + return editables; +} \ No newline at end of file diff --git a/src/main/js/lists/CivilRecordListCommon.jsx b/src/main/js/lists/CivilRecordListCommon.jsx new file mode 100644 index 0000000..452aee6 --- /dev/null +++ b/src/main/js/lists/CivilRecordListCommon.jsx @@ -0,0 +1,227 @@ +import { getServiceUri, pojoMetadata } from "../../../auto/js/metadata"; +import { VITAL_RECORD_ORDER_BY_FIRSTNAME } from "../../../auto/js/metadata/VitalRecordOrderBy"; +import { rest } from "../../../auto/js/services"; +import React from "react"; +import { Separator } from "../forms/CivilRecordFormCommon"; +import { GeoDataComponent } from "../../../auto/js/widgets/GeoDataComponent"; + + +export const civilRecordColumns = [ + { title: "image", field: "image", render: rowData => { e.target.onerror = null; e.target.src = "/public/avatar.png" }} style={{ width: 40, borderRadius: '50%', height: 40 }} /> }, + { title: "id", field: "id" }, + { title: "fourthname", field: "fourthname" }, + { title: "secondname", field: "secondname" }, + { title: "thirdname", field: "thirdname" }, + { title: "firstname", field: "firstname" }, + { title: "birthdate", field: "birthdate" }, +]; + +export const buildData = async (query) => { + let filter = query; + let data; + filter["vital-record"] = { inactiveList: [false] }; + filter["orderBy"] = VITAL_RECORD_ORDER_BY_FIRSTNAME; + filter.orderDirection = null; + filter["filter"] = query.search; + filter.offset = query.page * query.pageSize; + if (query.search && query.search != '') { + pojoMetadata["vital-record"].columns.forEach(element => { + if (element.type == 'text') { + filter["vital-record"][element.key] = query.search; + } + }); + filter["and"] = false; + } + return await getCivilRecordData(filter).then(response => { + data = filterData(response) + return countData(filter).then((count) => { return { data: data, totalCount: count, page: query.page } }) + }); +} + +const getCivilRecordData = async (filter) => { + return await rest.request(getServiceUri() + "vital-record/fuzzy/search", "POST", filter); +} + +const countData = async (filter) => { + return await rest.request(getServiceUri() + "vital-record/count/search-by-active/", "POST", filter); +} + +const filterData = (DefaultRows) => { + const newRows = []; + for (let i in DefaultRows) { + let row = DefaultRows[i]; + let face = null; + if (row.faceId != null) { + // faceUrl = getServiceUri() + "face/image/" + row.faceId; + let mimeType = "image/png"; + rest.read('face/image', row.faceId).then((response) => { + face = "data:".concat(mimeType, ";base64,", response); + row.image = (face != null) ? face : "/public/avatar.png"; + }) + } + let date = row.birthdate + if (date !== null) + row.birthdate = date[2] + '-' + date[1] + '-' + date[0]; + row.id = formatId(row.id.toString()) + newRows.push(row); + } + return newRows; +} + +function formatId(id) { + if (id.length < 9) { + let diff = 9 - id.length + while (diff !== 0) { + id = "0" + id; + diff = diff - 1; + } + } + let newString = id.slice(0, 3) + '-' + id.slice(3); + let finalForm = newString.slice(0, 7) + '-' + newString.slice(7) + return finalForm +} + +export const getErrorList = () => { + let list = []; + for (let i = 1; i < 14; i++) { + let code = (i < 10) ? "E" + "0" + i : "E" + i + list.push(code); + } + list.push("E20") + list.push("E21") + for (let i = 28; i < 32; i++) { + let code = "E" + i + list.push(code); + } + return list; +} + +export const advancedSearchfields = [ + + { name: "exactId", type: "number", x: 1, y: 1, layout: "col-md-4" }, + { name: "idSeparator", type: "custom", x: 1, y: 2, layout: "col-md-12", component: (name, disabled) => }, + { name: "caseSensitiveSearch", label: "Case Sensitive Search", type: "checkbox", x: 1, y: 3, layout: "col-md-3" }, + + { name: "firstname", type: "text", x: 1, y: 7, layout: "col-md-6" }, + { + name: "firstnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 7, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + + { name: "secondname", type: "text", x: 1, y: 5, layout: "col-md-6" }, + { + name: "secondnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 5, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + + { name: "thirdname", type: "text", x: 1, y: 6, layout: "col-md-6", defaultValue: "startsWith" }, + { + name: "thirdnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 6, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + + { name: "fourthname", type: "text", x: 1, y: 4, layout: "col-md-6" }, + { + name: "fourthnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 4, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + + { + name: "genderBox", label: "Gender", components: [ + { name: "male", label: "Male", type: "checkbox", x: 1, y: 1, layout: "col-md-3" }, + { name: "female", label: "Female", type: "checkbox", x: 2, y: 1, layout: "col-md-3" }, + ], type: "box", x: 3, y: 8, layout: "col-md-11 ms-2 mt-2" + },//mx-auto + { + name: "birthBox", label: "Birth Date", components: [ + { name: "rangeBirthdate", label: "exactbirthdate", type: "checkbox", x: 1, y: 1, layout: "col-md-12" }, + { + name: "exactBirthdate", type: "date", x: 1, y: 2, layout: "col-md-6", display: (data) => { + return !data.rangeBirthdate; + } + }, + + { + name: "birthdateStart", type: "date", x: 1, y: 3, layout: "col-md-6", display: (data) => { + return data.rangeBirthdate; + } + }, + { + name: "birthdateEnd", type: "date", x: 2, y: 3, layout: "col-md-6", display: (data) => { + return data.rangeBirthdate; + } + }, + ], type: "box", x: 1, y: 9, layout: "col-md-11 ms-2 mt-2 pt-1 pb-2" + }, + + { + name: "birthBox", label: "Birth Place", components: [ + { name: "anyBornOutsideCountry", label: "anyBornOutsideCountry", type: "checkbox", x: 1, y: 1, layout: "col-md-12" }, + { + name: "birthPlace", type: "custom", x: 1, y: 2, layout: "col-md-6", + component: (name, disabled) => , + display: (data) => { return !data.anyBornOutsideCountry } + }, + ], type: "box", x: 2, y: 10, layout: "col-md-11 ms-2 mt-2 pt-1 pb-2" + } +]; + +export const transformAdvancedSearchData = (formData) => { + const columns = []; + + const addColumn = (name, type, value, condition) => { + columns.push({ + name, + type, + [type === 'date' ? 'dateValue' : (type === 'text' ? 'textValue' : 'longValue')]: value, + searchType: condition ? condition : null, + }); + }; + (formData.firstname !== "") && addColumn('firstname', 'text', formData.firstname, formData.firstnameCondition); + + (formData.secondname !== "") && addColumn('secondname', 'text', formData.secondname, formData.secondnameCondition); + + (formData.thirdname !== "") && addColumn('thirdname', 'text', formData.thirdname, formData.thirdnameCondition); + + (formData.fourthname !== "") && addColumn('fourthname', 'text', formData.fourthname, formData.fourthnameCondition); + + (formData.exactId !== "") && addColumn('id', 'number', formData.exactId, null); + if (formData.anyBornOutsideCountry) + addColumn('birthPlace', 'text', '191', 'notStartsWith'); + else + (formData.birthPlace) && addColumn('birthPlace', 'text', formData.birthPlace, formData.birthPlace ? "startsWith" : null); + const birthdateRange = formData.birthdateStart && formData.birthdateEnd + ? { + min: formData.birthdateStart ? formData.birthdateStart : null, + max: formData.birthdateEnd ? formData.birthdateEnd : null, + } + : null; + + (birthdateRange != null || formData.exactBirthdate != null) && addColumn('birthdate', 'date', formData.exactBirthdate, null); + if ((birthdateRange != null || formData.exactBirthdate != null)) + columns[columns.length - 1].dateRange = birthdateRange; + + const gender = []; + formData.male ? gender.push("1") : null; + formData.female ? gender.push("2") : null; + if (gender.length) + columns.push({ + name: 'gender', + type: 'enum', + enumValues: gender, + }); + + return { columns, caseSensitiveSearch: formData.caseSensitiveSearch }; +}; \ No newline at end of file diff --git a/src/main/js/lists/DeathRecordListCommon.jsx b/src/main/js/lists/DeathRecordListCommon.jsx new file mode 100644 index 0000000..314c026 --- /dev/null +++ b/src/main/js/lists/DeathRecordListCommon.jsx @@ -0,0 +1,136 @@ +import React from "react"; + +import { GeoDataComponent } from "../../../auto/js/widgets/GeoDataComponent"; +import { Separator } from "../forms/CivilRecordFormCommon"; + +export const getErrorList = () => { + let list = []; + list.push("E19"); + list.push("E22"); + return list; +} + +export const advancedSearchfields = [ + { name: "caseSensitiveSearch", label: "Case Sensitive Search", type: "checkbox", x: 1, y: 1, layout: "col-md-3" }, + { name: "exactId", type: "number", x: 1, y: 2, layout: "col-md-4" }, + { name: "idSeparator", type: "custom", x: 1, y: 3, layout: "col-md-12", component: (name, disabled) => }, + + { name: "firstname", type: "text", x: 1, y: 6, layout: "col-md-6" }, + { + name: "firstnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 6, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + + { name: "secondname", type: "text", x: 1, y: 4, layout: "col-md-6" }, + { + name: "secondnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 4, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + + { name: "thirdname", type: "text", x: 1, y: 5, layout: "col-md-6" }, + { + name: "thirdnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 5, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + + { name: "fourthname", type: "text", x: 1, y: 3, layout: "col-md-6" }, + { + name: "fourthnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 3, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + + { + name: "genderBox", label: "Gender", components: [ + { name: "male", label: "Male", type: "checkbox", x: 1, y: 1, layout: "col-md-3" }, + { name: "female", label: "Female", type: "checkbox", x: 2, y: 1, layout: "col-md-3" }, + ], type: "box", x: 3, y: 7, layout: "col-md-11 ms-2 mt-2" + },//mx-auto + { + name: "deathBox", label: "Death Date", components: [ + { name: "rangedeathdate", label: "exactdeathdate", type: "checkbox", x: 1, y: 1, layout: "col-md-12" }, + { + name: "exactdeathdate", type: "date", x: 1, y: 2, layout: "col-md-6", display: (data) => { + return !data.rangedeathdate; + } + }, + + { + name: "deathdateStart", type: "date", x: 1, y: 3, layout: "col-md-6", display: (data) => { + return data.rangedeathdate; + } + }, + { + name: "deathdateEnd", type: "date", x: 2, y: 3, layout: "col-md-6", display: (data) => { + return data.rangedeathdate; + } + }, + ], type: "box", x: 1, y: 8, layout: "col-md-11 ms-2 mt-2 pt-1 pb-2" + }, + + { + name: "deathBox", label: "death Place", components: [ + { + name: "deathPlace", type: "custom", x: 1, y: 2, layout: "col-md-6", + component: (name, disabled) => , + display: (data) => { return !data.anyBornOutsideCountry } + }, + ], type: "box", x: 2, y: 10, layout: "col-md-11 ms-2 mt-2 pt-1 pb-2" + } +]; + +export const transformAdvancedSearchData = (formData) => { + const columns = []; + + const addColumn = (name, type, value, condition) => { + columns.push({ + name, + type, + [type === 'date' ? 'dateValue' : (type === 'text' ? 'textValue' : 'longValue')]: value, + searchType: condition ? condition : null, + }); + }; + (formData.firstname !== "") && addColumn('firstname', 'text', formData.firstname, formData.firstnameCondition); + + (formData.secondname !== "") && addColumn('secondname', 'text', formData.secondname, formData.secondnameCondition); + + (formData.thirdname !== "") && addColumn('thirdname', 'text', formData.thirdname, formData.thirdnameCondition); + + (formData.fourthname !== "") && addColumn('fourthname', 'text', formData.fourthname, formData.fourthnameCondition); + + (formData.exactId !== "") && addColumn('vitalRecordId', 'number', formData.exactId, null); + (formData.deathPlace) && addColumn('deathPlace', 'text', formData.deathPlace, formData.deathPlace ? "startsWith" : null); + const deathdateRange = formData.deathdateStart && formData.deathdateEnd + ? { + min: formData.deathdateStart ? formData.deathdateStart : null, + max: formData.deathdateEnd ? formData.deathdateEnd : null, + } + : null; + + (deathdateRange != null || formData.exactdeathdate != null) && addColumn('dateOfDeath', 'date', formData.exactdeathdate, null); + if ((deathdateRange != null || formData.exactdeathdate != null)) + columns[columns.length - 1].dateRange = deathdateRange; + + const gender = []; + formData.male ? gender.push("1") : null; + formData.female ? gender.push("2") : null; + if (gender.length) + columns.push({ + name: 'gender', + type: 'enum', + enumValues: gender, + }); + + return { columns, caseSensitiveSearch: formData.caseSensitiveSearch }; +}; \ No newline at end of file diff --git a/src/main/js/lists/EmailList.jsx b/src/main/js/lists/EmailList.jsx new file mode 100644 index 0000000..bf12039 --- /dev/null +++ b/src/main/js/lists/EmailList.jsx @@ -0,0 +1,59 @@ +import { pojoMetadata } from "../../../auto/js/metadata"; +import { EMAIL_ORDER_BY_EMAIL } from "../../../auto/js/metadata/EmailOrderBy"; +import { rest } from "../../../auto/js/services"; + +export const emailFields = [ + {title: "email", field: "email"} +] + +export const buildEmailData = async (query, id) => { + let filter = query; + let data; + filter["email"] = {civilStatusMtlbId: id}; + filter["orderBy"] = EMAIL_ORDER_BY_EMAIL; + filter.orderDirection = null; + filter.offset = query.page * query.pageSize; + if (query.search && query.search!='') { + pojoMetadata["email"].columns.forEach(element => { + if(element.type=='text'){ + filter["email"][element.key]= query.search; + } + }); + filter["and"] = false; + } + return await getData(filter).then(response => { + data = response; + return countData(filter).then((count) => {return {data: data, totalCount: count, page: query.page}}) + }); +} + +const getData = async (filter) => { + return await rest.search('email', filter) +} + +const countData = async (filter) => { + return await rest.count('email', filter); +} + +export const getEmailEditables = (id) => { + let editables = {} + editables.onRowAdd = newData => + new Promise((resolve, reject) => { + let dto = pojoMetadata['email'].form2dto(newData); + dto["civilStatusMtlbId"] = id; + try { + return rest.create('email', dto).then(() => resolve()); + } catch (err) { + alert(err); + } + }) + editables.onRowDelete = oldData => + new Promise((resolve, reject) => { + try { + return rest.purge('email', oldData.id).then(() => resolve()); + } catch (err) { + alert(err); + } + }) + return editables; +} \ No newline at end of file diff --git a/src/main/js/lists/IssuedIdCardListCommon.jsx b/src/main/js/lists/IssuedIdCardListCommon.jsx new file mode 100644 index 0000000..6725ad6 --- /dev/null +++ b/src/main/js/lists/IssuedIdCardListCommon.jsx @@ -0,0 +1,145 @@ +import React from "react"; + +import {getServiceUri, pojoMetadata} from "../../../auto/js/metadata"; +import {rest, t} from "../../../auto/js/services"; +import {ISSUED_DOCUMENTS_ORDER_BY_ID} from "../../../auto/js/metadata/IssuedDocumentsOrderBy"; +import {DOCUMENT_TYPE_ID_CARD} from "../../../auto/js/metadata/DocumentType"; +import { Separator } from "../forms/CivilRecordFormCommon"; + +export const issuedIdCardColumns = [ + {title: "documentId", field: "documentId"}, + {title: "vitalRecordId", field: "vitalRecordId"}, + {title: "Name", field: "fullName"}, + {title: "issuedDate", field: "issuedDate"}, + {title: "expires", field: "expires"}, + {title: "cancelledDate", field: "cancelledDate"} +]; + +export const buildData = async (query, advancedSearchData) => { + let filter = query; + let data; + filter["issued-documents"] = {documentTypeList: [DOCUMENT_TYPE_ID_CARD]}; + filter["orderBy"] = ISSUED_DOCUMENTS_ORDER_BY_ID; + if (advancedSearchData) + filter["query"] = advancedSearchData; + filter.orderDirection = null; + filter.offset = query.page * query.pageSize; + if (query.search && query.search != '') { + pojoMetadata["issued-documents"].columns.forEach(element => { + if (element.type == 'text') { + filter["issued-documents"][element.key] = query.search; + } + }); + filter["and"] = false; + } + return await getIssuedDocumentData(filter).then(response => { + data = filterData(response) + return countData(filter).then((count) => { + return {data: data, totalCount: count, page: query.page} + }) + }); +} +const getIssuedDocumentData = async (filter) => { + let searchEndpoint = (filter.query)?"issued-documents/advanced-search":"issued-documents/search-by-document-type/"; + return await rest.request(getServiceUri() + searchEndpoint, "POST", filter); +} +const countData = async (filter) => { + let countEndpoint = (filter.query)?"issued-documents/count/advanced-search":"issued-documents/count/search-by-document-type/"; + return await rest.request(getServiceUri() + countEndpoint, "POST", filter); +} +const filterData = (DefaultRows) => { + const newRows = []; + for (let i in DefaultRows) { + let row = DefaultRows[i]; + let issuedDate = row.issuedDate + if (issuedDate !== null) + row.issuedDate = issuedDate[2] + '-' + issuedDate[1] + '-' + issuedDate[0]; + let expires = row.expires + if (expires !== null) + row.expires = expires[2] + '-' + expires[1] + '-' + expires[0]; + let cancelledDate = row.cancelledDate + if (cancelledDate !== null) + row.cancelledDate = cancelledDate[2] + '-' + cancelledDate[1] + '-' + cancelledDate[0]; + newRows.push(row); + } + return newRows; +} + +function formatId(eId) { + if (eId.length < 9) { + let diff = 9 - eId.length + while (diff !== 0) { + eId = "0" + eId; + diff = diff - 1; + } + } + let newString = eId.slice(0, 3) + '-' + eId.slice(3); + let finalForm = newString.slice(0, 7) + '-' + newString.slice(7) + return finalForm +} + +export const getErrorList = () => { + let list = []; + list.push("E19"); + list.push("E22"); + return list; +} + +export const advancedSearchfields = [ + {name: "caseSensitiveSearch",label:"Case Sensitive Search", type: "checkbox", x:1, y:1, layout:"col-md-3"}, + {name: "exactId", type: "number", x:1, y: 2, layout:"col-md-4"}, + {name: "exactDocumentId", type: "text", x:2, y: 2, layout:"col-md-4"}, + {name: "idSeparator", type: "custom", x:1, y:4, layout:"col-md-12", component: (name, disabled) => }, + + {name: "fullName", type: "text", x:1, y:5, layout:"col-md-6"}, + {name:"fullNameCondition", options: [ + {"name":"fuzzy","label":"Fuzzy"}, + {"name":"exact","label":"Exact"}, + {"name":"startsWith","label":"Startswith"}, + ], type: "radio", x:2, y:5, layout:"col-md-6 pt-5",defaultValue:"startsWith"}, + + {name:"issuedBox", label: "Issued Date", components: [ + {name: "rangeIssueddate",label:"Exact Issued Date", type: "checkbox", x:1, y:1, layout:"col-md-12"}, + {name: "exactIssueddate", type: "date", x:1, y: 2, layout:"col-md-6", display: (data)=>{ + return !data.rangeIssueddate; + }}, + + {name: "issueddateStart", type: "date", x:1, y: 3, layout:"col-md-6",display: (data)=>{ + return data.rangeIssueddate; + }}, + {name: "issueddateEnd", type: "date", x:2, y: 3, layout:"col-md-6", display: (data)=>{ + return data.rangeIssueddate; + }}, + ], type: "box", x:1, y:8, layout:"col-md-11 ms-2 mt-2 pt-1 pb-2"}, +]; + +export const transformAdvancedSearchData = (formData) => { + const columns = []; + + const addColumn = (name, type, value, condition) => { + columns.push({ + name, + type, + [type === 'date' ? 'dateValue' : type === 'boolean' ? 'booleanValue' : (type === 'text' ? 'textValue' : 'longValue')]: value, + searchType: condition ? condition : null, + }); + }; + (formData.fullName !== "") && addColumn('fullName', 'text', formData.fullName, formData.fullNameCondition); + + + addColumn('documentType', 'number', 1, null); + (formData.exactDocumentId !== "") && addColumn('documentId', 'text', formData.exactDocumentId, "exact"); + (formData.exactId !== "") && addColumn('vitalRecordId', 'number', formData.exactId, null); + + const issueddateRange = formData.issueddateStart && formData.issueddateEnd + ? { + min: formData.issueddateStart ? formData.issueddateStart : null, + max: formData.issueddateEnd ? formData.issueddateEnd : null, + } + : null; + (issueddateRange != null || formData.exactIssueddate != null) && addColumn('issuedDate', 'date', formData.exactIssueddate, null); + if ((issueddateRange != null || formData.exactIssueddate != null)) + columns[columns.length - 1].dateRange = issueddateRange; + + return { columns, caseSensitiveSearch: formData.caseSensitiveSearch }; +}; diff --git a/src/main/js/lists/PhoneNumberList.jsx b/src/main/js/lists/PhoneNumberList.jsx new file mode 100644 index 0000000..c2c70e7 --- /dev/null +++ b/src/main/js/lists/PhoneNumberList.jsx @@ -0,0 +1,59 @@ +import { pojoMetadata } from "../../../auto/js/metadata"; +import { PHONE_NUMBER_ORDER_BY_PHONE_NUMBER } from "../../../auto/js/metadata/PhoneNumberOrderBy"; +import { rest } from "../../../auto/js/services"; + +export const phoneNumberFields = [ + {title: "phoneNumber", field: "phoneNumber"} +] + +export const buildPhoneNumberData = async (query, id) => { + let filter = query; + let data; + filter["phone-number"] = {civilStatusMtlbId: id}; + filter["orderBy"] = PHONE_NUMBER_ORDER_BY_PHONE_NUMBER; + filter.orderDirection = null; + filter.offset = query.page * query.pageSize; + if (query.search && query.search!='') { + pojoMetadata["phone-number"].columns.forEach(element => { + if(element.type=='text'){ + filter["phone-number"][element.key]= query.search; + } + }); + filter["and"] = false; + } + return await getData(filter).then(response => { + data = response; + return countData(filter).then((count) => {return {data: data, totalCount: count, page: query.page}}) + }); +} + +const getData = async (filter) => { + return await rest.search('phone-number', filter) +} + +const countData = async (filter) => { + return await rest.count('phone-number', filter); +} + +export const getPhoneNumberEditables = (id) => { + let editables = {} + editables.onRowAdd = newData => + new Promise((resolve, reject) => { + let dto = pojoMetadata['phone-number'].form2dto(newData); + dto["civilStatusMtlbId"] = id; + try { + return rest.create('phone-number', dto).then(() => resolve()); + } catch (err) { + alert(err); + } + }) + editables.onRowDelete = oldData => + new Promise((resolve, reject) => { + try { + return rest.purge('phone-number', oldData.id).then(() => resolve()); + } catch (err) { + alert(err); + } + }) + return editables; +} \ No newline at end of file diff --git a/src/main/js/lists/ReportingList.jsx b/src/main/js/lists/ReportingList.jsx new file mode 100644 index 0000000..b190876 --- /dev/null +++ b/src/main/js/lists/ReportingList.jsx @@ -0,0 +1,114 @@ +import React from "react"; +import {v4 as uuidv4} from 'uuid'; +import PrintIcon from '@material-ui/icons/Print'; + +import { pojoMetadata } from "../../../auto/js/metadata"; +import { JOB_MTLB_ORDER_BY_TIMESTAMP } from "../../../auto/js/metadata/JobMtlbOrderBy"; +import { MTLB_TYPE_GENERAL_STATISTICS } from "../../../auto/js/metadata/MtlbType"; +import { rest, t } from "../../../auto/js/services"; +import { createTableComponent } from "../../../auto/js/widgets/TableComponent"; +import GeneralStatistics from "../GeneralStatistics"; +import { PRINT_EVENT } from "../../../auto/js/events/Gui"; +import { MTLB_STATUS_ARCHIVED } from "../../../auto/js/metadata/MtlbStatus"; +import { formatDateTime } from "../../../auto/js/utils"; + +const reportingFields = [ + {title: "Application Time", field: "timestamp"}, + {title: "Status", field: "mtlbStatus"} +] + +export const displayGeneralStatisticsList = (gui) => { + + let GeneralStatisticsList = createTableComponent(reportingFields); + + const readList = (onFinish) => () => { + let uuid = uuidv4(); + return { + uuid, view: () => buildData(query)} actions={getTableActions()} editables={getEditables()} /> + }; + } + gui.goTo(readList()) +} + + + +const buildData = async (query) => { + let filter = query; + let data; + filter["job-mtlb"] = {mtlbType: MTLB_TYPE_GENERAL_STATISTICS}; + filter["orderBy"] = JOB_MTLB_ORDER_BY_TIMESTAMP; + filter.orderDirection = null; + filter.offset = query.page * query.pageSize; + if (query.search && query.search!='') { + pojoMetadata["job-mtlb"].columns.forEach(element => { + if(element.type=='text'){ + filter["job-mtlb"][element.key]= query.search; + } + }); + filter["and"] = false; + } + return await getData(filter).then(response => { + data = filterData(response); + return countData(filter).then((count) => {return {data: data, totalCount: count, page: query.page}}) + }); +} + +const filterData = (defaultRows) => { + const newRows = []; + for (let i in defaultRows) { + let row = defaultRows[i]; + let timestamp = row.timestamp; + if (timestamp != null) + row.timestamp = formatDateTime(timestamp); + newRows.push(row); + } + return newRows; +} + +const getData = async (filter) => { + return await rest.search('job-mtlb', filter) +} + +const countData = async (filter) => { + return await rest.count('job-mtlb', filter); +} + +const getTableActions = () => { + let actions = []; + actions.push( + { + icon: () => , + tooltip: t`Print`, + onClick: (event, rowData) => { + if (rowData.mtlbStatus === MTLB_STATUS_ARCHIVED) + printJob(rowData.id); + else + alert('Reporting processing not finished yet !') + } + } + ) + return actions; +} + +const getEditables = () => { + let editables = {} + editables.onRowDelete = oldData => + new Promise((resolve, reject) => { + try { + return rest.purge('job-mtlb', oldData.id).then(() => resolve()); + } catch (err) { + alert(err); + } + }) + return editables; +} + +const printJob = (id) => { + rest.read('job-mtlb', id).then(response => { + const printable = { + content:, + copyParentStyle:true + } + PRINT_EVENT.publish(printable) + }) +} \ No newline at end of file diff --git a/src/main/js/lists/UnionRecordListCommon.jsx b/src/main/js/lists/UnionRecordListCommon.jsx new file mode 100644 index 0000000..aab1aac --- /dev/null +++ b/src/main/js/lists/UnionRecordListCommon.jsx @@ -0,0 +1,119 @@ +import { t } from "../../../auto/js/services"; + +export const getErrorList = () => { + let list = []; + for (let i = 23; i < 32; i++) { + let code = "E" + i + list.push(code); + } + return list; +} + +export const advancedSearchfields = [ + { name: "caseSensitiveSearch", label: "Case Sensitive Search", type: "checkbox", x: 1, y: 1, layout: "col-md-3" }, + { name: "partner1VitalRecordId", type: "number", x: 1, y: 2, layout: "col-md-6" }, + { name: "partner2VitalRecordId", type: "number", x: 2, y: 2, layout: "col-md-6" }, + { name: "partner1Firstname", type: "text", x: 1, y: 4, layout: "col-md-6" }, + { + name: "partner1FirstnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 4, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + { name: "partner1Surname", type: "text", x: 1, y: 3, layout: "col-md-6" }, + { + name: "partner1SurnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 3, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + { name: "partner2Firstname", type: "text", x: 1, y: 6, layout: "col-md-6" }, + { + name: "partner2FirstnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 6, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + { name: "partner2Surname", type: "text", x: 1, y: 5, layout: "col-md-6" }, + { + name: "partner2SurnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 5, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + + { + name: "marriageBox", label: "Effect Date", components: [ + { name: "rangemarriagedate", label: "exactmarriagedate", type: "checkbox", x: 1, y: 1, layout: "col-md-12" }, + { + name: "exactmarriagedate", type: "date", x: 1, y: 2, layout: "col-md-6", display: (data) => { + return !data.rangemarriagedate; + } + }, + + { + name: "marriagedateStart", type: "date", x: 1, y: 3, layout: "col-md-6", display: (data) => { + return data.rangemarriagedate; + } + }, + { + name: "marriagedateEnd", type: "date", x: 2, y: 3, layout: "col-md-6", display: (data) => { + return data.rangemarriagedate; + } + }, + ], type: "box", x: 1, y: 8, layout: "col-md-11 ms-2 mt-2 pt-1 pb-2" + }, +]; + +export const transformAdvancedSearchData = (formData) => { + const columns = []; + + const addColumn = (name, type, value, condition) => { + columns.push({ + name, + type, + [type === 'date' ? 'dateValue' : type === 'boolean' ? 'booleanValue' : (type === 'text' ? 'textValue' : 'longValue')]: value, + searchType: condition ? condition : null, + }); + }; + (formData.partner1VitalRecordId !== null && formData.partner1VitalRecordId !== "") && addColumn('partner1VitalRecordId', 'number', formData.partner1VitalRecordId, null); + (formData.partner2VitalRecordId !== null && formData.partner2VitalRecordId !== "") && addColumn('partner2VitalRecordId', 'number', formData.partner2VitalRecordId, null); + + (formData.partner1Firstname !== "") && addColumn('partner1Firstname', 'text', formData.partner1Firstname, formData.partner1FirstnameCondition); + + (formData.partner2Firstname !== "") && addColumn('partner1Firstname', 'text', formData.partner2Firstname, formData.partner2FirstnameCondition); + + (formData.partner1Surname !== "") && addColumn('partner1Surname', 'text', formData.partner1Surname, formData.partner1SurnameCondition); + + (formData.partner2Surname !== "") && addColumn('partner2Surname', 'text', formData.partner2Surname, formData.partner2SurnameCondition); + const marriagedateRange = formData.marriagedateStart && formData.marriagedateEnd + ? { + min: formData.marriagedateStart ? formData.marriagedateStart : null, + max: formData.marriagedateEnd ? formData.marriagedateEnd : null, + } + : null; + + (marriagedateRange != null || formData.exactmarriagedate != null) && addColumn('dateOfMarriage', 'date', formData.exactmarriagedate, null); + if ((marriagedateRange != null || formData.exactmarriagedate != null)) + columns[columns.length - 1].dateRange = marriagedateRange; + + return { columns, caseSensitiveSearch: formData.caseSensitiveSearch }; +}; + + +export const filterData = (defaultRows) => { + const newRows = []; + for (let i in defaultRows) { + let row = defaultRows[i]; + if (row.dateOfEffect != null) + row.marriageStatus = t`Divorce`; + else + row.marriageStatus = t`Marriage` + newRows.push(row); + } + return newRows; +} diff --git a/src/main/js/lists/adoptionApplication/AdoptionApplicationListCommon.jsx b/src/main/js/lists/adoptionApplication/AdoptionApplicationListCommon.jsx new file mode 100644 index 0000000..b29722d --- /dev/null +++ b/src/main/js/lists/adoptionApplication/AdoptionApplicationListCommon.jsx @@ -0,0 +1,192 @@ +import React from "react"; +import { getServiceUri } from "../../../../auto/js/metadata"; +import { CIVIL_STATUS_MTLB_ORDER_BY_FIRSTNAME } from "../../../../auto/js/metadata/CivilStatusMtlbOrderBy"; +import { MTLB_TYPE_ADOPTION } from "../../../../auto/js/metadata/MtlbType"; +import { rest } from "../../../../auto/js/services"; +import { GeoDataComponent } from "../../../../auto/js/widgets/GeoDataComponent"; + +export const adoptionApplicationListColumns = [ + { title: "image", field: "image", render: rowData => { e.target.onerror = null; e.target.src = "/public/avatar.png" }} style={{ width: 40, borderRadius: '50%', height: 40 }} /> }, + { title: "vitalRecordId", field: "vitalRecordId" }, + { title: "fourthname", field: "fourthname" }, + { title: "secondname", field: "secondname" }, + { title: "thirdname", field: "thirdname" }, + { title: "firstname", field: "firstname" }, + { title: "birthdate", field: "birthdate" }, + +]; + +export const getData = async (filter) => { + let searchEndpoint = (filter.query) ? "civil-status-mtlb/advanced-search" : "civil-status-mtlb/search-by-mtlb-type-and-status/"; + return await rest.request(getServiceUri() + searchEndpoint, "POST", filter); +} + +export const countData = async (filter) => { + let countEndpoint = (filter.query) ? "civil-status-mtlb/count/advanced-search" : "civil-status-mtlb/count/search-by-mtlb-type-and-status/"; + return await rest.request(getServiceUri() + countEndpoint, "POST", filter); +} + +export const getOrderBy = () => { + return CIVIL_STATUS_MTLB_ORDER_BY_FIRSTNAME +} + +export const getMtlbTypeList = () => { + return [MTLB_TYPE_ADOPTION] +} + +export const filterData = (DefaultRows, token) => { + const newRows = []; + for (let i in DefaultRows) { + let row = DefaultRows[i]; + const imageUrl = getServiceUri() + 'civil-status-mtlb/face/' + row.id + "/" + token; + row.image = (imageUrl != null) ? imageUrl : "/public/avatar.png"; + let date = row.birthdate + if (date !== null) + row.birthdate = date[2] + '-' + date[1] + '-' + date[0]; + newRows.push(row); + } + return newRows; +} + +export const getErrorList = () => { + let list = []; + for (let i = 1; i < 18; i++) { + let code = (i < 10) ? "E" + "0" + i : "E" + i + list.push(code); + } + for (let i = 19; i < 23; i++) { + let code = (i < 10) ? "E" + "0" + i : "E" + i + list.push(code); + } + for (let i = 28; i < 32; i++) { + let code = (i < 10) ? "E" + "0" + i : "E" + i + list.push(code); + } + return list; +} + +export const advancedSearchfields = [ + { name: "caseSensitiveSearch", label: "Case Sensitive Search", type: "checkbox", x: 1, y: 1, layout: "col-md-3" }, + { name: "firstname", type: "text", x: 1, y: 6, layout: "col-md-6" }, + { + name: "firstnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 6, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + + { name: "secondname", type: "text", x: 1, y: 4, layout: "col-md-6" }, + { + name: "secondnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 4, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + + { name: "thirdname", type: "text", x: 1, y: 5, layout: "col-md-6" }, + { + name: "thirdnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 5, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + + { name: "fourthname", type: "text", x: 1, y: 3, layout: "col-md-6" }, + { + name: "fourthnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 3, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + + { + name: "genderBox", label: "Gender", components: [ + { name: "male", label: "Male", type: "checkbox", x: 1, y: 1, layout: "col-md-3" }, + { name: "female", label: "Female", type: "checkbox", x: 2, y: 1, layout: "col-md-3" }, + ], type: "box", x: 3, y: 7, layout: "col-md-11 ms-2 mt-2" + },//mx-auto + { + name: "birthBox", label: "Birth Date", components: [ + { name: "rangeBirthdate", label: "exactbirthdate", type: "checkbox", x: 1, y: 1, layout: "col-md-12" }, + { + name: "exactBirthdate", type: "date", x: 1, y: 2, layout: "col-md-6", display: (data) => { + return !data.rangeBirthdate; + } + }, + + { + name: "birthdateStart", type: "date", x: 1, y: 3, layout: "col-md-6", display: (data) => { + return data.rangeBirthdate; + } + }, + { + name: "birthdateEnd", type: "date", x: 2, y: 3, layout: "col-md-6", display: (data) => { + return data.rangeBirthdate; + } + }, + ], type: "box", x: 1, y: 8, layout: "col-md-11 ms-2 mt-2 pt-1 pb-2" + }, + + { + name: "birthBox", label: "Birth Place", components: [ + { name: "anyBornOutsideCountry", label: "anyBornOutsideCountry", type: "checkbox", x: 1, y: 1, layout: "col-md-12" }, + { + name: "birthPlace", type: "custom", x: 1, y: 2, layout: "col-md-6", + component: (name, disabled) => , + display: (data) => { return !data.anyBornOutsideCountry } + }, + ], type: "box", x: 2, y: 10, layout: "col-md-11 ms-2 mt-2 pt-1 pb-2" + } +]; + +export const transformAdvancedSearchData = (formData) => { + const columns = []; + + const addColumn = (name, type, value, condition) => { + columns.push({ + name, + type, + [type === 'date' ? 'dateValue' : type === 'boolean' ? 'booleanValue' : (type === 'text' ? 'textValue' : 'longValue')]: value, + searchType: condition ? condition : null, + }); + }; + (formData.firstname !== "") && addColumn('firstname', 'text', formData.firstname, formData.firstnameCondition); + + (formData.secondname !== "") && addColumn('secondname', 'text', formData.secondname, formData.secondnameCondition); + + (formData.thirdname !== "") && addColumn('thirdname', 'text', formData.thirdname, formData.thirdnameCondition); + + (formData.fourthname !== "") && addColumn('fourthname', 'text', formData.fourthname, formData.fourthnameCondition); + addColumn('mtlbType', 'number', 11, null); + addColumn('draft', 'boolean', false, null) + if (formData.anyBornOutsideCountry) + addColumn('birthPlace', 'text', '191', 'notStartsWith'); + else + (formData.birthPlace) && addColumn('birthPlace', 'text', formData.birthPlace, formData.birthPlace ? "startsWith" : null); + const birthdateRange = formData.birthdateStart && formData.birthdateEnd + ? { + min: formData.birthdateStart ? formData.birthdateStart : null, + max: formData.birthdateEnd ? formData.birthdateEnd : null, + } + : null; + + (birthdateRange != null || formData.exactBirthdate != null) && addColumn('birthdate', 'date', formData.exactBirthdate, null); + if ((birthdateRange != null || formData.exactBirthdate != null)) + columns[columns.length - 1].dateRange = birthdateRange; + + const gender = []; + formData.male ? gender.push("1") : null; + formData.female ? gender.push("2") : null; + if (gender.length) + columns.push({ + name: 'gender', + type: 'enum', + enumValues: gender, + }); + + return { columns, caseSensitiveSearch: formData.caseSensitiveSearch }; +}; \ No newline at end of file diff --git a/src/main/js/lists/amendmentApplication/AmendmentApplicationListCommon.jsx b/src/main/js/lists/amendmentApplication/AmendmentApplicationListCommon.jsx new file mode 100644 index 0000000..8b4ace3 --- /dev/null +++ b/src/main/js/lists/amendmentApplication/AmendmentApplicationListCommon.jsx @@ -0,0 +1,192 @@ +import React from "react"; +import { getServiceUri } from "../../../../auto/js/metadata"; +import { CIVIL_STATUS_MTLB_ORDER_BY_FIRSTNAME } from "../../../../auto/js/metadata/CivilStatusMtlbOrderBy"; +import { MTLB_TYPE_CIVIL_STATUS_CHANGE } from "../../../../auto/js/metadata/MtlbType"; +import { rest } from "../../../../auto/js/services"; +import { GeoDataComponent } from "../../../../auto/js/widgets/GeoDataComponent"; + +export const amendmentApplicationListColumns = [ + { title: "image", field: "image", render: rowData => { e.target.onerror = null; e.target.src = "/public/avatar.png" }} style={{ width: 40, borderRadius: '50%', height: 40 }} /> }, + { title: "vitalRecordId", field: "vitalRecordId" }, + { title: "fourthname", field: "fourthname" }, + { title: "secondname", field: "secondname" }, + { title: "thirdname", field: "thirdname" }, + { title: "firstname", field: "firstname" }, + { title: "birthdate", field: "birthdate" }, + +]; + +export const getData = async (filter) => { + let searchEndpoint = (filter.query) ? "civil-status-mtlb/advanced-search" : "civil-status-mtlb/search-by-mtlb-type-and-status/"; + return await rest.request(getServiceUri() + searchEndpoint, "POST", filter); +} + +export const countData = async (filter) => { + let countEndpoint = (filter.query) ? "civil-status-mtlb/count/advanced-search" : "civil-status-mtlb/count/search-by-mtlb-type-and-status/"; + return await rest.request(getServiceUri() + countEndpoint, "POST", filter); +} + +export const getOrderBy = () => { + return CIVIL_STATUS_MTLB_ORDER_BY_FIRSTNAME +} + +export const getMtlbTypeList = () => { + return [MTLB_TYPE_CIVIL_STATUS_CHANGE] +} + +export const filterData = (DefaultRows, token) => { + const newRows = []; + for (let i in DefaultRows) { + let row = DefaultRows[i]; + const imageUrl = getServiceUri() + 'civil-status-mtlb/face/' + row.id + "/" + token; + row.image = (imageUrl != null) ? imageUrl : "/public/avatar.png"; + let date = row.birthdate + if (date !== null) + row.birthdate = date[2] + '-' + date[1] + '-' + date[0]; + newRows.push(row); + } + return newRows; +} + +export const getErrorList = () => { + let list = []; + for (let i = 1; i < 18; i++) { + let code = (i < 10) ? "E" + "0" + i : "E" + i + list.push(code); + } + for (let i = 19; i < 23; i++) { + let code = (i < 10) ? "E" + "0" + i : "E" + i + list.push(code); + } + for (let i = 28; i < 32; i++) { + let code = (i < 10) ? "E" + "0" + i : "E" + i + list.push(code); + } + return list; +} + +export const advancedSearchfields = [ + { name: "caseSensitiveSearch", label: "Case Sensitive Search", type: "checkbox", x: 1, y: 1, layout: "col-md-3" }, + { name: "firstname", type: "text", x: 1, y: 6, layout: "col-md-6" }, + { + name: "firstnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 6, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + + { name: "secondname", type: "text", x: 1, y: 4, layout: "col-md-6" }, + { + name: "secondnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 4, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + + { name: "thirdname", type: "text", x: 1, y: 5, layout: "col-md-6" }, + { + name: "thirdnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 5, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + + { name: "fourthname", type: "text", x: 1, y: 3, layout: "col-md-6" }, + { + name: "fourthnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 3, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + + { + name: "genderBox", label: "Gender", components: [ + { name: "male", label: "Male", type: "checkbox", x: 1, y: 1, layout: "col-md-3" }, + { name: "female", label: "Female", type: "checkbox", x: 2, y: 1, layout: "col-md-3" }, + ], type: "box", x: 3, y: 7, layout: "col-md-11 ms-2 mt-2" + },//mx-auto + { + name: "birthBox", label: "Birth Date", components: [ + { name: "rangeBirthdate", label: "exactbirthdate", type: "checkbox", x: 1, y: 1, layout: "col-md-12" }, + { + name: "exactBirthdate", type: "date", x: 1, y: 2, layout: "col-md-6", display: (data) => { + return !data.rangeBirthdate; + } + }, + + { + name: "birthdateStart", type: "date", x: 1, y: 3, layout: "col-md-6", display: (data) => { + return data.rangeBirthdate; + } + }, + { + name: "birthdateEnd", type: "date", x: 2, y: 3, layout: "col-md-6", display: (data) => { + return data.rangeBirthdate; + } + }, + ], type: "box", x: 1, y: 8, layout: "col-md-11 ms-2 mt-2 pt-1 pb-2" + }, + + { + name: "birthBox", label: "Birth Place", components: [ + { name: "anyBornOutsideCountry", label: "anyBornOutsideCountry", type: "checkbox", x: 1, y: 1, layout: "col-md-12" }, + { + name: "birthPlace", type: "custom", x: 1, y: 2, layout: "col-md-6", + component: (name, disabled) => , + display: (data) => { return !data.anyBornOutsideCountry } + }, + ], type: "box", x: 2, y: 10, layout: "col-md-11 ms-2 mt-2 pt-1 pb-2" + } +]; + +export const transformAdvancedSearchData = (formData) => { + const columns = []; + + const addColumn = (name, type, value, condition) => { + columns.push({ + name, + type, + [type === 'date' ? 'dateValue' : type === 'boolean' ? 'booleanValue' : (type === 'text' ? 'textValue' : 'longValue')]: value, + searchType: condition ? condition : null, + }); + }; + (formData.firstname !== "") && addColumn('firstname', 'text', formData.firstname, formData.firstnameCondition); + + (formData.secondname !== "") && addColumn('secondname', 'text', formData.secondname, formData.secondnameCondition); + + (formData.thirdname !== "") && addColumn('thirdname', 'text', formData.thirdname, formData.thirdnameCondition); + + (formData.fourthname !== "") && addColumn('fourthname', 'text', formData.fourthname, formData.fourthnameCondition); + addColumn('mtlbType', 'number', 6, null); + addColumn('draft', 'boolean', false, null) + if (formData.anyBornOutsideCountry) + addColumn('birthPlace', 'text', '191', 'notStartsWith'); + else + (formData.birthPlace) && addColumn('birthPlace', 'text', formData.birthPlace, formData.birthPlace ? "startsWith" : null); + const birthdateRange = formData.birthdateStart && formData.birthdateEnd + ? { + min: formData.birthdateStart ? formData.birthdateStart : null, + max: formData.birthdateEnd ? formData.birthdateEnd : null, + } + : null; + + (birthdateRange != null || formData.exactBirthdate != null) && addColumn('birthdate', 'date', formData.exactBirthdate, null); + if ((birthdateRange != null || formData.exactBirthdate != null)) + columns[columns.length - 1].dateRange = birthdateRange; + + const gender = []; + formData.male ? gender.push("1") : null; + formData.female ? gender.push("2") : null; + if (gender.length) + columns.push({ + name: 'gender', + type: 'enum', + enumValues: gender, + }); + + return { columns, caseSensitiveSearch: formData.caseSensitiveSearch }; +}; \ No newline at end of file diff --git a/src/main/js/lists/amendmentDeathApplication/AmendmentDeathApplicationListCommon.jsx b/src/main/js/lists/amendmentDeathApplication/AmendmentDeathApplicationListCommon.jsx new file mode 100644 index 0000000..956d523 --- /dev/null +++ b/src/main/js/lists/amendmentDeathApplication/AmendmentDeathApplicationListCommon.jsx @@ -0,0 +1,192 @@ +import React from "react"; +import { getServiceUri } from "../../../../auto/js/metadata"; +import { CIVIL_STATUS_MTLB_ORDER_BY_FIRSTNAME } from "../../../../auto/js/metadata/CivilStatusMtlbOrderBy"; +import { MTLB_TYPE_CIVIL_STATUS_CHANGE, MTLB_TYPE_DEATH_RECORD_CHANGE } from "../../../../auto/js/metadata/MtlbType"; +import { rest } from "../../../../auto/js/services"; +import { GeoDataComponent } from "../../../../auto/js/widgets/GeoDataComponent"; + +export const amendmentDeathApplicationListColumns = [ + { title: "image", field: "image", render: rowData => { e.target.onerror = null; e.target.src = "/public/avatar.png" }} style={{ width: 40, borderRadius: '50%', height: 40 }} /> }, + { title: "vitalRecordId", field: "vitalRecordId" }, + { title: "fourthname", field: "fourthname" }, + { title: "secondname", field: "secondname" }, + { title: "thirdname", field: "thirdname" }, + { title: "firstname", field: "firstname" }, + { title: "birthdate", field: "birthdate" }, + +]; + +export const getData = async (filter) => { + let searchEndpoint = (filter.query) ? "civil-status-mtlb/advanced-search" : "civil-status-mtlb/search-by-mtlb-type-and-status/"; + return await rest.request(getServiceUri() + searchEndpoint, "POST", filter); +} + +export const countData = async (filter) => { + let countEndpoint = (filter.query) ? "civil-status-mtlb/count/advanced-search" : "civil-status-mtlb/count/search-by-mtlb-type-and-status/"; + return await rest.request(getServiceUri() + countEndpoint, "POST", filter); +} + +export const getOrderBy = () => { + return CIVIL_STATUS_MTLB_ORDER_BY_FIRSTNAME +} + +export const getMtlbTypeList = () => { + return [MTLB_TYPE_DEATH_RECORD_CHANGE] +} + +export const filterData = (DefaultRows, token) => { + const newRows = []; + for (let i in DefaultRows) { + let row = DefaultRows[i]; + const imageUrl = getServiceUri() + 'civil-status-mtlb/face/' + row.id + "/" + token; + row.image = (imageUrl != null) ? imageUrl : "/public/avatar.png"; + let date = row.birthdate + if (date !== null) + row.birthdate = date[2] + '-' + date[1] + '-' + date[0]; + newRows.push(row); + } + return newRows; +} + +export const getErrorList = () => { + let list = []; + for (let i = 1; i < 18; i++) { + let code = (i < 10) ? "E" + "0" + i : "E" + i + list.push(code); + } + for (let i = 19; i < 23; i++) { + let code = (i < 10) ? "E" + "0" + i : "E" + i + list.push(code); + } + for (let i = 28; i < 32; i++) { + let code = (i < 10) ? "E" + "0" + i : "E" + i + list.push(code); + } + return list; +} + +export const advancedSearchfields = [ + { name: "caseSensitiveSearch", label: "Case Sensitive Search", type: "checkbox", x: 1, y: 1, layout: "col-md-3" }, + { name: "firstname", type: "text", x: 1, y: 6, layout: "col-md-6" }, + { + name: "firstnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 6, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + + { name: "secondname", type: "text", x: 1, y: 4, layout: "col-md-6" }, + { + name: "secondnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 4, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + + { name: "thirdname", type: "text", x: 1, y: 5, layout: "col-md-6" }, + { + name: "thirdnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 5, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + + { name: "fourthname", type: "text", x: 1, y: 3, layout: "col-md-6" }, + { + name: "fourthnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 3, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + + { + name: "genderBox", label: "Gender", components: [ + { name: "male", label: "Male", type: "checkbox", x: 1, y: 1, layout: "col-md-3" }, + { name: "female", label: "Female", type: "checkbox", x: 2, y: 1, layout: "col-md-3" }, + ], type: "box", x: 3, y: 7, layout: "col-md-11 ms-2 mt-2" + },//mx-auto + { + name: "birthBox", label: "Birth Date", components: [ + { name: "rangeBirthdate", label: "exactbirthdate", type: "checkbox", x: 1, y: 1, layout: "col-md-12" }, + { + name: "exactBirthdate", type: "date", x: 1, y: 2, layout: "col-md-6", display: (data) => { + return !data.rangeBirthdate; + } + }, + + { + name: "birthdateStart", type: "date", x: 1, y: 3, layout: "col-md-6", display: (data) => { + return data.rangeBirthdate; + } + }, + { + name: "birthdateEnd", type: "date", x: 2, y: 3, layout: "col-md-6", display: (data) => { + return data.rangeBirthdate; + } + }, + ], type: "box", x: 1, y: 8, layout: "col-md-11 ms-2 mt-2 pt-1 pb-2" + }, + + { + name: "birthBox", label: "Birth Place", components: [ + { name: "anyBornOutsideCountry", label: "anyBornOutsideCountry", type: "checkbox", x: 1, y: 1, layout: "col-md-12" }, + { + name: "birthPlace", type: "custom", x: 1, y: 2, layout: "col-md-6", + component: (name, disabled) => , + display: (data) => { return !data.anyBornOutsideCountry } + }, + ], type: "box", x: 2, y: 10, layout: "col-md-11 ms-2 mt-2 pt-1 pb-2" + } +]; + +export const transformAdvancedSearchData = (formData) => { + const columns = []; + + const addColumn = (name, type, value, condition) => { + columns.push({ + name, + type, + [type === 'date' ? 'dateValue' : type === 'boolean' ? 'booleanValue' : (type === 'text' ? 'textValue' : 'longValue')]: value, + searchType: condition ? condition : null, + }); + }; + (formData.firstname !== "") && addColumn('firstname', 'text', formData.firstname, formData.firstnameCondition); + + (formData.secondname !== "") && addColumn('secondname', 'text', formData.secondname, formData.secondnameCondition); + + (formData.thirdname !== "") && addColumn('thirdname', 'text', formData.thirdname, formData.thirdnameCondition); + + (formData.fourthname !== "") && addColumn('fourthname', 'text', formData.fourthname, formData.fourthnameCondition); + addColumn('mtlbType', 'number', 28, null); + addColumn('draft', 'boolean', false, null) + if (formData.anyBornOutsideCountry) + addColumn('birthPlace', 'text', '191', 'notStartsWith'); + else + (formData.birthPlace) && addColumn('birthPlace', 'text', formData.birthPlace, formData.birthPlace ? "startsWith" : null); + const birthdateRange = formData.birthdateStart && formData.birthdateEnd + ? { + min: formData.birthdateStart ? formData.birthdateStart : null, + max: formData.birthdateEnd ? formData.birthdateEnd : null, + } + : null; + + (birthdateRange != null || formData.exactBirthdate != null) && addColumn('birthdate', 'date', formData.exactBirthdate, null); + if ((birthdateRange != null || formData.exactBirthdate != null)) + columns[columns.length - 1].dateRange = birthdateRange; + + const gender = []; + formData.male ? gender.push("1") : null; + formData.female ? gender.push("2") : null; + if (gender.length) + columns.push({ + name: 'gender', + type: 'enum', + enumValues: gender, + }); + + return { columns, caseSensitiveSearch: formData.caseSensitiveSearch }; +}; \ No newline at end of file diff --git a/src/main/js/lists/amendmentUnionApplication/AmendmentUnionApplicationListCommon.jsx b/src/main/js/lists/amendmentUnionApplication/AmendmentUnionApplicationListCommon.jsx new file mode 100644 index 0000000..619d8f3 --- /dev/null +++ b/src/main/js/lists/amendmentUnionApplication/AmendmentUnionApplicationListCommon.jsx @@ -0,0 +1,143 @@ +import React from "react"; +import { getServiceUri } from "../../../../auto/js/metadata"; +import { rest } from "../../../../auto/js/services"; +import { MTLB_TYPE_UNION_RECORD_CHANGE } from "../../../../auto/js/metadata/MtlbType"; +import { UNION_MTLB_ORDER_BY_PARTNER1_FIRSTNAME } from "../../../../auto/js/metadata/UnionMtlbOrderBy"; + +export const amendmentUnionApplicationListColumns = [ + { title: "partner1VitalRecordId", field: "partner1VitalRecordId" }, + { title: "partner1Surname", field: "partner1Surname" }, + { title: "partner1Firstname", field: "partner1Firstname" }, + { title: "partner2VitalRecordId", field: "partner2VitalRecordId" }, + { title: "partner2Surname", field: "partner2Surname" }, + { title: "partner2Firstname", field: "partner2Firstname" }, + +]; + +export const getData = async (filter) => { + let searchEndpoint = (filter.query) ? "union-mtlb/advanced-search" : "union-mtlb/search-by-union-mtlb-type-and-status/"; + return await rest.request(getServiceUri() + searchEndpoint, "POST", filter); +} + +export const countData = async (filter) => { + let countEndpoint = (filter.query) ? "union-mtlb/count/advanced-search" : "union-mtlb/count/search-by-union-mtlb-type-and-status/"; + return await rest.request(getServiceUri() + countEndpoint, "POST", filter); +} + +export const getOrderBy = () => { + return UNION_MTLB_ORDER_BY_PARTNER1_FIRSTNAME +} + +export const getMtlbTypeList = () => { + return [MTLB_TYPE_UNION_RECORD_CHANGE] +} + +export const filterData = (DefaultRows) => { + return DefaultRows; +} + +export const getErrorList = () => { + let list = []; + for (let i = 23; i < 32; i++) { + let code = "E" + i + list.push(code); + } + return list; +} + +export const advancedSearchfields = [ + { name: "caseSensitiveSearch", label: "Case Sensitive Search", type: "checkbox", x: 1, y: 1, layout: "col-md-3" }, + { name: "partner1VitalRecordId", type: "number", x: 1, y: 2, layout: "col-md-6" }, + { name: "partner2VitalRecordId", type: "number", x: 2, y: 2, layout: "col-md-6" }, + { name: "partner1Firstname", type: "text", x: 1, y: 4, layout: "col-md-6" }, + { + name: "partner1FirstnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 4, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + { name: "partner1Surname", type: "text", x: 1, y: 3, layout: "col-md-6" }, + { + name: "partner1SurnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 3, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + { name: "partner2Firstname", type: "text", x: 1, y: 6, layout: "col-md-6" }, + { + name: "partner2FirstnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 6, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + { name: "partner2Surname", type: "text", x: 1, y: 5, layout: "col-md-6" }, + { + name: "partner2SurnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 5, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + + { + name: "marriageBox", label: "Effect Date", components: [ + { name: "rangemarriagedate", label: "exactmarriagedate", type: "checkbox", x: 1, y: 1, layout: "col-md-12" }, + { + name: "exactmarriagedate", type: "date", x: 1, y: 2, layout: "col-md-6", display: (data) => { + return !data.rangemarriagedate; + } + }, + + { + name: "marriagedateStart", type: "date", x: 1, y: 3, layout: "col-md-6", display: (data) => { + return data.rangemarriagedate; + } + }, + { + name: "marriagedateEnd", type: "date", x: 2, y: 3, layout: "col-md-6", display: (data) => { + return data.rangemarriagedate; + } + }, + ], type: "box", x: 1, y: 8, layout: "col-md-11 ms-2 mt-2 pt-1 pb-2" + }, +]; + +export const transformAdvancedSearchData = (formData) => { + const columns = []; + + const addColumn = (name, type, value, condition) => { + columns.push({ + name, + type, + [type === 'date' ? 'dateValue' : type === 'boolean' ? 'booleanValue' : (type === 'text' ? 'textValue' : 'longValue')]: value, + searchType: condition ? condition : null, + }); + }; + (formData.partner1VitalRecordId !== null && formData.partner1VitalRecordId !== "") && addColumn('partner1VitalRecordId', 'number', formData.partner1VitalRecordId, null); + (formData.partner2VitalRecordId !== null && formData.partner2VitalRecordId !== "") && addColumn('partner2VitalRecordId', 'number', formData.partner2VitalRecordId, null); + + (formData.partner1Firstname !== "") && addColumn('partner1Firstname', 'text', formData.partner1Firstname, formData.partner1FirstnameCondition); + + (formData.partner2Firstname !== "") && addColumn('partner1Firstname', 'text', formData.partner2Firstname, formData.partner2FirstnameCondition); + + (formData.partner1Surname !== "") && addColumn('partner1Surname', 'text', formData.partner1Surname, formData.partner1SurnameCondition); + + (formData.partner2Surname !== "") && addColumn('partner2Surname', 'text', formData.partner2Surname, formData.partner2SurnameCondition); + addColumn('mtlbType', 'number', 29, null); + addColumn('draft', 'boolean', false, null); + const marriagedateRange = formData.marriagedateStart && formData.marriagedateEnd + ? { + min: formData.marriagedateStart ? formData.marriagedateStart : null, + max: formData.marriagedateEnd ? formData.marriagedateEnd : null, + } + : null; + + (marriagedateRange != null || formData.exactmarriagedate != null) && addColumn('declaredDate', 'date', formData.exactmarriagedate, null); + if ((marriagedateRange != null || formData.exactmarriagedate != null)) + columns[columns.length - 1].dateRange = marriagedateRange; + + return { columns, caseSensitiveSearch: formData.caseSensitiveSearch }; +}; \ No newline at end of file diff --git a/src/main/js/lists/birthRegistration/BirthRegistrationListCommon.jsx b/src/main/js/lists/birthRegistration/BirthRegistrationListCommon.jsx new file mode 100644 index 0000000..ecf4ea6 --- /dev/null +++ b/src/main/js/lists/birthRegistration/BirthRegistrationListCommon.jsx @@ -0,0 +1,187 @@ +import React from "react"; +import { getServiceUri } from "../../../../auto/js/metadata"; +import { CIVIL_STATUS_MTLB_ORDER_BY_FIRSTNAME } from "../../../../auto/js/metadata/CivilStatusMtlbOrderBy"; +import { MTLB_TYPE_BIRTH_REGISTRATION, MTLB_TYPE_CIVIL_STATUS_INCLUSION } from "../../../../auto/js/metadata/MtlbType"; +import { rest } from "../../../../auto/js/services"; +import { GeoDataComponent } from "../../../../auto/js/widgets/GeoDataComponent"; + +export const birthRegistrationListColumns = [ + { title: "image", field: "image", render: rowData => { e.target.onerror = null; e.target.src = "/public/avatar.png" }} style={{ width: 40, borderRadius: '50%', height: 40 }} /> }, + { title: "fourthname", field: "fourthname" }, + { title: "firstname", field: "firstname" }, + { title: "birthdate", field: "birthdate" }, + +]; + +export const getData = async (filter) => { + let searchEndpoint = (filter.query) ? "civil-status-mtlb/advanced-search" : "civil-status-mtlb/search-by-mtlb-type-and-status/"; + return await rest.request(getServiceUri() + searchEndpoint, "POST", filter); +} + +export const countData = async (filter) => { + let countEndpoint = (filter.query) ? "civil-status-mtlb/count/advanced-search" : "civil-status-mtlb/count/search-by-mtlb-type-and-status/"; + return await rest.request(getServiceUri() + countEndpoint, "POST", filter); +} + +export const getOrderBy = () => { + return CIVIL_STATUS_MTLB_ORDER_BY_FIRSTNAME +} + +export const getMtlbTypeList = () => { + return [MTLB_TYPE_BIRTH_REGISTRATION, MTLB_TYPE_CIVIL_STATUS_INCLUSION] +} + +export const filterData = (DefaultRows, token) => { + const newRows = []; + for (let i in DefaultRows) { + let row = DefaultRows[i]; + const imageUrl = getServiceUri() + 'civil-status-mtlb/face/' + row.id + "/" + token; + row.image = (imageUrl != null) ? imageUrl : "/public/avatar.png"; + let date = row.birthdate + if (date !== null) + row.birthdate = date[2] + '-' + date[1] + '-' + date[0]; + newRows.push(row); + } + return newRows; +} + +export const getErrorList = () => { + let list = []; + for (let i = 1; i < 18; i++) { + let code = (i < 10) ? "E" + "0" + i : "E" + i + list.push(code); + } + list.push("E20") + list.push("E21") + for (let i = 28; i < 32; i++) { + let code = (i < 10) ? "E" + "0" + i : "E" + i + list.push(code); + } + return list; +} + +export const advancedSearchfields = [ + { name: "caseSensitiveSearch", label: "Case Sensitive Search", type: "checkbox", x: 1, y: 1, layout: "col-md-3" }, + { name: "firstname", type: "text", x: 1, y: 6, layout: "col-md-6" }, + { + name: "firstnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 6, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + + { name: "secondname", type: "text", x: 1, y: 4, layout: "col-md-6" }, + { + name: "secondnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 4, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + + { name: "thirdname", type: "text", x: 1, y: 5, layout: "col-md-6" }, + { + name: "thirdnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 5, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + + { name: "fourthname", type: "text", x: 1, y: 3, layout: "col-md-6" }, + { + name: "fourthnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 3, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + + { + name: "genderBox", label: "Gender", components: [ + { name: "male", label: "Male", type: "checkbox", x: 1, y: 1, layout: "col-md-3" }, + { name: "female", label: "Female", type: "checkbox", x: 2, y: 1, layout: "col-md-3" }, + ], type: "box", x: 3, y: 7, layout: "col-md-11 ms-2 mt-2" + },//mx-auto + { + name: "birthBox", label: "Birth Date", components: [ + { name: "rangeBirthdate", label: "exactbirthdate", type: "checkbox", x: 1, y: 1, layout: "col-md-12" }, + { + name: "exactBirthdate", type: "date", x: 1, y: 2, layout: "col-md-6", display: (data) => { + return !data.rangeBirthdate; + } + }, + + { + name: "birthdateStart", type: "date", x: 1, y: 3, layout: "col-md-6", display: (data) => { + return data.rangeBirthdate; + } + }, + { + name: "birthdateEnd", type: "date", x: 2, y: 3, layout: "col-md-6", display: (data) => { + return data.rangeBirthdate; + } + }, + ], type: "box", x: 1, y: 8, layout: "col-md-11 ms-2 mt-2 pt-1 pb-2" + }, + + { + name: "birthBox", label: "Birth Place", components: [ + { name: "anyBornOutsideCountry", label: "anyBornOutsideCountry", type: "checkbox", x: 1, y: 1, layout: "col-md-12" }, + { + name: "birthPlace", type: "custom", x: 1, y: 2, layout: "col-md-6", + component: (name, disabled) => , + display: (data) => { return !data.anyBornOutsideCountry } + }, + ], type: "box", x: 2, y: 10, layout: "col-md-11 ms-2 mt-2 pt-1 pb-2" + } +]; + +export const transformAdvancedSearchData = (formData) => { + const columns = []; + + const addColumn = (name, type, value, condition) => { + columns.push({ + name, + type, + [type === 'date' ? 'dateValue' : type === 'boolean' ? 'booleanValue' : (type === 'text' ? 'textValue' : 'longValue')]: value, + searchType: condition ? condition : null, + }); + }; + (formData.firstname !== "") && addColumn('firstname', 'text', formData.firstname, formData.firstnameCondition); + + (formData.secondname !== "") && addColumn('secondname', 'text', formData.secondname, formData.secondnameCondition); + + (formData.thirdname !== "") && addColumn('thirdname', 'text', formData.thirdname, formData.thirdnameCondition); + + (formData.fourthname !== "") && addColumn('fourthname', 'text', formData.fourthname, formData.fourthnameCondition); + addColumn('mtlbType', 'number', 4, null); + addColumn('draft', 'boolean', false, null) + if (formData.anyBornOutsideCountry) + addColumn('birthPlace', 'text', '191', 'notStartsWith'); + else + (formData.birthPlace) && addColumn('birthPlace', 'text', formData.birthPlace, formData.birthPlace ? "startsWith" : null); + const birthdateRange = formData.birthdateStart && formData.birthdateEnd + ? { + min: formData.birthdateStart ? formData.birthdateStart : null, + max: formData.birthdateEnd ? formData.birthdateEnd : null, + } + : null; + + (birthdateRange != null || formData.exactBirthdate != null) && addColumn('birthdate', 'date', formData.exactBirthdate, null); + if ((birthdateRange != null || formData.exactBirthdate != null)) + columns[columns.length - 1].dateRange = birthdateRange; + + const gender = []; + formData.male ? gender.push("1") : null; + formData.female ? gender.push("2") : null; + if (gender.length) + columns.push({ + name: 'gender', + type: 'enum', + enumValues: gender, + }); + + return { columns, caseSensitiveSearch: formData.caseSensitiveSearch }; +}; \ No newline at end of file diff --git a/src/main/js/lists/deathRegistration/DeathRegistrationListCommon.jsx b/src/main/js/lists/deathRegistration/DeathRegistrationListCommon.jsx new file mode 100644 index 0000000..6e91f42 --- /dev/null +++ b/src/main/js/lists/deathRegistration/DeathRegistrationListCommon.jsx @@ -0,0 +1,178 @@ +import React from "react"; +import { getServiceUri } from "../../../../auto/js/metadata"; +import { CIVIL_STATUS_MTLB_ORDER_BY_FIRSTNAME } from "../../../../auto/js/metadata/CivilStatusMtlbOrderBy"; +import { MTLB_TYPE_DEATH_REGISTRATION } from "../../../../auto/js/metadata/MtlbType"; +import { rest } from "../../../../auto/js/services"; +import { GeoDataComponent } from "../../../../auto/js/widgets/GeoDataComponent"; + + +export const deathRegistrationListColumns = [ + { title: "id", field: "vitalRecordId" }, + { title: "fourthname", field: "fourthname" }, + { title: "secondname", field: "secondname" }, + { title: "thirdname", field: "thirdname" }, + { title: "firstname", field: "firstname" }, + { title: "dateOfDeath", field: "dateOfDeath" }, + +]; + +export const getData = async (filter) => { + let searchEndpoint = (filter.query) ? "civil-status-mtlb/advanced-search" : "civil-status-mtlb/search-by-mtlb-type-and-status/"; + return await rest.request(getServiceUri() + searchEndpoint, "POST", filter); +} + +export const countData = async (filter) => { + let countEndpoint = (filter.query) ? "civil-status-mtlb/count/advanced-search" : "civil-status-mtlb/count/search-by-mtlb-type-and-status/"; + return await rest.request(getServiceUri() + countEndpoint, "POST", filter); +} + +export const getOrderBy = () => { + return CIVIL_STATUS_MTLB_ORDER_BY_FIRSTNAME +} + +export const getMtlbTypeList = () => { + return [MTLB_TYPE_DEATH_REGISTRATION] +} + +export const filterData = (DefaultRows, token) => { + const newRows = []; + for (let i in DefaultRows) { + let row = DefaultRows[i]; + const imageUrl = getServiceUri() + 'civil-status-mtlb/face/' + row.id + "/" + token; + row.image = (imageUrl != null) ? imageUrl : "/public/avatar.png"; + let date = row.dateOfDeath + if (date !== null) + row.dateOfDeath = date[2] + '-' + date[1] + '-' + date[0]; + newRows.push(row); + } + return newRows; +} + +export const getErrorList = () => { + let list = []; + list.push("E19"); + list.push("E22"); + return list; +} + +export const advancedSearchfields = [ + { name: "caseSensitiveSearch", label: "Case Sensitive Search", type: "checkbox", x: 1, y: 1, layout: "col-md-3" }, + { name: "firstname", type: "text", x: 1, y: 6, layout: "col-md-6" }, + { + name: "firstnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 6, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + + { name: "secondname", type: "text", x: 1, y: 4, layout: "col-md-6" }, + { + name: "secondnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 4, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + + { name: "thirdname", type: "text", x: 1, y: 5, layout: "col-md-6" }, + { + name: "thirdnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 5, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + + { name: "fourthname", type: "text", x: 1, y: 3, layout: "col-md-6" }, + { + name: "fourthnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 3, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + + { + name: "genderBox", label: "Gender", components: [ + { name: "male", label: "Male", type: "checkbox", x: 1, y: 1, layout: "col-md-3" }, + { name: "female", label: "Female", type: "checkbox", x: 2, y: 1, layout: "col-md-3" }, + ], type: "box", x: 3, y: 7, layout: "col-md-11 ms-2 mt-2" + },//mx-auto + { + name: "deathDateBox", label: "Death Date", components: [ + { name: "deathdateRange", label: "deathdateRange", type: "checkbox", x: 1, y: 1, layout: "col-md-12" }, + { + name: "exactdeathdate", type: "date", x: 1, y: 2, layout: "col-md-6", display: (data) => { + return !data.deathdateRange; + } + }, + + { + name: "deathdateStart", type: "date", x: 1, y: 3, layout: "col-md-6", display: (data) => { + return data.rangedeathdate; + } + }, + { + name: "deathdateEnd", type: "date", x: 2, y: 3, layout: "col-md-6", display: (data) => { + return data.rangedeathdate; + } + }, + ], type: "box", x: 1, y: 8, layout: "col-md-11 ms-2 mt-2 pt-1 pb-2" + }, + + { + name: "deathBox", label: "Death Place", components: [ + { + name: "deathPlace", type: "custom", x: 1, y: 2, layout: "col-md-6", + component: (name, disabled) => , + display: (data) => { return !data.anyBornOutsideCountry } + }, + ], type: "box", x: 2, y: 10, layout: "col-md-11 ms-2 mt-2 pt-1 pb-2" + } +]; + +export const transformAdvancedSearchData = (formData) => { + const columns = []; + + const addColumn = (name, type, value, condition) => { + columns.push({ + name, + type, + [type === 'date' ? 'dateValue' : type === 'boolean' ? 'booleanValue' : (type === 'text' ? 'textValue' : 'longValue')]: value, + searchType: condition ? condition : null, + }); + }; + (formData.firstname !== "") && addColumn('firstname', 'text', formData.firstname, formData.firstnameCondition); + + (formData.secondname !== "") && addColumn('secondname', 'text', formData.secondname, formData.secondnameCondition); + + (formData.thirdname !== "") && addColumn('thirdname', 'text', formData.thirdname, formData.thirdnameCondition); + + (formData.fourthname !== "") && addColumn('fourthname', 'text', formData.fourthname, formData.fourthnameCondition); + addColumn('mtlbType', 'number', 12, null); + addColumn('draft', 'boolean', false, null); + (formData.deathPlace) && addColumn('deathPlace', 'text', formData.deathPlace, formData.deathPlace ? "startsWith" : null); + const deathdateRange = formData.deathdateStart && formData.deathdateEnd + ? { + min: formData.deathdateStart ? formData.deathdateStart : null, + max: formData.deathdateEnd ? formData.deathdateEnd : null, + } + : null; + + (deathdateRange != null || formData.exactdeathdate != null) && addColumn('dateOfDeath', 'date', formData.exactdeathdate, null); + if ((deathdateRange != null || formData.exactdeathdate != null)) + columns[columns.length - 1].dateRange = deathdateRange; + + const gender = []; + formData.male ? gender.push("1") : null; + formData.female ? gender.push("2") : null; + if (gender.length) + columns.push({ + name: 'gender', + type: 'enum', + enumValues: gender, + }); + + return { columns, caseSensitiveSearch: formData.caseSensitiveSearch }; +}; \ No newline at end of file diff --git a/src/main/js/lists/digitalization/DigitalizationApplicationList.jsx b/src/main/js/lists/digitalization/DigitalizationApplicationList.jsx new file mode 100644 index 0000000..b0278db --- /dev/null +++ b/src/main/js/lists/digitalization/DigitalizationApplicationList.jsx @@ -0,0 +1,183 @@ +import React, { useState } from "react"; +import {v4 as uuidv4} from 'uuid'; +import VisibilityIcon from '@material-ui/icons/Visibility'; +import { MTLB_STATUS_ARCHIVED, MTLB_STATUS_ASSIGNED, MTLB_STATUS_NOT_ASSIGNED, MTLB_STATUS_READY_FOR_APPROVAL } from "../../../../auto/js/metadata/MtlbStatus"; +import { MTLB_TYPE_DIGITALIZATION } from "../../../../auto/js/metadata/MtlbType"; +import { OPEN_VIEW_EVENT } from "../../../../auto/js/events/Gui"; +import { getServiceUri, pojoMetadata } from "../../../../auto/js/metadata"; +import { rest, t } from "../../../../auto/js/services"; +import { displayReadDigitalizationSearchForm } from "../../forms/digitalizationApplication/DigitalizationSearchForm"; +import { createTableComponent } from "../../../../auto/js/widgets/TableComponent"; +import { CIVIL_STATUS_MTLB_ORDER_BY_FIRSTNAME, CIVIL_STATUS_MTLB_ORDER_BY_ID } from "../../../../auto/js/metadata/CivilStatusMtlbOrderBy"; +import Facets from "../../../../auto/js/widgets/Facets"; +import { Checkbox, FormControlLabel } from "@mui/material"; +import { displayReadApprovedDigitalizationApplicationForm } from "../../forms/digitalizationApplication/ApprovedDigitalizationApplicationForm"; +import { displayReadReadyDigitalizationApplicationForm } from "../../forms/digitalizationApplication/ReadyDigitalizationApplicationForm"; +import { whoami } from "../../../../auto/js/users/UserInfo"; + +const fields = [ + {title: "formId", field: "id"}, + {title: "fourthname", field: "fourthname"}, + {title: "secondname", field: "secondname"}, + {title: "thirdname", field: "thirdname"}, + {title: "birthdate", field: "birthdate"}, + {title: "firstname", field: "firstname"}, +]; + +const DigitalizationListPage = ({uuid}) => { + const [approved, setApproved] = useState(false); + const [assigned, setAssigned] = useState(false); + const [unassigned, setUnassigned] = useState(false); + const [ready, setReady] = useState(false); + const[selectAllStatus, setSelectAllStatus] = useState(false); + let DigitalizationList = createTableComponent(fields); + + const onFacetChange = (key, value) => { + switch(key) { + case ("approved"): + setApproved(value.target.checked); + break; + case ("assigned"): + setAssigned(value.target.checked); + break; + case ("unassigned"): + setUnassigned(value.target.checked); + break; + case ("ready"): + setReady(value.target.checked); + break; + case ("selectAllStatus"): + setSelectAllStatus(value.target.checked); + setApproved(value.target.checked); + setAssigned(value.target.checked); + setUnassigned(value.target.checked); + setReady(value.target.checked); + break; + + } + } + + const buildData = async (query) => { + let filter = query; + let data; + let mtlbStatusList = []; + if (approved) + mtlbStatusList.push(MTLB_STATUS_ARCHIVED); + if (assigned) + mtlbStatusList.push(MTLB_STATUS_ASSIGNED); + if (ready) + mtlbStatusList.push(MTLB_STATUS_READY_FOR_APPROVAL); + if (unassigned) + mtlbStatusList.push(MTLB_STATUS_NOT_ASSIGNED); + if (!approved && !assigned && !ready && !unassigned) + mtlbStatusList = [MTLB_STATUS_ASSIGNED, MTLB_STATUS_READY_FOR_APPROVAL, MTLB_STATUS_NOT_ASSIGNED] + filter["civil-status-mtlb"] = {mtlbStatusList:(whoami().roles.includes('REGISTRAR') || whoami().roles.includes('ALL'))?mtlbStatusList:[MTLB_STATUS_ASSIGNED], mtlbTypeList: [MTLB_TYPE_DIGITALIZATION]}; + filter["orderBy"] = CIVIL_STATUS_MTLB_ORDER_BY_FIRSTNAME; + filter.orderDirection = null; + filter.offset = query.page * query.pageSize; + if (query.search && query.search!='') { + pojoMetadata["civil-status-mtlb"].columns.forEach(element => { + if(element.type=='text'){ + filter["civil-status-mtlb"][element.key]= query.search; + } + }); + filter["and"] = false; + } + return await getCivilRecordData(filter).then(response => { + data = filterData(response); + return countData(filter).then((count) => {return {data: data, totalCount: count, page: query.page}}) + }); + } + + const buildFacets = (key, value, label, handleChange) => { + return ( + <> + handleChange(key, event)} + color="primary" + value={value} + /> + } + label={label} + style={{width: '100%'}} + /> + + ) + } + + return ( + <> + {(whoami().roles.includes('REGISTRAR') || whoami().roles.includes('ALL'))? +
+ buildFacets(key, value, t(key), onFacetChange)} /> + buildData(query)} actions={getTableActions()} /> +
+ : buildData(query)} actions={getTableActions()} /> + } + + + ) +} + +export const displayDigitalizationApplicationList = () => { + + let uuid = uuidv4(); + OPEN_VIEW_EVENT.publish({ + uuid, view: () => + }); +} + +const getCivilRecordData = async (filter) => { + if (whoami().roles.includes('REGISTRAR') || whoami().roles.includes('ALL')) + return await rest.request(getServiceUri() + "civil-status-mtlb/search-by-mtlb-type-and-status/", "POST", filter); + else if (whoami().roles.includes('DIGITALIZER')) + return await rest.request(getServiceUri() + "civil-status-mtlb/digitalization/search", "POST", filter); +} + +const countData = async (filter) => { + if (whoami().roles.includes('REGISTRAR') || whoami().roles.includes('ALL')) + return await rest.request(getServiceUri() + "civil-status-mtlb/count/search-by-mtlb-type-and-status/", "POST", filter); + else if (whoami().roles.includes('DIGITALIZER')) + return await rest.request(getServiceUri() + "civil-status-mtlb/digitalization/count", "POST", filter); +} + +const getTableActions = () => { + let actions = []; + actions.push( + { + icon: () => , + tooltip: t`View`, + onClick: (event, rowData) => { + switch(rowData.mtlbStatus) { + case (MTLB_STATUS_ARCHIVED): + displayReadApprovedDigitalizationApplicationForm(rowData.id); + break; + case (MTLB_STATUS_READY_FOR_APPROVAL): + displayReadReadyDigitalizationApplicationForm(rowData.id); + break; + case (MTLB_STATUS_ASSIGNED): + displayReadDigitalizationSearchForm(rowData.id); + break; + case (MTLB_STATUS_NOT_ASSIGNED): + displayReadDigitalizationSearchForm(rowData.id); + break; + } + } + } + ) + return actions; +} + +export const filterData = (DefaultRows) => { + const newRows = []; + for (let i in DefaultRows) { + let row = DefaultRows[i]; + let date = row.birthdate + if ( date !== null) + row.birthdate = date[2] + '-' + date[1] + '-' + date[0]; + newRows.push(row); + } + return newRows; +} \ No newline at end of file diff --git a/src/main/js/lists/divorceRegistration/DivorceRegistrationListCommon.jsx b/src/main/js/lists/divorceRegistration/DivorceRegistrationListCommon.jsx new file mode 100644 index 0000000..4852f49 --- /dev/null +++ b/src/main/js/lists/divorceRegistration/DivorceRegistrationListCommon.jsx @@ -0,0 +1,151 @@ +import React from "react"; +import { getServiceUri } from "../../../../auto/js/metadata"; +import { MTLB_TYPE_DIVORCE } from "../../../../auto/js/metadata/MtlbType"; +import { UNION_MTLB_ORDER_BY_PARTNER1_FIRSTNAME } from "../../../../auto/js/metadata/UnionMtlbOrderBy"; +import { rest } from "../../../../auto/js/services"; +import { GeoDataComponent } from "../../../../auto/js/widgets/GeoDataComponent"; + + +export const divorceRegistrationListColumns = [ + { title: "unionRecordId", field: "unionRecordId" }, + { title: "dateOfEffect", field: "dateOfEffect" }, + { title: "dateOfOrder", field: "dateOfOrder" }, + +]; + +export const getData = async (filter) => { + let searchEndpoint = (filter.query) ? "union-mtlb/advanced-search" : "union-mtlb/search-by-union-mtlb-type-and-status/"; + return await rest.request(getServiceUri() + searchEndpoint, "POST", filter); +} + +export const countData = async (filter) => { + let countEndpoint = (filter.query) ? "union-mtlb/count/advanced-search" : "union-mtlb/count/search-by-union-mtlb-type-and-status/"; + return await rest.request(getServiceUri() + countEndpoint, "POST", filter); +} + +export const getOrderBy = () => { + return UNION_MTLB_ORDER_BY_PARTNER1_FIRSTNAME +} + +export const getMtlbTypeList = () => { + return [MTLB_TYPE_DIVORCE] +} + +export const filterData = (DefaultRows) => { + const newRows = []; + for (let i in DefaultRows) { + let row = DefaultRows[i]; + let effectDate = row.dateOfEffect + if (effectDate !== null) + row.dateOfEffect = effectDate[2] + '-' + effectDate[1] + '-' + effectDate[0]; + let orderDate = row.dateOfOrder + if (effectDate !== null) + row.dateOfOrder = orderDate[2] + '-' + orderDate[1] + '-' + orderDate[0]; + newRows.push(row); + } + return newRows; +} + +export const getErrorList = () => { + let list = []; + list.push("E32"); + return list; +} + +export const advancedSearchfields = [ + { name: "caseSensitiveSearch", label: "Case Sensitive Search", type: "checkbox", x: 1, y: 1, layout: "col-md-3" }, + { name: "partner1VitalRecordId", type: "number", x: 1, y: 2, layout: "col-md-6" }, + { name: "partner2VitalRecordId", type: "number", x: 2, y: 2, layout: "col-md-6" }, + { name: "partner1Firstname", type: "text", x: 1, y: 4, layout: "col-md-6" }, + { + name: "partner1FirstnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 4, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + { name: "partner1Surname", type: "text", x: 1, y: 3, layout: "col-md-6" }, + { + name: "partner1SurnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 3, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + { name: "partner2Firstname", type: "text", x: 1, y: 6, layout: "col-md-6" }, + { + name: "partner2FirstnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 6, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + { name: "partner2Surname", type: "text", x: 1, y: 5, layout: "col-md-6" }, + { + name: "partner2SurnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 5, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + + { + name: "divorceBox", label: "Effect Date", components: [ + { name: "rangedivorcedate", label: "exactdivorcedate", type: "checkbox", x: 1, y: 1, layout: "col-md-12" }, + { + name: "exactdivorcedate", type: "date", x: 1, y: 2, layout: "col-md-6", display: (data) => { + return !data.rangedivorcedate; + } + }, + + { + name: "divorcedateStart", type: "date", x: 1, y: 3, layout: "col-md-6", display: (data) => { + return data.rangedivorcedate; + } + }, + { + name: "divorcedateEnd", type: "date", x: 2, y: 3, layout: "col-md-6", display: (data) => { + return data.rangedivorcedate; + } + }, + ], type: "box", x: 1, y: 8, layout: "col-md-11 ms-2 mt-2 pt-1 pb-2" + }, +]; + +export const transformAdvancedSearchData = (formData) => { + const columns = []; + + const addColumn = (name, type, value, condition) => { + columns.push({ + name, + type, + [type === 'date' ? 'dateValue' : type === 'boolean' ? 'booleanValue' : (type === 'text' ? 'textValue' : 'longValue')]: value, + searchType: condition ? condition : null, + }); + }; + (formData.partner1VitalRecordId !== null && formData.partner1VitalRecordId !== "") && addColumn('partner1VitalRecordId', 'number', formData.partner1VitalRecordId, null); + (formData.partner2VitalRecordId !== null && formData.partner2VitalRecordId !== "") && addColumn('partner2VitalRecordId', 'number', formData.partner2VitalRecordId, null); + + (formData.partner1Firstname !== "") && addColumn('partner1Firstname', 'text', formData.partner1Firstname, formData.partner1FirstnameCondition); + + (formData.partner2Firstname !== "") && addColumn('partner1Firstname', 'text', formData.partner2Firstname, formData.partner2FirstnameCondition); + + (formData.partner1Surname !== "") && addColumn('partner1Surname', 'text', formData.partner1Surname, formData.partner1SurnameCondition); + + (formData.partner2Surname !== "") && addColumn('partner2Surname', 'text', formData.partner2Surname, formData.partner2SurnameCondition); + addColumn('mtlbType', 'number', 10, null); + addColumn('draft', 'boolean', false, null); + const divorcedateRange = formData.divorcedateStart && formData.divorcedateEnd + ? { + min: formData.divorcedateStart ? formData.divorcedateStart : null, + max: formData.divorcedateEnd ? formData.divorcedateEnd : null, + } + : null; + + (divorcedateRange != null || formData.exactdivorcedate != null) && addColumn('dateOfEffect', 'date', formData.exactdivorcedate, null); + if ((divorcedateRange != null || formData.exactdivorcedate != null)) + columns[columns.length - 1].dateRange = divorcedateRange; + + + return { columns, caseSensitiveSearch: formData.caseSensitiveSearch }; +}; \ No newline at end of file diff --git a/src/main/js/lists/familyTreeRegistration/FamilyTreeRegistrationListCommon.jsx b/src/main/js/lists/familyTreeRegistration/FamilyTreeRegistrationListCommon.jsx new file mode 100644 index 0000000..8229869 --- /dev/null +++ b/src/main/js/lists/familyTreeRegistration/FamilyTreeRegistrationListCommon.jsx @@ -0,0 +1,52 @@ +import React from "react"; +import { getServiceUri } from "../../../../auto/js/metadata"; +import { rest } from "../../../../auto/js/services"; +import { RVFOUR_BIRTH_MTLB_ORDER_BY_FIRSTNAME } from "../../../../auto/js/metadata/RvfourBirthMtlbOrderBy"; +import { MTLB_TYPE_RV4_BIRTH_FAMILY_TREE_RECORD, MTLB_TYPE_RV4_BIRTH_VITAL_RECORD } from "../../../../auto/js/metadata/MtlbType"; + +export const familyTreeRegistrationListColumns = [ + {title:"image", field:"image", render: rowData => {e.target.onerror = null; e.target.src="/public/avatar.png"}} style={{width: 40, borderRadius: '50%', height: 40}}/>}, + {title: "vitalRecordId", field: "vitalRecordId"}, + {title: "fourthname", field: "fourthname"}, + {title: "firstname", field: "firstname"}, + {title: "birthdate", field: "birthdate"}, + +]; + +export const getData = async (filter) => { + return await rest.request(getServiceUri() + "rvfour-birth-mtlb/search-by-mtlb-type-and-status/", "POST", filter); +} + +export const countData = async (filter) => { + return await rest.request(getServiceUri() + "rvfour-birth-mtlb/count/search-by-mtlb-type-and-status/", "POST", filter); +} + +export const getOrderBy = () => { + return RVFOUR_BIRTH_MTLB_ORDER_BY_FIRSTNAME +} + +export const getMtlbTypeList = () => { + return [MTLB_TYPE_RV4_BIRTH_FAMILY_TREE_RECORD] +} + +export const filterData = (DefaultRows) => { + const newRows = []; + for (let i in DefaultRows) { + let row = DefaultRows[i]; + let face = null; + if (row.face != null) { + let mimeType = row['faceMimeType']; + face = "data:".concat(mimeType, ";base64,", row.face); + } + row.image = (face != null)?face:"/public/avatar.png"; + let date = row.birthdate + if ( date !== null) + row.birthdate = date[2] + '-' + date[1] + '-' + date[0]; + newRows.push(row); + } + return newRows; +} + +export const getErrorList = () => { + return []; +} \ No newline at end of file diff --git a/src/main/js/lists/idCardApplication/IdCardApplicationListCommon.jsx b/src/main/js/lists/idCardApplication/IdCardApplicationListCommon.jsx new file mode 100644 index 0000000..71f1861 --- /dev/null +++ b/src/main/js/lists/idCardApplication/IdCardApplicationListCommon.jsx @@ -0,0 +1,121 @@ +import React from "react"; +import { getServiceUri } from "../../../../auto/js/metadata"; +import { ID_MTLB_ORDER_BY_VITAL_RECORD_ID } from "../../../../auto/js/metadata/IdMtlbOrderBy"; +import { MTLB_TYPE_ID_CARD } from "../../../../auto/js/metadata/MtlbType"; +import { rest, t } from "../../../../auto/js/services"; +import { Separator } from "../../forms/CivilRecordFormCommon"; + + +export const idCardApplicationListColumns = [ + { title: "image", field: "image", render: rowData => { e.target.onerror = null; e.target.src = "/public/avatar.png" }} style={{ width: 40, borderRadius: '50%', height: 40 }} /> }, + { title: "vitalRecordId", field: "vitalRecordId" }, + { title: "fourthname", field: "fourthname" }, + { title: "secondname", field: "secondname" }, + { title: "thirdname", field: "thirdname" }, + { title: "firstname", field: "firstname" }, + { title: "status", field: "status" }, +]; + +export const getData = async (filter) => { + let searchEndpoint = (filter.query) ? "id-mtlb/advanced-search" : "id-mtlb/search-by-id-mtlb-type-and-status/"; + return await rest.request(getServiceUri() + searchEndpoint, "POST", filter); +} + +export const countData = async (filter) => { + let countEndpoint = (filter.query) ? "id-mtlb/count/advanced-search" : "id-mtlb/count/search-by-id-mtlb-type-and-status/"; + return await rest.request(getServiceUri() + countEndpoint, "POST", filter); +} + +export const getOrderBy = () => { + return ID_MTLB_ORDER_BY_VITAL_RECORD_ID +} + +export const getMtlbTypeList = () => { + return [MTLB_TYPE_ID_CARD] +} + +export const filterData = (DefaultRows, token) => { + const newRows = []; + for (let i in DefaultRows) { + let row = DefaultRows[i]; + const imageUrl = getServiceUri() + 'id-mtlb/face/' + row.id + "/" + token; + row.image = (imageUrl != null) ? imageUrl : "/public/avatar.png"; + if (row.mtlbStatus != null) + row.status = t(row.mtlbStatus); + newRows.push(row); + } + return newRows; +} + +export const getErrorList = () => { + let list = []; + list.push("E19"); + list.push("E22"); + return list; +} + +export const advancedSearchfields = [ + { name: "caseSensitiveSearch", label: "Case Sensitive Search", type: "checkbox", x: 1, y: 1, layout: "col-md-3" }, + { name: "exactId", type: "number", x: 1, y: 2, layout: "col-md-4" }, + { name: "idSeparator", type: "custom", x: 1, y: 3, layout: "col-md-12", component: (name, disabled) => }, + + { name: "firstname", type: "text", x: 1, y: 6, layout: "col-md-6" }, + { + name: "firstnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 6, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + + { name: "secondname", type: "text", x: 1, y: 4, layout: "col-md-6" }, + { + name: "secondnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 4, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + + { name: "thirdname", type: "text", x: 1, y: 5, layout: "col-md-6" }, + { + name: "thirdnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 5, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + + { name: "fourthname", type: "text", x: 1, y: 3, layout: "col-md-6" }, + { + name: "fourthnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 3, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, +]; + +export const transformAdvancedSearchData = (formData) => { + const columns = []; + + const addColumn = (name, type, value, condition) => { + columns.push({ + name, + type, + [type === 'date' ? 'dateValue' : type === 'boolean' ? 'booleanValue' : (type === 'text' ? 'textValue' : 'longValue')]: value, + searchType: condition ? condition : null, + }); + }; + (formData.firstname !== "") && addColumn('firstname', 'text', formData.firstname, formData.firstnameCondition); + + (formData.secondname !== "") && addColumn('secondname', 'text', formData.secondname, formData.secondnameCondition); + + (formData.thirdname !== "") && addColumn('thirdname', 'text', formData.thirdname, formData.thirdnameCondition); + + (formData.fourthname !== "") && addColumn('fourthname', 'text', formData.fourthname, formData.fourthnameCondition); + addColumn('mtlbType', 'number', 1, null); + addColumn('draft', 'boolean', false, null); + (formData.exactId !== "") && addColumn('vitalRecordId', 'number', formData.exactId, null); + return { columns, caseSensitiveSearch: formData.caseSensitiveSearch }; +}; diff --git a/src/main/js/lists/marriageRegistration/MarriageRegistrationListCommon.jsx b/src/main/js/lists/marriageRegistration/MarriageRegistrationListCommon.jsx new file mode 100644 index 0000000..cffd42a --- /dev/null +++ b/src/main/js/lists/marriageRegistration/MarriageRegistrationListCommon.jsx @@ -0,0 +1,145 @@ +import React from "react"; +import { getServiceUri } from "../../../../auto/js/metadata"; +import { MTLB_TYPE_MARRIAGE } from "../../../../auto/js/metadata/MtlbType"; +import { UNION_MTLB_ORDER_BY_PARTNER1_FIRSTNAME } from "../../../../auto/js/metadata/UnionMtlbOrderBy"; +import { rest } from "../../../../auto/js/services"; + + +export const marriageRegistrationListColumns = [ + { title: "partner1VitalRecordId", field: "partner1VitalRecordId" }, + { title: "partner1Surname", field: "partner1Surname" }, + { title: "partner1Firstname", field: "partner1Firstname" }, + { title: "partner2VitalRecordId", field: "partner2VitalRecordId" }, + { title: "partner2Surname", field: "partner2Surname" }, + { title: "partner2Firstname", field: "partner2Firstname" }, + { title: "place", field: "place" }, +]; + + +export const getData = async (filter) => { + let searchEndpoint = (filter.query) ? "union-mtlb/advanced-search" : "union-mtlb/search-by-union-mtlb-type-and-status/"; + return await rest.request(getServiceUri() + searchEndpoint, "POST", filter); +} + +export const countData = async (filter) => { + let countEndpoint = (filter.query) ? "union-mtlb/count/advanced-search" : "union-mtlb/count/search-by-union-mtlb-type-and-status/"; + return await rest.request(getServiceUri() + countEndpoint, "POST", filter); +} + +export const getOrderBy = () => { + return UNION_MTLB_ORDER_BY_PARTNER1_FIRSTNAME +} + +export const getMtlbTypeList = () => { + return [MTLB_TYPE_MARRIAGE] +} + +export const filterData = (DefaultRows) => { + return DefaultRows; +} + +export const getErrorList = () => { + let list = []; + for (let i = 23; i < 32; i++) { + let code = "E" + i + list.push(code); + } + return list; +} + +export const advancedSearchfields = [ + { name: "caseSensitiveSearch", label: "Case Sensitive Search", type: "checkbox", x: 1, y: 1, layout: "col-md-3" }, + { name: "partner1VitalRecordId", type: "number", x: 1, y: 2, layout: "col-md-6" }, + { name: "partner2VitalRecordId", type: "number", x: 2, y: 2, layout: "col-md-6" }, + { name: "partner1Firstname", type: "text", x: 1, y: 4, layout: "col-md-6" }, + { + name: "partner1FirstnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 4, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + { name: "partner1Surname", type: "text", x: 1, y: 3, layout: "col-md-6" }, + { + name: "partner1SurnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 3, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + { name: "partner2Firstname", type: "text", x: 1, y: 6, layout: "col-md-6" }, + { + name: "partner2FirstnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 6, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + { name: "partner2Surname", type: "text", x: 1, y: 5, layout: "col-md-6" }, + { + name: "partner2SurnameCondition", options: [ + { "name": "fuzzy", "label": "Fuzzy" }, + { "name": "exact", "label": "Exact" }, + { "name": "startsWith", "label": "Startswith" }, + ], type: "radio", x: 2, y: 5, layout: "col-md-6 pt-5", defaultValue: "startsWith" + }, + + { + name: "marriageBox", label: "Effect Date", components: [ + { name: "rangemarriagedate", label: "exactmarriagedate", type: "checkbox", x: 1, y: 1, layout: "col-md-12" }, + { + name: "exactmarriagedate", type: "date", x: 1, y: 2, layout: "col-md-6", display: (data) => { + return !data.rangemarriagedate; + } + }, + + { + name: "marriagedateStart", type: "date", x: 1, y: 3, layout: "col-md-6", display: (data) => { + return data.rangemarriagedate; + } + }, + { + name: "marriagedateEnd", type: "date", x: 2, y: 3, layout: "col-md-6", display: (data) => { + return data.rangemarriagedate; + } + }, + ], type: "box", x: 1, y: 8, layout: "col-md-11 ms-2 mt-2 pt-1 pb-2" + }, +]; + +export const transformAdvancedSearchData = (formData) => { + const columns = []; + + const addColumn = (name, type, value, condition) => { + columns.push({ + name, + type, + [type === 'date' ? 'dateValue' : type === 'boolean' ? 'booleanValue' : (type === 'text' ? 'textValue' : 'longValue')]: value, + searchType: condition ? condition : null, + }); + }; + (formData.partner1VitalRecordId !== null && formData.partner1VitalRecordId !== "") && addColumn('partner1VitalRecordId', 'number', formData.partner1VitalRecordId, null); + (formData.partner2VitalRecordId !== null && formData.partner2VitalRecordId !== "") && addColumn('partner2VitalRecordId', 'number', formData.partner2VitalRecordId, null); + + (formData.partner1Firstname !== "") && addColumn('partner1Firstname', 'text', formData.partner1Firstname, formData.partner1FirstnameCondition); + + (formData.partner2Firstname !== "") && addColumn('partner1Firstname', 'text', formData.partner2Firstname, formData.partner2FirstnameCondition); + + (formData.partner1Surname !== "") && addColumn('partner1Surname', 'text', formData.partner1Surname, formData.partner1SurnameCondition); + + (formData.partner2Surname !== "") && addColumn('partner2Surname', 'text', formData.partner2Surname, formData.partner2SurnameCondition); + addColumn('mtlbType', 'number', 9, null); + addColumn('draft', 'boolean', false, null); + const marriagedateRange = formData.marriagedateStart && formData.marriagedateEnd + ? { + min: formData.marriagedateStart ? formData.marriagedateStart : null, + max: formData.marriagedateEnd ? formData.marriagedateEnd : null, + } + : null; + + (marriagedateRange != null || formData.exactmarriagedate != null) && addColumn('declaredDate', 'date', formData.exactmarriagedate, null); + if ((marriagedateRange != null || formData.exactmarriagedate != null)) + columns[columns.length - 1].dateRange = marriagedateRange; + + return { columns, caseSensitiveSearch: formData.caseSensitiveSearch }; +}; \ No newline at end of file diff --git a/src/main/js/metadata/CustomMetadata.jsx b/src/main/js/metadata/CustomMetadata.jsx new file mode 100644 index 0000000..f9fc915 --- /dev/null +++ b/src/main/js/metadata/CustomMetadata.jsx @@ -0,0 +1,34 @@ +export const formComponentFields = { + 'vital-record' : [ + {name:"id", type:"number"}, + {name:"face", type:"image"}, + {name: "firstname", type: "text" }, + {name: "secondname", type: "text" }, + {name: "thirdname", type: "text" }, + {name: "fourthname", type: "text" }, + {name: "gender", type: "number" }, + {name: "maritalStatus", type: "number" }, + {name: "birthdate", type: "date" }, + {name: "birthDayUnknown", type: "checkbox" }, + {name: "birthMonthUnknown", type: "checkbox" }, + {name: "birthYearUnknown", type: "checkbox" }, + {name: "voter", type: "checkbox" }, + {name: "reportedFatherName", type: "text" }, + {name: "reportedMotherName", type: "text" }, + {name: "notes", type: "text" } + ] +} + +export const entityImageUrl = { + "vital-record": "face/find-latest-image-by-max-vital-record-id/", + "civil-status-mtlb": "" +} + +export const fieldsLayout = { + "vital-record" : { + "col-md-12": + ["notes","id", "face", "birthdate", "birthDayUnknown", "birthMonthUnknown", "birthYearUnknown", "voter"], + "col-md-6": + ["reportedMotherName","maritalStatus", "firstname", "secondname", "thirdname", "fourthname", "gender", "reportedFatherName"] + } +} \ No newline at end of file diff --git a/src/main/js/pages/SpreadSheetData.jsx b/src/main/js/pages/SpreadSheetData.jsx new file mode 100644 index 0000000..2d43122 --- /dev/null +++ b/src/main/js/pages/SpreadSheetData.jsx @@ -0,0 +1,43 @@ +import React from "react"; +//import { getRowsCount } from "../../../auto/js/events"; +import { getEntityIdCol, getServiceUri } from "../../../auto/js/metadata"; +import { rest } from "../../../auto/js/services"; +import { entityImageUrl } from "../metadata/CustomMetadata"; + +export const getSpreadSheetData = async (subsection, filter) => { + switch(subsection) { + case "vital-record": + let data; + let rowsCount; + return await getVitalRecordData(filter).then(response => { + data = filterData(response, "vital-record"); + rowsCount = response.length; + }).then(() => {return {data:data, rowsCount:rowsCount}}); + case "civil-status-mtlb": + let civiltStatusData; + let civiltStatusRowsCount; + console.log(filter); + return await getCivilStatusMtlbData(filter).then(response => { + civiltStatusData = filterData(response, "civil-status-mtlb"); + civiltStatusRowsCount = response.length; + }).then(() => {return {data:civiltStatusData, rowsCount:civiltStatusRowsCount}}); + } +} + +const filterData = (DefaultRows, subsection) => { + const newRows = []; + for (let i in DefaultRows) { + let row = DefaultRows[i]; + row.imageUrl = getServiceUri() + entityImageUrl[subsection] + row[getEntityIdCol(subsection)]; + let date = row.birthdate + if ( date !== null) + row.birthdate = date[2] + '-' + date[1] + '-' + date[0]; + newRows.push(row); + } + return newRows; +} + +const getVitalRecordData = async (filter) => { + return await rest.search("vital-record", filter) + +} \ No newline at end of file diff --git a/src/main/js/pages/Welcome.jsx b/src/main/js/pages/Welcome.jsx new file mode 100644 index 0000000..7475a6b --- /dev/null +++ b/src/main/js/pages/Welcome.jsx @@ -0,0 +1,16 @@ +import React from "react"; +import { t } from "../../../auto/js/services"; +export class Welcome extends React.Component { + constructor(props) { + super(props); + } + + render() { + return ( + <> +

{t`Welcome`}

+ welcome image + + ); + } +} \ No newline at end of file diff --git a/src/main/js/pages/form.css b/src/main/js/pages/form.css new file mode 100644 index 0000000..d9aaacd --- /dev/null +++ b/src/main/js/pages/form.css @@ -0,0 +1,323 @@ +body { + overflow: hidden; + } +:root { + --gray-900: #1a202c; + --gray-800: #2d3748; + --gray-700: #4a5568; + --gray-600: #718096; + --gray-500: #a0aec0; + --gray-400: #cbd5e0; + --gray-300: #e2e8f0; + --gray-200: #edf2f7; + --gray-100: #f7fafc; + --red-100: #fff5f5; + --red-200: #fed7d7; + --red-300: #feb2b2; + --red-400: #fc8181; + --red-500: #f56565; + --red-600: #e53e3e; + --red-700: #c53030; + --red-800: #9b2c2c; + --red-900: #742a2a; + --blue-100: #ebf8ff; + --blue-200: #bee3f8; + --blue-300: #90cdf4; + --blue-400: #63b3ed; + --blue-500: #4299e1; + --blue-600: #3182ce; + --blue-700: #2b6cb0; + --blue-800: #2c5282; + --blue-900: #2a4365; + --white: white; + --red: #f56565; + --text-decoration-color: var(--gray-400); + --text-color: var(--gray-800); + --focus-ring-color: var(--blue-500); +} + + +.date-form { + width: 100%; + padding: 0.65rem 0.5rem; + margin-bottom: 1rem; + font-size: 1rem; + border: 2px solid var(--gray-200); + background-color: var(--gray-100); + color: var(--gray-800); + border-radius: 10px; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; +} + +.select { + width: 40%; + padding: 0.65rem 0.5rem; + margin-bottom: 1rem; + font-size: 1rem; + border: 2px solid var(--gray-200); + background-color: var(--gray-100); + color: var(--gray-800); + border-radius: 10px; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; +} + +label.checkbox { + font-weight: normal; +} + +button[type="submit"] { + margin: 13rem; + margin-top: 1rem; + padding: 0.5rem 1.25rem; + font-size: 1rem; + border-radius: 10px; + background-color: var(--gray-700); + border: 2px solid var(--gray-700); + color: white; + text-decoration: none; + font-weight: bold; + margin-bottom: 1rem; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + display: flex; + line-height: initial; + transition: background-color 200ms ease-in-out, border 200ms ease-in-out, + transform 200ms ease-in-out; + -webkit-touch-callout: none; + -webkit-user-select: none; + user-select: none; +} +button[type="cancel"] { + margin: 13rem; + margin-top: 1rem; + padding: 0.5rem 1.25rem; + font-size: 1rem; + border-radius: 10px; + background-color: var(--gray-700); + border: 2px solid var(--gray-700); + color: white; + text-decoration: none; + font-weight: bold; + margin-bottom: 1rem; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + display: flex; + line-height: initial; + transition: background-color 200ms ease-in-out, border 200ms ease-in-out, + transform 200ms ease-in-out; + -webkit-touch-callout: none; + -webkit-user-select: none; + user-select: none; +} + +select { + margin: 0; + -webkit-appearance: none; + box-sizing: border-box; + padding: 0.65rem 0.5rem; + font-size: 1rem; + border: 2px solid var(--gray-200); + border-radius: 10px; + color: var(--gray-700); + height: auto; + background-color: var(--gray-100); + background-image: url('data:image/svg+xml;utf8,'); + background-repeat: no-repeat; + background-size: 1rem; + background-position: center right 0.5rem; +} + +@media (prefers-color-scheme: dark) { + select { + background-color: var(--gray-800); + background-image: url('data:image/svg+xml;utf8,'); + border-color: var(--gray-700); + color: white; + } +} + +@media (hover: hover) { + input[type="submit"]:hover, + input[type="reset"]:hover, + input[type="button"]:hover, + button:hover { + cursor: pointer; + background-color: var(--gray-800); + } +} + +@media (hover: hover) and (prefers-color-scheme: dark) { + input[type="submit"]:hover, + input[type="reset"]:hover, + input[type="button"]:hover, + button:hover { + cursor: pointer; + background-color: var(--gray-300); + } +} + +button:focus-visible, +input[type="submit"]:focus-visible, +input[type="reset"]:focus-visible, +input[type="button"]:focus-visible { + border-color: var(--focus-ring-color); + outline: none; +} + +.react-contextmenu { + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; + font-size: 16px; + color: #373a3c; + text-align: left; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 0.25rem; + outline: none; + opacity: 0; + pointer-events: none; + transition: opacity 250ms ease !important; +} + +.react-contextmenu.react-contextmenu--visible { + opacity: 1; + pointer-events: auto; +} + +.react-contextmenu-item { + padding: 3px 20px; + font-weight: 400; + line-height: 1.5; + color: #373a3c; + text-align: inherit; + white-space: nowrap; + background: 0 0; + border: 0; + cursor: pointer; +} + +.react-contextmenu-item.react-contextmenu-item--active, +.react-contextmenu-item.react-contextmenu-item--selected { + color: #fff; + background-color: #20a0ff; + border-color: #20a0ff; + text-decoration: none; +} + +.react-contextmenu-item.react-contextmenu-item--disabled, +.react-contextmenu-item.react-contextmenu-item--disabled:hover { + color: #878a8c; + background-color: transparent; + border-color: rgba(0, 0, 0, 0.15); +} + +.react-contextmenu-item--divider { + margin-bottom: 3px; + padding: 2px 0; + border-bottom: 1px solid rgba(0, 0, 0, 0.15); + cursor: inherit; +} +.react-contextmenu-item--divider:hover { + background-color: transparent; + border-color: rgba(0, 0, 0, 0.15); +} + +.react-contextmenu-item.react-contextmenu-submenu { + padding: 0; +} + +.react-contextmenu-item.react-contextmenu-submenu > .react-contextmenu-item { +} + +.react-contextmenu-item.react-contextmenu-submenu + > .react-contextmenu-item:after { + content: "▶"; + display: inline-block; + position: absolute; + right: 7px; +} + +.example-multiple-targets::after { + content: attr(data-count); + display: block; +} + +.col-md-6{ + margin-top: 3px; + margin-bottom: 3px; + max-width: 100% !important; +} + +.MuiInputLabel-formControl{ + left: 40%!important; + position: static !important; +} +.MuiFormControl-marginNormal { + margin-top: 0px !important; + margin-bottom: 0px !important; +} +.MuiSelect-select{ + text-align: justify; + min-width: 14.4rem!important; +} +.MuiInputBase-inputMultiline{ + min-width: 16rem!important; +} +.ValidationError{ + color: red; + position: relative; + left: 32%; +} + +.MuiTypography-colorInherit { + top: 20%; + position: absolute; +} + +.MuiChip-root { + padding: 12px!important; +} +.MuiSlider-root { + width: 250px!important; +} +.center { + display: block; + margin-left: auto; + margin-right: auto; +} +.fine-uploader-dropzone-container.react-fine-uploader-gallery-dropzone { + margin-bottom: 30px !important; +} +.column { + float: left; + width: 50%; + padding: 10px; +} +.left { + width: 75%; +} + +.right { + width: 25%; +} + +label + .MuiInput-formControl { + margin-top: 0 !important; +} + +.MuiFormControl-root { + margin-top: 20px !important; +} + +.MuiFormControlLabel-root { + margin-top: 20px !important; + margin-bottom: 0 !important; +} \ No newline at end of file diff --git a/src/main/js/pages/printable.css b/src/main/js/pages/printable.css new file mode 100644 index 0000000..faae0f3 --- /dev/null +++ b/src/main/js/pages/printable.css @@ -0,0 +1,22 @@ +@media screen { + .printable-area { + display: none; + } +} + + +.printable-list table, .printable-list th, .printable-list td { + border:1px solid rgb(180, 178, 178); +} + +dd { + display: block; + margin-left: 40px; + font-size: 1rem; +} +p, dt { + font-weight: normal; + font-size: 1rem; + height:fit-content; + -webkit-line-clamp: inherit; +} \ No newline at end of file diff --git a/src/main/js/router/Menu.jsx b/src/main/js/router/Menu.jsx new file mode 100644 index 0000000..a937c4e --- /dev/null +++ b/src/main/js/router/Menu.jsx @@ -0,0 +1,286 @@ +import { displayNewBirthRegistrationForm } from '../../../auto/js/forms/birthRegistration/NewBirthRegistrationForm' +import { displayCivilRecordAdvancedSearch, displayCivilRecordsList } from '../../../auto/js/lists/CivilRecordList' +import { displayNewOccupationForm } from '../../../auto/js/forms/metadata/OccupationForm' +import { displayNewTranslationsForm } from '../../../auto/js/forms/metadata/TranslationsForm' +import { displayNewCountryForm } from '../../../auto/js/forms/metadata/CountryForm' +import { displayCountriesList } from '../../../auto/js/lists/metadata/CountriesList' +import { displayOccupationList } from '../../../auto/js/lists/metadata/OccupationList' +import { displayTranslationsList } from '../../../auto/js/lists/metadata/TranslationsList' +import { displayNewDeathRegistrationForm } from '../../../auto/js/forms/deathRegistration/NewDeathRegistrationForm' +import { displayDeathRecordAdvancedSearch, displayDeathRecordList } from '../../../auto/js/lists/DeathRecordList' +import { displayNewMarriageRegistrationForm } from '../../../auto/js/forms/marriageRegistration/NewMarriageRegistrationForm' +import { displayNewDivorceRegistrationForm } from '../../../auto/js/forms/divorceRegistration/NewDivorceRegistrationForm' +import { displayUnionRecordAdvancedSearch, displayUnionRecordList } from '../../../auto/js/lists/UnionRecordList' +import { whoami } from '../../../auto/js/users/UserInfo'; +import { displayBirthRegistrationAdvancedSearch, displayBirthRegistrationList } from '../../../auto/js/lists/birthRegistration/BirthRegistrationList' +import { displayAmendmentApplicationList, displayAmendmentApplicationAdvancedSearch } from '../../../auto/js/lists/amendmentApplication/AmendmentApplicationList' +import { displayDeathRegistrationAdvancedSearch, displayDeathRegistrationList } from '../../../auto/js/lists/deathRegistration/DeathRegistrationList' +import { displayIdCardApplicationAdvancedSearch, displayIdCardApplicationList } from '../../../auto/js/lists/idCardApplication/IdCardApplicationList' +import { displayMarriageRegistrationAdvancedSearch, displayMarriageRegistrationList } from '../../../auto/js/lists/marriageRegistration/MarriageRegistrationList' +import { displayDivorceRegistrationAdvancedSearch, displayDivorceRegistrationList } from '../../../auto/js/lists/divorceRegistration/DivorceRegistrationList' +import { displayDigitalizationApplicationList } from '../../../auto/js/lists/digitalization/DigitalizationApplicationList' +import { displayFamilyTreeRegistrationList } from '../../../auto/js/lists/familyTreeRegistration/FamilyTreeRegistrationList' +import { displayIdCardAdvancedSearch, displayIdCardList } from '../../../auto/js/lists/IssuedIdCardList' +import { displayLocationList } from '../../../auto/js/lists/metadata/LocationList' +import { displayProvinceList } from '../../../auto/js/lists/metadata/ProvinceList' +import { displayNewProvinceForm } from '../../../auto/js/forms/metadata/ProvinceForm' +import { displayZoneList } from '../../../auto/js/lists/metadata/ZoneList' +import { displayNewZoneForm } from '../../../auto/js/forms/metadata/ZoneForm' +import { displayDistrictList } from '../../../auto/js/lists/metadata/DistrictList' +import { displayNewDistrictForm } from '../../../auto/js/forms/metadata/DistrictForm' +import { displayIslandList } from '../../../auto/js/lists/metadata/IslandList' +import { displayNewIslandForm } from '../../../auto/js/forms/metadata/IslandForm' +import { displayNewLocationForm } from '../../../auto/js/forms/metadata/LocationForm' +import { applyForGeneralStatisticsReport } from '../GeneralStatistics' +import { displayGeneralStatisticsList } from '../lists/ReportingList' +import { displayTemporaryCertificateWorkflow } from '../forms/TemporaryCertificateManager' +import { displayAdoptionApplicationAdvancedSearch, displayAdoptionApplicationList } from '../../../auto/js/lists/adoptionApplication/AdoptionApplicationList' +import { displayAmendmentDeathApplicationAdvancedSearch, displayAmendmentDeathApplicationList } from '../../../auto/js/lists/amendmentDeathApplication/AmendmentDeathApplicationList' +import { displayAmendmentUnionApplicationAdvancedSearch, displayAmendmentUnionApplicationList } from '../../../auto/js/lists/amendmentUnionApplication/AmendmentUnionApplicationList' +import { displayCountryList } from '../../../auto/js/lists/metadata/CountryList' +import { OPEN_CONFIRMATION_DIALOG } from '../../../auto/js/events/Gui' +export const menu = () => { + return { + ...((whoami().roles.includes('ALL') || whoami().roles.includes('REGISTRAR')) && { + "civil-records": { + submenu: { + "birth-applications": { + options: { + new: { label: "New", do: (gui) => displayTemporaryCertificateWorkflow(gui) }, + // temporaryCertificate: { label: "Temporary Certificate", do: (gui) => displayTemporaryCertificateWorkflow(gui) }, + applications: { label: "Applications", do: (gui) => displayBirthRegistrationList(gui) }, + advancedSearch: { label: "Advanced Search", do: (gui) => displayBirthRegistrationAdvancedSearch(gui) }, + }, + label: "Birth Applications" + }, + "amendment-application": { + options: { + applications: { label: "Applications", do: (gui) => displayAmendmentApplicationList(gui) }, + advancedSearch: { label: "Advanced Search", do: (gui) => displayAmendmentApplicationAdvancedSearch(gui) } + }, + label: "Amendments" + }, + "adoption-application": { + options: { + applications: { label: "Applications", do: (gui) => displayAdoptionApplicationList(gui) }, + advancedSearch: { label: "Advanced Search", do: (gui) => displayAdoptionApplicationAdvancedSearch(gui) } + }, + label: "Adoptions" + }, + "birth-registry": { + options: { + search: { label: "Records", do: (gui) => displayCivilRecordsList(gui) }, + advancedSearch: { label: "Advanced Search", do: (gui) => displayCivilRecordAdvancedSearch(gui) } + }, + label: "Birth Registry" + } + }, + label: "Birth" + }, + "marriage-records": { + submenu: { + "marriage-registration": { + options: { + new: { label: "New", do: (gui) => (displayNewMarriageRegistrationForm(gui)) }, + applications: { label: "Applications", do: (gui) => displayMarriageRegistrationList(gui) }, + advancedSearch: { label: "Advanced Search", do: (gui) => displayMarriageRegistrationAdvancedSearch(gui) } + }, + label: "Marriage Registration" + }, + "divorce-registration": { + options: { + applications: { label: "Applications", do: (gui) => displayDivorceRegistrationList(gui) }, + advancedSearch: { label: "Advanced Search", do: (gui) => displayDivorceRegistrationAdvancedSearch(gui) } + + }, + label: "Divorce Registration" + }, + "union-amendment": { + options: { + applications: { label: "Applications", do: (gui) => displayAmendmentUnionApplicationList(gui) }, + advancedSearch: { label: "Advanced Search", do: (gui) => displayAmendmentUnionApplicationAdvancedSearch(gui) } + + }, + label: "Amendments" + }, + "records": { + options: { + search: { label: "Records", do: (gui) => displayUnionRecordList(gui) }, + advancedSearch: { label: "Advanced Search", do: (gui) => displayUnionRecordAdvancedSearch(gui) } + + }, + label: "Registry" + } + }, + label: "Marriage & Divorces" + }, + "death-records": { + submenu: { + "death-registration": { + options: { + new: { label: "New", do: (gui) => (displayNewDeathRegistrationForm(gui, undefined, () => displayDeathRegistrationList(gui))) }, + applications: { label: "Applications", do: (gui) => displayDeathRegistrationList(gui) }, + advancedSearch: { label: "Advanced Search", do: (gui) => displayDeathRegistrationAdvancedSearch(gui) } + + }, + label: "Death Applications" + }, + "death-amendment": { + options: { + applications: { label: "Applications", do: (gui) => displayAmendmentDeathApplicationList(gui) }, + advancedSearch: { label: "Advanced Search", do: (gui) => displayAmendmentDeathApplicationAdvancedSearch(gui) } + + }, + label: "Amendments" + }, + "death-registry": { + options: { + search: { label: "Records", do: (gui) => displayDeathRecordList(gui) }, + advancedSearch: { label: "Advanced Search", do: (gui) => displayDeathRecordAdvancedSearch(gui) } + }, + label: "Death Registry" + } + }, + label: "Death" + }, + "id-database": { + submenu: { + "id-cards": { + options: { + applications: { label: "Applications", do: (gui) => displayIdCardApplicationList(gui) }, + advancedSearch: { label: "Advanced Search", do: (gui) => displayIdCardApplicationAdvancedSearch(gui) } + }, + label: "ID Card Applications" + }, + other: { + options: { + search: { label: "Issued Documents", do: (gui) => displayIdCardList(gui) }, + advancedSearch: { label: "Advanced Search", do: (gui) => displayIdCardAdvancedSearch(gui) } + } + } + }, + label: "ID Cards" + } + }), + ...((whoami().roles.includes('ALL') || whoami().roles.includes('DIGITALIZER') || whoami().roles.includes('REGISTRAR')) && { + "digitalization": { + submenu: { + "digitalization": { + options: { + "digitalization-forms": { label: "Digitalization Forms", do: (gui) => displayDigitalizationApplicationList(gui) } + } + } + }, + label: "Digitalization" + } + }), + ...((whoami().roles.includes('ALL') || whoami().roles.includes('MAINTENANCE')) && { + "crvs-admin": { + submenu: { + "occupations": { + options: { + list: { label: "Occupations", do: (gui) => displayOccupationList(gui) }, + new: { label: "New", do: (gui) => gui.goTo(displayNewOccupationForm()) }, + }, + label: "Occupations" + }, + "countries": { + options: { + list: { label: "Countries", do: (gui) => displayCountriesList(gui) }, + new: { label: "New", do: (gui) => gui.goTo(displayNewCountryForm(() => displayConfirmationDialog({ displayListFunc: displayCountriesList, message: "New Country submitted." }, gui))) }, + }, + label: "Countries" + }, + "translations": { + options: { + list: { label: "Translations", do: (gui) => displayTranslationsList(gui) }, + new: { label: "New", do: (gui) => displayNewTranslationsForm(gui) }, + }, + label: "Translations" + }, + }, + label: "Configuration" + } + }), + ...((whoami().roles.includes('ALL') || whoami().roles.includes('MAINTENANCE')) && { + "geography": { + submenu: { + "province": { + options: { + list: { label: "Province List", do: (gui) => displayProvinceList(gui) }, + new: { label: "New", do: (gui) => gui.goTo(displayNewProvinceForm(() => displayConfirmationDialog({ displayListFunc: displayProvinceList, message: "New Province submitted." }, gui))) }, + }, + label: "Province" + }, + "zone": { + options: { + list: { label: "Zone List", do: (gui) => displayZoneList(gui) }, + new: { label: "New", do: (gui) => gui.goTo(displayNewZoneForm(() => displayConfirmationDialog({ displayListFunc: displayZoneList, message: "New Zone submitted." }, gui))) }, + }, + label: "Zone" + }, + "district": { + options: { + list: { label: "District List", do: (gui) => displayDistrictList(gui) }, + new: { label: "New", do: (gui) => gui.goTo(displayNewDistrictForm(() => displayConfirmationDialog({ displayListFunc: displayDistrictList, message: "New District submitted." }, gui))) }, + }, + label: "District" + }, + "island": { + options: { + list: { label: "Island List", do: (gui) => displayIslandList(gui) }, + new: { label: "New", do: (gui) => gui.goTo(displayNewIslandForm(() => displayConfirmationDialog({ displayListFunc: displayIslandList, message: "New Island submitted." }, gui))) }, + }, + label: "Island" + }, + "location": { + options: { + list: { label: "Location List", do: (gui) => displayLocationList(gui) }, + new: { label: "New", do: (gui) => gui.goTo(displayNewLocationForm(() => displayConfirmationDialog({ displayListFunc: displayLocationList, message: "New Location submitted." }, gui))) }, + }, + label: "Location" + }, + }, + label: "Geography" + } + }), + ...((whoami().roles.includes('ALL') || whoami().roles.includes('REGISTRAR')) && { + "rv4": { + submenu: { + "rv4": { + options: { + searchFamilyTree: { label: "Family Tree Applications", do: (gui) => displayFamilyTreeRegistrationList(gui) } + }, + label: "Rv4 Applications" + } + }, + label: "Rv4" + } + }), + ...((whoami().roles.includes('ALL') || whoami().roles.includes('REGISTRAR')) && { + "reports": { + submenu: { + "report-applications": { + options: { + apply: { label: "Narrative Reports", do: (gui) => displayGeneralStatisticsList(gui) } + }, + label: "General Statistics" + }, + "actions": { + options: { + apply: { label: "Request Narrative Reports", do: (gui) => applyForGeneralStatisticsReport(gui) } + }, + label: "Actions" + } + }, + label: "Reports" + } + }) + + } +} + +export const displayConfirmationDialog = (options, gui) => { + let data = { title: "Confirmation", message: options.message, onClick: () => gui.goTo(options.displayListFunc(gui)) }; + OPEN_CONFIRMATION_DIALOG.publish(data); +} diff --git a/src/main/js/tasks/ApproveApplicationTask.jsx b/src/main/js/tasks/ApproveApplicationTask.jsx new file mode 100644 index 0000000..e97a34b --- /dev/null +++ b/src/main/js/tasks/ApproveApplicationTask.jsx @@ -0,0 +1,14 @@ +import { formState } from "../../../auto/js/forms/FormState"; +import { displayReadReadyBirthRegistrationForm } from "../../../auto/js/forms/birthRegistration/ReadyBirthRegistrationForm"; +import { Task } from "./Task"; + +export class ApproveApplicationTask extends Task { + constructor(id, name, gui) { + super(id, name, gui); + } + + start = (onFinishCallback) => { + this.onFinishCallback = onFinishCallback; + this.gui.goTo(displayReadReadyBirthRegistrationForm(this.complete), formState.getState().civilStatusMtlbId, null) + } +} \ No newline at end of file diff --git a/src/main/js/tasks/BirthApplicationTask.jsx b/src/main/js/tasks/BirthApplicationTask.jsx new file mode 100644 index 0000000..6cd8231 --- /dev/null +++ b/src/main/js/tasks/BirthApplicationTask.jsx @@ -0,0 +1,21 @@ +import { formState } from "../../../auto/js/forms/FormState"; +import { saveBirthRegistrationForm } from "../../../auto/js/forms/birthRegistration/BirthRegistrationApi"; +import { readNewBirthRegistrationForm } from "../../../auto/js/forms/birthRegistration/NewBirthRegistrationForm"; +import { buildBirthRegistrationFormEmptyObject } from "../forms/birthRegistration/BirthRegistrationFormCommon"; +import { Task } from "./Task"; + +export class BirthApplicationTask extends Task { + constructor(id, name, gui) { + super(id, name, gui); + } + + start = (onFinishCallback) => { + this.onFinishCallback = onFinishCallback; + let data = buildBirthRegistrationFormEmptyObject(); + data.draft = true; + saveBirthRegistrationForm(data).then((response) => { + formState.addState('civilStatusMtlbId', response); + this.gui.goTo(readNewBirthRegistrationForm(this.complete), response, null) + }) + } +} \ No newline at end of file diff --git a/src/main/js/tasks/DeathApplication.jsx b/src/main/js/tasks/DeathApplication.jsx new file mode 100644 index 0000000..be3eebb --- /dev/null +++ b/src/main/js/tasks/DeathApplication.jsx @@ -0,0 +1,7 @@ +import React from 'react'; +import { displayNewDeathRegistrationForm } from '../../../auto/js/forms/deathRegistration/NewDeathRegistrationForm'; + + +export const process = (manager) => { + displayNewDeathRegistrationForm(manager.gui, manager.args, manager.complete); +} \ No newline at end of file diff --git a/src/main/js/tasks/DeathApplicationRegistration.jsx b/src/main/js/tasks/DeathApplicationRegistration.jsx new file mode 100644 index 0000000..0e97f07 --- /dev/null +++ b/src/main/js/tasks/DeathApplicationRegistration.jsx @@ -0,0 +1,87 @@ +import React from 'react'; +import {v4 as uuidv4} from 'uuid'; +import { Centrifuge } from "centrifuge"; +import { formState } from "../../../auto/js/forms/FormState"; +import { MTLB_STATUS_ARCHIVED, MTLB_STATUS_READY_FOR_APPROVAL } from "../../../auto/js/metadata/MtlbStatus"; +import { rest } from "../../../auto/js/services"; +import { loadingIcon } from "../../../auto/js/loadingIcon"; +import { getServiceUri } from "../../../auto/js/metadata"; + + +export const process = (manager) => { + manager.gui.goTo(displayServerRegistrationLoading(manager.complete), formState.getState().civilStatusMtlbId, null); +} + +const displayServerRegistrationLoading = (onFinish) => (id) => { + let uuid = uuidv4(); + return { + uuid, view: () => onFinish()}/> + } +} + +export class LoadingComponent extends React.Component { + constructor(props) { + super(props) + this.state = { + status: MTLB_STATUS_READY_FOR_APPROVAL, + } + + this.centrifuge = new Centrifuge("wss://rv5.gov.vu/connection/websocket", { + token: rest.oidcService.token, + getToken: function () { + return new Promise((resolve, reject) => { + rest.oidcService.updateToken(55).then(function () { + resolve(rest.oidcService.token); + }).catch(function (err) { + reject(err); + rest.oidcService.logout(); + }); + }) + } + }); + + this.centrifuge.connect(); + this.sub = this.centrifuge.newSubscription("1." + props.id); + } + + componentDidMount() { + this.getServiceStatus(); + } + + componentWillUnmount() { + if (this.interval) { + clearInterval(this.interval); + } + } + + getServiceStatus = () => { + this.interval = setInterval(() => { + let filter = {}; + filter.type = 1; + filter.id = this.props.id + rest.request(getServiceUri() + 'apply/get-service-status', 'POST', filter).then(response => { + if (response.serviceStatus === MTLB_STATUS_ARCHIVED) { + this.sub.off('publication', this.handleStatusChange); + this.props.onFinish() + clearInterval(this.interval); + } + }) + }, 3000) + }; + + handleStatusChange = (ctx) => { + if (ctx.data.value.key === "status") { + this.setState({status: ctx.data.value.value}); + if (ctx.data.value.value === MTLB_STATUS_ARCHIVED) { + this.sub.off('publication', this.handleStatusChange); + this.props.onFinish() + } + } + } + + render() { + this.sub.on('publication', this.handleStatusChange).subscribe(); + return loadingIcon; + } + +} \ No newline at end of file diff --git a/src/main/js/tasks/DeathApproveApplication.jsx b/src/main/js/tasks/DeathApproveApplication.jsx new file mode 100644 index 0000000..a1bba1a --- /dev/null +++ b/src/main/js/tasks/DeathApproveApplication.jsx @@ -0,0 +1,8 @@ +import React from 'react'; +import { formState } from '../../../auto/js/forms/FormState'; +import { displayReadReadyDeathRegistrationForm } from '../../../auto/js/forms/deathRegistration/ReadyDeathRegistrationForm'; + + +export const process = (manager) => { + manager.gui.goTo(displayReadReadyDeathRegistrationForm(manager.complete), formState.getState().civilStatusMtlbId, null) +} \ No newline at end of file diff --git a/src/main/js/tasks/DeathServerApproval.jsx b/src/main/js/tasks/DeathServerApproval.jsx new file mode 100644 index 0000000..3f6075c --- /dev/null +++ b/src/main/js/tasks/DeathServerApproval.jsx @@ -0,0 +1,88 @@ +import React from 'react'; +import {v4 as uuidv4} from 'uuid'; +import { Centrifuge } from "centrifuge"; +import { formState } from "../../../auto/js/forms/FormState"; +import { MTLB_STATUS_READY_FOR_APPROVAL, MTLB_STATUS_SUBMITTED } from "../../../auto/js/metadata/MtlbStatus"; +import { rest } from "../../../auto/js/services"; +import { loadingIcon } from "../../../auto/js/loadingIcon"; +import { getServiceUri } from "../../../auto/js/metadata"; + + +export const process = (manager) => { + + manager.gui.goTo(displayServerApprovalLoading(manager.complete), formState.getState().civilStatusMtlbId, null); +} + +const displayServerApprovalLoading = (onFinish) => (id) => { + let uuid = uuidv4(); + return { + uuid, view: () => onFinish()}/> + } +} + +export class LoadingComponent extends React.Component { + constructor(props) { + super(props) + this.state = { + status: MTLB_STATUS_SUBMITTED, + } + + this.centrifuge = new Centrifuge("wss://rv5.gov.vu/connection/websocket", { + token: rest.oidcService.token, + getToken: function () { + return new Promise((resolve, reject) => { + rest.oidcService.updateToken(55).then(function () { + resolve(rest.oidcService.token); + }).catch(function (err) { + reject(err); + rest.oidcService.logout(); + }); + }) + } + }); + + this.centrifuge.connect(); + this.sub = this.centrifuge.newSubscription("1." + props.id); + } + + componentDidMount() { + this.getServiceStatus(); + } + + componentWillUnmount() { + if (this.interval) { + clearInterval(this.interval); + } + } + + getServiceStatus = () => { + this.interval = setInterval(() => { + let filter = {}; + filter.type = 1; + filter.id = this.props.id + rest.request(getServiceUri() + 'apply/get-service-status', 'POST', filter).then(response => { + if (response.serviceStatus === MTLB_STATUS_READY_FOR_APPROVAL) { + this.sub.off('publication', this.handleStatusChange); + this.props.onFinish() + clearInterval(this.interval); + } + }) + }, 3000) + }; + + handleStatusChange = (ctx) => { + if (ctx.data.value.key === "status") { + this.setState({status: ctx.data.value.value}); + if (ctx.data.value.value === MTLB_STATUS_READY_FOR_APPROVAL) { + this.sub.off('publication', this.handleStatusChange); + this.props.onFinish() + } + } + } + + render() { + this.sub.on('publication', this.handleStatusChange).subscribe(); + return loadingIcon; + } + +} \ No newline at end of file diff --git a/src/main/js/tasks/IdCardApplication.jsx b/src/main/js/tasks/IdCardApplication.jsx new file mode 100644 index 0000000..4856edc --- /dev/null +++ b/src/main/js/tasks/IdCardApplication.jsx @@ -0,0 +1,8 @@ +import React from 'react'; +import { rest } from '../../../auto/js/services'; +import { displayNewIdCardApplicationForm } from '../../../auto/js/forms/idCardApplication/NewIdCardApplicationForm'; + + +export const process = (manager) => { + displayNewIdCardApplicationForm(manager.gui, manager.args, manager.complete); +} \ No newline at end of file diff --git a/src/main/js/tasks/IdCardApplicationRegistration.jsx b/src/main/js/tasks/IdCardApplicationRegistration.jsx new file mode 100644 index 0000000..ccdc835 --- /dev/null +++ b/src/main/js/tasks/IdCardApplicationRegistration.jsx @@ -0,0 +1,87 @@ +import React from 'react'; +import {v4 as uuidv4} from 'uuid'; +import { Centrifuge } from "centrifuge"; +import { formState } from "../../../auto/js/forms/FormState"; +import { MTLB_STATUS_ARCHIVED, MTLB_STATUS_READY_FOR_APPROVAL } from "../../../auto/js/metadata/MtlbStatus"; +import { rest } from "../../../auto/js/services"; +import { loadingIcon } from "../../../auto/js/loadingIcon"; +import { getServiceUri } from "../../../auto/js/metadata"; + + +export const process = (manager) => { + manager.gui.goTo(displayServerRegistrationLoading(manager.complete), formState.getState().idMtlbId, null); +} + +const displayServerRegistrationLoading = (onFinish) => (id) => { + let uuid = uuidv4(); + return { + uuid, view: () => onFinish()}/> + } +} + +export class LoadingComponent extends React.Component { + constructor(props) { + super(props) + this.state = { + status: MTLB_STATUS_READY_FOR_APPROVAL, + } + + this.centrifuge = new Centrifuge("wss://rv5.gov.vu/connection/websocket", { + token: rest.oidcService.token, + getToken: function () { + return new Promise((resolve, reject) => { + rest.oidcService.updateToken(55).then(function () { + resolve(rest.oidcService.token); + }).catch(function (err) { + reject(err); + rest.oidcService.logout(); + }); + }) + } + }); + + this.centrifuge.connect(); + this.sub = this.centrifuge.newSubscription("2." + props.id); + } + + componentDidMount() { + this.getServiceStatus(); + } + + componentWillUnmount() { + if (this.interval) { + clearInterval(this.interval); + } + } + + getServiceStatus = () => { + this.interval = setInterval(() => { + let filter = {}; + filter.type = 2; + filter.id = this.props.id + rest.request(getServiceUri() + 'apply/get-service-status', 'POST', filter).then(response => { + if (response.serviceStatus === MTLB_STATUS_ARCHIVED) { + this.sub.off('publication', this.handleStatusChange); + this.props.onFinish() + clearInterval(this.interval); + } + }) + }, 3000) + }; + + handleStatusChange = (ctx) => { + if (ctx.data.value.key === "status") { + this.setState({status: ctx.data.value.value}); + if (ctx.data.value.value === MTLB_STATUS_ARCHIVED) { + this.sub.off('publication', this.handleStatusChange); + this.props.onFinish() + } + } + } + + render() { + this.sub.on('publication', this.handleStatusChange).subscribe(); + return loadingIcon; + } + +} \ No newline at end of file diff --git a/src/main/js/tasks/IdCardApproveApplication.jsx b/src/main/js/tasks/IdCardApproveApplication.jsx new file mode 100644 index 0000000..f20ce27 --- /dev/null +++ b/src/main/js/tasks/IdCardApproveApplication.jsx @@ -0,0 +1,8 @@ +import React from 'react'; +import { displayReadReadyIdCardApplicationForm } from '../../../auto/js/forms/idCardApplication/ReadyIdCardApplicationForm'; +import { formState } from '../../../auto/js/forms/FormState'; + + +export const process = (manager) => { + manager.gui.goTo(displayReadReadyIdCardApplicationForm(manager.complete), formState.getState().idMtlbId, null) +} \ No newline at end of file diff --git a/src/main/js/tasks/IdCardServerApproval.jsx b/src/main/js/tasks/IdCardServerApproval.jsx new file mode 100644 index 0000000..3856e65 --- /dev/null +++ b/src/main/js/tasks/IdCardServerApproval.jsx @@ -0,0 +1,88 @@ +import React from 'react'; +import {v4 as uuidv4} from 'uuid'; +import { Centrifuge } from "centrifuge"; +import { formState } from "../../../auto/js/forms/FormState"; +import { MTLB_STATUS_READY_FOR_APPROVAL, MTLB_STATUS_SUBMITTED } from "../../../auto/js/metadata/MtlbStatus"; +import { rest } from "../../../auto/js/services"; +import { loadingIcon } from "../../../auto/js/loadingIcon"; +import { getServiceUri } from "../../../auto/js/metadata"; + + +export const process = (manager) => { + + manager.gui.goTo(displayServerApprovalLoading(manager.complete), formState.getState().idMtlbId, null); +} + +const displayServerApprovalLoading = (onFinish) => (id) => { + let uuid = uuidv4(); + return { + uuid, view: () => onFinish()}/> + } +} + +export class LoadingComponent extends React.Component { + constructor(props) { + super(props) + this.state = { + status: MTLB_STATUS_SUBMITTED, + } + + this.centrifuge = new Centrifuge("wss://rv5.gov.vu/connection/websocket", { + token: rest.oidcService.token, + getToken: function () { + return new Promise((resolve, reject) => { + rest.oidcService.updateToken(55).then(function () { + resolve(rest.oidcService.token); + }).catch(function (err) { + reject(err); + rest.oidcService.logout(); + }); + }) + } + }); + + this.centrifuge.connect(); + this.sub = this.centrifuge.newSubscription("2." + props.id); + } + + componentDidMount() { + this.getServiceStatus(); + } + + componentWillUnmount() { + if (this.interval) { + clearInterval(this.interval); + } + } + + getServiceStatus = () => { + this.interval = setInterval(() => { + let filter = {}; + filter.type = 2; + filter.id = this.props.id + rest.request(getServiceUri() + 'apply/get-service-status', 'POST', filter).then(response => { + if (response.serviceStatus === MTLB_STATUS_READY_FOR_APPROVAL) { + this.sub.off('publication', this.handleStatusChange); + this.props.onFinish() + clearInterval(this.interval); + } + }) + }, 3000) + }; + + handleStatusChange = (ctx) => { + if (ctx.data.value.key === "status") { + this.setState({status: ctx.data.value.value}); + if (ctx.data.value.value === MTLB_STATUS_READY_FOR_APPROVAL) { + this.sub.off('publication', this.handleStatusChange); + this.props.onFinish() + } + } + } + + render() { + this.sub.on('publication', this.handleStatusChange).subscribe(); + return loadingIcon; + } + +} \ No newline at end of file diff --git a/src/main/js/tasks/PrintCertificateTask.jsx b/src/main/js/tasks/PrintCertificateTask.jsx new file mode 100644 index 0000000..711a710 --- /dev/null +++ b/src/main/js/tasks/PrintCertificateTask.jsx @@ -0,0 +1,17 @@ +import { readCivilRecordForm } from "../../../auto/js/forms/CivilRecordForm"; +import { formState } from "../../../auto/js/forms/FormState"; +import { loadBirthRegistrationFormData } from "../../../auto/js/forms/birthRegistration/BirthRegistrationApi"; +import { Task } from "./Task"; + +export class PrintCertificateTask extends Task { + constructor(id, name, gui) { + super(id, name, gui); + } + + start = (onFinishCallback) => { + this.onFinishCallback = onFinishCallback; + loadBirthRegistrationFormData(formState.getState().civilStatusMtlbId).then((response) => { + this.gui.goTo(readCivilRecordForm(this.complete), response.vitalRecordId, null) + }) + } +} \ No newline at end of file diff --git a/src/main/js/tasks/PrintDeathCertificate.jsx b/src/main/js/tasks/PrintDeathCertificate.jsx new file mode 100644 index 0000000..c799069 --- /dev/null +++ b/src/main/js/tasks/PrintDeathCertificate.jsx @@ -0,0 +1,18 @@ +import React from 'react'; +import { formState } from '../../../auto/js/forms/FormState'; +import { loadDeathRegistrationFormData } from '../forms/deathRegistration/DeathRegistrationFormCommon'; +import { rest } from '../../../auto/js/services'; +import { getServiceUri } from '../../../auto/js/metadata'; +import { displayReadDeathRecordForm } from '../../../auto/js/forms/DeathRecordForm'; + + +export const process = (manager) => { + loadDeathRegistrationFormData(formState.getState().civilStatusMtlbId).then((response) => { + let filter = {and: true}; + filter['death-record-document'] = {vitalRecordId: response.vitalRecordId}; + rest.request(getServiceUri() + '/' + 'death-record/search-document/', 'POST', filter).then(dr => { + if (dr.length) + manager.gui.goTo(displayReadDeathRecordForm(manager.complete), dr[0].id, null) + }) + }) +} \ No newline at end of file diff --git a/src/main/js/tasks/PrintIdCard.jsx b/src/main/js/tasks/PrintIdCard.jsx new file mode 100644 index 0000000..dd43b63 --- /dev/null +++ b/src/main/js/tasks/PrintIdCard.jsx @@ -0,0 +1,8 @@ +import React from 'react'; +import { displayReadApprovedIdCardApplicationForm } from '../../../auto/js/forms/idCardApplication/ApprovedIdCardApplicationForm'; +import { formState } from '../../../auto/js/forms/FormState'; + + +export const process = (manager) => { + manager.gui.goTo(displayReadApprovedIdCardApplicationForm(manager.complete), formState.getState().idMtlbId, null) +} \ No newline at end of file diff --git a/src/main/js/tasks/RecordRegistrationTask.jsx b/src/main/js/tasks/RecordRegistrationTask.jsx new file mode 100644 index 0000000..cf79103 --- /dev/null +++ b/src/main/js/tasks/RecordRegistrationTask.jsx @@ -0,0 +1,100 @@ +import React from "react"; +import {v4 as uuidv4} from 'uuid'; +import { Centrifuge } from "centrifuge"; +import { formState } from "../../../auto/js/forms/FormState"; +import { Task } from "./Task"; +import { MTLB_STATUS_ARCHIVED, MTLB_STATUS_READY_FOR_APPROVAL } from "../../../auto/js/metadata/MtlbStatus"; +import { rest } from "../../../auto/js/services"; +import { loadingIcon } from "../../../auto/js/loadingIcon"; +import { getServiceUri } from "../../../auto/js/metadata"; + +export class RecordRegistrationTask extends Task { + constructor(id, name, gui) { + super(id, name, gui); + } + + start = (onFinishCallback) => { + this.onFinishCallback = onFinishCallback; + this.gui.goTo(displayRecordRegistrationLoading(this.complete), formState.getState().civilStatusMtlbId, null); + } +} + +const displayRecordRegistrationLoading = (onFinish) => (id) => { + let uuid = uuidv4(); + return { + uuid, view: () => onFinish()}/> + } +} + +export class LoadingComponent extends React.Component { + constructor(props) { + super(props) + this.state = { + status: MTLB_STATUS_READY_FOR_APPROVAL, + } + + this.centrifuge = new Centrifuge("wss://rv5.gov.vu/connection/websocket", { + token: rest.oidcService.token, + getToken: function () { + return new Promise((resolve, reject) => { + rest.oidcService.updateToken(55).then(function () { + resolve(rest.oidcService.token); + }).catch(function (err) { + reject(err); + rest.oidcService.logout(); + }); + }) + } + }); + + this.centrifuge.on('connecting', function (ctx) { + console.log(`connecting: ${ctx.code}, ${ctx.reason}`); + }).on('connected', function (ctx) { + console.log(`connected over ${ctx.transport}`); + }).on('disconnected', function (ctx) { + console.log(`disconnected: ${ctx.code}, ${ctx.reason}`); + }).connect(); + this.sub = this.centrifuge.newSubscription("1." + this.props.id); + } + + componentDidMount() { + this.getServiceStatus(); + } + + componentWillUnmount() { + if (this.interval) { + clearInterval(this.interval); + } + } + + getServiceStatus = () => { + this.interval = setInterval(() => { + let filter = {}; + filter.type = 1; + filter.id = this.props.id + rest.request(getServiceUri() + 'apply/get-service-status', 'POST', filter).then(response => { + if (response.serviceStatus === MTLB_STATUS_ARCHIVED) { + this.sub.off('publication', this.handleStatusChange); + this.props.onFinish() + clearInterval(this.interval); + } + }) + }, 3000) + }; + + handleStatusChange = (ctx) => { + if (ctx.data.value.key === "status") { + this.setState({status: ctx.data.value.value}); + if (ctx.data.value.value === MTLB_STATUS_ARCHIVED) { + this.props.onFinish() + this.sub.off('publication', this.handleStatusChange); + } + } + } + + render() { + this.sub.on('publication', this.handleStatusChange).subscribe(); + return loadingIcon; + } + +} \ No newline at end of file diff --git a/src/main/js/tasks/ServerApprovalTask.jsx b/src/main/js/tasks/ServerApprovalTask.jsx new file mode 100644 index 0000000..1d2779c --- /dev/null +++ b/src/main/js/tasks/ServerApprovalTask.jsx @@ -0,0 +1,94 @@ +import React from "react"; +import {v4 as uuidv4} from 'uuid'; +import { Centrifuge } from "centrifuge"; +import { formState } from "../../../auto/js/forms/FormState"; +import { Task } from "./Task"; +import { MTLB_STATUS_READY_FOR_APPROVAL, MTLB_STATUS_SUBMITTED } from "../../../auto/js/metadata/MtlbStatus"; +import { rest } from "../../../auto/js/services"; +import { loadingIcon } from "../../../auto/js/loadingIcon"; +import { getServiceUri } from "../../../auto/js/metadata"; + +export class ServerApprovalTask extends Task { + constructor(id, name, gui) { + super(id, name, gui); + } + + start = (onFinishCallback) => { + this.onFinishCallback = onFinishCallback; + this.gui.goTo(displayServerApprovalLoading(this.complete), formState.getState().civilStatusMtlbId, null); + } +} + +const displayServerApprovalLoading = (onFinish) => (id) => { + let uuid = uuidv4(); + return { + uuid, view: () => onFinish()}/> + } +} + +export class LoadingComponent extends React.Component { + constructor(props) { + super(props) + this.state = { + status: MTLB_STATUS_SUBMITTED, + } + + this.centrifuge = new Centrifuge("wss://rv5.gov.vu/connection/websocket", { + token: rest.oidcService.token, + getToken: function () { + return new Promise((resolve, reject) => { + rest.oidcService.updateToken(55).then(function () { + resolve(rest.oidcService.token); + }).catch(function (err) { + reject(err); + rest.oidcService.logout(); + }); + }) + } + }); + + this.centrifuge.connect(); + this.sub = this.centrifuge.newSubscription("1." + props.id); + } + + componentDidMount() { + this.getServiceStatus(); + } + + componentWillUnmount() { + if (this.interval) { + clearInterval(this.interval); + } + } + + getServiceStatus = () => { + this.interval = setInterval(() => { + let filter = {}; + filter.type = 1; + filter.id = this.props.id + rest.request(getServiceUri() + 'apply/get-service-status', 'POST', filter).then(response => { + if (response.serviceStatus === MTLB_STATUS_READY_FOR_APPROVAL) { + this.sub.off('publication', this.handleStatusChange); + this.props.onFinish() + clearInterval(this.interval); + } + }) + }, 3000) + }; + + handleStatusChange = (ctx) => { + if (ctx.data.value.key === "status") { + this.setState({status: ctx.data.value.value}); + if (ctx.data.value.value === MTLB_STATUS_READY_FOR_APPROVAL) { + this.sub.off('publication', this.handleStatusChange); + this.props.onFinish() + } + } + } + + render() { + this.sub.on('publication', this.handleStatusChange).subscribe(); + return loadingIcon; + } + +} \ No newline at end of file diff --git a/src/main/js/tasks/Task.jsx b/src/main/js/tasks/Task.jsx new file mode 100644 index 0000000..dde98bd --- /dev/null +++ b/src/main/js/tasks/Task.jsx @@ -0,0 +1,28 @@ +import React from "react"; + +export class Task { + + constructor(id, name, gui) { + this.id = id; + this.name = name; + this.completed = false; + this.gui = gui; + this.onFinishCallback; + } + + complete = () => { + this.completed = true; + if (this.onFinishCallback) { + this.onFinishCallback(this.id); + } + } + + // Placeholder for process function + start = (callback) => { + + } + getState = () => { + return this.completed; + } + +} \ No newline at end of file diff --git a/src/main/js/tasks/ValidateAddress.jsx b/src/main/js/tasks/ValidateAddress.jsx new file mode 100644 index 0000000..e0b2c93 --- /dev/null +++ b/src/main/js/tasks/ValidateAddress.jsx @@ -0,0 +1,7 @@ +import React from 'react'; +import { readCivilRecordAdminInfo } from "../forms/CivilRecordAdminInfo" + + +export const process = (manager) => { + manager.gui.goTo(readCivilRecordAdminInfo(manager.complete), manager.args.id) +} \ No newline at end of file diff --git a/src/main/js/utils.js b/src/main/js/utils.js new file mode 100644 index 0000000..59e0809 --- /dev/null +++ b/src/main/js/utils.js @@ -0,0 +1,96 @@ +import { formState } from "../../auto/js/forms/FormState"; +import { getServiceUri } from "../../auto/js/metadata"; +import { ADDRESS_ORDER_BY_AREA_ID } from "../../auto/js/metadata/AddressOrderBy"; +import { geoDataMetadataLoader } from "../../auto/js/metadata/GeoDataMetadataLoader"; +import { geoMetadataLoader } from "../../auto/js/metadata/GeoMetadataLoader"; +import { rest } from "../../auto/js/services"; + +const gender = {1:"MALE", 2:"FEMALE"}; +const maritalStatus = {1:"SINGLE", 2:"MARRIED", 3:"DIVORCED", 4:"WIDOWED"}; + +export const loadPersonData = async (id) => { + const token = await rest.getToken(getServiceUri() + 'token/get-auth-code'); + return await rest.read("vital-record", id).then(response => { + let address = null; + if (response.status) + return undefined; + else { + if (response.maritalStatus) + response.maritalStatus = maritalStatus[response.maritalStatus]; + if (response.gender) + response.gender = gender[response.gender]; + response['address'] = address; + if (response.faceId != null) { + + let faceUrl = getServiceUri() + "face/image/" + response.faceId + "/" + token; + response['image'] = { x: 0.5, y: 0.5, scale: 1, rotate: 0, url: faceUrl, isEmpty: false }; + } + else { + response['image'] = { x: 0.5, y: 0.5, scale: 1, rotate: 0, url: '/public/avatar.png', isEmpty: true }; + } + formState.addState('birthdate', response.birthdate); + return response; + } + }).then((form) => { + if (!form) + return undefined + else + return buildAddressData({},form.id).then(address => { + form['address'] = address; + return form; + }) + }) +} + +export const filterPersonData = (data) => { + + let faceUrl = null; + if (data.faceId != null) { + faceUrl = getServiceUri() + "face/image/" + data.faceId; + } + data['image'] = { x: 0.5, y: 0.5, scale: 1, rotate: 0, url: (faceUrl != null) ? faceUrl : '/public/avatar.png', isEmpty: (faceUrl != null) }; + if (data.maritalStatus) + data.maritalStatus = maritalStatus[data.maritalStatus]; + if (data.gender) + data.gender = gender[data.gender]; + return data; + +} + +export const buildAddressData = async (query, id) => { + let filter = query; + filter["address"] = {vitalRecordId: id}; + filter["orderBy"] = ADDRESS_ORDER_BY_AREA_ID; + filter.orderDirection = null; + filter.offset = query.page * query.pageSize; + if (query.search && query.search!='') { + pojoMetadata["address"].columns.forEach(element => { + if(element.type=='text'){ + filter["address"][element.key]= query.search; + } + }); + filter["and"] = false; + } + return await getData(filter).then(response => { + if (response.length) { + let areaId = response[response.length - 1].areaId; + return areaId; + } + else + return "" + }); +} + +const getData = async (filter) => { + return await rest.search('address', filter) +} + +export const Separator = () => { + return ( + <> +
+
+
+ + ); +}; diff --git a/src/main/js/widgets/AddressComponent.jsx b/src/main/js/widgets/AddressComponent.jsx new file mode 100644 index 0000000..45b3fc8 --- /dev/null +++ b/src/main/js/widgets/AddressComponent.jsx @@ -0,0 +1,49 @@ +import * as React from 'react'; +import { useField } from "formik"; +import { Observable } from '../../../auto/js/events/Observable'; +import { geoMetadataLoader } from '../../../auto/js/metadata/GeoMetadataLoader'; +import { AutoCompleteInput } from '../../../auto/js/widgets'; +import { t } from '../../../auto/js/services'; + +const provinceObservable = new Observable(); +const zoneObservable = new Observable(); +const districtObservable = new Observable(); +const islandObservable = new Observable(); + +export function AddressComponent (props) { + const [field, meta, helpers] = useField(props.name); + const { value } = meta; + const { setValue } = helpers; + + const handleProvinceChange = (value) => { + provinceObservable.publish(geoMetadataLoader.getChilds(value.key)) + setValue(value.key); + } + const handleZoneChange = (value) => { + zoneObservable.publish(geoMetadataLoader.getChilds(value.key)) + setValue(value.key); + } + const handleDistrictChange = (value) => { + districtObservable.publish(geoMetadataLoader.getChilds(value.key)) + setValue(value.key); + } + const handleIslandChange = (value) => { + islandObservable.publish(geoMetadataLoader.getChilds(value.key)) + setValue(value.key); + } + const handleLocationChange = (value) => { + setValue(value.key); + } + console.log(value) + console.log(props.data) + return ( + <> +

{props.name}

+ geoMetadataLoader.getChilds(geoMetadataLoader.rootid)} label={t`Province`} handleChange={(data) => handleProvinceChange(data)} /> + ""} label={t`Area Council`} handleChange={(data) => handleZoneChange(data)} observable={provinceObservable} /> + ""} label={t`District`} handleChange={(data) => handleDistrictChange(data)} observable={zoneObservable} /> + ""} label={t`Island`} handleChange={(data) => handleIslandChange(data)} observable={districtObservable} /> + ""} label={t`Location`} handleChange={(data) => handleLocationChange(data)} observable={islandObservable} /> + + ) +} \ No newline at end of file diff --git a/src/main/js/widgets/AdvancedSearchComponent.jsx b/src/main/js/widgets/AdvancedSearchComponent.jsx new file mode 100644 index 0000000..26397e8 --- /dev/null +++ b/src/main/js/widgets/AdvancedSearchComponent.jsx @@ -0,0 +1,69 @@ +import React, { useEffect, useState } from "react"; +import Paper from '@mui/material/Paper'; +import Draggable from 'react-draggable'; + +import { buildEmptyObject, createFormComponent } from "../../../auto/js/widgets"; +import { DraggableFilterDialog } from "./DraggableFilterComponentUpgrade"; +import { t } from "../../../auto/js/services"; +import { OPEN_ADVANCED_SEARCH } from "../../../auto/js/events/Gui"; +import { useConstructor } from "../../../auto/js/utils"; + + +function PaperComponent(props) { + return ( + + + + ); +} + +export const AdvancedSearchComponent = (props) => { + const [formData, setFormData] = useState(undefined) + const [openAdvancedSearch, setOpenAdvancedSearch] = useState(false); + const [searchFilters, setSearchFilters] = useState(undefined); + + useConstructor(() => { + OPEN_ADVANCED_SEARCH.subscribe((filters) => { + openAdvancedSearchDialog(filters) + }) + }); + + const buildFormData = async () => { + return formData; + } + + const openAdvancedSearchDialog = (filters) => { + setSearchFilters(filters) + setOpenAdvancedSearch(true) + } + + const closeAdvancedSearch = () => { + setOpenAdvancedSearch(false) + } + + let SearchForm = createFormComponent((searchFilters)?searchFilters.fields:[]); + + const onSubmit = (data) => { + (searchFilters)?searchFilters.onSubmit(data):null; + //setFormData(data); + setOpenAdvancedSearch(false) + } + let name = ''; + if (searchFilters) + name = searchFilters.name; + return ( + <> + { buildFormData() :async () => buildEmptyObject((searchFilters)?searchFilters.fields:[])} buttons={getButtons} onSubmit={onSubmit} /> + }/>} + + ) +} + +const getButtons = () => { + return + } \ No newline at end of file diff --git a/src/main/js/widgets/AdvancedSearchPersonComponent.jsx b/src/main/js/widgets/AdvancedSearchPersonComponent.jsx new file mode 100644 index 0000000..2d6caa0 --- /dev/null +++ b/src/main/js/widgets/AdvancedSearchPersonComponent.jsx @@ -0,0 +1,326 @@ +import React, { useState } from "react"; +import { useField } from "formik"; +import { FormLabel } from '@mui/material'; +import LoadingOverlay from 'react-loading-overlay-ts'; +import { rest, t } from "../../../auto/js/services"; +import { ImageViewer, buildEmptyObject, createFormComponent } from "../../../auto/js/widgets"; +import { formatDate } from "../../../auto/js/utils"; +import { geoDataMetadataLoader } from "../../../auto/js/metadata/GeoDataMetadataLoader"; +import { Button } from "@material-ui/core"; +import Paper from '@mui/material/Paper'; +import Draggable from 'react-draggable'; +import { VITAL_RECORD_ORDER_BY_FIRSTNAME } from "../../../auto/js/metadata/VitalRecordOrderBy"; +import { getServiceUri, pojoMetadata } from "../../../auto/js/metadata"; +import { createTableComponent } from "../../../auto/js/widgets/TableComponent"; +import { birthRecordColumns, parentsSearchFormfields, transformFormData } from "../forms/CivilRecordFormCommon"; +import { DraggableFilterDialog } from "./DraggableFilterComponentUpgrade"; +import { formState } from "../../../auto/js/forms/FormState"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faHandPointLeft } from "@fortawesome/free-regular-svg-icons"; +import { faMagnifyingGlass } from "@fortawesome/pro-regular-svg-icons"; + +function PaperComponent(props) { + return ( + + + + ); +} +function PaperListComponent(props) { + return ( + + + + ); +} + +export const AdvancedSearchPersonComponent = ({...props}) => { + const [field, meta, helpers] = useField(props.name); + const { value } = meta; + const { setValue } = helpers; + const [searchResult, setSearchResult] = useState(true); + const [searchText, setSearchText] = useState(""); + const [open, setOpen] = useState(false); + const [listOpen, setListOpen] = useState(false); + const [formData, setFormData] = useState(null); + const [transformedData, setTransformedData] = useState(null); + + const onRequestSearchWithId = (id) => { + setValue(id); + setSearchResult(true); + } + const handleClose = () => { + setOpen(false); + }; + const handleListClose = () => { + setListOpen(false); + }; + const submit = (formData) => { + const columns = transformFormData(formData); + setFormData(formData); + setTransformedData(columns); + setListOpen(true); + return columns ; + } + + const openDraggableComponent = () => { + setOpen(true); + } + + const getButtons = () => { + return + } + + const buildFormData = async () => { + return formData; + } + let SearchForm = createFormComponent((props.parentsSearchFormfields)?props.parentsSearchFormfields:parentsSearchFormfields); + let CivilRecordsList = createTableComponent(birthRecordColumns); + + const getVitalRecordFromSearch = async (filter) => { + return await rest.request(getServiceUri() + "vital-record/advanced-search", "POST", filter); + } + + const countData = async (filter) => { + return await rest.request(getServiceUri() + "vital-record/count/advanced-search", "POST", filter); + } + + const filterData = (DefaultRows, token) => { + const newRows = []; + for (let i in DefaultRows) { + let faceUrl = null; + let row = DefaultRows[i]; + if (row.faceId != null) { + faceUrl = getServiceUri() + "face/image/" + row.faceId + "/" + token; + } + row.image = (faceUrl != null)?faceUrl:"/public/avatar.png"; + let date = row.birthdate + if (date !== null) + row.birthdate = date[2] + '-' + date[1] + '-' + date[0]; + newRows.push(row); + } + return newRows; + } + + const buildData = async (query) => { + const token = await rest.getToken(getServiceUri() + 'token/get-auth-code'); + let filter = query; + let data; + filter["vital-record"] = {inactiveList: [false]}; + filter["orderBy"] = VITAL_RECORD_ORDER_BY_FIRSTNAME; + filter.orderDirection = null; + filter["filter"] = query.search; + filter["query"] = transformedData; + filter.offset = query.page * query.pageSize; + if (query.search && query.search!='') { + pojoMetadata["vital-record"].columns.forEach(element => { + if(element.type=='text'){ + filter["vital-record"][element.key]= query.search; + } + }); + } + return await getVitalRecordFromSearch(filter).then(response => { + data = filterData(response, token) + return countData(filter).then((count) => {return {data: data, totalCount: count, page: query.page}}) + }); + } + + const getTableActions = () => { + let actions = []; + actions.push( + { + icon: () => , + tooltip: t`Choose`, + onClick: (event, rowData) => { + onRequestSearchWithId(rowData.id); + setListOpen(false); + setOpen(false); + } + } + ) + return actions; + } + + + return( + <> + + {(!props.readOnly) && + <> + openDraggableComponent()} style={{textDecoration: 'underline', cursor: 'pointer'}} > + {(props.label)?t(props.label):t(props.name)} + openDraggableComponent()} style={{ fontSize: '1.1em', marginLeft: '10px' }}/> + + } + {(searchResult && value)? + props.loadData(value)} disabledPhoto={props.disabledPhoto} fieldName={props.name}/> + :null} + {open && { + if (props.buildEmptyObject !== undefined) { + return props.buildEmptyObject((props.parentsSearchFormfields)?props.parentsSearchFormfields:parentsSearchFormfields); + } else { + return buildEmptyObject((props.parentsSearchFormfields)?props.parentsSearchFormfields:parentsSearchFormfields); + } + } + } buttons={getButtons} onSubmit={submit} /> + }/>} + {listOpen && buildData(query)} columns={birthRecordColumns} actions={getTableActions()} />} />} + + ) +} + +class Person extends React.Component { + constructor(props) { + super(props); + this.formRef = React.createRef() + this.state = { + data: undefined, + loading: true, + loadingMessage: '' + } + this.props.loadData().then((data) => { + if (data) { + formState.addState(this.props.fieldName + "-gender",data.gender) + formState.addState(this.props.fieldName + "-birthdate",data.birthdate) + } + this.setState({ data: data, loading: false }) + }); + } + + componentDidUpdate(prevProps, prevState) { + this.props.loadData().then((data) => { + if (data) { + formState.addState(this.props.fieldName + "-gender",data.gender) + formState.addState(this.props.fieldName + "-birthdate",data.birthdate) + if (prevState.data) { + if (prevState.data.id !== data.id) + this.setState({ data: data, loading: false }) + } + else + this.setState({ data: data, loading: false }) + } + }); + } + + openPersonTab = (id) => { + var currentUrl = window.location.href; + var url; + if (currentUrl.includes("#")) { + var parts = currentUrl.split("#"); + url = parts[0] + '#' + 'viewvr:id=' + id; + } + else + url = window.location.hash + '#' + 'viewvr:id=' + id; + window.open(url, '_blank'); + } + + render() { + let fullname = ''; + let birthdate; + let birthPlace = []; + let address = []; + if (this.state.data) { + birthdate = this.state.data.birthdate? formatDate(this.state.data.birthdate):t`Unknown`; + fullname += this.state.data.firstname ? this.state.data.firstname + ' ' : ''; + fullname += this.state.data.secondname ? this.state.data.secondname + ' ' : ''; + fullname += this.state.data.thirdname ? this.state.data.thirdname + ' ' : ''; + fullname += this.state.data.fourthname ? this.state.data.fourthname + ' ' : ''; + fullname += this.state.data.fifthname ? this.state.data.fifthname + ' ' : ''; + if (this.state.data.birthPlace != null) { + let birthPlaceComponents = this.state.data.birthPlace.split("."); + let place = this.state.data.birthPlace; + birthPlace.push( +

{(geoDataMetadataLoader.getArea(place))?t(geoDataMetadataLoader.getArea(place).name):t("INVALID DATA") + " (" + t(geoDataMetadataLoader.getAreaLevelName(place)) + ")"}

+ ) + for (let i = 0; i < birthPlaceComponents.length - 1 ; i ++) { + let parentAreaId = place.substring(0, place.lastIndexOf(".")); + place = parentAreaId; + birthPlace.push( +

{(geoDataMetadataLoader.getArea(parentAreaId))?t(geoDataMetadataLoader.getArea(parentAreaId).name):t("INVALID DATA") + " (" + t(geoDataMetadataLoader.getAreaLevelName(parentAreaId)) + ")"}

+ ) + } + } + else + birthPlace.push(

{t`Unknown Birth Place`}

) + if (this.state.data.address) { + let addressComponents = this.state.data.address.split("."); + let place = this.state.data.address; + address.push( +

{(geoDataMetadataLoader.getArea(place))?t(geoDataMetadataLoader.getArea(place).name):t("INVALID DATA") + " (" + t(geoDataMetadataLoader.getAreaLevelName(place)) + ")"}

+ ) + for (let i = 0; i < addressComponents.length - 1 ; i ++) { + let parentAreaId = place.substring(0, place.lastIndexOf(".")); + place = parentAreaId; + address.push( +

{(geoDataMetadataLoader.getArea(parentAreaId))?t(geoDataMetadataLoader.getArea(parentAreaId).name):t("INVALID DATA") + " (" + t(geoDataMetadataLoader.getAreaLevelName(parentAreaId)) + ")"}

+ ) + } + } + else + address.push(

{t`Unknown`}

); + } + return ( + <> + + {(this.state.data)? +
+ {(!this.props.disabledPhoto) && +
+ +
} +

{t`Personal Details`}

+

{fullname}

+

{t`ID`} #: {this.state.data.id}

+

{t`Mother`}:

+ {(this.state.data.motherId)? +

{t`ID`} # {this.state.data.motherId}

: +

{t`Reported Name`}: {this.state.data.reportedMotherName}

+ } +

{t`Father`}:

+ {(this.state.data.fatherId)? +

{t`ID`} #: {this.state.data.fatherId}

: +

{t`Reported Name`}: {this.state.data.reportedFadherName}

+ } +
+
+ +
+
+

{t`Birth Details`}

+

{birthdate}
+ {birthPlace}

+

{t`Current Residency`}

+ {address} +
+
+
+
+

{t`Other Details`}

+

{this.state.data.maritalStatus}

+

{this.state.data.gender}

+
+
+
+ +
+
: +
{t`Person not found`}
+ } +
+ + ) + } +} \ No newline at end of file diff --git a/src/main/js/widgets/AutocompleteListSelector.jsx b/src/main/js/widgets/AutocompleteListSelector.jsx new file mode 100644 index 0000000..cabe533 --- /dev/null +++ b/src/main/js/widgets/AutocompleteListSelector.jsx @@ -0,0 +1,89 @@ +import React from "react"; +import { Chip, TextField, Autocomplete } from '@mui/material'; +import RemoveCircleOutlineSharp from '@mui/icons-material/RemoveCircleOutlineSharp'; +import { useField } from "formik"; + +/** + * Transforms the input as described in the api to the form required by the + * GUI components + * + * @param allOptions The options object as provided to the Widget + * @param list The list of IDs of the options displayed as chips + * @returns An array of objects in the form {id: number, label: str} + * that stores the options that are referenced in the list + */ +function preprocessInput(allOptions, list) { + let options = []; + + if (list != null) + list = list.map((elem) => String(elem)); + else + list = []; + for (const [key, value] of Object.entries(allOptions)) { + if (!list.includes(key)) { + options.push({ + "id": parseInt(key), + "label": value + }); + } + } + + return options; +} + +/** + * + * @param options object in the form {id1: label1, id2: label2...} representing all possible options + * for the auto complete + * @param props must contain a "name" property + */ +function AutocompleteListSelector(props) { + const [field, meta, helpers] = useField(props.name); + + const value = meta.value; + const setValue = helpers.setValue; + + return ( +
+ option.label} + onChange={(e, newValue) => { + setValue([...value, newValue.id]); + }} + aria-label={props.label} + renderTags={() => {}} + renderInput={params => ( + + )} + /> +
+ { + value.map((obj, index) => { + return } + onDelete={() => { + const updatedChips = value.filter(entry => entry !== obj); + setValue(updatedChips); + }} + /> + }) + } +
+
+ ) +} + +export default AutocompleteListSelector; \ No newline at end of file diff --git a/src/main/js/widgets/ConfirmationDialog.jsx b/src/main/js/widgets/ConfirmationDialog.jsx new file mode 100644 index 0000000..e83ccf3 --- /dev/null +++ b/src/main/js/widgets/ConfirmationDialog.jsx @@ -0,0 +1,50 @@ +import React, { useEffect, useState } from "react"; +import Paper from '@mui/material/Paper'; +import Draggable from 'react-draggable'; + +import { buildEmptyObject, createFormComponent } from "../../../auto/js/widgets"; +import { DraggableFilterDialog } from "./DraggableFilterComponentUpgrade"; +import { t } from "../../../auto/js/services"; +import { OPEN_CONFIRMATION_DIALOG } from "../../../auto/js/events/Gui"; +import { useConstructor } from "../../../auto/js/utils"; +import { AlertDialog } from "../../../auto/js/widgets"; + + +export const ConfirmationDialog = (props) => { + const [data, setData] = useState(props.data) + const [openConfirmation, setOpenConfirmation] = useState(false); + + useConstructor(() => { + OPEN_CONFIRMATION_DIALOG.subscribe((data) => { + openConfirmationDialog(data) + }) + }); + + const buildDialogData = async () => { + return data; + } + + const openConfirmationDialog = (data) => { + setData(data) + setOpenConfirmation(true) + } + + const closeConfirmation = () => { + setOpenConfirmation(false) + } + + const agree = () => { + closeConfirmation(); + data.onClick(); + } + + return ( + <> + {} + + ) +} + +const getButtons = () => { + return +} \ No newline at end of file diff --git a/src/main/js/widgets/ContactComponent.jsx b/src/main/js/widgets/ContactComponent.jsx new file mode 100644 index 0000000..68adc62 --- /dev/null +++ b/src/main/js/widgets/ContactComponent.jsx @@ -0,0 +1,61 @@ +import React from "react"; +import { createTableComponent } from "../../../auto/js/widgets/TableComponent"; +import { addressFields, buildAddressData, getAddressEditables } from "../../../auto/js/lists/AddressList"; +import { buildEmailData, emailFields, getEmailEditables } from "../../../auto/js/lists/EmailList"; +import { buildPhoneNumberData, getPhoneNumberEditables, phoneNumberFields } from "../../../auto/js/lists/PhoneNumberList"; +import { Accordion, AccordionDetails, AccordionSummary, Typography } from "@mui/material"; +import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; +import { t } from "../../../auto/js/services"; + +export class ContactComponent extends React.Component { + constructor(props) { + super(props); + } + + render() { + let AddressList = createTableComponent(addressFields); + let EmailList = createTableComponent(emailFields); + let PhoneNumberList = createTableComponent(phoneNumberFields); + + return ( + <> + + } + aria-controls="panel1a-content" + id="panel1a-header" + > + {t`Address`} + + + buildAddressData(query, this.props.id)} editable={getAddressEditables(this.props.id)} /> + + + + } + aria-controls="panel1a-content" + id="panel1a-header" + > + {t`Email`} + + + buildEmailData(query, this.props.id)} editable={getEmailEditables(this.props.id)} /> + + + + } + aria-controls="panel1a-content" + id="panel1a-header" + > + {t`PhoneNumber`} + + + buildPhoneNumberData(query, this.props.id)} editable={getPhoneNumberEditables(this.props.id)} /> + + + + ) + } +} \ No newline at end of file diff --git a/src/main/js/widgets/CountryAutoCompleteInput.jsx b/src/main/js/widgets/CountryAutoCompleteInput.jsx new file mode 100644 index 0000000..ab21e14 --- /dev/null +++ b/src/main/js/widgets/CountryAutoCompleteInput.jsx @@ -0,0 +1,35 @@ +import * as React from 'react'; +import { useField } from "formik"; + +import { geoDataMetadataLoader } from '../../../auto/js/metadata/GeoDataMetadataLoader'; +import { SimpleAutoCompleteInput } from '../../../auto/js/widgets/SimpleAutoCompleteInput'; +import { t } from '../../../auto/js/services'; + +export function CountryAutoCompleteInput(props) { + const [field, meta, helpers] = useField(props.name); + const { value } = meta; + const { setValue } = helpers; + + let countryValue; + + const handleChange = (value) => { + if (props.handleChange) + props.handleChange(value); + setValue(geoDataMetadataLoader.getAreaId(value.key)); + }; + + if(props.default && value == null) { + let country = geoDataMetadataLoader.getArea(props.default); + countryValue = { key: country.id, value: country.name }; + setValue(geoDataMetadataLoader.getAreaId(countryValue.key)) + } + + if (value != null) { + let country = geoDataMetadataLoader.getArea(value); + countryValue = { key: country.id, value: country.name }; + } + + return ( + geoDataMetadataLoader.getRootNodes()} label={t(props.name)} handleChange={(data) => handleChange(data)} defaultValue={countryValue} disabled={props.readOnly}/> + ); +} \ No newline at end of file diff --git a/src/main/js/widgets/DraggableFilterComponentUpgrade.jsx b/src/main/js/widgets/DraggableFilterComponentUpgrade.jsx new file mode 100644 index 0000000..f2e0d9e --- /dev/null +++ b/src/main/js/widgets/DraggableFilterComponentUpgrade.jsx @@ -0,0 +1,28 @@ +import Dialog from '@mui/material/Dialog'; +import DialogActions from '@mui/material/DialogActions'; +import DialogContent from '@mui/material/DialogContent'; +import DialogContentText from '@mui/material/DialogContentText'; +import DialogTitle from '@mui/material/DialogTitle'; +import React, { useState } from "react"; + +export const DraggableFilterDialog = ({ open, onClose, paperComponent ,title, description, children, buttons }) => ( + + + {title} + + + + {{description}?

{description}

: null} +
+ {children} +
+
+
+ {buttons} +
+); \ No newline at end of file diff --git a/src/main/js/widgets/FileComponent.jsx b/src/main/js/widgets/FileComponent.jsx new file mode 100644 index 0000000..a75493e --- /dev/null +++ b/src/main/js/widgets/FileComponent.jsx @@ -0,0 +1,152 @@ +import React, { useState } from "react"; +import { FormControl, FormLabel, IconButton, InputLabel, TextField } from '@mui/material'; +import { t } from "../../../auto/js/services"; +import { ImageViewer } from "../../../auto/js/widgets"; +import "../../../auto/js/pages/Form.css"; +import { Button } from "@material-ui/core"; +import DeleteIcon from '@mui/icons-material/Delete'; +import EditIcon from '@mui/icons-material/Edit'; +import CheckIcon from '@mui/icons-material/Check'; +import CloseIcon from '@mui/icons-material/Close'; + + + +export class FileComponent extends React.Component { + constructor(props) { + super(props); + this.formRef = React.createRef() + this.state = { + data: props.data, + loading: true, + loadingMessage: '', + isEditing: false + } + } + + openEdit = () => { + this.setState({ isEditing: true }); + } + + handleSave = ({ fileName, description }) => { + let newData = this.state.data; + newData.fileName = fileName; + newData.description = description; + this.setState({ isEditing: false, data: newData }); + this.props.updateFileData({ fileName: fileName, description: description, id: this.state.data.id }) + }; + + handleCancel = () => { + this.setState({ isEditing: false }); + } + + render() { + let fileName = ''; + let description = ''; + let previewUrl = null; + let preview = {}; + if (this.state.data) { + fileName = this.state.data.fileName ? this.state.data.fileName : ''; + description = this.state.data.description ? this.state.data.description + ' ' : ''; + if (this.props.previewUrl && this.props.token) + previewUrl = this.props.previewUrl() + "/" + this.props.token; + preview = { x: 0.5, y: 0.5, scale: 1, rotate: 0, url: (previewUrl != null) ? previewUrl : '/public/file-preview.png', onErrorUrl: '/public/file-preview.png', isEmpty: false } + } + return ( + <> + {(this.state.data) ? +
+ {(!this.props.disabledPhoto) && +
+ +
} +

{t`File Details`}

+ {(this.state.isEditing) ? + + : <> +

{t`File Name`}: {fileName}

+

{t`Description`}: {description}

+ + } +
+
+ {(!this.props.readOnly) &&
+ this.openEdit()}> + + + + + +
} +
+ +
+
: +
{t`File not found`}
+ } + + ) + } +} + +const EditableForm = ({ fileName, description, onSave, oncancel }) => { + const [editedFileName, setEditedFileName] = useState(fileName); + const [editedDescription, setEditedDescription] = useState(description); + + const handleSave = () => { + onSave({ fileName: editedFileName, description: editedDescription }); + }; + + const handleCancel = () => { + oncancel() + } + + return ( +
+
+ + + {t`File Name`} + + setEditedFileName(e.target.value)} + type={"text"} + InputLabelProps={{ shrink: false }} + /> + +
+
+ + + {`Description`} + + setEditedDescription(e.target.value)} + type={"text"} + InputLabelProps={{ shrink: false }} + /> + +
+
+ + + + + + +
+
+ ); +}; \ No newline at end of file diff --git a/src/main/js/widgets/FileInput.jsx b/src/main/js/widgets/FileInput.jsx new file mode 100644 index 0000000..2ed50df --- /dev/null +++ b/src/main/js/widgets/FileInput.jsx @@ -0,0 +1,57 @@ +import React, { useEffect, useRef, useState } from "react"; +import Uppy from '@uppy/core'; +import XHRUpload from '@uppy/xhr-upload'; +import ThumbnailGenerator from '@uppy/thumbnail-generator'; +import { Dashboard } from '@uppy/react'; + +// Don't forget the CSS: core and the UI components + plugins you are using. +import '@uppy/core/dist/style.min.css'; +import '@uppy/dashboard/dist/style.min.css'; +import '@uppy/webcam/dist/style.min.css'; +import { AttachmentsArea } from "../../../auto/js/widgets"; +import { rest } from "../../../auto/js/services"; +import { FILE_UPLOADED_EVENT } from "../../../auto/js/events/Gui"; +import './file.css'; + + +export const FileInput = (props) => { + + const uppy = new Uppy().use(XHRUpload, {}).use(ThumbnailGenerator, { + thumbnailWidth: 100, // Adjust the thumbnail width as needed' + });; + + uppy.getPlugin("XHRUpload").setOptions({ + endpoint: props.uploadUrl + }) + + uppy.on('file-added', (file) => { + uppy.getPlugin("XHRUpload").setOptions({ + headers: { + 'Authorization': `Bearer ${rest.getBearerToken()}`, + } + }) + }) + uppy.on('thumbnail:generated', (file, preview) => { + fetchBlobAsUint8Array(preview).then((blob) => { + uppy.setFileMeta(file.id, { + preview: blob + }); + uppy.upload(); + }) + }); + uppy.on('upload-success', (file, response) => { + FILE_UPLOADED_EVENT.publish({id: response.body.id, name: file.name}); + }) + + return ( + <> + +{ (!props.readOnly)?:null +} + ) +} + +async function fetchBlobAsUint8Array(blobUrl) { + const response = await fetch(blobUrl); + return await response.blob(); +} \ No newline at end of file diff --git a/src/main/js/widgets/JumpingGameComponent.jsx b/src/main/js/widgets/JumpingGameComponent.jsx new file mode 100644 index 0000000..bf7775c --- /dev/null +++ b/src/main/js/widgets/JumpingGameComponent.jsx @@ -0,0 +1,1394 @@ +import React from 'react'; +import * as THREE from "three"; +import './jumping-game.css'; +//THREEJS RELATED VARIABLES +export const JumpingGameComponent = () => { + var scene, + camera, fieldOfView, aspectRatio, nearPlane, farPlane, + gobalLight, shadowLight, backLight, + renderer, + container, + controls, + clock; + var delta = 0; + var floorRadius = 200; + var speed = 6; + var distance = 0; + var level = 1; + var levelInterval; + var levelUpdateFreq = 3000; + var initSpeed = 5; + var maxSpeed = 48; + var monsterPos = .65; + var monsterPosTarget = .65; + var floorRotation = 0; + var collisionObstacle = 10; + var collisionBonus = 20; + var gameStatus = "play"; + var cameraPosGame = 160; + var cameraPosGameOver = 260; + var monsterAcceleration = 0.004; + var malusClearColor = 0xb44b39; + var malusClearAlpha = 0; + var audio = new Audio('https://s3-us-west-2.amazonaws.com/s.cdpn.io/264161/Antonio-Vivaldi-Summer_01.mp3'); + + var fieldGameOver, fieldDistance; + + //SCREEN & MOUSE VARIABLES + + var HEIGHT, WIDTH, windowHalfX, windowHalfY, + mousePos = { + x: 0, + y: 0 + }; + + //3D OBJECTS VARIABLES + + var hero; + + + // Materials + var blackMat = new THREE.MeshPhongMaterial({ + color: 0x100707, + shading:THREE.FlatShading, + }); + + var brownMat = new THREE.MeshPhongMaterial({ + color: 0xb44b39, + shininess:0, + shading:THREE.FlatShading, + }); + + var greenMat = new THREE.MeshPhongMaterial({ + color: 0x7abf8e, + shininess:0, + shading:THREE.FlatShading, + }); + + var pinkMat = new THREE.MeshPhongMaterial({ + color: 0xdc5f45,//0xb43b29,//0xff5b49, + shininess:0, + shading:THREE.FlatShading, + }); + + var lightBrownMat = new THREE.MeshPhongMaterial({ + color: 0xe07a57, + shading:THREE.FlatShading, + }); + + var whiteMat = new THREE.MeshPhongMaterial({ + color: 0xa49789, + shading:THREE.FlatShading, + }); + var skinMat = new THREE.MeshPhongMaterial({ + color: 0xff9ea5, + shading:THREE.FlatShading + }); + + + // OTHER VARIABLES + + var PI = Math.PI; + + //INIT THREE JS, SCREEN AND MOUSE EVENTS + + function initScreenAnd3D() { + + HEIGHT = window.innerHeight; + WIDTH = window.innerWidth; + windowHalfX = WIDTH / 2; + windowHalfY = HEIGHT / 2; + + scene = new THREE.Scene(); + + scene.fog = new THREE.Fog(0xd6eae6, 160,350); + + aspectRatio = WIDTH / HEIGHT; + fieldOfView = 50; + nearPlane = 1; + farPlane = 2000; + camera = new THREE.PerspectiveCamera( + fieldOfView, + aspectRatio, + nearPlane, + farPlane + ); + camera.position.x = 0; + camera.position.z = cameraPosGame; + camera.position.y = 30; + camera.lookAt(new THREE.Vector3(0, 30, 0)); + + renderer = new THREE.WebGLRenderer({ + alpha: true, + antialias: true + }); + renderer.setPixelRatio(window.devicePixelRatio); + renderer.setClearColor( malusClearColor, malusClearAlpha); + + renderer.setSize(WIDTH, HEIGHT); + renderer.shadowMap.enabled = true; + + container = document.getElementById('world'); + container.appendChild(renderer.domElement); + + window.addEventListener('resize', handleWindowResize, false); + document.addEventListener('mousedown', handleMouseDown, false); + document.addEventListener("touchend", handleMouseDown, false); + + /* + controls = new THREE.OrbitControls(camera, renderer.domElement); + //controls.minPolarAngle = -Math.PI / 2; + //controls.maxPolarAngle = Math.PI / 2; + //controls.noZoom = true; + controls.noPan = true; + //*/ + + clock = new THREE.Clock(); + + } + + function handleWindowResize() { + HEIGHT = window.innerHeight; + WIDTH = window.innerWidth; + windowHalfX = WIDTH / 2; + windowHalfY = HEIGHT / 2; + renderer.setSize(WIDTH, HEIGHT); + camera.aspect = WIDTH / HEIGHT; + camera.updateProjectionMatrix(); + } + + + function handleMouseDown(event){ + if (gameStatus == "play") hero.jump(); + else if (gameStatus == "readyToReplay"){ + replay(); + } + } + + function createLights() { + globalLight = new THREE.AmbientLight(0xffffff, .9); + + shadowLight = new THREE.DirectionalLight(0xffffff, 1); + shadowLight.position.set(-30, 40, 20); + shadowLight.castShadow = true; + shadowLight.shadow.camera.left = -400; + shadowLight.shadow.camera.right = 400; + shadowLight.shadow.camera.top = 400; + shadowLight.shadow.camera.bottom = -400; + shadowLight.shadow.camera.near = 1; + shadowLight.shadow.camera.far = 2000; + shadowLight.shadow.mapSize.width = shadowLight.shadow.mapSize.height = 2048; + + scene.add(globalLight); + scene.add(shadowLight); + + } + + function createFloor() { + + floorShadow = new THREE.Mesh(new THREE.SphereGeometry(floorRadius, 50, 50), new THREE.MeshPhongMaterial({ + color: 0x7abf8e, + specular:0x000000, + shininess:1, + transparent:true, + opacity:.5 + })); + //floorShadow.rotation.x = -Math.PI / 2; + floorShadow.receiveShadow = true; + + floorGrass = new THREE.Mesh(new THREE.SphereGeometry(floorRadius-.5, 50, 50), new THREE.MeshBasicMaterial({ + color: 0x7abf8e + })); + //floor.rotation.x = -Math.PI / 2; + floorGrass.receiveShadow = false; + + floor = new THREE.Group(); + floor.position.y = -floorRadius; + + floor.add(floorShadow); + floor.add(floorGrass); + scene.add(floor); + + } + + Hero = function() { + this.status = "running"; + this.runningCycle = 0; + this.mesh = new THREE.Group(); + this.body = new THREE.Group(); + this.mesh.add(this.body); + + var torsoGeom = new THREE.CubeGeometry(7, 7, 10, 1); + + this.torso = new THREE.Mesh(torsoGeom, brownMat); + this.torso.position.z = 0; + this.torso.position.y = 7; + this.torso.castShadow = true; + this.body.add(this.torso); + + var pantsGeom = new THREE.CubeGeometry(9, 9, 5, 1); + this.pants = new THREE.Mesh(pantsGeom, whiteMat); + this.pants.position.z = -3; + this.pants.position.y = 0; + this.pants.castShadow = true; + this.torso.add(this.pants); + + var tailGeom = new THREE.CubeGeometry(3, 3, 3, 1); + tailGeom.applyMatrix(new THREE.Matrix4().makeTranslation(0,0,-2)); + this.tail = new THREE.Mesh(tailGeom, lightBrownMat); + this.tail.position.z = -4; + this.tail.position.y = 5; + this.tail.castShadow = true; + this.torso.add(this.tail); + + this.torso.rotation.x = -Math.PI/8; + + var headGeom = new THREE.CubeGeometry(10, 10, 13, 1); + + headGeom.applyMatrix(new THREE.Matrix4().makeTranslation(0,0,7.5)); + this.head = new THREE.Mesh(headGeom, brownMat); + this.head.position.z = 2; + this.head.position.y = 11; + this.head.castShadow = true; + this.body.add(this.head); + + var cheekGeom = new THREE.CubeGeometry(1, 4, 4, 1); + this.cheekR = new THREE.Mesh(cheekGeom, pinkMat); + this.cheekR.position.x = -5; + this.cheekR.position.z = 7; + this.cheekR.position.y = -2.5; + this.cheekR.castShadow = true; + this.head.add(this.cheekR); + + this.cheekL = this.cheekR.clone(); + this.cheekL.position.x = - this.cheekR.position.x; + this.head.add(this.cheekL); + + + var noseGeom = new THREE.CubeGeometry(6, 6, 3, 1); + this.nose = new THREE.Mesh(noseGeom, lightBrownMat); + this.nose.position.z = 13.5; + this.nose.position.y = 2.6; + this.nose.castShadow = true; + this.head.add(this.nose); + + var mouthGeom = new THREE.CubeGeometry(4, 2, 4, 1); + mouthGeom.applyMatrix(new THREE.Matrix4().makeTranslation(0,0,3)); + mouthGeom.applyMatrix(new THREE.Matrix4().makeRotationX(Math.PI/12)); + this.mouth = new THREE.Mesh(mouthGeom, brownMat); + this.mouth.position.z = 8; + this.mouth.position.y = -4; + this.mouth.castShadow = true; + this.head.add(this.mouth); + + + var pawFGeom = new THREE.CubeGeometry(3,3,3, 1); + this.pawFR = new THREE.Mesh(pawFGeom, lightBrownMat); + this.pawFR.position.x = -2; + this.pawFR.position.z = 6; + this.pawFR.position.y = 1.5; + this.pawFR.castShadow = true; + this.body.add(this.pawFR); + + this.pawFL = this.pawFR.clone(); + this.pawFL.position.x = - this.pawFR.position.x; + this.pawFL.castShadow = true; + this.body.add(this.pawFL); + + var pawBGeom = new THREE.CubeGeometry(3,3,6, 1); + this.pawBL = new THREE.Mesh(pawBGeom, lightBrownMat); + this.pawBL.position.y = 1.5; + this.pawBL.position.z = 0; + this.pawBL.position.x = 5; + this.pawBL.castShadow = true; + this.body.add(this.pawBL); + + this.pawBR = this.pawBL.clone(); + this.pawBR.position.x = - this.pawBL.position.x; + this.pawBR.castShadow = true; + this.body.add(this.pawBR); + + var earGeom = new THREE.CubeGeometry(7, 18, 2, 1); + earGeom.vertices[6].x+=2; + earGeom.vertices[6].z+=.5; + + earGeom.vertices[7].x+=2; + earGeom.vertices[7].z-=.5; + + earGeom.vertices[2].x-=2; + earGeom.vertices[2].z-=.5; + + earGeom.vertices[3].x-=2; + earGeom.vertices[3].z+=.5; + earGeom.applyMatrix(new THREE.Matrix4().makeTranslation(0,9,0)); + + this.earL = new THREE.Mesh(earGeom, brownMat); + this.earL.position.x = 2; + this.earL.position.z = 2.5; + this.earL.position.y = 5; + this.earL.rotation.z = -Math.PI/12; + this.earL.castShadow = true; + this.head.add(this.earL); + + this.earR = this.earL.clone(); + this.earR.position.x = -this.earL.position.x; + this.earR.rotation.z = -this.earL.rotation.z; + this.earR.castShadow = true; + this.head.add(this.earR); + + var eyeGeom = new THREE.CubeGeometry(2,4,4); + + this.eyeL = new THREE.Mesh(eyeGeom, whiteMat); + this.eyeL.position.x = 5; + this.eyeL.position.z = 5.5; + this.eyeL.position.y = 2.9; + this.eyeL.castShadow = true; + this.head.add(this.eyeL); + + var irisGeom = new THREE.CubeGeometry(.6,2,2); + + this.iris = new THREE.Mesh(irisGeom, blackMat); + this.iris.position.x = 1.2; + this.iris.position.y = 1; + this.iris.position.z = 1; + this.eyeL.add(this.iris); + + this.eyeR = this.eyeL.clone(); + this.eyeR.children[0].position.x = -this.iris.position.x; + + + this.eyeR.position.x = -this.eyeL.position.x; + this.head.add(this.eyeR); + + this.body.traverse(function(object) { + if (object instanceof THREE.Mesh) { + object.castShadow = true; + object.receiveShadow = true; + } + }); + } + + BonusParticles = function(){ + this.mesh = new THREE.Group(); + var bigParticleGeom = new THREE.CubeGeometry(10,10,10,1); + var smallParticleGeom = new THREE.CubeGeometry(5,5,5,1); + this.parts = []; + for (var i=0; i<10; i++){ + var partPink = new THREE.Mesh(bigParticleGeom, pinkMat); + var partGreen = new THREE.Mesh(smallParticleGeom, greenMat); + partGreen.scale.set(.5,.5,.5); + this.parts.push(partPink); + this.parts.push(partGreen); + this.mesh.add(partPink); + this.mesh.add(partGreen); + } + } + + BonusParticles.prototype.explose = function(){ + var _this = this; + var explosionSpeed = .5; + for(var i=0; i.2) TweenMax.to([this.eyeR.scale, this.eyeL.scale], sp/8, {y:0, ease:Power1.easeInOut, yoyo:true, repeat:1}); + + } + + Hero.prototype.hang = function(){ + var _this = this; + var sp = 1; + var ease = Power4.easeOut; + + TweenMax.killTweensOf(this.eyeL.scale); + TweenMax.killTweensOf(this.eyeR.scale); + + this.body.rotation.x = 0; + this.torso.rotation.x = 0; + this.body.position.y = 0; + this.torso.position.y = 7; + + TweenMax.to(this.mesh.rotation, sp, {y:0, ease:ease}); + TweenMax.to(this.mesh.position, sp, {y:-7, z:6, ease:ease}); + TweenMax.to(this.head.rotation, sp, {x:Math.PI/6, ease:ease, onComplete:function(){_this.nod();}}); + + TweenMax.to(this.earL.rotation, sp, {x:Math.PI/3, ease:ease}); + TweenMax.to(this.earR.rotation, sp, {x:Math.PI/3, ease:ease}); + + TweenMax.to(this.pawFL.position, sp, {y:-1, z:3, ease:ease}); + TweenMax.to(this.pawFR.position, sp, {y:-1, z:3, ease:ease}); + TweenMax.to(this.pawBL.position, sp, {y:-2, z:-3, ease:ease}); + TweenMax.to(this.pawBR.position, sp, {y:-2, z:-3, ease:ease}); + + TweenMax.to(this.eyeL.scale, sp, {y:1, ease:ease}); + TweenMax.to(this.eyeR.scale, sp, {y:1, ease:ease}); + } + + Monster.prototype.nod = function(){ + var _this = this; + var sp = 1 + Math.random()*2; + + // HEAD + var tHeadRotY = -Math.PI/3 + Math.random()*.5; + var tHeadRotX = Math.PI/3 - .2 + Math.random()*.4; + TweenMax.to(this.head.rotation, sp, {x:tHeadRotX, y:tHeadRotY, ease:Power4.easeInOut, onComplete:function(){_this.nod()}}); + + // TAIL + + var tTailRotY = -Math.PI/4; + TweenMax.to(this.tail.rotation, sp/8, {y:tTailRotY, ease:Power1.easeInOut, yoyo:true, repeat:8}); + + // EYES + + TweenMax.to([this.eyeR.scale, this.eyeL.scale], sp/20, {y:0, ease:Power1.easeInOut, yoyo:true, repeat:1}); + } + + Monster.prototype.sit = function(){ + var sp = 1.2; + var ease = Power4.easeOut; + var _this = this; + TweenMax.to(this.torso.rotation, sp, {x:-1.3, ease:ease}); + TweenMax.to(this.torso.position, sp, {y:-5, ease:ease, onComplete:function(){ + _this.nod(); + gameStatus = "readyToReplay"; + }}); + + TweenMax.to(this.head.rotation, sp, {x:Math.PI/3, y :-Math.PI/3, ease:ease}); + TweenMax.to(this.tail.rotation, sp, {x:2, y:Math.PI/4, ease:ease}); + TweenMax.to(this.pawBL.rotation, sp, {x:-.1, ease:ease}); + TweenMax.to(this.pawBR.rotation, sp, {x:-.1, ease:ease}); + TweenMax.to(this.pawFL.rotation, sp, {x:1, ease:ease}); + TweenMax.to(this.pawFR.rotation, sp, {x:1, ease:ease}); + TweenMax.to(this.mouth.rotation, sp, {x:.3, ease:ease}); + TweenMax.to(this.eyeL.scale, sp, {y:1, ease:ease}); + TweenMax.to(this.eyeR.scale, sp, {y:1, ease:ease}); + + //TweenMax.to(this.body.rotation, sp, {y:Math.PI/4}); + + } + + + Carrot = function() { + this.angle = 0; + this.mesh = new THREE.Group(); + + var bodyGeom = new THREE.CylinderGeometry(5,3, 10, 4,1); + bodyGeom.vertices[8].y+=2; + bodyGeom.vertices[9].y-=3; + + this.body = new THREE.Mesh(bodyGeom, pinkMat); + + var leafGeom = new THREE.CubeGeometry(5,10,1,1); + leafGeom.applyMatrix(new THREE.Matrix4().makeTranslation(0,5,0)); + leafGeom.vertices[2].x-=1; + leafGeom.vertices[3].x-=1; + leafGeom.vertices[6].x+=1; + leafGeom.vertices[7].x+=1; + + this.leaf1 = new THREE.Mesh(leafGeom,greenMat); + this.leaf1.position.y = 7; + this.leaf1.rotation.z = .3; + this.leaf1.rotation.x = .2; + + this.leaf2 = this.leaf1.clone(); + this.leaf2.scale.set(1,1.3,1); + this.leaf2.position.y = 7; + this.leaf2.rotation.z = -.3; + this.leaf2.rotation.x = -.2; + + this.mesh.add(this.body); + this.mesh.add(this.leaf1); + this.mesh.add(this.leaf2); + + this.body.traverse(function(object) { + if (object instanceof THREE.Mesh) { + object.castShadow = true; + object.receiveShadow = true; + } + }); + } + + Hedgehog = function() { + this.angle = 0; + this.status="ready"; + this.mesh = new THREE.Group(); + var bodyGeom = new THREE.CubeGeometry(6,6,6,1); + this.body = new THREE.Mesh(bodyGeom, blackMat); + + var headGeom = new THREE.CubeGeometry(5,5,7,1); + this.head= new THREE.Mesh(headGeom, lightBrownMat); + this.head.position.z = 6; + this.head.position.y = -.5; + + var noseGeom = new THREE.CubeGeometry(1.5,1.5,1.5,1); + this.nose = new THREE.Mesh(noseGeom, blackMat); + this.nose.position.z = 4; + this.nose.position.y = 2; + + var eyeGeom = new THREE.CubeGeometry(1,3,3); + + this.eyeL = new THREE.Mesh(eyeGeom, whiteMat); + this.eyeL.position.x = 2.2; + this.eyeL.position.z = -.5; + this.eyeL.position.y = .8; + this.eyeL.castShadow = true; + this.head.add(this.eyeL); + + var irisGeom = new THREE.CubeGeometry(.5,1,1); + + this.iris = new THREE.Mesh(irisGeom, blackMat); + this.iris.position.x = .5; + this.iris.position.y = .8; + this.iris.position.z = .8; + this.eyeL.add(this.iris); + + this.eyeR = this.eyeL.clone(); + this.eyeR.children[0].position.x = -this.iris.position.x; + this.eyeR.position.x = -this.eyeL.position.x; + + var spikeGeom = new THREE.CubeGeometry(.5,2,.5,1); + spikeGeom.applyMatrix(new THREE.Matrix4().makeTranslation(0,1,0)); + + for (var i=0; i<9; i++){ + var row = (i%3); + var col = Math.floor(i/3); + var sb = new THREE.Mesh(spikeGeom, blackMat); + sb.rotation.x =-Math.PI/2 + (Math.PI/12*row) -.5 + Math.random(); + sb.position.z = -3; + sb.position.y = -2 + row*2; + sb.position.x = -2 + col*2; + this.body.add(sb); + var st = new THREE.Mesh(spikeGeom, blackMat); + st.position.y = 3; + st.position.x = -2 + row*2; + st.position.z = -2 + col*2; + st.rotation.z = Math.PI/6 - (Math.PI/6*row) -.5 + Math.random(); + this.body.add(st); + + var sr = new THREE.Mesh(spikeGeom, blackMat); + sr.position.x = 3; + sr.position.y = -2 + row*2; + sr.position.z = -2 + col*2; + sr.rotation.z = -Math.PI/2 + (Math.PI/12*row) -.5 + Math.random(); + this.body.add(sr); + + var sl = new THREE.Mesh(spikeGeom, blackMat); + sl.position.x = -3; + sl.position.y = -2 + row*2; + sl.position.z = -2 + col*2; + sl.rotation.z = Math.PI/2 - (Math.PI/12*row) -.5 + Math.random();; + this.body.add(sl); + } + + this.head.add(this.eyeR); + var earGeom = new THREE.CubeGeometry(2, 2, .5, 1); + this.earL = new THREE.Mesh(earGeom, lightBrownMat); + this.earL.position.x = 2.5; + this.earL.position.z = -2.5; + this.earL.position.y = 2.5; + this.earL.rotation.z = -Math.PI/12; + this.earL.castShadow = true; + this.head.add(this.earL); + + this.earR = this.earL.clone(); + this.earR.position.x = -this.earL.position.x; + this.earR.rotation.z = -this.earL.rotation.z; + this.earR.castShadow = true; + this.head.add(this.earR); + + var mouthGeom = new THREE.CubeGeometry( 1, 1,.5, 1); + this.mouth = new THREE.Mesh(mouthGeom, blackMat); + this.mouth.position.z = 3.5; + this.mouth.position.y = -1.5; + this.head.add(this.mouth); + + + this.mesh.add(this.body); + this.body.add(this.head); + this.head.add(this.nose); + + this.mesh.traverse(function(object) { + if (object instanceof THREE.Mesh) { + object.castShadow = true; + object.receiveShadow = true; + } + }); + } + + Hedgehog.prototype.nod = function(){ + var _this = this; + var speed = .1 + Math.random()*.5; + var angle = -Math.PI/4 + Math.random()*Math.PI/2; + TweenMax.to(this.head.rotation, speed, {y:angle, onComplete:function(){ + _this.nod(); + }}); + } + + + function createHero() { + hero = new Hero(); + hero.mesh.rotation.y = Math.PI/2; + scene.add(hero.mesh); + hero.nod(); + } + + function createMonster() { + + monster = new Monster(); + monster.mesh.position.z = 20; + //monster.mesh.scale.set(1.2,1.2,1.2); + scene.add(monster.mesh); + updateMonsterPosition(); + + } + + function updateMonsterPosition(){ + monster.run(); + monsterPosTarget -= delta*monsterAcceleration; + monsterPos += (monsterPosTarget-monsterPos) *delta; + if (monsterPos < .56){ + gameOver(); + } + + var angle = Math.PI*monsterPos; + monster.mesh.position.y = - floorRadius + Math.sin(angle)*(floorRadius + 12); + monster.mesh.position.x = Math.cos(angle)*(floorRadius+15); + monster.mesh.rotation.z = -Math.PI/2 + angle; + } + + function gameOver(){ + fieldGameOver.className = "show"; + gameStatus = "gameOver"; + monster.sit(); + hero.hang(); + monster.heroHolder.add(hero.mesh); + TweenMax.to(this, 1, {speed:0}); + TweenMax.to(camera.position, 3, {z:cameraPosGameOver, y: 60, x:-30}); + carrot.mesh.visible = false; + obstacle.mesh.visible = false; + clearInterval(levelInterval); + } + + function replay(){ + + gameStatus = "preparingToReplay" + + fieldGameOver.className = ""; + + TweenMax.killTweensOf(monster.pawFL.position); + TweenMax.killTweensOf(monster.pawFR.position); + TweenMax.killTweensOf(monster.pawBL.position); + TweenMax.killTweensOf(monster.pawBR.position); + + TweenMax.killTweensOf(monster.pawFL.rotation); + TweenMax.killTweensOf(monster.pawFR.rotation); + TweenMax.killTweensOf(monster.pawBL.rotation); + TweenMax.killTweensOf(monster.pawBR.rotation); + + TweenMax.killTweensOf(monster.tail.rotation); + TweenMax.killTweensOf(monster.head.rotation); + TweenMax.killTweensOf(monster.eyeL.scale); + TweenMax.killTweensOf(monster.eyeR.scale); + + //TweenMax.killTweensOf(hero.head.rotation); + + monster.tail.rotation.y = 0; + + TweenMax.to(camera.position, 3, {z:cameraPosGame, x:0, y:30, ease:Power4.easeInOut}); + TweenMax.to(monster.torso.rotation,2, {x:0, ease:Power4.easeInOut}); + TweenMax.to(monster.torso.position,2, {y:0, ease:Power4.easeInOut}); + TweenMax.to(monster.pawFL.rotation,2, {x:0, ease:Power4.easeInOut}); + TweenMax.to(monster.pawFR.rotation,2, {x:0, ease:Power4.easeInOut}); + TweenMax.to(monster.mouth.rotation,2, {x:.5, ease:Power4.easeInOut}); + + + TweenMax.to(monster.head.rotation,2, {y:0, x:-.3, ease:Power4.easeInOut}); + + TweenMax.to(hero.mesh.position, 2, { x:20, ease:Power4.easeInOut}); + TweenMax.to(hero.head.rotation, 2, { x:0, y:0, ease:Power4.easeInOut}); + TweenMax.to(monster.mouth.rotation, 2, {x:.2, ease:Power4.easeInOut}); + TweenMax.to(monster.mouth.rotation, 1, {x:.4, ease:Power4.easeIn, delay: 1, onComplete:function(){ + + resetGame(); + }}); + + } + + Fir = function() { + var height = 200; + var truncGeom = new THREE.CylinderGeometry(2,2,height, 6,1); + truncGeom.applyMatrix(new THREE.Matrix4().makeTranslation(0,height/2,0)); + this.mesh = new THREE.Mesh(truncGeom, greenMat); + this.mesh.castShadow = true; + } + + var firs = new THREE.Group(); + + function createFirs(){ + + var nTrees = 100; + for(var i=0; i< nTrees; i++){ + var phi = i*(Math.PI*2)/nTrees; + var theta = Math.PI/2; + //theta += .25 + Math.random()*.3; + theta += (Math.random()>.05)? .25 + Math.random()*.3 : - .35 - Math.random()*.1; + + var fir = new Tree(); + fir.mesh.position.x = Math.sin(theta)*Math.cos(phi)*floorRadius; + fir.mesh.position.y = Math.sin(theta)*Math.sin(phi)*(floorRadius-10); + fir.mesh.position.z = Math.cos(theta)*floorRadius; + + var vec = fir.mesh.position.clone(); + var axis = new THREE.Vector3(0,1,0); + fir.mesh.quaternion.setFromUnitVectors(axis, vec.clone().normalize()); + floor.add(fir.mesh); + } + } + + function createCarrot(){ + carrot = new Carrot(); + scene.add(carrot.mesh); + } + + function updateCarrotPosition(){ + carrot.mesh.rotation.y += delta * 6; + carrot.mesh.rotation.z = Math.PI/2 - (floorRotation+carrot.angle); + carrot.mesh.position.y = -floorRadius + Math.sin(floorRotation+carrot.angle) * (floorRadius+50); + carrot.mesh.position.x = Math.cos(floorRotation+carrot.angle) * (floorRadius+50); + + } + + function updateObstaclePosition(){ + if (obstacle.status=="flying")return; + + // TODO fix this, + if (floorRotation+obstacle.angle > 2.5 ){ + obstacle.angle = -floorRotation + Math.random()*.3; + obstacle.body.rotation.y = Math.random() * Math.PI*2; + } + + obstacle.mesh.rotation.z = floorRotation + obstacle.angle - Math.PI/2; + obstacle.mesh.position.y = -floorRadius + Math.sin(floorRotation+obstacle.angle) * (floorRadius+3); + obstacle.mesh.position.x = Math.cos(floorRotation+obstacle.angle) * (floorRadius+3); + + } + + function updateFloorRotation(){ + floorRotation += delta*.03 * speed; + floorRotation = floorRotation%(Math.PI*2); + floor.rotation.z = floorRotation; + } + + function createObstacle(){ + obstacle = new Hedgehog(); + obstacle.body.rotation.y = -Math.PI/2; + obstacle.mesh.scale.set(1.1,1.1,1.1); + obstacle.mesh.position.y = floorRadius+4; + obstacle.nod(); + scene.add(obstacle.mesh); + } + + function createBonusParticles(){ + bonusParticles = new BonusParticles(); + bonusParticles.mesh.visible = false; + scene.add(bonusParticles.mesh); + + } + + + + function checkCollision(){ + var db = hero.mesh.position.clone().sub(carrot.mesh.position.clone()); + var dm = hero.mesh.position.clone().sub(obstacle.mesh.position.clone()); + + if(db.length() < collisionBonus){ + getBonus(); + } + + if(dm.length() < collisionObstacle && obstacle.status != "flying"){ + getMalus(); + } + } + + function getBonus(){ + bonusParticles.mesh.position.copy(carrot.mesh.position); + bonusParticles.mesh.visible = true; + bonusParticles.explose(); + carrot.angle += Math.PI/2; + //speed*=.95; + monsterPosTarget += .025; + + } + + function getMalus(){ + obstacle.status="flying"; + var tx = (Math.random()>.5)? -20-Math.random()*10 : 20+Math.random()*5; + TweenMax.to(obstacle.mesh.position, 4, {x:tx, y:Math.random()*50, z:350, ease:Power4.easeOut}); + TweenMax.to(obstacle.mesh.rotation, 4, {x:Math.PI*3, z:Math.PI*3, y:Math.PI*6, ease:Power4.easeOut, onComplete:function(){ + obstacle.status = "ready"; + obstacle.body.rotation.y = Math.random() * Math.PI*2; + obstacle.angle = -floorRotation - Math.random()*.4; + + obstacle.angle = obstacle.angle%(Math.PI*2); + obstacle.mesh.rotation.x = 0; + obstacle.mesh.rotation.y = 0; + obstacle.mesh.rotation.z = 0; + obstacle.mesh.position.z = 0; + + }}); + // + monsterPosTarget -= .04; + TweenMax.from(this, .5, {malusClearAlpha:.5, onUpdate:function(){ + renderer.setClearColor(malusClearColor, malusClearAlpha ); + }}) + } + + function updateDistance(){ + distance += delta*speed; + var d = distance/2; + fieldDistance.innerHTML = Math.floor(d); + } + + function updateLevel(){ + if (speed >= maxSpeed) return; + level++; + speed += 2; + } + + function loop(){ + delta = clock.getDelta(); + updateFloorRotation(); + + if (gameStatus == "play"){ + + if (hero.status == "running"){ + hero.run(); + } + updateDistance(); + updateMonsterPosition(); + updateCarrotPosition(); + updateObstaclePosition(); + checkCollision(); + } + + render(); + requestAnimationFrame(loop); + } + + function render(){ + renderer.render(scene, camera); + } + + window.addEventListener('load', init, false); + + function init(event){ + initScreenAnd3D(); + createLights(); + createFloor() + createHero(); + createMonster(); + createFirs(); + createCarrot(); + createBonusParticles(); + createObstacle(); + initUI(); + resetGame(); + loop(); + + //setInterval(hero.blink.bind(hero), 3000); + } + + function resetGame(){ + scene.add(hero.mesh); + hero.mesh.rotation.y = Math.PI/2; + hero.mesh.position.y = 0; + hero.mesh.position.z = 0; + hero.mesh.position.x = 0; + + monsterPos = .56; + monsterPosTarget = .65; + speed = initSpeed; + level = 0; + distance = 0; + carrot.mesh.visible = true; + obstacle.mesh.visible = true; + gameStatus = "play"; + hero.status = "running"; + hero.nod(); + audio.play(); + updateLevel(); + levelInterval = setInterval(updateLevel, levelUpdateFreq); + } + + function initUI(){ + fieldDistance = document.getElementById("distValue"); + fieldGameOver = document.getElementById("gameoverInstructions"); + + } + + + + //////////////////////////////////////////////// + // MODELS + //////////////////////////////////////////////// + + // TREE + + Tree = function(){ + this.mesh = new THREE.Object3D(); + this.trunc = new Trunc(); + this.mesh.add(this.trunc.mesh); + } + + + Trunc = function(){ + var truncHeight = 50 + Math.random()*150; + var topRadius = 1+Math.random()*5; + var bottomRadius = 5+Math.random()*5; + var mats = [blackMat, brownMat, pinkMat, whiteMat, greenMat, lightBrownMat, pinkMat]; + var matTrunc = blackMat;//mats[Math.floor(Math.random()*mats.length)]; + var nhSegments = 3;//Math.ceil(2 + Math.random()*6); + var nvSegments = 3;//Math.ceil(2 + Math.random()*6); + var geom = new THREE.CylinderGeometry(topRadius,bottomRadius,truncHeight, nhSegments, nvSegments); + geom.applyMatrix(new THREE.Matrix4().makeTranslation(0,truncHeight/2,0)); + + this.mesh = new THREE.Mesh(geom, matTrunc); + + for (var i=0; i.7){ + var size = Math.random()*3; + var fruitGeometry = new THREE.CubeGeometry(size,size,size,1); + var matFruit = mats[Math.floor(Math.random()*mats.length)]; + var fruit = new THREE.Mesh(fruitGeometry, matFruit); + fruit.position.x = v.x; + fruit.position.y = v.y+3; + fruit.position.z = v.z; + fruit.rotation.x = Math.random()*Math.PI; + fruit.rotation.y = Math.random()*Math.PI; + + this.mesh.add(fruit); + } + + // BRANCHES + + if (Math.random()>.5 && v.y > 10 && v.y < truncHeight - 10){ + var h = 3 + Math.random()*5; + var thickness = .2 + Math.random(); + + var branchGeometry = new THREE.CylinderGeometry(thickness/2, thickness, h, 3, 1); + branchGeometry.applyMatrix(new THREE.Matrix4().makeTranslation(0,h/2,0)); + var branch = new THREE.Mesh(branchGeometry, matTrunc); + branch.position.x = v.x; + branch.position.y = v.y; + branch.position.z = v.z; + + var vec = new THREE.Vector3(v.x, 2, v.z); + var axis = new THREE.Vector3(0,1,0); + branch.quaternion.setFromUnitVectors(axis, vec.clone().normalize()); + + + this.mesh.add(branch); + } + + } + + + this.mesh.castShadow = true; + } + + return ( + <> +
+
+ Game Over +
+
+
distance
+
000
+
+ +
Click to jump — Grab the carrots / avoid the hedgehogs
+ + ) + +} \ No newline at end of file diff --git a/src/main/js/widgets/PersonViewer.jsx b/src/main/js/widgets/PersonViewer.jsx new file mode 100644 index 0000000..1e5f32e --- /dev/null +++ b/src/main/js/widgets/PersonViewer.jsx @@ -0,0 +1,110 @@ +import React, { useState } from "react"; +import { useField } from "formik"; +import { t } from "../../../auto/js/services"; +import { ImageViewer } from "../../../auto/js/widgets"; +import { formatDate, useConstructor } from "../../../auto/js/utils"; +import { geoMetadataLoader } from "../../../auto/js/metadata/GeoMetadataLoader"; + +export const PersonViewer = ({...props}) => { + const [field, meta, helpers] = useField(props.name); + const { value } = meta; + const { setValue } = helpers; + + const onChange = (newData) => { + if (newData != null) { + setValue(newData); + } + } + + useConstructor(() => { + if (props.observable) + props.observable.subscribe(onChange); + }); + + return( + <> + {(value)? + + :null} + + ) +} + +class Person extends React.Component { + constructor(props) { + super(props); + this.formRef = React.createRef() + this.state = { + data: props.data, + loadingMessage: '' + } + } + + componentDidUpdate() { + if (this.state.data !== this.props.data) + this.setState({data: this.props.data}) + } + + render() { + let fullname = ''; + let birthdate; + let birthPlace = []; + if (this.state.data) { + birthdate = this.state.data.birthdate? formatDate(this.state.data.birthdate):'Unknown'; + fullname += this.state.data.firstname ? this.state.data.firstname + ' ' : ''; + fullname += this.state.data.secondname ? this.state.data.secondname + ' ' : ''; + fullname += this.state.data.thirdname ? this.state.data.thirdname + ' ' : ''; + fullname += this.state.data.fourthname ? this.state.data.fourthname + ' ' : ''; + fullname += this.state.data.fifthname ? this.state.data.fifthname + ' ' : ''; + if (this.state.data.birthPlace != null) { + let birthPlaceComponents = this.state.data.birthPlace.split("."); + let place = this.state.data.birthPlace; + birthPlace.push( +

{geoMetadataLoader.getArea(place).name}

+ ) + for (let i = 0; i < birthPlaceComponents.length - 1 ; i ++) { + let parentAreaId = place.substring(0, place.lastIndexOf(".")); + place = parentAreaId; + birthPlace.push( +

{geoMetadataLoader.getArea(parentAreaId).name}

+ ) + } + } + } + + return ( + <> + {(this.state.data)? +
+
+ +
+

Personal Details

+

{fullname}

+

{t`ID`} #: {this.state.data.id}

+

{this.state.data.gender}

+
+
+ +
+
+

{t`Birth Details`}

+

{birthdate}
+ {birthPlace}

+
+
+
+
+

{t`Other Details`}

+

{this.state.data.maritalStatus}

+
+
+
: +
{t`Person not found`}
+ } + + + ) + } +} + diff --git a/src/main/js/widgets/PrintableArea.jsx b/src/main/js/widgets/PrintableArea.jsx new file mode 100644 index 0000000..b6e9b61 --- /dev/null +++ b/src/main/js/widgets/PrintableArea.jsx @@ -0,0 +1,12 @@ +import React from 'react'; + +export class PrintableArea extends React.PureComponent { + constructor(props) { + super(props); + } + + render() { + return this.props.children; + } +}; + diff --git a/src/main/js/widgets/SearchComponent.jsx b/src/main/js/widgets/SearchComponent.jsx new file mode 100644 index 0000000..3fc9768 --- /dev/null +++ b/src/main/js/widgets/SearchComponent.jsx @@ -0,0 +1,31 @@ +import React, { useState } from "react"; +import { useField } from "formik"; +import { FormLabel } from '@mui/material'; +import LoadingOverlay from 'react-loading-overlay-ts'; +import SearchBar from "material-ui-search-bar"; +import { t } from "../../../auto/js/services"; + +export const SearchComponent = (props) => { + const [searchText, setSearchText] = useState(""); + + const onChange = (text) => { + setSearchText(text); + } + const onRequestSearch = () => { + if (searchText != null && searchText != "") { + props.loadData(searchText).then((data) => props.observable.publish(data)); + } + } + + return( + <> + {t(props.name)} + {(!props.readOnly) && } + + ) +} + + diff --git a/src/main/js/widgets/Section.jsx b/src/main/js/widgets/Section.jsx new file mode 100644 index 0000000..16405e7 --- /dev/null +++ b/src/main/js/widgets/Section.jsx @@ -0,0 +1,12 @@ +import React from "react"; +import { t } from "../../../auto/js/services" + +export const Section = ({name}) => { + return ( + <> +
+

{t(name)}

+
+ + ) +} \ No newline at end of file diff --git a/src/main/js/widgets/ToolBar.jsx b/src/main/js/widgets/ToolBar.jsx new file mode 100644 index 0000000..375cc82 --- /dev/null +++ b/src/main/js/widgets/ToolBar.jsx @@ -0,0 +1,48 @@ +import React from 'react'; +import { makeStyles } from '@material-ui/core/styles'; +import AppBar from '@material-ui/core/AppBar'; +import Toolbar from '@material-ui/core/Toolbar'; +import Button from '@material-ui/core/Button'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; + +import { t, rest } from '../../../auto/js/services'; + +import toolbarStyles from './ToolBar.styl'; +import { LanguageSelector } from '../../../auto/js/widgets/LanguageSelector'; + +import { whoami } from '../../../auto/js/users/UserInfo'; +import { UserAvatar } from '../../../auto/js/users/Avatars'; + +const useStyles = makeStyles(theme => ({ + root: { + flexGrow: 1, + }, + menuButton: { + marginRight: theme.spacing(2), + }, + title: { + flexGrow: 1, + }, +})); + +export function ToolBar(props) { + const classes = useStyles(); + + return ( +
+ + + logo.png + + {UserAvatar(whoami())} + + + +
+ ); +} diff --git a/src/main/js/widgets/ToolBar.styl b/src/main/js/widgets/ToolBar.styl new file mode 100644 index 0000000..b58f63d --- /dev/null +++ b/src/main/js/widgets/ToolBar.styl @@ -0,0 +1,477 @@ +.container-fluid { + padding-right: 0px; + padding-left: 0px; + margin-right: auto; + margin-left: auto; +} +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; +} +.collapse { + display: none; + &.in { display: block; } + tr&.in { display: table-row; } + tbody&.in { display: table-row-group; } +} +.logo { + width:36px; + height:36px; + margin-left: 15px; + margin-right: 15px; +} +.nav:before, +.nav:after, +.navbar:before, +.navbar:after, +.navbar-header:before, +.navbar-header:after, +.navbar-collapse:before, +.navbar-collapse:after { + display: table; + content: ""; +} +.nav:after, +.navbar:after, +.navbar-header:after, +.navbar-collapse:after { + clear: both; +} +.nav { + padding-left: 0; + margin-bottom: 0; + list-style: none; +} +.navbar { + position: relative; + min-height: 50px; + border: 1px solid transparent; +} +@media (min-width: 768px) { + .navbar { + border-radius: 4px; + } +} +@media (min-width: 768px) { + .navbar-header { + float: left; + } +} +.navbar-collapse { + padding-right: 0; + padding-left: 0; + overflow-x: visible; + -webkit-overflow-scrolling: touch; + border-top: 1px solid transparent; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1); +} +.navbar-collapse.in { + overflow-y: auto; +} +@media (min-width: 768px) { + .navbar-collapse { + width: auto; + border-top: 0; + -webkit-box-shadow: none; + box-shadow: none; + } + .navbar-collapse.collapse { + display: block !important; + height: auto !important; + padding-bottom: 0; + overflow: visible !important; + } + .navbar-collapse.in { + overflow-y: visible; + } + .navbar-fixed-top .navbar-collapse, + .navbar-static-top .navbar-collapse, + .navbar-fixed-bottom .navbar-collapse { + padding-right: 0; + padding-left: 0; + } +} +.navbar-fixed-top .navbar-collapse, +.navbar-fixed-bottom .navbar-collapse { + max-height: 340px; +} +@media (max-device-width: 480px) and (orientation: landscape) { + .navbar-fixed-top .navbar-collapse, + .navbar-fixed-bottom .navbar-collapse { + max-height: 200px; + } +} +.container > .navbar-header, +.container-fluid > .navbar-header, +.container > .navbar-collapse, +.container-fluid > .navbar-collapse { + margin-right: 0; + margin-left: 0; +} +@media (min-width: 768px) { + .container > .navbar-header, + .container-fluid > .navbar-header, + .container > .navbar-collapse, + .container-fluid > .navbar-collapse { + margin-right: 0; + margin-left: 0; + } +} +.navbar-static-top { + z-index: 1000; + border-width: 0 0 1px; +} +@media (min-width: 768px) { + .navbar-static-top { + border-radius: 0; + } +} +.navbar-fixed-top, +.navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + z-index: 1030; +} +@media (min-width: 768px) { + .navbar-fixed-top, + .navbar-fixed-bottom { + border-radius: 0; + } +} +.navbar-fixed-top { + top: 0; + border-width: 0 0 1px; +} +.navbar-fixed-bottom { + bottom: 0; + margin-bottom: 0; + border-width: 1px 0 0; +} +.navbar-brand { + float: left; + height: 50px; + padding: 15px 15px; + font-size: 18px; + line-height: 20px; +} +.navbar-brand, +.navbar-brand:hover, +.navbar-brand:focus { + text-decoration: none; +} +.navbar-brand > img { + display: block; +} +@media (min-width: 768px) { + .navbar > .container .navbar-brand, + .navbar > .container-fluid .navbar-brand { + margin-left: 0; + } +} +.navbar-toggle { + position: relative; + float: right; + padding: 9px 10px; + margin-top: 8px; + margin-right: 15px; + margin-bottom: 8px; + background-color: transparent; + background-image: none; + border: 1px solid transparent; + border-radius: 4px; + cursor: pointer; +} +.navbar-toggle:focus { + outline: 0; +} +.navbar-toggle .icon-bar { + display: block; + width: 22px; + height: 2px; + border-radius: 1px; +} +.navbar-toggle .icon-bar + .icon-bar { + margin-top: 4px; +} +@media (min-width: 768px) { + .navbar-toggle { + display: none; + } +} +.navbar-nav { + margin: 7.5px 0; +} +.navbar-nav > li > a { + padding-top: 10px; + padding-bottom: 10px; + line-height: 20px; +} +@media (max-width: 767px) { + .navbar-nav .open .dropdown-menu { + position: static; + float: none; + width: auto; + margin-top: 0; + background-color: transparent; + border: 0; + -webkit-box-shadow: none; + box-shadow: none; + } + .navbar-nav .open .dropdown-menu > li > a, + .navbar-nav .open .dropdown-menu .dropdown-header { + padding: 5px 15px 5px 25px; + } + .navbar-nav .open .dropdown-menu > li > a { + line-height: 20px; + } + .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-nav .open .dropdown-menu > li > a:focus { + background-image: none; + } +} +@media (min-width: 768px) { + .navbar-nav { + float: left; + margin: 0; + } + .navbar-nav > li { + float: left; + } + .navbar-nav > li > a { + padding-top: 15px; + padding-bottom: 15px; + } +} +.navbar-form { + padding: 10px 15px; + margin-top: 8px; + margin-right: 0; + margin-bottom: 8px; + margin-left: 0; + border-top: 1px solid transparent; + border-bottom: 1px solid transparent; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1); +} +@media (min-width: 768px) { + .navbar-form .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .navbar-form .form-control-static { + display: inline-block; + } + .navbar-form .input-group { + display: inline-table; + vertical-align: middle; + } + .navbar-form .input-group .input-group-addon, + .navbar-form .input-group .input-group-btn, + .navbar-form .input-group .form-control { + width: auto; + } + .navbar-form .input-group > .form-control { + width: 100%; + } + .navbar-form .control-label { + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .radio, + .navbar-form .checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .radio label, + .navbar-form .checkbox label { + padding-left: 0; + } + .navbar-form .radio input[type="radio"], + .navbar-form .checkbox input[type="checkbox"] { + position: relative; + margin-left: 0; + } + .navbar-form .has-feedback .form-control-feedback { + top: 0; + } +} +@media (max-width: 767px) { + .navbar-form .form-group { + margin-bottom: 5px; + } + .navbar-form .form-group:last-child { + margin-bottom: 0; + } +} +@media (min-width: 768px) { + .navbar-form { + width: auto; + padding-top: 0; + padding-bottom: 0; + margin-right: 0; + margin-left: 0; + border: 0; + -webkit-box-shadow: none; + box-shadow: none; + } +} +.navbar-nav > li > .dropdown-menu { + margin-top: 0; + border-top-left-radius: 0; + border-top-right-radius: 0; +} +.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu { + margin-bottom: 0; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.navbar-btn { + margin-top: 8px; + margin-bottom: 8px; +} +.navbar-btn.btn-sm { + margin-top: 10px; + margin-bottom: 10px; +} +.navbar-btn.btn-xs { + margin-top: 14px; + margin-bottom: 14px; +} +.navbar-text { + margin-top: 15px; + margin-bottom: 15px; +} +@media (min-width: 768px) { + .navbar-text { + float: left; + margin-right: 15px; + margin-left: 15px; + } +} +@media (min-width: 768px) { + .navbar-left { + float: left !important; + } + .navbar-right { + float: right !important; + margin-right:0; + } + .navbar-right ~ .navbar-right { + margin-right: 0; + } +} +.navbar-default { + background-color: #f8f8f8; + border-color: #e7e7e7; +} +.navbar-default .navbar-brand { + color: #777; +} +.navbar-default .navbar-brand:hover, +.navbar-default .navbar-brand:focus { + color: #5e5e5e; + background-color: transparent; +} +.navbar-default .navbar-text { + color: #777; +} +.navbar-default .navbar-nav > li > a { + color: #777; +} +.navbar-default .navbar-nav > li > a:hover, +.navbar-default .navbar-nav > li > a:focus { + color: #333; + background-color: transparent; +} +.navbar-default .navbar-nav > .active > a, +.navbar-default .navbar-nav > .active > a:hover, +.navbar-default .navbar-nav > .active > a:focus { + color: #555; + background-color: #e7e7e7; +} +.navbar-default .navbar-nav > .disabled > a, +.navbar-default .navbar-nav > .disabled > a:hover, +.navbar-default .navbar-nav > .disabled > a:focus { + color: #ccc; + background-color: transparent; +} +.navbar-default .navbar-toggle { + border-color: #ddd; +} +.navbar-default .navbar-toggle:hover, +.navbar-default .navbar-toggle:focus { + background-color: #ddd; +} +.navbar-default .navbar-toggle .icon-bar { + background-color: #888; +} +.navbar-default .navbar-collapse, +.navbar-default .navbar-form { + border-color: #e7e7e7; +} +.navbar-default .navbar-nav > .open > a, +.navbar-default .navbar-nav > .open > a:hover, +.navbar-default .navbar-nav > .open > a:focus { + color: #555; + background-color: #e7e7e7; +} +@media (max-width: 767px) { + .navbar-default .navbar-nav .open .dropdown-menu > li > a { + color: #777; + } + .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus { + color: #333; + background-color: transparent; + } + .navbar-default .navbar-nav .open .dropdown-menu > .active > a, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #555; + background-color: #e7e7e7; + } + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #ccc; + background-color: transparent; + } +} +.navbar-default .navbar-link { + color: #777; +} +.navbar-default .navbar-link:hover { + color: #333; +} +.navbar-default .btn-link { + color: #777; +} +.navbar-default .btn-link:hover, +.navbar-default .btn-link:focus { + color: #333; +} + +.toolbar { + background-color: #414148 +} +.SearchBar-iconButton-88 { + right:13%!important; +} \ No newline at end of file diff --git a/src/main/js/widgets/file.css b/src/main/js/widgets/file.css new file mode 100644 index 0000000..d0e6562 --- /dev/null +++ b/src/main/js/widgets/file.css @@ -0,0 +1,7 @@ +a.uppy-Dashboard-poweredBy { + display: none; +} +.uppy-Dashboard-inner { + width: 100%!important; + height: 150px!important; +} \ No newline at end of file diff --git a/src/main/js/widgets/jumping-game.css b/src/main/js/widgets/jumping-game.css new file mode 100644 index 0000000..aca543a --- /dev/null +++ b/src/main/js/widgets/jumping-game.css @@ -0,0 +1,106 @@ + +@import url('https://fonts.googleapis.com/css?family=Voltaire'); + + +#world{ + position: absolute; + width:100%; + height: 100%; + background-color: #dbe6e6; + overflow: hidden; +} + + +#gameoverInstructions{ + position:absolute; + font-family:'Voltaire', sans-serif; + font-weight:bold; + text-transform: uppercase; + font-size:120px; + text-align:center; + color:#ffc5a2; + opacity:0; + left:50%; + top:50%; + width:100%; + transform : translate(-50%,-100%); + user-select: none; + transition: all 500ms ease-in-out; + + &.show{ + opacity:1; + transform : translate(-50%,-50%); + transition: all 500ms ease-in-out; + }; +} + + +#dist{ + position:absolute; + left:50%; + top:50px; + transform:translate(-50%,0%); + user-select: none; +} + +.label{ + position:relative; + font-family:'Voltaire', sans-serif; + text-transform:uppercase; + color:#ffa873; + font-size:12px; + letter-spacing:2px; + text-align:center; + margin-bottom:5px; +} + + +#distValue{ + position:relative; + text-transform:uppercase; + color:#dc5f45; + font-size:40px; + font-family:'Voltaire'; + text-align:center; +} + +#credits{ + position:absolute; + width:100%; + margin: auto; + bottom:0; + margin-bottom:20px; + font-family:'Voltaire', sans-serif; + color:#544027; + font-size:12px; + letter-spacing:0.5px; + text-transform: uppercase; + text-align : center; + user-select: none; +} +#credits a { + color:#544027; + +} + +#credits a:hover { + color:#dc5f45; +} + +#instructions{ + position:absolute; + width:100%; + bottom:0; + margin: auto; + margin-bottom:50px; + font-family:'Voltaire', sans-serif; + color:#dc5f45; + font-size:16px; + letter-spacing:1px; + text-transform: uppercase; + text-align : center; + user-select: none; +} +.lightInstructions { + color:#5f9042; +} \ No newline at end of file diff --git a/src/main/resources/var/www/html/public/1n-match-found.png b/src/main/resources/var/www/html/public/1n-match-found.png new file mode 100644 index 0000000..ef78916 Binary files /dev/null and b/src/main/resources/var/www/html/public/1n-match-found.png differ diff --git a/src/main/resources/var/www/html/public/activity.jpg b/src/main/resources/var/www/html/public/activity.jpg new file mode 100644 index 0000000..e2c77e5 Binary files /dev/null and b/src/main/resources/var/www/html/public/activity.jpg differ diff --git a/src/main/resources/var/www/html/public/approved.png b/src/main/resources/var/www/html/public/approved.png new file mode 100644 index 0000000..748e696 Binary files /dev/null and b/src/main/resources/var/www/html/public/approved.png differ diff --git a/src/main/resources/var/www/html/public/archived.png b/src/main/resources/var/www/html/public/archived.png new file mode 100644 index 0000000..0ca7db1 Binary files /dev/null and b/src/main/resources/var/www/html/public/archived.png differ diff --git a/src/main/resources/var/www/html/public/avatar.png b/src/main/resources/var/www/html/public/avatar.png new file mode 100644 index 0000000..e7bdbef Binary files /dev/null and b/src/main/resources/var/www/html/public/avatar.png differ diff --git a/src/main/resources/var/www/html/public/birth-certificate-pattern.svg b/src/main/resources/var/www/html/public/birth-certificate-pattern.svg new file mode 100644 index 0000000..b0d3978 --- /dev/null +++ b/src/main/resources/var/www/html/public/birth-certificate-pattern.svg @@ -0,0 +1,94 @@ + + + + + diff --git a/src/main/resources/var/www/html/public/coa-header.png b/src/main/resources/var/www/html/public/coa-header.png new file mode 100644 index 0000000..7de89df Binary files /dev/null and b/src/main/resources/var/www/html/public/coa-header.png differ diff --git a/src/main/resources/var/www/html/public/coa.png b/src/main/resources/var/www/html/public/coa.png new file mode 100644 index 0000000..deb13f3 Binary files /dev/null and b/src/main/resources/var/www/html/public/coa.png differ diff --git a/src/main/resources/var/www/html/public/cryingbaby1.jpg b/src/main/resources/var/www/html/public/cryingbaby1.jpg new file mode 100644 index 0000000..af657a8 Binary files /dev/null and b/src/main/resources/var/www/html/public/cryingbaby1.jpg differ diff --git a/src/main/resources/var/www/html/public/cryingbaby2.jpg b/src/main/resources/var/www/html/public/cryingbaby2.jpg new file mode 100644 index 0000000..fa7b58e Binary files /dev/null and b/src/main/resources/var/www/html/public/cryingbaby2.jpg differ diff --git a/src/main/resources/var/www/html/public/cryingbaby3.jpg b/src/main/resources/var/www/html/public/cryingbaby3.jpg new file mode 100644 index 0000000..bbcd724 Binary files /dev/null and b/src/main/resources/var/www/html/public/cryingbaby3.jpg differ diff --git a/src/main/resources/var/www/html/public/edit-picture.png b/src/main/resources/var/www/html/public/edit-picture.png new file mode 100644 index 0000000..96ddd0a Binary files /dev/null and b/src/main/resources/var/www/html/public/edit-picture.png differ diff --git a/src/main/resources/var/www/html/public/file-preview.png b/src/main/resources/var/www/html/public/file-preview.png new file mode 100644 index 0000000..9a7c230 Binary files /dev/null and b/src/main/resources/var/www/html/public/file-preview.png differ diff --git a/src/main/resources/var/www/html/public/finger-not-found.png b/src/main/resources/var/www/html/public/finger-not-found.png new file mode 100644 index 0000000..03760b1 Binary files /dev/null and b/src/main/resources/var/www/html/public/finger-not-found.png differ diff --git a/src/main/resources/var/www/html/public/flag.png b/src/main/resources/var/www/html/public/flag.png new file mode 100644 index 0000000..1e46d89 Binary files /dev/null and b/src/main/resources/var/www/html/public/flag.png differ diff --git a/src/main/resources/var/www/html/public/loading.gif b/src/main/resources/var/www/html/public/loading.gif new file mode 100644 index 0000000..36cfdef Binary files /dev/null and b/src/main/resources/var/www/html/public/loading.gif differ diff --git a/src/main/resources/var/www/html/public/logo.png b/src/main/resources/var/www/html/public/logo.png new file mode 100644 index 0000000..b9f624a Binary files /dev/null and b/src/main/resources/var/www/html/public/logo.png differ diff --git a/src/main/resources/var/www/html/public/logos-green.png b/src/main/resources/var/www/html/public/logos-green.png new file mode 100644 index 0000000..8552fab Binary files /dev/null and b/src/main/resources/var/www/html/public/logos-green.png differ diff --git a/src/main/resources/var/www/html/public/logos-id.svg b/src/main/resources/var/www/html/public/logos-id.svg new file mode 100644 index 0000000..e8b8c3c --- /dev/null +++ b/src/main/resources/var/www/html/public/logos-id.svg @@ -0,0 +1,3357 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/var/www/html/public/logos.png b/src/main/resources/var/www/html/public/logos.png new file mode 100644 index 0000000..2298b62 Binary files /dev/null and b/src/main/resources/var/www/html/public/logos.png differ diff --git a/src/main/resources/var/www/html/public/manual-check.png b/src/main/resources/var/www/html/public/manual-check.png new file mode 100644 index 0000000..61217f9 Binary files /dev/null and b/src/main/resources/var/www/html/public/manual-check.png differ diff --git a/src/main/resources/var/www/html/public/offical-approved-stamp.svg b/src/main/resources/var/www/html/public/offical-approved-stamp.svg new file mode 100644 index 0000000..37137fe --- /dev/null +++ b/src/main/resources/var/www/html/public/offical-approved-stamp.svg @@ -0,0 +1,682 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/var/www/html/public/pattern.png b/src/main/resources/var/www/html/public/pattern.png new file mode 100644 index 0000000..ada743f Binary files /dev/null and b/src/main/resources/var/www/html/public/pattern.png differ diff --git a/src/main/resources/var/www/html/public/printed-ID-card-pattern.svg b/src/main/resources/var/www/html/public/printed-ID-card-pattern.svg new file mode 100644 index 0000000..0938c48 --- /dev/null +++ b/src/main/resources/var/www/html/public/printed-ID-card-pattern.svg @@ -0,0 +1,46 @@ + + + + + + + + + + + diff --git a/src/main/resources/var/www/html/public/printed-id-fingerprint.svg b/src/main/resources/var/www/html/public/printed-id-fingerprint.svg new file mode 100644 index 0000000..93d9c4b --- /dev/null +++ b/src/main/resources/var/www/html/public/printed-id-fingerprint.svg @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/var/www/html/public/qr-code-temp.png b/src/main/resources/var/www/html/public/qr-code-temp.png new file mode 100644 index 0000000..5c1b7a3 Binary files /dev/null and b/src/main/resources/var/www/html/public/qr-code-temp.png differ diff --git a/src/main/resources/var/www/html/public/rejected.png b/src/main/resources/var/www/html/public/rejected.png new file mode 100644 index 0000000..d2e228e Binary files /dev/null and b/src/main/resources/var/www/html/public/rejected.png differ diff --git a/src/main/resources/var/www/html/public/signature-temp-back.png b/src/main/resources/var/www/html/public/signature-temp-back.png new file mode 100644 index 0000000..630573b Binary files /dev/null and b/src/main/resources/var/www/html/public/signature-temp-back.png differ diff --git a/src/main/resources/var/www/html/public/signature-temp.png b/src/main/resources/var/www/html/public/signature-temp.png new file mode 100644 index 0000000..e0b0706 Binary files /dev/null and b/src/main/resources/var/www/html/public/signature-temp.png differ diff --git a/src/main/resources/var/www/html/public/welcome.png b/src/main/resources/var/www/html/public/welcome.png new file mode 100644 index 0000000..52a81b1 Binary files /dev/null and b/src/main/resources/var/www/html/public/welcome.png differ diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..e3f36e1 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], + "allowJs": true, + "skipLibCheck": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "strict": true, + "sourceMap": true, + "forceConsistentCasingInFileNames": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": false, + "jsx": "react" + }, + "include": [ + "src" + ] +} diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 0000000..6735eaa --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,83 @@ +var HtmlWebpackPlugin = require('html-webpack-plugin'); +module.exports = { + entry: __dirname + "/src/auto/js/App.jsx", + output: { + filename: "bundle.js", + path: __dirname + "/dist/var/www/html/" + }, + + // Enable sourcemaps for debugging webpack's output. + devtool: "source-map", + + resolve: { + // Add '.ts' and '.tsx' as resolvable extensions. + extensions: [".ts", ".tsx", ".js", ".jsx", ".json"] + }, + + module: { + rules: [ + { + test: /\.jsx?$/, + loader: 'babel-loader', + exclude: /(node_modules|bower_components)/, + options: { + presets: ['@babel/preset-env', + '@babel/preset-react'], + plugins: ['@babel/plugin-proposal-class-properties', + ['@babel/plugin-transform-runtime', + { + 'regenerator': true + } + ], + "babel-plugin-macros" + ] + } + }, + { + test: /\.styl$/, + use: [ + 'style-loader', + { + loader: 'css-loader', + options: { + modules: true, + localsConvention: 'camelCase', + importLoaders: 1, + // 0 => no loaders (default); + // 1 => postcss-loader; + // 2 => postcss-loader, sass-loader + modules: { + localIdentName: '[path][name]__[local]', + }, + }, + }, + 'stylus-loader' + ] + }, + { + test: /\.css$/i, + use: ['style-loader', 'css-loader'], + }, + { + test: /\.scss$/, // Match SCSS files + use: [ + 'style-loader', // Inject styles into the DOM + 'css-loader', // Handle CSS imports + 'sass-loader' // Compile SCSS to CSS + ], + }, + // All files with a '.ts' or '.tsx' extension will be handled by 'awesome-typescript-loader'. + { test: /\.tsx?$/, loader: "ts-loader" }, + + // All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'. + { enforce: "pre", test: /\.js$/, loader: "source-map-loader" } + ] + }, + + plugins: [ + new HtmlWebpackPlugin({ + filename: __dirname + '/dist/var/www/html/index.html', + template: __dirname + '/src/auto/js/index.html' + }) + ] +}; \ No newline at end of file