diff --git a/ui/app/components/Chip/index.js b/ui/app/components/Chip/index.js index d89ab5d40..343ad2c04 100644 --- a/ui/app/components/Chip/index.js +++ b/ui/app/components/Chip/index.js @@ -5,7 +5,7 @@ const Chip = ({ children, close, onClose }) => { return (
{children} - {close ? close : null} + {close ? close : null}
); }; diff --git a/ui/app/components/ColorPicker/index.js b/ui/app/components/ColorPicker/index.js new file mode 100644 index 000000000..2e18f8d84 --- /dev/null +++ b/ui/app/components/ColorPicker/index.js @@ -0,0 +1,68 @@ +import React, { PropTypes } from 'react'; +import { CirclePicker } from 'react-color'; + +function ColorPicker(props) { // eslint-disable-line react/prefer-stateless-function + + const styles = { + color: { + borderRadius: '3px', + background: props.color, + width: '100%', + height: '2.2rem' + }, + swatch_container: { + padding: '0', + height: '3.1rem', + border: '1px solid #c5cbd8', + borderRadius: '3px', + }, + swatch: { + padding: '5px', + background: '#fff', + display: 'inline-block', + cursor: 'pointer', + width: '100%', + }, + popover: { + background: '#FFFFFF', + border: '1px solid #c5cbd8', + borderRadius: '3px', + padding: '5px', + position: 'absolute', + zIndex: '999', + }, + cover: { + position: 'fixed', + top: '0px', + right: '0px', + bottom: '0px', + left: '0px', + }, + }; + + return ( +
+
+
+
+ { props.displayColorPicker ?
+
+ +
: null } +
+ ); +} + +ColorPicker.propTypes = { + handleClose: React.PropTypes.func, + handleClick: React.PropTypes.func, + handleColorChange: React.PropTypes.func, + color: React.PropTypes.string, + displayColorPicker: React.PropTypes.bool, +}; + +ColorPicker.defaultProps = { + s: 1, +}; + +export default ColorPicker; diff --git a/ui/app/components/Header/index.js b/ui/app/components/Header/index.js index e10215cbf..daff0d1f0 100644 --- a/ui/app/components/Header/index.js +++ b/ui/app/components/Header/index.js @@ -2,14 +2,23 @@ import React from 'react'; class Header extends React.Component { // eslint-disable-line react/prefer-stateless-function render() { + + const { breadcrumbs } = this.props; + return (
- First - Second - Third - Forth + { + breadcrumbs.map( (breadcrumb, index) => { + if (breadcrumb.link){ + return {breadcrumb.label} + } + else { + return {breadcrumb.label} + } + }) + }
@@ -17,4 +26,8 @@ class Header extends React.Component { // eslint-disable-line react/prefer-state } } +Header.propTypes = { + breadcrumbs: React.PropTypes.array.isRequired, +}; + export default Header; diff --git a/ui/app/components/InputLabel/index.js b/ui/app/components/InputLabel/index.js index 8cc6840b8..72e257a34 100644 --- a/ui/app/components/InputLabel/index.js +++ b/ui/app/components/InputLabel/index.js @@ -4,7 +4,7 @@ import { FormattedMessage } from 'react-intl'; function InputLabel(props) { // eslint-disable-line react/prefer-stateless-function return ( -
+
); diff --git a/ui/app/components/Preloader/Spinner.js b/ui/app/components/Preloader/Spinner.js new file mode 100644 index 000000000..4d3205293 --- /dev/null +++ b/ui/app/components/Preloader/Spinner.js @@ -0,0 +1,63 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _react = require('react'); + +var _react2 = _interopRequireDefault(_react); + +var _propTypes = require('prop-types'); + +var _propTypes2 = _interopRequireDefault(_propTypes); + +var _classnames = require('classnames'); + +var _classnames2 = _interopRequireDefault(_classnames); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var Spinner = function Spinner(_ref) { + var color = _ref.color, + only = _ref.only; + + var spinnerClasses = { + 'spinner-layer': true + }; + if (only) { + spinnerClasses['spinner-' + color + '-only'] = true; + } else { + spinnerClasses['spinner-' + color] = true; + } + return _react2.default.createElement( + 'div', + { className: (0, _classnames2.default)(spinnerClasses) }, + _react2.default.createElement( + 'div', + { className: 'circle-clipper left' }, + _react2.default.createElement('div', { className: 'circle' }) + ), + _react2.default.createElement( + 'div', + { className: 'gap-patch' }, + _react2.default.createElement('div', { className: 'circle' }) + ), + _react2.default.createElement( + 'div', + { className: 'circle-clipper right' }, + _react2.default.createElement('div', { className: 'circle' }) + ) + ); +}; + +Spinner.defaultProps = { + only: true +}; + +Spinner.propTypes = { + color: _propTypes2.default.string, + only: _propTypes2.default.bool +}; + +exports.default = Spinner; \ No newline at end of file diff --git a/ui/app/components/Preloader/index.js b/ui/app/components/Preloader/index.js new file mode 100644 index 000000000..bc908122a --- /dev/null +++ b/ui/app/components/Preloader/index.js @@ -0,0 +1,106 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _react = require('react'); + +var _react2 = _interopRequireDefault(_react); + +var _propTypes = require('prop-types'); + +var _propTypes2 = _interopRequireDefault(_propTypes); + +var _classnames = require('classnames'); + +var _classnames2 = _interopRequireDefault(_classnames); + +var _Spinner = require('./Spinner'); + +var _Spinner2 = _interopRequireDefault(_Spinner); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var colors = ['blue', 'red', 'yellow', 'green']; + +var Preloader = function (_Component) { + _inherits(Preloader, _Component); + + function Preloader() { + _classCallCheck(this, Preloader); + + return _possibleConstructorReturn(this, (Preloader.__proto__ || Object.getPrototypeOf(Preloader)).apply(this, arguments)); + } + + _createClass(Preloader, [{ + key: 'render', + value: function render() { + var classes = { + 'preloader-wrapper': true, + active: this.props.active + }; + + if (this.props.size) { + classes[this.props.size] = true; + } + + var spinners = void 0; + if (this.props.flashing) { + spinners = []; + colors.map(function (color) { + spinners.push(_react2.default.createElement(_Spinner2.default, { color: color, only: false, key: color })); + }); + } else { + spinners = _react2.default.createElement(_Spinner2.default, { color: this.props.color }); + } + return _react2.default.createElement( + 'div', + { className: (0, _classnames2.default)(this.props.className, classes) }, + spinners + ); + } + }]); + + return Preloader; +}(_react.Component); + +Preloader.propTypes = { + className: _propTypes2.default.string, + /** + * The scale of the circle + * @default 'medium' + */ + size: _propTypes2.default.oneOf(['big', 'small', 'medium']), + /** + * Whether to spin + * @default true + */ + active: _propTypes2.default.bool, + /** + * The color of the circle, if not flashing + * @default 'blue' + */ + color: _propTypes2.default.string, + /** + * Wheter to circle four different colors + * @default false + */ + flashing: _propTypes2.default.bool +}; + +Preloader.defaultProps = { + active: true, + flashing: false, + color: 'blue' +}; + +exports.default = Preloader; \ No newline at end of file diff --git a/ui/app/containers/AgentDetailPage/index.js b/ui/app/containers/AgentDetailPage/index.js index 5b440f35e..91f9ba4a1 100644 --- a/ui/app/containers/AgentDetailPage/index.js +++ b/ui/app/containers/AgentDetailPage/index.js @@ -1,7 +1,9 @@ import React from 'react'; import Helmet from 'react-helmet'; -import { Row } from 'react-materialize'; +import { Row, + Col, + } from 'react-materialize'; import { connect } from 'react-redux'; import { createStructuredSelector } from 'reselect'; import Content from '../../components/Content'; @@ -9,6 +11,8 @@ import Form from '../../components/Form'; import FormTextInput from '../../components/FormTextInput'; import Header from '../../components/Header'; import SliderInput from '../../components/SliderInput'; +import Preloader from '../../components/Preloader'; + import { loadCurrentAgent } from '../App/actions'; import { makeSelectCurrentAgent, @@ -41,18 +45,28 @@ export class AgentDetailPage extends React.PureComponent { // eslint-disable-lin error, currentAgent, }; + + let breadcrumbs = []; + if (!currentAgent) { return (
 
); } + else { + breadcrumbs = [{ link: `/agent/${currentAgent.id}`, label: `Agent: ${currentAgent.agentName}`},]; + } + return (
+ + { agentProps.loading ? : null } + -
+

Agent: {currentAgent.agentName}

{currentAgent.description}

diff --git a/ui/app/containers/AgentPage/index.js b/ui/app/containers/AgentPage/index.js index 7c2592f55..c1cf52cb8 100644 --- a/ui/app/containers/AgentPage/index.js +++ b/ui/app/containers/AgentPage/index.js @@ -6,6 +6,7 @@ import Form from 'components/Form'; import FormTextInput from 'components/FormTextInput'; import Header from 'components/Header'; import SliderInput from 'components/SliderInput'; +import Preloader from '../../components/Preloader'; import { makeSelectAgent, @@ -18,6 +19,7 @@ import Helmet from 'react-helmet'; import { Input, Row, + Col, } from 'react-materialize'; import { connect } from 'react-redux'; import { createStructuredSelector } from 'reselect'; @@ -99,13 +101,16 @@ export class AgentPage extends React.PureComponent { // eslint-disable-line reac return (
+ + { agentProps.loading ? : null } + -
+
diff --git a/ui/app/containers/DomainListPage/index.js b/ui/app/containers/DomainListPage/index.js index ea1ad265b..28fe6e42c 100644 --- a/ui/app/containers/DomainListPage/index.js +++ b/ui/app/containers/DomainListPage/index.js @@ -1,6 +1,7 @@ import React from 'react'; import Helmet from 'react-helmet'; -import { Row, } from 'react-materialize'; +import { Row, + Col, } from 'react-materialize'; import { connect } from 'react-redux'; import { push } from 'react-router-redux'; import { createStructuredSelector } from 'reselect'; @@ -10,6 +11,8 @@ import ContentHeader from '../../components/ContentHeader'; import DomainsTable from '../../components/DomainsTable/index'; import Form from '../../components/Form'; import Header from '../../components/Header'; +import Preloader from '../../components/Preloader'; + import { loadAgentDomains, resetAgentDomains, @@ -56,15 +59,26 @@ export class DomainListPage extends React.PureComponent { // eslint-disable-line agentDomains, }; + let breadcrumbs = []; + if (currentAgent){ + breadcrumbs = [{ link: `/agent/${currentAgent.id}`, label: `Agent: ${currentAgent.agentName}`}, { label: 'Domains'},]; + } + else { + breadcrumbs = [{ label: 'Domains'}, ]; + } + return (
+ + { domainProps.loading ? : null } + -
+
@@ -83,7 +97,6 @@ export class DomainListPage extends React.PureComponent { // eslint-disable-line

- {JSON.stringify(currentAgent)}
diff --git a/ui/app/containers/DomainPage/index.js b/ui/app/containers/DomainPage/index.js index 2deba66d8..81b9514b5 100644 --- a/ui/app/containers/DomainPage/index.js +++ b/ui/app/containers/DomainPage/index.js @@ -1,6 +1,8 @@ import React from 'react'; import Helmet from 'react-helmet'; -import { Row } from 'react-materialize'; +import { Row, + Col, + } from 'react-materialize'; import { connect } from 'react-redux'; import { createStructuredSelector } from 'reselect'; import ActionButton from '../../components/ActionButton'; @@ -11,6 +13,7 @@ import Form from '../../components/Form'; import FormTextInput from '../../components/FormTextInput'; import Header from '../../components/Header'; import SliderInput from '../../components/SliderInput'; +import Preloader from '../../components/Preloader'; import { createDomain } from '../../containers/App/actions'; import { @@ -51,21 +54,33 @@ export class DomainPage extends React.PureComponent { // eslint-disable-line rea } render() { - const { loading, error, domain } = this.props; + const { loading, error, domain, currentAgent } = this.props; const domainProps = { loading, error, domain, }; + + let breadcrumbs = []; + if (currentAgent){ + breadcrumbs = [{ link: `/agent/${currentAgent.id}`, label: `Agent: ${currentAgent.agentName}`}, { label: '+ Creating domains'},]; + } + else { + breadcrumbs = [{ label: '+ Creating domains'}, ]; + } + return (
+ + { domainProps.loading ? : null } + -
+
diff --git a/ui/app/containers/EntityPage/actions.js b/ui/app/containers/EntityPage/actions.js index 0699adea4..491e5fc7e 100644 --- a/ui/app/containers/EntityPage/actions.js +++ b/ui/app/containers/EntityPage/actions.js @@ -4,6 +4,8 @@ import { CHANGE_ENTITY_DATA, REMOVE_EXAMPLE, REMOVE_SYNONYM, + SWITCH_COLOR_PICKER_DISPLAY, + CLOSE_COLOR_PICKER, } from './constants'; export function changeEntityData(payload) { @@ -41,3 +43,15 @@ export function addSynonym(payload) { }; } +export function switchColorPickerDisplay() { + return { + type: SWITCH_COLOR_PICKER_DISPLAY, + }; +} + +export function closeColorPicker() { + return { + type: CLOSE_COLOR_PICKER, + }; +} + diff --git a/ui/app/containers/EntityPage/constants.js b/ui/app/containers/EntityPage/constants.js index 5fc7c0433..c5ae4d03b 100644 --- a/ui/app/containers/EntityPage/constants.js +++ b/ui/app/containers/EntityPage/constants.js @@ -3,3 +3,5 @@ export const REMOVE_EXAMPLE = 'boilerplate/EntityPage/REMOVE_EXAMPLE'; export const ADD_EXAMPLE = 'boilerplate/EntityPage/ADD_EXAMPLE'; export const REMOVE_SYNONYM = 'boilerplate/EntityPage/REMOVE_SYNONYM'; export const ADD_SYNONYM = 'boilerplate/EntityPage/ADD_SYNONYM'; +export const SWITCH_COLOR_PICKER_DISPLAY = 'boilerplate/EntityPage/SWITCH_COLOR_PICKER_DISPLAY'; +export const CLOSE_COLOR_PICKER = 'boilerplate/EntityPage/CLOSE_COLOR_PICKER'; \ No newline at end of file diff --git a/ui/app/containers/EntityPage/index.js b/ui/app/containers/EntityPage/index.js index 3a49c2da4..356917ac5 100644 --- a/ui/app/containers/EntityPage/index.js +++ b/ui/app/containers/EntityPage/index.js @@ -1,7 +1,9 @@ import React from 'react'; import Helmet from 'react-helmet'; -import { Row, } from 'react-materialize'; +import { Row, + Col, + } from 'react-materialize'; import { connect } from 'react-redux'; import { createStructuredSelector } from 'reselect'; import ActionButton from '../../components/ActionButton'; @@ -14,6 +16,9 @@ import InputLabel from '../../components/InputLabel'; import Table from '../../components/Table'; import TableContainer from '../../components/TableContainer'; import TableHeader from '../../components/TableHeader'; +import ColorPicker from '../../components/ColorPicker'; +import Preloader from '../../components/Preloader'; + import { createEntity, } from '../../containers/App/actions'; import { makeSelectCurrentAgent, @@ -28,11 +33,13 @@ import { changeEntityData, removeExample, removeSynonym, + switchColorPickerDisplay, + closeColorPicker, } from './actions'; import Examples from './Components/Examples'; import messages from './messages'; -import { makeSelectEntityData } from './selectors'; +import { makeSelectEntityData, makeDisplayColorPicker } from './selectors'; export class EntityPage extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function constructor() { @@ -59,22 +66,34 @@ export class EntityPage extends React.PureComponent { // eslint-disable-line rea } render() { - const { loading, error, entity } = this.props; + const { loading, error, entity, displayColorPicker, currentAgent } = this.props; const entityProps = { loading, error, entity, + displayColorPicker, }; + let breadcrumbs = []; + if (currentAgent){ + breadcrumbs = [{ link: `/agent/${currentAgent.id}`, label: `Agent: ${currentAgent.agentName}`}, { label: '+ Creating entities'},]; + } + else { + breadcrumbs = [{ label: '+ Creating entities'}, ]; + } + return (
+ + { entityProps.loading ? : null } + -
+
@@ -85,6 +104,15 @@ export class EntityPage extends React.PureComponent { // eslint-disable-line rea inputId="entityName" onChange={(evt) => this.onChangeInput(evt, 'entityName')} required + s={10} + /> + + @@ -110,7 +138,7 @@ export class EntityPage extends React.PureComponent { // eslint-disable-line rea examples={this.props.entityData.examples} addExampleFunction={this.props.onAddExample} removeExampleFunction={this.props.onRemoveExample} - removeSynonymFunction={this.props.onAddExample} + removeSynonymFunction={this.props.onRemoveSynonym} addSynonymFunction={this.props.onAddSynonym} /> @@ -179,12 +207,22 @@ export function mapDispatchToProps(dispatch) { if (evt !== undefined && evt.preventDefault) evt.preventDefault(); dispatch(createEntity()); }, + handleClick: () => { + dispatch(switchColorPickerDisplay()); + }, + handleClose: () => { + dispatch(closeColorPicker()); + }, + handleColorChange: (color) => { + dispatch(changeEntityData({ value: color, field: 'uiColor' })); + }, }; } const mapStateToProps = createStructuredSelector({ entity: makeSelectEntity(), entityData: makeSelectEntityData(), + displayColorPicker: makeDisplayColorPicker(), loading: makeSelectLoading(), error: makeSelectError(), currentAgent: makeSelectCurrentAgent(), diff --git a/ui/app/containers/EntityPage/messages.js b/ui/app/containers/EntityPage/messages.js index cd15badd7..b4eb10027 100644 --- a/ui/app/containers/EntityPage/messages.js +++ b/ui/app/containers/EntityPage/messages.js @@ -18,6 +18,10 @@ export default defineMessages({ id: 'boilerplate.containers.EntityPage.create_entity.entityName', defaultMessage: 'Entity Name', }, + entityColor: { + id: 'boilerplate.containers.EntityPage.create_entity.entityColor', + defaultMessage: 'Entity Color', + }, entityNamePlaceholder: { id: 'boilerplate.containers.EntityPage.create_entity.entity_name_placeholder', defaultMessage: 'Type a name here', diff --git a/ui/app/containers/EntityPage/reducer.js b/ui/app/containers/EntityPage/reducer.js index bb78abcfb..3e886e54a 100644 --- a/ui/app/containers/EntityPage/reducer.js +++ b/ui/app/containers/EntityPage/reducer.js @@ -6,13 +6,17 @@ import { CHANGE_ENTITY_DATA, REMOVE_EXAMPLE, REMOVE_SYNONYM, + SWITCH_COLOR_PICKER_DISPLAY, + CLOSE_COLOR_PICKER, } from './constants'; // The initial state of the App const initialState = fromJS({ + displayColorPicker: false, entityData: { agent: null, entityName: '', + uiColor: '#e91e63', examples: [], }, }); @@ -23,6 +27,11 @@ function entityReducer(state = initialState, action) { switch (action.type) { case CHANGE_ENTITY_DATA: + if (action.payload.field === 'uiColor'){ + return state + .updateIn(['entityData'], x => x.set(action.payload.field, action.payload.value.hex)) + .set('displayColorPicker', false); + } return state .updateIn(['entityData'], x => x.set(action.payload.field, action.payload.value)); case REMOVE_EXAMPLE: @@ -43,6 +52,10 @@ function entityReducer(state = initialState, action) { examples = examples.map(example => example.get('value') === action.payload.example ? example.update('synonyms', synonyms => synonyms.push(action.payload.synonym)) : example); return state .setIn(['entityData', 'examples'], examples); + case SWITCH_COLOR_PICKER_DISPLAY: + return state.set('displayColorPicker', !state.get('displayColorPicker')); + case CLOSE_COLOR_PICKER: + return state.set('displayColorPicker', false); default: return state; } diff --git a/ui/app/containers/EntityPage/selectors.js b/ui/app/containers/EntityPage/selectors.js index 581e628ea..0347b3551 100644 --- a/ui/app/containers/EntityPage/selectors.js +++ b/ui/app/containers/EntityPage/selectors.js @@ -7,7 +7,13 @@ const makeSelectEntityData = () => createSelector( (entityState) => entityState.get('entityData').toJS(), ); +const makeDisplayColorPicker = () => createSelector( + selectEntity, + (displayColorPickerState) => displayColorPickerState.get('displayColorPicker'), +); + export { selectEntity, makeSelectEntityData, + makeDisplayColorPicker, }; diff --git a/ui/app/containers/HomePage/index.js b/ui/app/containers/HomePage/index.js index 6e30f84e7..f727ce037 100644 --- a/ui/app/containers/HomePage/index.js +++ b/ui/app/containers/HomePage/index.js @@ -2,10 +2,11 @@ import Header from 'components/Header'; import React from 'react'; export default class HomePage extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function + render() { return (
-
+
); } diff --git a/ui/app/containers/IntentListPage/index.js b/ui/app/containers/IntentListPage/index.js index 6662f6ca4..f1977cf37 100644 --- a/ui/app/containers/IntentListPage/index.js +++ b/ui/app/containers/IntentListPage/index.js @@ -3,6 +3,7 @@ import Helmet from 'react-helmet'; import { Input, Row, + Col, } from 'react-materialize'; import { connect } from 'react-redux'; import { push } from 'react-router-redux'; @@ -13,6 +14,8 @@ import ContentHeader from '../../components/ContentHeader'; import Form from '../../components/Form'; import Header from '../../components/Header'; import IntentsTable from '../../components/IntentsTable/index'; +import Preloader from '../../components/Preloader'; + import { loadAgentDomains, loadDomainIntents, @@ -71,13 +74,21 @@ export class IntentListPage extends React.PureComponent { // eslint-disable-line } render() { - const { loading, error, agentDomains, domainIntents } = this.props; + const { loading, error, agentDomains, domainIntents, currentAgent } = this.props; const domainProps = { loading, error, agentDomains, }; + let breadcrumbs = []; + if (currentAgent){ + breadcrumbs = [{ link: `/agent/${currentAgent.id}`, label: `Agent: ${currentAgent.agentName}`}, { label: 'Intents'},]; + } + else { + breadcrumbs = [{ label: 'Intents'}, ]; + } + let domainsSelect = []; if (agentDomains !== false) { domainsSelect = agentDomains.map((domain) => ({ @@ -89,13 +100,16 @@ export class IntentListPage extends React.PureComponent { // eslint-disable-line return (
+ + { domainProps.loading ? : null } + -
+
diff --git a/ui/app/containers/IntentPage/Components/AgentEntities.js b/ui/app/containers/IntentPage/Components/AgentEntities.js index bf4b0d8a4..c12c6ced4 100644 --- a/ui/app/containers/IntentPage/Components/AgentEntities.js +++ b/ui/app/containers/IntentPage/Components/AgentEntities.js @@ -18,10 +18,7 @@ export function AgentEntities(props) { items = props.agentEntities.map((agentEntity, agentIndex) => { let entityColor = props.dirOfColors[agentEntity.entityName]; if (!entityColor) { - const randomColorIndex = Math.floor(Math.random() * props.colorArray.length); - entityColor = props.colorArray[randomColorIndex]; - props.dirOfColors[agentEntity.entityName] = entityColor; - props.colorArray.splice(randomColorIndex, 1); + props.dirOfColors[agentEntity.entityName] = agentEntity.uiColor; } return ( - + @{agentEntity.entityName} @@ -60,7 +57,6 @@ AgentEntities.propTypes = { userSays: React.PropTypes.string, onClickFunction: React.PropTypes.func, dirOfColors: React.PropTypes.object, - colorArray: React.PropTypes.array, index: React.PropTypes.number, createEntity: React.PropTypes.bool, }; diff --git a/ui/app/containers/IntentPage/Components/AvailableSlots.js b/ui/app/containers/IntentPage/Components/AvailableSlots.js index b6084c550..476b2ebe9 100644 --- a/ui/app/containers/IntentPage/Components/AvailableSlots.js +++ b/ui/app/containers/IntentPage/Components/AvailableSlots.js @@ -11,12 +11,6 @@ export function AvailableSlots(props) { items = props.slots.map((slot, index) => { const agentEntity = props.agentEntities.filter((agentEntity) => agentEntity.entityName === slot.entity)[0]; let entityColor = props.dirOfColors[slot.entity]; - if (!entityColor) { - const randomColorIndex = Math.floor(Math.random() * props.colorArray.length); - entityColor = props.colorArray[randomColorIndex]; - props.dirOfColors[slot.entity] = entityColor; - props.colorArray.splice(randomColorIndex, 1); - } return ( {`{${slot.slotName}}`} ); @@ -37,7 +31,6 @@ AvailableSlots.propTypes = { ]), onClickFunction: React.PropTypes.func, dirOfColors: React.PropTypes.object, - colorArray: React.PropTypes.array, }; export default AvailableSlots; diff --git a/ui/app/containers/IntentPage/Components/FormattedText.js b/ui/app/containers/IntentPage/Components/FormattedText.js index f0e9c3ee2..9f64fff4a 100644 --- a/ui/app/containers/IntentPage/Components/FormattedText.js +++ b/ui/app/containers/IntentPage/Components/FormattedText.js @@ -8,16 +8,11 @@ export function FormattedText(props) { const taggedText = props.text.substring(entity.start - props.lastStart, entity.end - props.lastStart); const afterTaggedText = props.text.substring(entity.end - props.lastStart, props.text.length); let highlightColor = props.dirOfColors[entity.entity]; - if (!highlightColor) { - const randomColorIndex = Math.floor(Math.random() * props.colorArray.length); - highlightColor = props.colorArray[randomColorIndex]; - props.colorArray.splice(randomColorIndex, 1); - } formattedElement = ( {beforeTaggedText} {taggedText} - + ); } else { @@ -37,7 +32,6 @@ FormattedText.propTypes = { entityIndex: React.PropTypes.number, lastStart: React.PropTypes.number, dirOfColors: React.PropTypes.object, - colorArray: React.PropTypes.array, }; export default FormattedText; diff --git a/ui/app/containers/IntentPage/Components/SlotAgentEntities.js b/ui/app/containers/IntentPage/Components/SlotAgentEntities.js index 097fffe7c..10c7d7b3e 100644 --- a/ui/app/containers/IntentPage/Components/SlotAgentEntities.js +++ b/ui/app/containers/IntentPage/Components/SlotAgentEntities.js @@ -12,10 +12,7 @@ export function SlotAgentEntities(props) { items = props.agentEntities.map((agentEntity, agentIndex) => { let entityColor = props.dirOfColors[agentEntity.entityName]; if (!entityColor) { - const randomColorIndex = Math.floor(Math.random() * props.colorArray.length); - entityColor = props.colorArray[randomColorIndex]; - props.dirOfColors[agentEntity.entityName] = entityColor; - props.colorArray.splice(randomColorIndex, 1); + props.dirOfColors[agentEntity.entityName] = agentEntity.uiColor; } return ( ); } @@ -26,7 +25,6 @@ Slots.propTypes = { React.PropTypes.bool, ]), dirOfColors: React.PropTypes.object, - colorArray: React.PropTypes.array, }; export default Slots; diff --git a/ui/app/containers/IntentPage/Components/SlotsRows.js b/ui/app/containers/IntentPage/Components/SlotsRows.js index 4937809db..1a763af4b 100644 --- a/ui/app/containers/IntentPage/Components/SlotsRows.js +++ b/ui/app/containers/IntentPage/Components/SlotsRows.js @@ -9,7 +9,7 @@ export function SlotsRows(props) { const agentEntity = props.agentEntities.filter((agentEntity) => agentEntity.entityName === slot.entity)[0]; return ( - + { }} dirOfColors={props.dirOfColors} - colorArray={props.colorArray} /> @@ -57,7 +56,6 @@ SlotsRows.propTypes = { React.PropTypes.bool, ]), dirOfColors: React.PropTypes.object, - colorArray: React.PropTypes.array, }; export default SlotsRows; diff --git a/ui/app/containers/IntentPage/Components/TextPrompts.js b/ui/app/containers/IntentPage/Components/TextPrompts.js index dc8c1282e..a4bf0a3e4 100644 --- a/ui/app/containers/IntentPage/Components/TextPrompts.js +++ b/ui/app/containers/IntentPage/Components/TextPrompts.js @@ -19,7 +19,7 @@ export function TextPrompts(props) { ); return ( - + { rows } diff --git a/ui/app/containers/IntentPage/Components/UserSayings.js b/ui/app/containers/IntentPage/Components/UserSayings.js index 62c42f987..fe0ef49d1 100644 --- a/ui/app/containers/IntentPage/Components/UserSayings.js +++ b/ui/app/containers/IntentPage/Components/UserSayings.js @@ -8,7 +8,6 @@ export function UserSayings(props) { onRemoveExample={props.onRemoveExample} onTagEntity={props.onTagEntity} agentEntities={props.agentEntities} - colorArray={props.colorArray} dirOfColors={props.dirOfColors} />; } @@ -19,7 +18,6 @@ UserSayings.propTypes = { onTagEntity: React.PropTypes.func, agentEntities: React.PropTypes.array, dirOfColors: React.PropTypes.object, - colorArray: React.PropTypes.array, }; export default UserSayings; diff --git a/ui/app/containers/IntentPage/Components/UserSayingsRows.js b/ui/app/containers/IntentPage/Components/UserSayingsRows.js index 35e15e7a3..93a3d1c0c 100644 --- a/ui/app/containers/IntentPage/Components/UserSayingsRows.js +++ b/ui/app/containers/IntentPage/Components/UserSayingsRows.js @@ -25,7 +25,7 @@ export function UserSayingsRows(props) { let formattedText = null; if (value.entities.length > 0) { const sortedEntities = value.entities.sort(compareEntities); - formattedText = ; + formattedText = ; } return ( @@ -38,7 +38,6 @@ export function UserSayingsRows(props) { userSays={textValue} onClickFunction={props.onTagEntity} dirOfColors={props.dirOfColors} - colorArray={props.colorArray} createEntity={true} /> @@ -63,7 +62,6 @@ UserSayingsRows.propTypes = { onTagEntity: React.PropTypes.func, agentEntities: React.PropTypes.array, dirOfColors: React.PropTypes.object, - colorArray: React.PropTypes.array, }; export default UserSayingsRows; diff --git a/ui/app/containers/IntentPage/index.js b/ui/app/containers/IntentPage/index.js index ecaef4a58..cdaf073fe 100644 --- a/ui/app/containers/IntentPage/index.js +++ b/ui/app/containers/IntentPage/index.js @@ -5,6 +5,7 @@ import Helmet from 'react-helmet'; import { Input, Row, + Col, } from 'react-materialize'; import { connect } from 'react-redux'; import { createStructuredSelector } from 'reselect'; @@ -18,6 +19,7 @@ import InputLabel from '../../components/InputLabel'; import Table from '../../components/Table'; import TableContainer from '../../components/TableContainer'; import TableHeader from '../../components/TableHeader'; +import Preloader from '../../components/Preloader'; import Toggle from '../../components/Toggle'; import { @@ -61,7 +63,6 @@ const returnFormattedOptions = (options) => options.map((option, index) => ( )); -const colorArray = ['#f44336', '#E91E63', '#9C27B0', '#673AB7', '#3F51B5', '#2196F3', '#03A9F4', '#00BCD4', '#009688', '#4CAF50', '#8BC34A']; const dirOfColors = {}; export class IntentPage extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function @@ -108,7 +109,7 @@ export class IntentPage extends React.PureComponent { // eslint-disable-line rea } render() { - const { loading, error, intent, scenario, agentDomains, agentEntities } = this.props; + const { loading, error, intent, scenario, agentDomains, agentEntities, currentAgent } = this.props; const intentProps = { loading, error, @@ -124,16 +125,27 @@ export class IntentPage extends React.PureComponent { // eslint-disable-line rea domainsSelect.unshift({ value: 'default', text: 'Please choose a domain to place your intent', disabled: 'disabled' }); } + let breadcrumbs = []; + if (currentAgent){ + breadcrumbs = [{ link: `/agent/${currentAgent.id}`, label: `Agent: ${currentAgent.agentName}`}, { label: '+ Creating intents'},]; + } + else { + breadcrumbs = [{ label: '+ Creating intents'}, ]; + } + return (
+ + { intentProps.loading ? : null } + -
+
@@ -183,7 +195,7 @@ export class IntentPage extends React.PureComponent { // eslint-disable-line rea onRemoveExample={this.props.onRemoveExample} onTagEntity={this.props.onTagEntity} agentEntities={agentEntities} - colorArray={colorArray} dirOfColors={dirOfColors} + dirOfColors={dirOfColors} /> @@ -201,7 +213,7 @@ export class IntentPage extends React.PureComponent { // eslint-disable-line rea @@ -247,7 +258,6 @@ export class IntentPage extends React.PureComponent { // eslint-disable-line rea slots={this.props.scenarioData.slots} agentEntities={agentEntities} onClickFunction={this.props.onAutoCompleteEntityFunction} - colorArray={colorArray} dirOfColors={dirOfColors} /> { if (slot.slotName === action.payload.slotName) { - slot.textPrompts.splice(slot.textPrompts.indexOf(action.payload.textPrompt)); + slot.textPrompts.splice(slot.textPrompts.indexOf(action.payload.textPrompt), 1); } return slot; }); diff --git a/ui/app/containers/WebhookPage/index.js b/ui/app/containers/WebhookPage/index.js index e87792986..e48efe241 100644 --- a/ui/app/containers/WebhookPage/index.js +++ b/ui/app/containers/WebhookPage/index.js @@ -1,13 +1,16 @@ import React from 'react'; import Helmet from 'react-helmet'; -import { Row, } from 'react-materialize'; +import { Row, + Col, + } from 'react-materialize'; import { connect } from 'react-redux'; import { createStructuredSelector } from 'reselect'; import ActionButton from '../../components/ActionButton'; import Content from '../../components/Content'; import ContentHeader from '../../components/ContentHeader'; import Form from '../../components/Form'; +import Preloader from '../../components/Preloader'; import FormTextInput from '../../components/FormTextInput'; import Header from '../../components/Header'; @@ -50,22 +53,33 @@ export class WebhookPage extends React.PureComponent { // eslint-disable-line re } render() { - const { loading, error, webhook } = this.props; + const { loading, error, webhook, currentAgent } = this.props; const webhookProps = { loading, error, webhook, }; + let breadcrumbs = []; + if (currentAgent){ + breadcrumbs = [{ link: `/agent/${currentAgent.id}`, label: `Agent: ${currentAgent.agentName}`}, { label: '+ Add Webhook'},]; + } + else { + breadcrumbs = [{ label: '+ Add Webhook'}, ]; + } + return (
+ + { webhookProps.loading ? : null } + -
+
diff --git a/ui/app/global-styles.js b/ui/app/global-styles.js index b0f05f2d7..1e4a9cf55 100644 --- a/ui/app/global-styles.js +++ b/ui/app/global-styles.js @@ -467,4 +467,12 @@ injectGlobal` form p.range-field { margin-left: 0; } + .chip .remove{ + cursor:pointer; + float:right; + font-size:16px; + line-height:32px; + padding-left:8px + } + `; diff --git a/ui/package.json b/ui/package.json index ed14bc4be..2e2364643 100644 --- a/ui/package.json +++ b/ui/package.json @@ -226,6 +226,7 @@ "minimist": "1.2.0", "react": "15.4.1", "react-chips": "^0.6.3", + "react-color": "^2.13.8", "react-dom": "15.4.1", "react-helmet": "3.2.2", "react-intl": "2.1.5",