Commit 0085ccce authored by Shani's avatar Shani

Merge branch 'dev' into 'dev'

Dev sync

See merge request !945
parents 2d1cb17b 73346123
......@@ -5,7 +5,7 @@ var globalSetting = {
// serverUrl : "http://10.162.20.247", // Shani
serverUrl: "http://billrun",
//serverUrl: "",
serverApiVersion: '5.8.7.3',
serverApiVersion: '5.8.8',
serverApiTimeOut: 300000, // 5 minutes
serverApiDebug: false,
serverApiDebugQueryString: 'XDEBUG_SESSION_START=netbeans-xdebug',
......
var globalSetting = {
storageVersion: '0.0.1',
serverUrl: "",
serverApiVersion: '5.8.7.3',
serverApiVersion: '5.8.8',
serverApiTimeOut: 300000, // 5 minutes
serverApiDebug: false,
serverApiDebugQueryString: 'XDEBUG_SESSION_START=netbeans-xdebug',
......
......@@ -68,8 +68,10 @@ fieldset[disabled] .btn {
white-space:nowrap;
}
.pl0{ padding-left: 0!important; }
.pt0{ padding-top: 0!important; }
.pr0{ padding-right: 0!important; }
.pb0{ padding-bottom: 0!important; }
.pl0{ padding-left: 0!important; }
.mt10{ margin-top: 10px!important; }
.mr10{ margin-right: 10px!important; }
.mb10{ margin-bottom: 10px!important; }
......
......@@ -3,7 +3,7 @@ const GroupsInclude = {
products: "Products should be unique for all plans",
shared_desc: "The includes will be shared with all the customer's subscribers. This is useful for family or organization package",
pooled_desc: 'When the \'Pooled\' option is activated, each subscriber, under the same customer, will \'Add\' its \'Includes\' allocation to the customer pool. The allocation can be either monetary allocation or a volume [call minutes, GBs of data, etc] based.',
quantityAffected_desc: 'When the \'Quantity Effected\' option is activated, each subscriber, under the same customer, will \'Add\' its \'Includes\' allocation to the customer pool, multiplied by the subscribers\' service quantity. The allocation can be either monetary allocation or a volume [call minutes, GBs of data, etc] based.',
quantityAffected_desc: 'When the \'Quantity Affected\' option is activated, each subscriber, under the same customer, will \'Add\' its \'Includes\' allocation to the customer pool, multiplied by the subscribers\' service quantity. The allocation can be either monetary allocation or a volume [call minutes, GBs of data, etc] based.',
};
export default GroupsInclude;
import { updateSetting } from './settingsActions';
import { getEventConvertedConditions } from '../components/Events/EventsUtil';
import Immutable from 'immutable';
import uuid from 'uuid';
import isNumber from 'is-number';
import {
saveSettings,
updateSetting,
removeSettingField,
pushToSetting,
getSettings,
} from './settingsActions';
import { pushToList } from './listActions';
import {
usageTypesDataSelector,
propertyTypeSelector,
eventsSelector,
} from '../selectors/settingsSelector';
import {
effectOnEventUsagetFieldsSelector,
} from '../selectors/eventSelectors';
import { apiBillRun, apiBillRunErrorHandler, apiBillRunSuccessHandler } from '../common/Api';
import {
getProductsByKeysQuery,
saveSettingsQuery,
} from '../common/ApiQueries';
import { getValueByUnit } from '../common/Util';
export const saveEvent = (entityType, index, event) => (dispatch, getState) => { // eslint-disable-line import/prefer-default-export
const getEventConvertedConditions = (propertyTypes, usageTypes, item, toBaseUnit = true) => {
const convertedConditions = item.get('conditions', Immutable.List()).withMutations((conditionsWithMutations) => {
conditionsWithMutations.forEach((cond, index) => {
const unit = cond.get('unit', '');
const usaget = cond.get('usaget', '');
if (unit !== '' && usaget !== '') {
const value = cond.get('value', 0);
const newValue = getValueByUnit(propertyTypes, usageTypes, usaget, unit, value, toBaseUnit);
conditionsWithMutations.setIn([index, 'value'], newValue);
}
});
});
return !convertedConditions.isEmpty()
? convertedConditions
: Immutable.List();
};
const getEventConvertedThreshold = (propertyTypes, usageTypes, item, toBaseUnit = true) => {
const convertedThreshold = item.getIn(['threshold_conditions', 0], Immutable.List()).withMutations((thresholdWithMutations) => {
thresholdWithMutations.forEach((threshold, index) => {
const unit = threshold.get('unit', '');
const usaget = threshold.get('usaget', '');
const value = threshold.get('value', 0);
if (unit !== '' && usaget !== '') {
if (Immutable.List.isList(value) || Array.isArray(value)) {
const arrayVal = value.map((val) => {
const newValue = getValueByUnit(propertyTypes, usageTypes, usaget, unit, val, toBaseUnit);
return isNumber(newValue) ? parseFloat(newValue) : newValue;
});
thresholdWithMutations.setIn([index, 'value'], arrayVal);
} else {
const newValue = getValueByUnit(propertyTypes, usageTypes, usaget, unit, value, toBaseUnit);
const val = isNumber(newValue) ? parseFloat(newValue) : newValue;
thresholdWithMutations.setIn([index, 'value'], val);
}
}
if (!toBaseUnit && Immutable.Iterable.isIterable(value)) {
thresholdWithMutations.setIn([index, 'value'], value.toList());
}
if (!toBaseUnit && !Immutable.Iterable.isIterable(value) && ['in', 'nin'].includes(threshold.get('op', ''))) {
thresholdWithMutations.setIn([index, 'value'], Immutable.List([value]));
}
});
});
return !convertedThreshold.isEmpty()
? convertedThreshold
: Immutable.List();
};
const convertFromApiToUi = (event, eventType, params) => event.withMutations((eventWithMutations) => {
const { propertyTypes, usageTypesData, effectOnUsagetFields } = params;
const eventUsageTypeFromEvent = Immutable.Map().withMutations((eventUsageTypeWithMutations) => {
if (eventType === 'fraud') {
event.getIn(['conditions', 0]).forEach((cond) => {
if (effectOnUsagetFields.includes(cond.get('field', ''))) {
eventUsageTypeWithMutations.set(cond.get('field', ''), cond.get('value', Immutable.List()));
}
});
}
});
const uiFlags = Immutable.Map({
id: uuid.v4(),
eventUsageType: eventUsageTypeFromEvent,
});
eventWithMutations.set('conditions', getEventConvertedConditions(propertyTypes, usageTypesData, event, false));
eventWithMutations.setIn(['threshold_conditions', 0], getEventConvertedThreshold(propertyTypes, usageTypesData, event, false));
eventWithMutations.set('ui_flags', uiFlags);
});
const convertFromUiToApi = (event, eventType, params) =>
event.withMutations((eventWithMutations) => {
const { propertyTypes, usageTypesData } = params;
eventWithMutations.delete('ui_flags');
if (eventType === 'fraud') {
const withoutEmptyConditions = eventWithMutations.getIn(['conditions', 0], Immutable.List())
.filter(cond => (cond.get('field', '') !== '' && cond.get('op', '')));
eventWithMutations.setIn(['conditions', 0], withoutEmptyConditions);
}
eventWithMutations.set('conditions', getEventConvertedConditions(propertyTypes, usageTypesData, eventWithMutations, true));
eventWithMutations.setIn(['threshold_conditions', 0], getEventConvertedThreshold(propertyTypes, usageTypesData, eventWithMutations, true));
});
export const getEvents = (eventCategory = '') => (dispatch, getState) => {
const settingsPath = (eventCategory === '') ? 'events' : `events.${eventCategory}`;
return dispatch(getSettings(settingsPath)).then(() => {
// Add local ID to events
const state = getState();
const usageTypesData = usageTypesDataSelector(state);
const propertyTypes = propertyTypeSelector(state);
const effectOnUsagetFields = effectOnEventUsagetFieldsSelector(state, { eventType: 'fraud' });
const params = ({ usageTypesData, propertyTypes, effectOnUsagetFields });
const settingsEvents = state.settings.get('events', Immutable.List());
settingsEvents.forEach((events, eventType) => {
if (!['settings'].includes(eventType) && (eventCategory === '' || eventCategory === eventType)) {
const eventsWithId = events.map(event => convertFromApiToUi(event, eventType, params));
dispatch(updateSetting('events', eventType, eventsWithId));
}
});
});
};
export const saveEvents = (eventCategory = '') => (dispatch, getState) => {
// remove local ID to events
const state = getState();
const usageTypesData = usageTypesDataSelector(state);
const propertyTypes = propertyTypeSelector(state);
const convertedEvent = event.withMutations((eventWithMutations) => {
eventWithMutations.set('conditions', getEventConvertedConditions(propertyTypes, usageTypesData, event, true));
const settingsEvents = state.settings.get('events', Immutable.List());
const params = ({ usageTypesData, propertyTypes });
settingsEvents.forEach((events, eventType) => {
if (!['settings'].includes(eventType) && (eventCategory === '' || eventCategory === eventType)) {
const eventsWithId = events.map(event => convertFromUiToApi(event, eventType, params));
dispatch(updateSetting('events', eventType, eventsWithId));
}
});
return dispatch(updateSetting('events', [entityType, index], convertedEvent));
const settingsPath = (eventCategory === '') ? 'events' : `events.${eventCategory}`;
return dispatch(saveSettings([settingsPath]));
};
export const saveEvent = (eventCategory, event) => (dispatch, getState) => {
const state = getState();
const usageTypesData = usageTypesDataSelector(state);
const propertyTypes = propertyTypeSelector(state);
const params = ({ usageTypesData, propertyTypes });
const convertedEvent = convertFromUiToApi(event, eventCategory, params);
const category = `event.${eventCategory}`;
const queries = saveSettingsQuery(convertedEvent, category);
return apiBillRun(queries)
.then(success => dispatch(apiBillRunSuccessHandler(success)))
.catch(error => dispatch(apiBillRunErrorHandler(error)));
};
export const addEvent = (eventType, event) => (dispatch) => {
const newEvent = event.setIn(['ui_flags', 'id'], uuid.v4());
return dispatch(pushToSetting('events', newEvent, eventType));
};
export const updateEvent = (eventType, event) => (dispatch, getState) => {
const events = eventsSelector(getState(), { eventType });
const index = events.findIndex(e => e.getIn(['ui_flags', 'id'], '') === event.getIn(['ui_flags', 'id'], ''));
if (index !== -1) {
return dispatch(updateSetting('events', [eventType, index], event));
}
return Promise.reject();
};
export const removeEvent = (eventType, event) => (dispatch, getState) => {
const events = eventsSelector(getState(), { eventType });
const index = events.findIndex(e => e.getIn(['ui_flags', 'id'], '') === event.getIn(['ui_flags', 'id'], ''));
if (index !== -1) {
return dispatch(removeSettingField('events', [eventType, index]));
}
return false;
};
export const saveEventSettings = () => dispatch => dispatch(saveSettings(['events.settings']));
export const updateEventSettings = (path, value) => dispatch => dispatch(updateSetting('events', ['settings', ...path], value));
export const getEventSettings = () => dispatch => dispatch(getSettings(['events.settings']));
export const getEventRates = eventRatesKeys => dispatch =>
dispatch(pushToList('event_products', getProductsByKeysQuery(eventRatesKeys.toArray(), { key: 1, rates: 1 })));
......@@ -8,6 +8,11 @@ export const ONBOARDING_SET_STATE = 'SET_ON_BOARDING_STATE';
export const CONFIRM_SHOW = 'CONFIRM_SHOW';
export const CONFIRM_HIDE = 'CONFIRM_HIDE';
export const EDIT_FORM_SHOW = 'EDIT_FORM_SHOW';
export const EDIT_FORM_HIDE = 'EDIT_FORM_HIDE';
export const EDIT_FORM_SET_ITEM = 'EDIT_FORM_SET_ITEM';
export const EDIT_FORM_UPDATE_ITEM_FIELD = 'EDIT_FORM_UPDATE_ITEM_FIELD';
export const EDIT_FORM_DELETE_ITEM_FIELD = 'EDIT_FORM_DELETE_ITEM_FIELD';
export const onBoardingStates = {
READY: 'READY',
......@@ -80,3 +85,29 @@ export const showConfirmModal = confirm => ({
export const hideConfirmModal = () => ({
type: CONFIRM_HIDE,
});
export const showFormModal = (item, component, config) => ({
type: EDIT_FORM_SHOW,
item,
component,
config,
});
export const hideFormModal = () => ({
type: EDIT_FORM_HIDE,
});
export const setFormModalItem = item => ({
type: EDIT_FORM_SET_ITEM,
item,
});
export const updateFormModalItemField = (path, value) => ({
type: EDIT_FORM_UPDATE_ITEM_FIELD,
path,
value,
});
export const removeFormModalItemField = path => ({
type: EDIT_FORM_DELETE_ITEM_FIELD,
path,
});
......@@ -106,7 +106,7 @@ const convert = (settings) => {
filters = []
} = settings;
const connections = receiver ? (receiver.connections ? receiver.connections: {}) : {};
const connections = receiver ? (receiver.connections ? receiver.connections: []) : [];
const field_widths = (parser.type === "fixed" && parser.structure) ? parser.structure.map(struct => struct.width) : [];
const usaget_type = (!_.result(processor, 'usaget_mapping') || processor.usaget_mapping.length < 1) ?
"static" :
......@@ -469,10 +469,9 @@ export function removeRatingField(rateCategory, usaget, priority, index) {
};
}
export function removeReceiver(receiver, index) {
export function removeReceiver(index) {
return {
type: REMOVE_RECEIVER,
receiver,
index,
};
}
......
......@@ -61,6 +61,7 @@ export const getFieldNameType = (type) => {
case 'subscriber':
return 'subscription';
case 'lines':
case 'line':
case 'usage':
return 'lines';
case 'service':
......@@ -497,9 +498,15 @@ export const escapeRegExp = text =>
export const createRateListNameByArgs = (query = Immutable.Map()) => query.reduce((acc, value, key) => `${acc}.${key}.${value}`, 'rates');
export const setFieldTitle = (field, entity) => (field.has('title')
? field
: field.set('title', getFieldName(field.get('field_name', ''), getFieldNameType(entity), sentenceCase(field.get('field_name', '')))));
export const setFieldTitle = (field, entity, keyProperty = 'field_name') => {
if (field.has('title')) {
return field;
}
const entityName = getFieldNameType(!entity && field.has('entity') ? field.get('entity') : entity);
const key = field.get(keyProperty, '');
const defaultLable = sentenceCase(field.get(keyProperty, ''));
return field.set('title', getFieldName(key, entityName, defaultLable));
};
export const toImmutableList = (value) => {
if ([undefined, null].includes(value)) {
......@@ -513,3 +520,19 @@ export const toImmutableList = (value) => {
}
return Immutable.List([value]);
};
export const sortFieldOption = (optionsA, optionB) => {
const a = optionsA.get('title', '').toUpperCase(); // ignore upper and lowercase
const b = optionB.get('title', '').toUpperCase(); // ignore upper and lowercase
if (a < b) {
return -1;
}
if (a > b) {
return 1;
}
return 0;
};
export const onlyLineForeignFields = lineField => lineField.has('foreign');
export const foreignFieldWithoutDates = foreignField => foreignField.getIn(['foreign', 'translate', 'type'], '') !== 'unixTimeToString';
......@@ -297,7 +297,7 @@ export default class DiscountDetails extends Component {
{ (!discount.getIn(['params', 'service'], Immutable.List()).isEmpty()) && <hr /> }
<FormGroup>
<Col componentClass={ControlLabel} sm={3} lg={2}>
{ getFieldName('Overall Limit', 'discounts')}
{ getFieldName('Discount Overall Limit', 'discounts')}
</Col>
<Col sm={8} lg={9}>
<Field suffix={getSymbolFromCurrency(currency)} value={discount.get('limit', '')} onChange={this.onChangeLimit} fieldType="unlimited" unlimitedValue="" editable={editable} />
......
......@@ -18,16 +18,17 @@ const Action = (props) => {
'fa-pencil': type === 'edit',
'fa-files-o': type === 'clone',
'fa-file-excel-o': type === 'export_csv',
'danger-red': type === 'remove' || type === 'enable',
'danger-red': ['enable', 'remove'].includes(type),
'fa-trash-o': type === 'remove',
'fa-toggle-off': type === 'enable',
'fa-toggle-on': type === 'disable',
'fa-plus': type === 'add',
'fa-plus': ['add', 'expand'].includes(type),
'fa-calendar': type === 'move',
'fa-repeat': type === 'reopen',
'fa-cloud-upload': type === 'import',
'fa-refresh': type === 'refresh',
'fa-arrow-left': type === 'back',
'fa-minus': type === 'collapse',
});
const onClick = () => {
......
import React, { PropTypes, Component } from 'react';
import Immutable from 'immutable';
import { connect } from 'react-redux';
import { Form, FormGroup, Col, ControlLabel, Button, Panel } from 'react-bootstrap';
import { getConditionDescription } from './EventsUtil';
import Field from '../Field';
import { ModalWrapper } from '../Elements';
import ConditionBalance from './ConditionsTypes/ConditionBalance';
import { usageTypesDataSelector, propertyTypeSelector, currencySelector } from '../../selectors/settingsSelector';
import { Form, FormGroup, Col, ControlLabel, Panel } from 'react-bootstrap';
import { getConditionDescription } from './../EventsUtil';
import Field from '../../Field';
import { Actions, CreateButton } from '../../Elements';
import BalanceEventCondition from './BalanceEventCondition';
import { usageTypesDataSelector, propertyTypeSelector, currencySelector } from '../../../selectors/settingsSelector';
class EventForm extends Component {
class BalanceEvent extends Component {
static propTypes = {
item: PropTypes.instanceOf(Immutable.Map),
onCancel: PropTypes.func.isRequired,
onSave: PropTypes.func.isRequired,
onUpdateField: PropTypes.func.isRequired,
updateField: PropTypes.func.isRequired,
conditionType: PropTypes.string,
propertyTypes: PropTypes.instanceOf(Immutable.List),
usageTypesData: PropTypes.instanceOf(Immutable.List),
......@@ -35,13 +33,18 @@ class EventForm extends Component {
onChangeField = path => (e) => {
const { value } = e.target;
this.props.onUpdateField(path, value);
this.props.updateField(path, value);
};
onChangeActive = (e) => {
const { value } = e.target;
this.props.updateField(['active'], value === 'yes');
};
addCondition = () => {
const { item } = this.props;
const conditions = item.get('conditions', Immutable.List()).push(Immutable.Map());
this.props.onUpdateField(['conditions'], conditions);
this.props.updateField(['conditions'], conditions);
this.setState({
editedConditionIndex: conditions.size - 1,
});
......@@ -62,7 +65,7 @@ class EventForm extends Component {
removeCondition = index => () => {
const { item } = this.props;
const conditions = item.get('conditions', Immutable.List()).delete(index);
this.props.onUpdateField(['conditions'], conditions);
this.props.updateField(['conditions'], conditions);
};
renderConditionEditForm = (condition, index) => {
......@@ -71,10 +74,10 @@ class EventForm extends Component {
case 'balance':
default:
return (
<ConditionBalance
<BalanceEventCondition
item={condition}
index={index}
onChangeField={this.props.onUpdateField}
onChangeField={this.props.updateField}
propertyTypes={propertyTypes}
usageTypesData={usageTypesData}
/>
......@@ -82,90 +85,105 @@ class EventForm extends Component {
}
}
renderCondition = (condition, index) => (
<FormGroup className="form-inner-edit-row" key={index}>
<Col sm={10}>
{
getConditionDescription(this.props.conditionType, condition, {
propertyTypes: this.props.propertyTypes,
usageTypesData: this.props.usageTypesData,
currency: this.props.currency,
activityType: 'counter',
})
}
</Col>
<Col sm={1} hidden={this.state.editedConditionIndex === index}>
<Button onClick={this.editCondition(index)} bsStyle="link">
<i className="fa fa-fw fa-pencil" />
</Button>
</Col>
<Col sm={1} hidden={this.state.editedConditionIndex !== index}>
<Button onClick={this.hideEditCondition} bsStyle="link">
<i className="fa fa-fw fa-minus" />
</Button>
</Col>
<Col sm={1}>
<Button onClick={this.removeCondition(index)} bsStyle="link">
<i className="fa fa-fw danger-red fa-trash-o" />
</Button>
</Col>
<Col sm={12}>
<Panel collapsible expanded={this.state.editedConditionIndex === index}>
{ this.renderConditionEditForm(condition, index) }
</Panel>
</Col>
</FormGroup>
);
showConditionDetails = (index) => {
const { editedConditionIndex } = this.state;
return editedConditionIndex === index;
}
renderAddConditionButton = () => (
<Button className="btn-primary" onClick={this.addCondition}><i className="fa fa-plus" />&nbsp;Add New Condition</Button>
);
getConditionActions = index => [
{ type: 'edit', onClick: this.editCondition(index), show: !this.showConditionDetails(index) },
{ type: 'collapse', onClick: this.hideEditCondition, show: this.showConditionDetails(index) },
{ type: 'remove', onClick: this.removeCondition(index) },
];
renderCondition = (condition, index) => {
const { conditionType, propertyTypes, usageTypesData, currency } = this.props;
const activityType = 'counter';
const params = ({ propertyTypes, usageTypesData, currency, activityType });
return (
<FormGroup key={index} className="mb0">
<Col sm={12}>
<div style={{ paddingRight: 100, display: 'inline-block' }}>
{ getConditionDescription(conditionType, condition, params) }
</div>
<span style={{ marginLeft: -100, paddingRight: 15 }} className="pull-right List row">
<Actions actions={this.getConditionActions(index)} />
</span>
</Col>
<Col sm={12}>
<Panel collapsible expanded={this.state.editedConditionIndex === index}>
{ this.renderConditionEditForm(condition, index) }
</Panel>
</Col>
</FormGroup>
);
}
renderConditions = () => (
this.props.item.get('conditions', Immutable.List()).map(this.renderCondition).toArray()
);
renderConditionsHeader = () => (
<FormGroup className="form-inner-edit-row">
<Col sm={12}>
<strong>Conditions</strong>
</Col>
</FormGroup>
);
onSaveEvent = () => {
};
render() {
const { item, onSave, onCancel } = this.props;
const { item } = this.props;
return (
<ModalWrapper title={`Event ${item.get('event_code', '')}`} show={true} onOk={onSave} onCancel={onCancel} labelOk="Save" >
<Form horizontal>
<Form horizontal>
<Panel header={<span>Details</span>}>
<FormGroup>
<Col componentClass={ControlLabel} md={4}>
<Col componentClass={ControlLabel} sm={3}>
Event Code
</Col>
<Col sm={5}>
<Col sm={7}>
<Field id="label" onChange={this.onChangeField(['event_code'])} value={item.get('event_code', '')} />
</Col>
</FormGroup>
<FormGroup>
<Col sm={12}>
{ this.renderConditionsHeader() }
<Col componentClass={ControlLabel} sm={3}>
Description
</Col>
<Col sm={7}>
<Field id="description" onChange={this.onChangeField(['event_description'])} value={item.get('event_description', '')} />
</Col>
</FormGroup>
<FormGroup>
<Col componentClass={ControlLabel} sm={3}>Status</Col>
<Col sm={7}>
<span>
<span style={{ display: 'inline-block', marginRight: 20 }}>
<Field
fieldType="radio"
onChange={this.onChangeActive}
name="step-active-status"
value="yes"
label="Active"
checked={item.get('active', true)}
/>
</span>
<span style={{ display: 'inline-block' }}>
<Field
fieldType="radio"
onChange={this.onChangeActive}
name="step-active-status"
value="no"
label="Not Active"
checked={!item.get('active', true)}
/>
</span>
</span>
</Col>
</FormGroup>
</Panel>
<Panel header={<span>Conditions</span>}>
<FormGroup>
<Col sm={12}>
{ this.renderConditions() }
</Col>
<Col sm={12}>
{ this.renderAddConditionButton() }
<CreateButton onClick={this.addCondition} label="Add New Condition" />
</Col>
</FormGroup>
</Form>
</ModalWrapper>
</Panel>
</Form>
);
}
}
......@@ -176,4 +194,4 @@ const mapStateToProps = (state, props) => ({
currency: currencySelector(state, props),
});
export default connect(mapStateToProps)(EventForm);
export default connect(mapStateToProps)(BalanceEvent);
import React, { PropTypes, Component } from 'react';
import { connect } from 'react-redux';
import Immutable from 'immutable';
import { Form, FormGroup, Row, Col, Panel, Label } from 'react-bootstrap';
import { CreateButton, LoadingItemPlaceholder } from '../../Elements';
import {
eventPropertyTypesSelector,
eventThresholdOperatorsSelectOptionsSelector,
eventThresholdFieldsSelectOptionsSelector,
} from '../../../selectors/eventSelectors';
import { eventsSettingsSelector } from '../../../selectors/settingsSelector';
import FraudEventDetails from './FraudEventDetails';
import FraudEventCondition from './FraudEventCondition';
import FraudEventThreshold from './FraudEventThreshold';
import { getSettings } from '../../../actions/settingsActions';
import { getEventRates } from '../../../actions/eventActions';
class FraudEvent extends Component {
static propTypes = {
item: PropTypes.instanceOf(Immutable.Map),
mode: PropTypes.string,
eventsSettings: PropTypes.instanceOf(Immutable.Map),
eventPropertyType: PropTypes.instanceOf(Immutable.Set),
thresholdFieldsSelectOptions: PropTypes.array,
thresholdOperatorsSelectOptions: PropTypes.array,
updateField: PropTypes.func.isRequired,
dispatch: PropTypes.func.isRequired,
};
static defaultProps = {
item: Immutable.Map(),
mode: 'create',
eventsSettings: Immutable.Map(),
eventPropertyType: Immutable.Set(),
thresholdFieldsSelectOptions: [],
thresholdOperatorsSelectOptions: [],