Skip to content

Commit

Permalink
feat: ADDON-61556 Introduced checkbox group component (#394)
Browse files Browse the repository at this point in the history
* feat: ADDON-61556 Introduced checkbox group component

* feat: ADDON-61556 Developed checkbox groups component

* feat: ADDON-61556 Validation part has updated

* feat: ADDON-61556 Added select all and clear all buttons

* feat: ADDON-61556 Revert unwanted code

* feat: ADDON-61556 Fix minor css issue

* feat: ADDON-61556 Fix issue

* refactor: ADDON-61556 Addressed review comments
  • Loading branch information
tbalar-splunk authored Sep 6, 2023
1 parent 4697783 commit 9ffed80
Show file tree
Hide file tree
Showing 7 changed files with 587 additions and 166 deletions.
356 changes: 280 additions & 76 deletions ui/src/main/webapp/components/BaseFormView.jsx

Large diffs are not rendered by default.

71 changes: 71 additions & 0 deletions ui/src/main/webapp/components/CheckboxGroupsComponent.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import ColumnLayout from '@splunk/react-ui/ColumnLayout';
import Text from '@splunk/react-ui/Text';
import { isFalse, isTrue } from '../util/util';
import { StyledColumnLayout, StyledSwitch } from './StyledComponent';

function CheckboxGroupsComponent(props) {
const { field, label, value, checkboxTextFieldValue, handleChange } = props;

const [isDisabled, setIsDisabled] = useState(!value);

useEffect(() => {
setIsDisabled(!value);
}, [value]);

const handleChangeCheckbox = () => {
if (value && isTrue(value)) {
handleChange(field, 0);
setIsDisabled(true);
} else {
handleChange(field, 1);
setIsDisabled(false);
}
};

const handleChangeTextBox = (event) => {
handleChange(field, event.target.value, 'checkboxGroups');
};

return (
<StyledColumnLayout>
<ColumnLayout.Row>
<ColumnLayout.Column span={5}>
<StyledSwitch
key={field}
value={value}
onClick={handleChangeCheckbox}
selected={!(value ? isFalse(value) : true)}
appearance="checkbox"
>
{label}
</StyledSwitch>
</ColumnLayout.Column>
<ColumnLayout.Column span={2}>
<Text
inline
disabled={isDisabled}
value={checkboxTextFieldValue ? checkboxTextFieldValue.toString() : ''}
onChange={handleChangeTextBox}
type="text"
/>
</ColumnLayout.Column>
</ColumnLayout.Row>
</StyledColumnLayout>
);
}

CheckboxGroupsComponent.propTypes = {
value: PropTypes.oneOfType([PropTypes.bool, PropTypes.number, PropTypes.string]),
checkboxTextFieldValue: PropTypes.oneOfType([
PropTypes.bool,
PropTypes.number,
PropTypes.string,
]),
handleChange: PropTypes.func.isRequired,
label: PropTypes.string,
field: PropTypes.string,
};

export default CheckboxGroupsComponent;
38 changes: 10 additions & 28 deletions ui/src/main/webapp/components/ControlWrapper.jsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,11 @@
import React from 'react';
import PropTypes from 'prop-types';
import ControlGroup from '@splunk/react-ui/ControlGroup';
import styled from 'styled-components';

import MarkdownMessage from './MarkdownMessage';
import CONTROL_TYPE_MAP from '../constants/ControlTypeMap';
import { CustomElement, CheckboxElement, ControlGroupWrapper } from './StyledComponent';

const CustomElement = styled.div`
margin-left: 30px;
`;

const ControlGroupWrapper = styled(ControlGroup).attrs((props) => ({
'data-name': props.dataName,
}))`
width: 100%;
max-width: 100%;
> * {
&:first-child {
width: 240px !important;
}
&:nth-child(3) {
margin-left: 270px !important;
width: 320px;
}
}
span[class*='ControlGroupStyles__StyledAsterisk-'] {
color: red;
}
`;
const CHECKBOX_GROUPS = 'checkboxGroups';

class ControlWrapper extends React.PureComponent {
static isString = (str) => !!(typeof str === 'string' || str instanceof String);
Expand Down Expand Up @@ -78,7 +54,9 @@ class ControlWrapper extends React.PureComponent {
rowView = this.controlType
? React.createElement(this.controlType, {
handleChange,
label: this.props.entity.label,
value: this.props.value,
checkboxTextFieldValue: this.props.checkboxTextFieldValue,
field,
controlOptions: this.props.entity.options,
error: this.props.error,
Expand All @@ -105,7 +83,10 @@ class ControlWrapper extends React.PureComponent {
);

return (
this.props.display && (
this.props.display &&
(this.props.entity.type === CHECKBOX_GROUPS ? (
<CheckboxElement>{rowView}</CheckboxElement>
) : (
<ControlGroupWrapper
label={label}
help={helpText}
Expand All @@ -116,7 +97,7 @@ class ControlWrapper extends React.PureComponent {
>
<CustomElement>{rowView}</CustomElement>
</ControlGroupWrapper>
)
))
);
}
}
Expand All @@ -125,6 +106,7 @@ ControlWrapper.propTypes = {
mode: PropTypes.string,
utilityFuncts: PropTypes.object,
value: PropTypes.any,
checkboxTextFieldValue: PropTypes.any,
display: PropTypes.bool,
error: PropTypes.bool,
entity: PropTypes.object,
Expand Down
143 changes: 143 additions & 0 deletions ui/src/main/webapp/components/StyledComponent.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import styled from 'styled-components';
import CollapsiblePanel from '@splunk/react-ui/CollapsiblePanel';
import ColumnLayout from '@splunk/react-ui/ColumnLayout';
import Switch from '@splunk/react-ui/Switch';
import ControlGroup from '@splunk/react-ui/ControlGroup';

const CollapsiblePanelWrapper = styled(CollapsiblePanel)`
span {
button {
background-color: #f2f4f5;
font-size: 16px;
margin: 15px 0;
&:hover:not([disabled]),
&:focus:not([disabled]),
&:active:not([disabled]) {
background-color: #f2f4f5;
box-shadow: none;
}
}
}
`;

const CustomGroupLabel = styled.div`
padding: 6px 10px;
background-color: #f2f4f5;
margin: 0 0 15px 0;
font-size: 16px;
`;

const CheckboxGroupContainer = styled.div`
position: relative;
`;

const CheckboxLabelContainer = styled.div`
display: flex;
width: 280px;
justify-content: space-between;
`;

const CheckboxGroupPanelWrapper = styled(CollapsiblePanel)`
span {
button {
background-color: #f2f4f5;
margin: 1px 0 1px 270px;
width: 320px;
&:hover:not([disabled]),
&:focus:not([disabled]),
&:active:not([disabled]) {
background-color: #f2f4f5;
box-shadow: none;
}
}
button > span:nth-child(2) {
width: 280px;
}
}
`;

const CustomCheckboxGroupsLabel = styled.div`
display: inline-flex;
position: absolute;
width: 240px !important;
padding: 6px 0;
justify-content: flex-end;
`;

const StyledColumnLayout = styled(ColumnLayout)`
width: 320px !important;
`;

const StyledSwitch = styled(Switch)`
padding-left: 10px !important;
> * {
&:nth-child(2) {
margin-left: 8px;
}
}
span {
color: red;
font-weight: bold;
margin-left: 5px;
}
`;

const CustomElement = styled.div`
margin-left: 30px;
`;

const CheckboxElement = styled.div`
margin-left: 270px;
margin-top: 2px;
`;

const ControlGroupWrapper = styled(ControlGroup).attrs((props) => ({
'data-name': props.dataName,
}))`
width: 100%;
max-width: 100%;
> * {
&:first-child {
width: 240px !important;
}
&:nth-child(3) {
margin-left: 270px !important;
width: 320px;
}
}
span[class*='ControlGroupStyles__StyledAsterisk-'] {
color: red;
}
`;

const CheckboxGroupsToggleButtonWrapper = styled.div`
position: relative;
margin-left: 270px;
margin-top: 10px;
`;

const StyledPadding4 = styled.div`
padding-top: 4px;
padding-bottom: 4px;
`;

export {
CollapsiblePanelWrapper,
CustomGroupLabel,
CheckboxLabelContainer,
CheckboxGroupPanelWrapper,
CustomCheckboxGroupsLabel,
StyledColumnLayout,
StyledSwitch,
CheckboxGroupContainer,
CustomElement,
CheckboxElement,
ControlGroupWrapper,
CheckboxGroupsToggleButtonWrapper,
StyledPadding4,
};
2 changes: 2 additions & 0 deletions ui/src/main/webapp/constants/ControlTypeMap.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import RadioComponent from '../components/RadioComponent';
import PlaceholderComponent from '../components/PlaceholderComponent';
import CustomControl from '../components/CustomControl';
import FileInputComponent from '../components/FileInputComponent';
import CheckboxGroupsComponent from '../components/CheckboxGroupsComponent';

export default {
text: TextComponent,
Expand All @@ -19,5 +20,6 @@ export default {
radio: RadioComponent,
file: FileInputComponent,
placeholder: PlaceholderComponent,
checkboxGroups: CheckboxGroupsComponent,
custom: CustomControl,
};
Loading

0 comments on commit 9ffed80

Please sign in to comment.