Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reactify number #1174

Merged
merged 9 commits into from
May 31, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 80 additions & 1 deletion mocks/mocks/data/formio-api/number.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"description": "",
"additionalDescriptionText": "",
"validate": {
"required": true,
"required": false,
"custom": "",
"min": 10,
"max": 100,
Expand All @@ -62,6 +62,7 @@
"tableView": false,
"validateOn": "blur",
"type": "number",
"inputType": "numeric",
"spellcheck": false,
"navId": "eqzaqlm",
"placeholder": "",
Expand Down Expand Up @@ -109,6 +110,84 @@
"allowMultipleMasks": false,
"addons": [],
"id": "eulnrki"
},
{
"fieldSize": "input--m",
"description": "",
"additionalDescriptionText": "",
"validate": {
"required": false,
"custom": "",
"min": "",
"max": "",
"customPrivate": false,
"strictDateValidation": false,
"multiple": false,
"unique": false,
"step": "any",
"integer": ""
},
"errors": "",
"conditional": {
"show": null,
"when": null,
"eq": ""
},
"customConditional": "",
"label": "Desimaltall",
"additionalDescriptionLabel": "",
"key": "number2",
"input": true,
"tableView": false,
"validateOn": "blur",
"type": "number",
"spellcheck": false,
"navId": "eqzaqsm",
"placeholder": "",
"prefix": "",
"customClass": "",
"suffix": "",
"multiple": false,
"defaultValue": null,
"protected": false,
"unique": false,
"persistent": true,
"hidden": false,
"clearOnHide": true,
"refreshOn": "",
"redrawOn": "",
"modalEdit": false,
"dataGridLabel": false,
"labelPosition": "top",
"errorLabel": "",
"tooltip": "",
"hideLabel": false,
"tabindex": "",
"disabled": false,
"autofocus": false,
"dbIndex": false,
"customDefaultValue": "",
"calculateValue": "",
"calculateServer": false,
"widget": {
"type": "input"
},
"attributes": {},
"overlay": {
"style": "",
"left": "",
"top": "",
"width": "",
"height": ""
},
"allowCalculateOverride": false,
"encrypted": false,
"showCharCount": false,
"showWordCount": false,
"properties": {},
"allowMultipleMasks": false,
"addons": [],
"id": "eqzaqsm"
}
],
"placeholder": "",
Expand Down
49 changes: 45 additions & 4 deletions packages/fyllut/cypress/e2e/components/number.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
* Tests that the number component is working as expected
*/

import { TEXTS } from '@navikt/skjemadigitalisering-shared-domain';

