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

feat: implement floating point number field #421

Merged
merged 14 commits into from
Dec 1, 2022
Merged
Show file tree
Hide file tree
Changes from 13 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
38 changes: 38 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/form-js-editor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"@bpmn-io/form-js-viewer": "^0.10.0-alpha.1",
"@bpmn-io/properties-panel": "^0.25.0",
"array-move": "^3.0.1",
"big.js": "^6.2.1",
Skaiir marked this conversation as resolved.
Show resolved Hide resolved
"dragula": "^3.7.3",
"ids": "^1.0.0",
"min-dash": "^4.0.0",
Expand Down
1 change: 1 addition & 0 deletions packages/form-js-editor/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export default [
'ids',
'min-dash',
'array-move',
'big.js',
'preact',
'preact/jsx-runtime',
'preact/hooks',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
ConditionGroup,
CustomValuesGroup,
GeneralGroup,
SerializationGroup,
ValidationGroup,
ValuesGroups
} from './groups';
Expand All @@ -28,6 +29,7 @@ function getGroups(field, editField) {
const groups = [
GeneralGroup(field, editField),
ConditionGroup(field, editField),
SerializationGroup(field, editField),
Skaiir marked this conversation as resolved.
Show resolved Hide resolved
...ValuesGroups(field, editField),
ValidationGroup(field, editField),
CustomValuesGroup(field, editField)
Expand Down
13 changes: 13 additions & 0 deletions packages/form-js-editor/src/features/properties-panel/Util.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import Big from 'big.js';

export function arrayAdd(array, index, item) {
const copy = [ ...array ];

Expand All @@ -18,6 +20,17 @@ export function prefixId(id) {
return `fjs-properties-panel-${ id }`;
}


export function countDecimals(number) {
const num = Big(number);
if (num.toString() === num.toFixed(0)) return 0;
return num.toFixed().split('.')[1].length || 0;
}

export function isValidNumber(value) {
return (typeof value === 'number' || typeof value === 'string') && value !== '' && !isNaN(Number(value));
}

export function stopPropagation(listener) {
return (event) => {
event.stopPropagation();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
import {
isNumberFieldEntryEdited,
isSelectEntryEdited,
isTextFieldEntryEdited,
isTextAreaEntryEdited,
NumberFieldEntry,
SelectEntry,
TextFieldEntry,
TextAreaEntry
} from '@bpmn-io/properties-panel';

import { get } from 'min-dash';

import { useService } from '../hooks';
import Big from 'big.js';

import { INPUTS, VALUES_INPUTS } from '../Util';
import { useService } from '../hooks';

import { countDecimals, INPUTS, isValidNumber, VALUES_INPUTS } from '../Util';

export default function DefaultOptionEntry(props) {
const {
Expand Down Expand Up @@ -52,7 +51,7 @@ export default function DefaultOptionEntry(props) {
entries.push({
...defaultOptions,
component: DefaultValueNumber,
isEdited: isNumberFieldEntryEdited
isEdited: isTextFieldEntryEdited
});
}

Expand Down Expand Up @@ -138,25 +137,50 @@ function DefaultValueNumber(props) {
label
} = props;

const {
decimalDigits,
serializeToString = false
} = field;

const debounce = useService('debounce');

const path = [ 'defaultValue' ];

const getValue = () => {
return get(field, path, '');
const getValue = (e) => {

let value = get(field, path);

if (!isValidNumber(value)) return;

// Enforces decimal notation so that we do not submit defaults in exponent form
return serializeToString ? Big(value).toFixed() : value;
};

const setValue = (value) => {
return editField(field, path, value);

let newValue;

if (isValidNumber(value)) {
newValue = serializeToString ? value : Number(value);
}

return editField(field, path, newValue);
};

return NumberFieldEntry({
const decimalDigitsSet = decimalDigits || decimalDigits === 0;

return TextFieldEntry({
debounce,
label,
element: field,
getValue,
id,
label,
setValue
setValue,
validate: (value) => {
if (value === undefined || value === null) return;
if (!isValidNumber(value)) return 'Should be a valid number';
if (decimalDigitsSet && countDecimals(value) > decimalDigits) return `Should not contain more than ${decimalDigits} decimal digits`;
}
});
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import { NumberFieldEntry, isNumberFieldEntryEdited, TextFieldEntry, isTextFieldEntryEdited } from '@bpmn-io/properties-panel';

import Big from 'big.js';
import { get } from 'min-dash';
import { useService } from '../hooks';
import { countDecimals, isValidNumber } from '../Util';

export default function NumberEntries(props) {
const {
editField,
field,
id
} = props;

const {
type
} = field;

if (type !== 'number') {
return [];
}

const entries = [];

entries.push({
id: id + '-decimalDigits',
component: NumberDecimalDigits,
isEdited: isNumberFieldEntryEdited,
editField,
field
});

entries.push({
id: id + '-step',
component: NumberArrowStep,
isEdited: isTextFieldEntryEdited,
editField,
field
});

return entries;
}

function NumberDecimalDigits(props) {

const {
editField,
field,
id
} = props;

const debounce = useService('debounce');

const getValue = (e) => get(field, [ 'decimalDigits' ]);

const setValue = (value) => editField(field, [ 'decimalDigits' ], value);

return NumberFieldEntry({
debounce,
label: 'Decimal digits',
element: field,
min: 0,
step: 1,
getValue,
id,
setValue
});

}

function NumberArrowStep(props) {

const {
editField,
field,
id
} = props;

const {
decimalDigits
} = field;

const debounce = useService('debounce');

const getValue = (e) => {

let value = get(field, [ 'increment' ]);

if (!isValidNumber(value)) return null;

return value;
};

const setValue = (value) => editField(field, [ 'increment' ], value);

const decimalDigitsSet = decimalDigits || decimalDigits === 0;

return TextFieldEntry({
debounce,
label: 'Increment',
element: field,
getValue,
id,
setValue,
validate: (value) => {

if (value === undefined || value === null) return;

if (!isValidNumber(value)) return 'Should be a valid number.';

if (Big(value).cmp(0) <= 0) return 'Should be greater than zero.';

if (decimalDigitsSet) {
const minimumValue = Big(`1e-${decimalDigits}`);

if (Big(value).cmp(minimumValue) < 0) return `Should be at least ${minimumValue.toString()}.`;
if (countDecimals(value) > decimalDigits) return `Should not contain more than ${decimalDigits} decimal digits.`;

}
}
});

}
Loading