Skip to content

Commit

Permalink
[FSADT1-999] Add birth date to frontend (#643)
Browse files Browse the repository at this point in the history
* feat: add a date input component

Specially for date of birth.

* refactor: extract date part component

* fix: always revalidate day

* feat: add the date of birth to the form

* refactor: reuse enum DatePart

* feat: add condition for displaying the birthdate

* feat: add birthdate label

* style: replace single-quote with double-quote

* fix: disable the next button properly

Replaces the types of event emmited and used to determine when to enable the next button.

* fix: adjust validations and events

* fix: issue after returning to the step containing the date

* feat: add business validations

* feat: apply text mask

* feat: auto-move to next date part

* feat: perform conditional validation

* fix: revalidate everything on revalidate-bus

* test: fill the birthdate field

* feat: replace some messages

* fix: prevent highlighting all parts on error

* docs: improve code comment

* fix: make complexity of regex linear

Fixes the security risk pointed by sonarcloud.

* refactor: move date part validations to props

Moves from `DateValidator` to props for part-specific business validations.
  • Loading branch information
fterra-encora authored Nov 30, 2023
1 parent 32c87c5 commit 72f549f
Show file tree
Hide file tree
Showing 9 changed files with 712 additions and 3 deletions.
6 changes: 3 additions & 3 deletions frontend/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@
// @ts-nocheck
// Generated by unplugin-vue-components
// Read more: https://github.com/vuejs/core/pull/3399
import '@vue/runtime-core'

export {}

declare module '@vue/runtime-core' {
declare module 'vue' {
export interface GlobalComponents {
AddressGroupComponent: typeof import('./src/components/grouping/AddressGroupComponent.vue')['default']
AutoCompleteInputComponent: typeof import('./src/components/forms/AutoCompleteInputComponent.vue')['default']
ContactGroupComponent: typeof import('./src/components/grouping/ContactGroupComponent.vue')['default']
DataFetcher: typeof import('./src/components/DataFetcher.vue')['default']
DateInputComponent: typeof import('./src/components/forms/DateInputComponent/index.vue')['default']
DateInputPart: typeof import('./src/components/forms/DateInputComponent/DateInputPart.vue')['default']
DropdownInputComponent: typeof import('./src/components/forms/DropdownInputComponent.vue')['default']
ErrorNotificationGroupingComponent: typeof import('./src/components/grouping/ErrorNotificationGroupingComponent.vue')['default']
MainHeaderComponent: typeof import('./src/components/MainHeaderComponent.vue')['default']
Expand Down
6 changes: 6 additions & 0 deletions frontend/cypress/e2e/FormGeneral.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ describe("General Form", () => {

cy.wait("@selectCompany");

cy.get("#birthdate").should("be.visible");

cy.get("#birthdateYear").shadow().find("input").should("have.value", "").type("2001");
cy.get("#birthdateMonth").shadow().find("input").should("have.value", "").type("05");
cy.get("#birthdateDay").shadow().find("input").should("have.value", "").type("30");

cy.get('[data-test="wizard-next-button"]').should("be.visible").click();

cy.logout();
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/assets/styles/global.scss
Original file line number Diff line number Diff line change
Expand Up @@ -1208,6 +1208,10 @@ cds-header-panel[expanded] {
transition: opacity 300ms cubic-bezier(0.5, 0, 0.1, 1), background-color 300ms cubic-bezier(0.5, 0, 0.1, 1);
}

.date-label {
margin-bottom: 1rem;
}



/* Small (up to 671px) */
Expand Down
66 changes: 66 additions & 0 deletions frontend/src/components/forms/DateInputComponent/DateInputPart.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<script setup lang="ts">
// Carbon
import '@carbon/web-components/es/components/text-input/index';
// Types
import { DatePart } from "./common";
// Define the input properties for this component
const props = defineProps<{
parentId: string;
datePart: DatePart;
selectedValue: string;
enabled?: boolean;
invalid: boolean;
}>();
const emit = defineEmits<{
blur: [event: FocusEvent]
input: [event: Event]
}>();
const datePartName = DatePart[props.datePart];
const capitalizedDatePart = datePartName[0].toUpperCase() + datePartName.substring(1);
const id = props.parentId + capitalizedDatePart;
defineExpose({
id,
});
const placeholders = {
[DatePart.year]: "YYYY",
[DatePart.month]: "MM",
[DatePart.day]: "DD"
};
const placeholder = placeholders[props.datePart];
const mask = "#".repeat(placeholder.length);
</script>

<template>
<div class="input-group">
<div class="cds--text-input__label-wrapper">
<label :id="parentId + capitalizedDatePart + 'Label'" :for="id" class="cds-text-input-label">
{{ enabled ? capitalizedDatePart : null }}
</label>
</div>
<cds-text-input
v-if="enabled"
:id="id"
type="tel"
:placeholder="placeholders[datePart]"
:value="selectedValue"
:disabled="!enabled"
:invalid="invalid"
@blur="(e) => emit('blur', e)"
@input="(e) => emit('input', e)"
:data-focus="id"
:data-scroll="id"
:data-id="'input-' + parentId + '-' + datePartName"
v-shadow="4"
v-masked="mask"
/>
</div>
</template>
5 changes: 5 additions & 0 deletions frontend/src/components/forms/DateInputComponent/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export enum DatePart {
year,
month,
day,
};
Loading

0 comments on commit 72f549f

Please sign in to comment.