describe('number component', () => {
beforeEach(() => {
cy.defaultIntercepts();
Expand All @@ -10,15 +12,54 @@ describe('number component', () => {
cy.clickStart();
});

describe('happy path', () => {
it('should render number component', () => {
cy.findByRole('textbox', { name: 'Tall' }).should('exist').type('50');
describe('decimals', () => {
it('Try and set decimal values', () => {
cy.findByRole('textbox', { name: /^Tall/ }).should('exist').type('10,1');
cy.findByRole('textbox', { name: /^Desimaltall/ })
.should('exist')
.type('10,1');
cy.clickNextStep();
cy.findByRole('link', { name: `Tall er ikke et gyldig heltall.` }).should('exist');
cy.findByRole('textbox', { name: /^Tall/ }).should('exist').type('{selectall}10');
cy.clickNextStep();
cy.findByRole('heading', { name: 'Oppsummering' }).should('exist');
});

it('Set decimal value with dot, change to comma when going back from summary', () => {
cy.findByRole('textbox', { name: /^Desimaltall/ })
.should('exist')
.type('10.1');
cy.clickNextStep();
cy.findByRoleWhenAttached('link', { name: TEXTS.grensesnitt.summaryPage.editAnswers }).should('exist').click();
cy.findByRole('textbox', {
name: /^Desimaltall/,
}).should('have.value', '10,1');
});

it('Set decimal value with spaces, change to no spaces when going back from summary', () => {
cy.findByRole('textbox', { name: /^Desimaltall/ })
.should('exist')
.type('1 0 0 0 0 0,1');
cy.clickNextStep();
cy.findByRoleWhenAttached('link', { name: TEXTS.grensesnitt.summaryPage.editAnswers }).should('exist').click();
cy.findByRole('textbox', {
name: /^Desimaltall/,
}).should('have.value', '100\u00a0000,1');
});
});

describe('integer', () => {
it('Try and set integer values', () => {
cy.findByRole('textbox', { name: /^Tall/ }).should('exist').type('10');
cy.findByRole('textbox', { name: /^Desimaltall/ })
.should('exist')
.type('10');
cy.clickNextStep();
cy.findByRole('heading', { name: 'Oppsummering' }).should('exist');
});
});

describe('errors', () => {
describe('min/max values', () => {
// Min = 10
it('should show error for min value', () => {
cy.findByRole('textbox', { name: 'Tall' }).should('exist').type('9');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,7 @@ class BaseComponent extends FormioReactComponent {
return (
<>
{this.t(this.component?.label ?? '')}
{this.component?.validate?.required && !this.component?.readOnly
? ''
: showOptional && ` (${this.t('valgfritt')})`}
{this.isRequired() && !this.component?.readOnly ? '' : showOptional && ` (${this.t('valgfritt')})`}
{showDiffTag && this.getDiffTag()}
</>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Component } from '@navikt/skjemadigitalisering-shared-domain';

const editFormInputType = (): Component => {
return {
type: 'select',
label: 'Input type',
key: 'inputType',
dataSrc: 'values',
data: {
values: [
{ label: 'Desimaltall', value: 'decimal' },
{ label: 'Heltall', value: 'numeric' },
],
},
};
};

export default editFormInputType;
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import editFormDisabled from './editFormDisabled';
import editFormFieldSizeField from './editFormFieldSize';
import editFormHidden from './editFormHidden';
import editFormHideLabel from './editFormHideLabel';
import editFormInputType from './editFormInputType';
import editFormIsAttachmentPanel from './editFormIsAttachmentPanel';
import editFormInline from './editFormIsInline';
import editFormLabel from './editFormLabel';
Expand Down Expand Up @@ -58,6 +59,7 @@ const editFormDisplay = {
hidden: editFormHidden,
isAttachmentPanel: editFormIsAttachmentPanel,
titleSize: editFormTitleSizeField,
inputType: editFormInputType,
};

export default editFormDisplay;
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ interface ReactComponentType {
getRef(name: any): any;
setRef(name: any, ref: any): void;
checkValidity(data: any, dirty: any | boolean, row: any, silentCheck: boolean): boolean;
checkComponentValidity(data, dirty, row, options = {});
getValue(): any;
hasChanged(before: any, after: any): boolean;
clearOnHide(): void;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { TextField as NavTextField } from '@navikt/ds-react';
import { InputMode } from '@navikt/skjemadigitalisering-shared-domain';
import BaseComponent from '../../base/BaseComponent';
import textFieldBuilder from './TextField.builder';
import textFieldForm from './TextField.form';

export type InputMode = 'none' | 'text' | 'tel' | 'url' | 'email' | 'numeric' | 'decimal' | 'search';

class TextField extends BaseComponent {
static schema() {
return BaseComponent.schema({
Expand All @@ -13,7 +12,6 @@ class TextField extends BaseComponent {
key: 'tekstfelt',
spellcheck: true,
inputType: 'text',
inputFormat: 'plain',
});
}

Expand All @@ -33,13 +31,17 @@ class TextField extends BaseComponent {
return 'text';
}

handleChange(value: string): any {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sjekk any

super.updateValue(value, { modified: true });
}

renderReact(element) {
element.render(
<NavTextField
id={this.getId()}
defaultValue={this.getValue()}
ref={(ref) => this.setReactInstance(ref)}
onChange={(event) => this.updateValue(event.currentTarget.value, { modified: true })}
onChange={(event) => this.handleChange(event.currentTarget.value)}
label={this.getLabel()}
hideLabel={this.getHideLabel()}
description={this.getDescription()}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { InputMode } from '@navikt/skjemadigitalisering-shared-domain';
import BaseComponent from '../../base/BaseComponent';
import TextField, { InputMode } from '../../core/textfield/TextField';
import TextField from '../../core/textfield/TextField';
import emailBuilder from './Email.builder';
import emailForm from './Email.form';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const numberForm = () => {
return createTabs(
display([
editFormDisplay.label(),
editFormDisplay.inputType(),
editFormDisplay.fieldSize(),
editFormDisplay.description(),
editFormDisplay.additionalDescription(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,84 @@
import FormioNumber from 'formiojs/components/number/Number';
import { InputMode, numberUtils, TEXTS } from '@navikt/skjemadigitalisering-shared-domain';
import BaseComponent from '../../base/BaseComponent';
import TextField from '../../core/textfield/TextField';
import numberForm from './Number.form';

class Number extends FormioNumber {
// TODO: Try and see if can get delimiter (tusenskilletegn) default set for all numbers.
class Number extends TextField {
static schema() {
return FormioNumber.schema({
return BaseComponent.schema({
label: 'Tall',
type: 'number',
key: 'number',
fieldSize: 'input--m',
key: 'tall',
spellcheck: false,
inputType: 'decimal',
});
}

static editForm() {
return numberForm();
}

getInputMode(): InputMode {
return this.component?.inputType || 'decimal';
}

getMinValue() {
return this.component?.validate?.min;
}

getMaxValue() {
return this.component?.validate?.max;
}

checkComponentValidity(data, dirty, row, options = {}) {
const validity = super.checkComponentValidity(data, dirty, row, options);

if (validity) {
const errorMessage = this.validateNumber();
if (errorMessage) {
return this.setComponentValidity([this.createError(errorMessage, undefined)], dirty, undefined);
}
}

return validity;
}

validateNumber() {
if (this.getValue() === '' || this.getValue() === undefined) {
return;
}

if (this.getInputMode() === 'decimal') {
if (!numberUtils.isValidDecimal(this.getValue())) return this.translateWithLabel(TEXTS.validering.decimal);
} else if (this.getInputMode() === 'numeric') {
if (!numberUtils.isValidInteger(this.getValue())) return this.translateWithLabel(TEXTS.validering.integer);
}

if (!numberUtils.isBiggerOrEqualMin(this.getValue(), this.getMinValue())) {
return this.translateWithLabel(TEXTS.validering.min, { min: numberUtils.toLocaleString(this.getMinValue()) });
}

if (!numberUtils.isSmallerOrEqualMax(this.getValue(), this.getMaxValue())) {
return this.translateWithLabel(TEXTS.validering.max, { max: numberUtils.toLocaleString(this.getMaxValue()) });
}
}

translateWithLabel(key: string, options = {}) {
return this.t(key, { field: this.getLabel({ labelTextOnly: true }), ...options });
}

handleChange(value: string): any {
return super.handleChange(this.replaceCommasAndSpaces(value));
}

setValue(value: string): any {
// Need to format the number if it is saved or if you come back from summary page.
super.setValue(numberUtils.toLocaleString(value));
}

replaceCommasAndSpaces(value: string) {
return value?.replace(/,/g, '.').replace(/\s/g, '');
}
}

export default Number;
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% if (ctx.component.type === "textfield" || ctx.component.type === "textarea" || ctx.component.type === "orgNr" || ctx.component.type === "bankAccount" || ctx.component.type === "htmlelement" || ctx.component.type === "radiopanel" || ctx.component.type === "attachment" || ctx.component.type === "email" || ctx.component.type === "activities" || ctx.component.type === "accordion" || ctx.component.type === "navDatepicker" || ctx.component.type === "navCheckbox") { %}
{% if (ctx.component.type === "textfield" || ctx.component.type === "textarea" || ctx.component.type === "orgNr" || ctx.component.type === "bankAccount" || ctx.component.type === "htmlelement" || ctx.component.type === "radiopanel" || ctx.component.type === "attachment" || ctx.component.type === "email" || ctx.component.type === "activities" || ctx.component.type === "accordion" || ctx.component.type === "navDatepicker" || ctx.component.type === "navCheckbox" || ctx.component.type === "number") { %}
{{ctx.element}}
{% } else { %}
{% if (ctx.component.description && ctx.component.type !== "datagrid" && ctx.component.descriptionPosition === "above") { %}
Expand Down
3 changes: 3 additions & 0 deletions packages/shared-domain/src/form/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,11 @@ export interface Component {
latestAllowedDate?: string;
getValue?: () => string;
rerender?: () => void;
inputType?: InputMode;
}

export type InputMode = 'none' | 'text' | 'tel' | 'url' | 'email' | 'numeric' | 'decimal' | 'search';

export interface ComponentProperties {
vedleggstittel?: string;
vedleggskode?: string;
Expand Down
Loading
Loading