github.com/stampzilla/stampzilla-go@v2.0.0-rc9+incompatible/nodes/stampzilla-server/web/src/routes/automation/components/formComponents.js (about)

     1  import PropTypes from 'prop-types';
     2  import React from 'react';
     3  import classnames from 'classnames';
     4  import { connect } from 'react-redux';
     5  
     6  export const ObjectFieldTemplate = (props) => {
     7    if (props.title !== undefined) {
     8      return (
     9        <div className="card mb-4 bg-dark text-white">
    10          <div className="card-header">
    11            <div>
    12              <strong>{props.title}</strong>
    13            </div>
    14            <small>{props.description}</small>
    15          </div>
    16          <div
    17            className={classnames({
    18              'card-body': true,
    19            })}
    20          >
    21            {props.properties.map(prop => prop.content)}
    22          </div>
    23        </div>
    24      );
    25    }
    26  
    27    return typeof props.uiSchema.tableMode !== 'undefined' ? (
    28      <div className="row">
    29        {props.properties.map(prop => (
    30          <div key={prop.name} className="col-sm-6">
    31            {prop.content}
    32          </div>
    33        ))}
    34      </div>
    35    ) : (
    36      <React.Fragment>
    37        {props.properties.map(prop => prop.content)}
    38      </React.Fragment>
    39    );
    40  };
    41  ObjectFieldTemplate.propTypes = {
    42    title: PropTypes.string,
    43    description: PropTypes.string,
    44    properties: PropTypes.arrayOf(
    45      PropTypes.shape({
    46        content: PropTypes.node,
    47      }),
    48    ),
    49    uiSchema: PropTypes.shape({
    50      tableMode: PropTypes.bool,
    51    }),
    52  };
    53  
    54  export const CustomCheckbox = (props) => {
    55    const {
    56      id,
    57      value,
    58      required,
    59      disabled,
    60      readonly,
    61      label,
    62      autofocus,
    63      onChange,
    64    } = props;
    65    return (
    66      <div
    67        className={`checkbox custom-control custom-checkbox ${
    68          disabled || readonly ? 'disabled' : ''
    69        }`}
    70      >
    71        <input
    72          type="checkbox"
    73          className="custom-control-input"
    74          id={id}
    75          checked={typeof value === 'undefined' ? false : value}
    76          required={required}
    77          disabled={disabled || readonly}
    78          autoFocus={autofocus}
    79          onChange={event => onChange(event.target.checked)}
    80        />
    81        <label className="custom-control-label" htmlFor={id}>
    82          <span>{label}</span>
    83        </label>
    84      </div>
    85    );
    86  };
    87  CustomCheckbox.propTypes = {
    88    id: PropTypes.string,
    89    value: PropTypes.bool,
    90    required: PropTypes.bool,
    91    disabled: PropTypes.bool,
    92    readonly: PropTypes.bool,
    93    label: PropTypes.string,
    94    autofocus: PropTypes.bool,
    95    onChange: PropTypes.func,
    96  };
    97  
    98  const IconButton = (props) => {
    99    const {
   100      type = 'default', icon, className, ...otherProps
   101    } = props;
   102    return (
   103      <button
   104        type="button"
   105        className={`btn btn-${type} ${className}`}
   106        {...otherProps}
   107      >
   108        <i className={`fa fa-${icon}`} />
   109      </button>
   110    );
   111  };
   112  IconButton.propTypes = {
   113    type: PropTypes.string,
   114    icon: PropTypes.string,
   115    className: PropTypes.string,
   116  };
   117  
   118  const DefaultArrayItem = (props) => {
   119    const btnStyle = {
   120      flex: 1,
   121      paddingLeft: 6,
   122      paddingRight: 6,
   123      fontWeight: 'bold',
   124    };
   125    return (
   126      <div
   127        key={props.index}
   128        className={classnames(['row mb-3', props.className])}
   129      >
   130        <div className={props.hasToolbar ? 'col-sm-9' : 'col-sm-12'}>
   131          {props.children}
   132        </div>
   133  
   134        {props.hasToolbar && (
   135          <div className="col-sm-3 array-item-toolbox">
   136            <div
   137              className="btn-group"
   138              style={{
   139                display: 'flex',
   140                justifyContent: 'space-around',
   141              }}
   142            >
   143              {(props.hasMoveUp || props.hasMoveDown) && (
   144                <IconButton
   145                  type="secondary"
   146                  icon="arrow-up"
   147                  className="array-item-move-up"
   148                  tabIndex="-1"
   149                  style={btnStyle}
   150                  disabled={props.disabled || props.readonly || !props.hasMoveUp}
   151                  onClick={props.onReorderClick(props.index, props.index - 1)}
   152                />
   153              )}
   154              {(props.hasMoveUp || props.hasMoveDown) && (
   155                <IconButton
   156                  type="secondary"
   157                  icon="arrow-down"
   158                  className="array-item-move-down"
   159                  tabIndex="-1"
   160                  style={btnStyle}
   161                  disabled={
   162                    props.disabled || props.readonly || !props.hasMoveDown
   163                  }
   164                  onClick={props.onReorderClick(props.index, props.index + 1)}
   165                />
   166              )}
   167              {props.hasRemove && (
   168                <IconButton
   169                  type="danger"
   170                  icon="trash"
   171                  className="array-item-remove"
   172                  tabIndex="-1"
   173                  style={btnStyle}
   174                  disabled={props.disabled || props.readonly}
   175                  onClick={props.onDropIndexClick(props.index)}
   176                />
   177              )}
   178            </div>
   179          </div>
   180        )}
   181      </div>
   182    );
   183  };
   184  
   185  DefaultArrayItem.propTypes = {
   186    // schema: PropTypes.object.isRequired,
   187    uiSchema: PropTypes.shape({
   188      'ui:options': PropTypes.shape({
   189        addable: PropTypes.bool,
   190        orderable: PropTypes.bool,
   191        removable: PropTypes.bool,
   192      }),
   193    }),
   194    // idSchema: PropTypes.object,
   195    // errorSchema: PropTypes.object,
   196    // onChange: PropTypes.func.isRequired,
   197    // onBlur: PropTypes.func,
   198    // onFocus: PropTypes.func,
   199    // formData: PropTypes.array,
   200    // required: PropTypes.bool,
   201    disabled: PropTypes.bool,
   202    readonly: PropTypes.bool,
   203    // autofocus: PropTypes.bool,
   204    registry: PropTypes.shape({
   205      widgets: PropTypes.objectOf(
   206        PropTypes.oneOfType([PropTypes.func, PropTypes.shape({})]),
   207      ).isRequired,
   208      fields: PropTypes.objectOf(PropTypes.func).isRequired,
   209      definitions: PropTypes.object.isRequired,
   210      formContext: PropTypes.object.isRequired,
   211    }),
   212    onDropIndexClick: PropTypes.func,
   213    hasRemove: PropTypes.bool,
   214    hasMoveUp: PropTypes.bool,
   215    hasMoveDown: PropTypes.bool,
   216    children: PropTypes.node,
   217    hasToolbar: PropTypes.bool,
   218    className: PropTypes.string,
   219    index: PropTypes.string,
   220    onReorderClick: PropTypes.func,
   221  };
   222  
   223  export const ArrayFieldTemplate = (props) => {
   224    const { title } = props;
   225    return (
   226      <div>
   227        <label>
   228          <span>{title}</span>
   229        </label>
   230        {props.items && props.items.map(DefaultArrayItem)}
   231        {props.canAdd && (
   232          <IconButton
   233            icon="plus"
   234            className="btn-block btn-success"
   235            onClick={props.onAddClick}
   236          />
   237        )}
   238      </div>
   239    );
   240  };
   241  ArrayFieldTemplate.propTypes = {
   242    title: PropTypes.string,
   243    canAdd: PropTypes.bool,
   244    onAddClick: PropTypes.func,
   245    items: PropTypes.arrayOf(PropTypes.shape({})),
   246  };
   247  
   248  const stateToTextColor = (status) => {
   249    if (!status) {
   250      return 'text-secondary';
   251    }
   252  
   253    if (status.get('error')) {
   254      return 'text-danger';
   255    }
   256  
   257    if (status.get('active')) {
   258      return 'text-success';
   259    }
   260  
   261    return '';
   262  };
   263  
   264  export class RuleConditions extends React.Component {
   265    constructor(props) {
   266      super(props);
   267      this.state = { ...props.formData };
   268    }
   269  
   270    componentWillReceiveProps(props) {
   271      if (props.formData !== this.state) {
   272        this.setState({ ...props.formData });
   273      }
   274    }
   275  
   276    onChange = (name, value) => (checked) => {
   277      this.setState(
   278        {
   279          [name]: checked ? value : undefined,
   280        },
   281        () => this.props.onChange(this.state),
   282      );
   283    };
   284  
   285    render() {
   286      const {
   287        rules, schema, uiSchema, status,
   288      } = this.props;
   289      const {
   290        id, title, required, description,
   291      } = schema;
   292      return (
   293        <div>
   294          <label htmlFor={id}>
   295            {title}
   296            {required ? '*' : null}
   297          </label>
   298          <p id="root_for__description" className="field-description">
   299            {description}
   300          </p>
   301          <table>
   302            <thead>
   303              <tr>
   304                <th>Active</th>
   305                <th>Standby</th>
   306                <th>Rule</th>
   307              </tr>
   308            </thead>
   309            <tbody>
   310              {rules
   311                .filter(rule => rule.get('uuid') !== uiSchema.current)
   312                .map(rule => (
   313                  <tr key={rule.get('uuid')}>
   314                    <td className="text-center">
   315                      <CustomCheckbox
   316                        id={`${rule.get('uuid')}-true`}
   317                        value={this.state[rule.get('uuid')] === true}
   318                        onChange={this.onChange(rule.get('uuid'), true)}
   319                      />
   320                    </td>
   321                    <td className="text-center">
   322                      <CustomCheckbox
   323                        id={`${rule.get('uuid')}-false`}
   324                        value={this.state[rule.get('uuid')] === false}
   325                        onChange={this.onChange(rule.get('uuid'), false)}
   326                      />
   327                    </td>
   328                    <td
   329                      className={stateToTextColor(status.get(rule.get('uuid')))}
   330                    >
   331                      {rule.get('name')}
   332                    </td>
   333                  </tr>
   334                ))
   335                .toArray()}
   336            </tbody>
   337          </table>
   338        </div>
   339      );
   340      // <input type="number" value={lon} onChange={this.onChange('lon')} />
   341    }
   342  }
   343  
   344  const mapStateToProps = state => ({
   345    rules: state.getIn(['rules', 'list']),
   346    status: state.getIn(['rules', 'state']),
   347  });
   348  
   349  export const ConnectedRuleConditions = connect(mapStateToProps)(RuleConditions);