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

Feature/disable and enabled props #640

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
14 changes: 10 additions & 4 deletions src/web/forms/DynamicForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import {
} from '../../actions';

import {
checkVisibility,
referAndGetBool,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Does 'refer' in this method name refer to doctor referral? Slightly unclear what this method does...

} from './utils';
import FieldInsertPanel from './editor/FieldInsertPanel';
import FieldEditor from './editor/FieldEditor';
Expand Down Expand Up @@ -63,10 +63,16 @@ function makeCreateChildFields(

const elements = !styles ? [] : styles.map((field, i) => {
// Handle "show" prop
if (!checkVisibility(state, rootModel, field.show)) {
if (!referAndGetBool(state, rootModel, field.show)) {
return null;
}

// Translate "disabled" and "enabled" prop to boolean value
Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe it is more appropriate to name something like checkEnabledToBool? (as it seems its main purpose is for check disable/enable -> bool output)

const disabled = (
referAndGetBool(state, rootModel, field.disabled, false) ||
!referAndGetBool(state, rootModel, field.enabled, true)
);

const childFieldPath = `${fieldPath}[${i}]`;
const component = fieldComponents[field.class] || fieldComponents.textinput;
let children = null;
Expand Down Expand Up @@ -108,15 +114,15 @@ function makeCreateChildFields(
component,
{
key: i,
...field,
model: field.field ? `${rootModel}.${field.field}` : null,
label: field.label,
fieldOptions: fieldOptions[field.field],
disabled,
warning: warnings[field.field],
rootModel,
fieldEditProps,
getPreviousData: field.ditto && getPreviousData &&
(() => getPreviousData && getPreviousData(field.field)),
...field,
},
children
);
Expand Down
42 changes: 26 additions & 16 deletions src/web/forms/__tests__/utils-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,21 @@
jest.unmock('lodash.get');
jest.unmock('../utils');

import { checkVisibility } from '../utils';
import { referAndGetBool } from '../utils';

describe('checkVisibility', () => {
it('returns false if `show` prop is false', () => {
expect(checkVisibility({}, 'hoge', false)).toBe(false);
describe('referAndGetBool', () => {
it('returns false if orgProp is false', () => {
expect(referAndGetBool({}, 'hoge', false)).toBe(false);
});

it('returns true if orgProp is true', () => {
expect(referAndGetBool({}, 'hoge', true)).toBe(true);
});

it('returns defaultValue if orgProp is undefined', () => {
expect(referAndGetBool({}, 'hoge', undefined)).toBe(true);
expect(referAndGetBool({}, 'hoge', undefined, true)).toBe(true);
expect(referAndGetBool({}, 'hoge', undefined, false)).toBe(false);
});

it('returns referred value if show prop is given as string', () => {
Expand All @@ -38,8 +48,8 @@ describe('checkVisibility', () => {
},
};

expect(checkVisibility(state, 'root', 'foo.bar')).toBe(true);
expect(checkVisibility(state, 'root', 'hoge.fuga')).toBe(false);
expect(referAndGetBool(state, 'root', 'foo.bar')).toBe(true);
expect(referAndGetBool(state, 'root', 'hoge.fuga')).toBe(false);
});

it('handles Array as referent', () => {
Expand All @@ -49,8 +59,8 @@ describe('checkVisibility', () => {
},
};

expect(checkVisibility(state, 'root', 'foo:aaa')).toBe(true);
expect(checkVisibility(state, 'root', 'foo:bbb')).toBe(false);
expect(referAndGetBool(state, 'root', 'foo:aaa')).toBe(true);
expect(referAndGetBool(state, 'root', 'foo:bbb')).toBe(false);
});

it('handles an empty array as falthy', () => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

falthy -> falsy

Expand All @@ -60,7 +70,7 @@ describe('checkVisibility', () => {
},
};

expect(checkVisibility(state, 'root', 'foo')).toBe(false);
expect(referAndGetBool(state, 'root', 'foo')).toBe(false);
});

it('handles empty rootPath', () => {
Expand All @@ -71,8 +81,8 @@ describe('checkVisibility', () => {
},
};

expect(checkVisibility(state, null, 'foo')).toBe(true);
expect(checkVisibility(state, 'hoge', 'foo')).toBe(false);
expect(referAndGetBool(state, null, 'foo')).toBe(true);
expect(referAndGetBool(state, 'hoge', 'foo')).toBe(false);
});

it('handles OR condition', () => {
Expand All @@ -83,7 +93,7 @@ describe('checkVisibility', () => {
},
};

expect(checkVisibility(state, 'root', 'foo|bar')).toBe(true);
expect(referAndGetBool(state, 'root', 'foo|bar')).toBe(true);
});

it('handles negative', () => {
Expand All @@ -98,8 +108,8 @@ describe('checkVisibility', () => {
},
};

expect(checkVisibility(state, 'root', '!foo.bar')).toBe(false);
expect(checkVisibility(state, 'root', '!hoge.fuga')).toBe(true);
expect(referAndGetBool(state, 'root', '!foo.bar')).toBe(false);
expect(referAndGetBool(state, 'root', '!hoge.fuga')).toBe(true);
});

it('handles negative on Array referent', () => {
Expand All @@ -109,7 +119,7 @@ describe('checkVisibility', () => {
},
};

expect(checkVisibility(state, 'root', '!foo:aaa')).toBe(false);
expect(checkVisibility(state, 'root', '!foo:bbb')).toBe(true);
expect(referAndGetBool(state, 'root', '!foo:aaa')).toBe(false);
expect(referAndGetBool(state, 'root', '!foo:bbb')).toBe(true);
});
});
11 changes: 3 additions & 8 deletions src/web/forms/fields/SubformList/Row.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import React from 'react';
import classNames from 'classnames';
import _get from 'lodash.get';
import type { FormFieldDefinition } from '.';
import { checkVisibility } from '../../utils';
import { referAndGetBool } from '../../utils';

import { TextInputComponent } from '../TextInput';
import { CheckboxComponent } from '../Checkbox';
Expand Down Expand Up @@ -68,13 +68,8 @@ export default ({
<div className="column">
<div className="columns is-mobile is-multiline is-variable is-1">
{fields.map((field, i) => {
if (typeof field.show !== 'undefined'
&& !checkVisibility(_value, null, field.show)) {
return null;
} else if (typeof field.hide !== 'undefined'
&& checkVisibility(_value, null, field.hide)) {
return null;
}
if (!referAndGetBool(_value, null, field.show, true)) return null;
if (referAndGetBool(_value, null, field.hide, false)) return null;

const component = typeof field.class === 'string'
? fieldComponents[field.class] : field.class;
Expand Down
1 change: 1 addition & 0 deletions src/web/forms/fields/SubformList/__tests__/Row-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ jest.unmock('react-redux');
jest.unmock('lodash.get');
jest.unmock('lodash.set');
jest.unmock('../Row');
jest.unmock('../../../utils');
jest.unmock('../../common/fieldify');

import React from 'react';
Expand Down
3 changes: 3 additions & 0 deletions src/web/forms/fields/TextInput/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ const ReadOnly = ({
export const TextInputComponent = ({
value,
onChange,
disabled = false,
style,
type = 'text',
prefix,
Expand All @@ -80,6 +81,7 @@ export const TextInputComponent = ({
}: {
value: ?string,
onChange: (newValue: string) => void,
disabled: boolean,
style?: Object,
type?: string,
prefix?: string,
Expand Down Expand Up @@ -152,6 +154,7 @@ export const TextInputComponent = ({
[`is-${size}`]: size,
}
)}
disabled={disabled}
style={{
...style,
...overrideStyle,
Expand Down
16 changes: 10 additions & 6 deletions src/web/forms/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,17 @@ function checkCondition(state: Object, rootPath: ?string, condition: string): bo
return !!referent;
}

export function checkVisibility(state: Object, rootPath: ?string, showProp: string|boolean = true) {
if (showProp === false) {
return false;
}
export function referAndGetBool(
state: Object,
rootPath: ?string,
orgProp: string|boolean,
defaultValue: boolean=true
) {
if (typeof orgProp === 'undefined') return defaultValue;
if (typeof orgProp === 'boolean') return orgProp;

if (typeof showProp === 'string') {
const conditions = showProp.split('|');
if (typeof orgProp === 'string') {
const conditions = orgProp.split('|');

return conditions.some(condition => {
let _condition = condition;
Expand Down