diff --git a/.github/workflows/ci_workflow.yml b/.github/workflows/ci_workflow.yml new file mode 100644 index 0000000..7dcf320 --- /dev/null +++ b/.github/workflows/ci_workflow.yml @@ -0,0 +1,52 @@ +name: CI + +on: [pull_request] + +jobs: + build: + env: + working-directory: . + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v1 + with: + node-version: '12' + - name: Build + run: | + docker build -t bot-flow . + working-directory: ${{env.working-directory}} + test: + env: + working-directory: ./app + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v1 + with: + node-version: '12' + - name: Install dependencies + run: | + yarn install + working-directory: ${{env.working-directory}} + - name: Run tests + run: | + yarn test --ci --coverage --color + working-directory: ${{env.working-directory}} + lint: + env: + working-directory: ./app + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v1 + with: + node-version: '12' + - name: Install dependencies + run: | + yarn install + working-directory: ${{env.working-directory}} + - name: Run eslint + run: | + yarn lint + working-directory: ${{env.working-directory}} \ No newline at end of file diff --git a/app/.eslintrc.json b/app/.eslintrc.json new file mode 100644 index 0000000..13b8277 --- /dev/null +++ b/app/.eslintrc.json @@ -0,0 +1,27 @@ +{ + "env": { + "browser": true, + "es6": true, + "jest": true + }, + "extends": [ + "plugin:react/recommended", + "airbnb" + ], + "globals": { + "Atomics": "readonly", + "SharedArrayBuffer": "readonly" + }, + "parserOptions": { + "ecmaFeatures": { + "jsx": true + }, + "ecmaVersion": 2018, + "sourceType": "module" + }, + "plugins": [ + "react" + ], + "rules": { + } +} \ No newline at end of file diff --git a/app/package.json b/app/package.json index 2dc7b2f..52b91e0 100644 --- a/app/package.json +++ b/app/package.json @@ -22,7 +22,8 @@ "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", - "eject": "react-scripts eject" + "eject": "react-scripts eject", + "lint": "eslint ./src/**/*.js" }, "eslintConfig": { "extends": "react-app" @@ -42,7 +43,12 @@ "devDependencies": { "enzyme": "^3.10.0", "enzyme-adapter-react-16": "^1.14.0", - "eslint-plugin-import": "^2.18.2", + "eslint": "6.6.0", + "eslint-config-airbnb": "^18.2.1", + "eslint-plugin-import": "^2.22.1", + "eslint-plugin-jsx-a11y": "^6.4.1", + "eslint-plugin-react": "^7.22.0", + "eslint-plugin-react-hooks": "^4.2.0", "react-test-renderer": "^16.9.0" } } diff --git a/app/src/components/CustomSnackbar.js b/app/src/components/CustomSnackbar.js index 54a9b20..cf79230 100644 --- a/app/src/components/CustomSnackbar.js +++ b/app/src/components/CustomSnackbar.js @@ -1,4 +1,4 @@ -import React from "react"; +import React from 'react'; import clsx from 'clsx'; import CheckCircleIcon from '@material-ui/icons/CheckCircle'; @@ -19,7 +19,7 @@ const variantIcon = { info: InfoIcon, }; -const useStyles1 = makeStyles(theme => ({ +const useStyles1 = makeStyles((theme) => ({ success: { backgroundColor: green[600], }, @@ -47,19 +47,21 @@ const useStyles1 = makeStyles(theme => ({ export default function SnackbarContentCustom(props) { const classes = useStyles1(); - const { className, message, onClose, variant, } = props; + const { + className, message, onClose, variant, + } = props; const Icon = variantIcon[variant]; return ( {message} - } + )} action={[ @@ -67,4 +69,4 @@ export default function SnackbarContentCustom(props) { ]} /> ); -} \ No newline at end of file +} diff --git a/app/src/components/DeleteSnackbar.js b/app/src/components/DeleteSnackbar.js index 2473e04..fdb6900 100644 --- a/app/src/components/DeleteSnackbar.js +++ b/app/src/components/DeleteSnackbar.js @@ -1,40 +1,40 @@ - -import React, { Component } from "react"; -import {message} from '../utils/messages'; +import React, { Component } from 'react'; import { Button } from '@material-ui/core'; import Snackbar from '@material-ui/core/Snackbar'; +import { message } from '../utils/messages'; class DeleteSnackbar extends Component { - handleUndoSnack() { - this.props.handleUndo(); - this.props.handleSnackbarClick(); - } + handleUndoSnack() { + this.props.handleUndo(); + this.props.handleSnackbarClick(); + } - render() { - return ( - this.props.handleSnackbarClick(false)} - ContentProps={{ - 'aria-describedby': 'message-id', - }} - message={{message.deleted}} - action={[ - - ]} - /> - ) - } + render() { + return ( + this.props.handleSnackbarClick(false)} + ContentProps={{ + 'aria-describedby': 'message-id', + }} + message={{message.deleted}} + action={[ + , + ]} + /> + ); + } } -export default DeleteSnackbar; \ No newline at end of file +export default DeleteSnackbar; diff --git a/app/src/components/DeletionConfirmationDialog.js b/app/src/components/DeletionConfirmationDialog.js index bd8baac..f038633 100644 --- a/app/src/components/DeletionConfirmationDialog.js +++ b/app/src/components/DeletionConfirmationDialog.js @@ -1,37 +1,34 @@ - -import React from "react"; -import { message } from '../utils/messages'; +import React from 'react'; import { Button } from '@material-ui/core'; import Dialog from '@material-ui/core/Dialog'; import DialogActions from '@material-ui/core/DialogActions'; import DialogTitle from '@material-ui/core/DialogTitle'; +import { message } from '../utils/messages'; -const DeletionConfirmationDialog = ({ dialog_status, handleClose, deleteItem }) => { - return ( - - {message.delete_confirmation} - - - - - +const DeletionConfirmationDialog = ({ dialog_status, handleClose, deleteItem }) => ( + + {message.delete_confirmation} + + + + + - ) -} +); -export default DeletionConfirmationDialog; \ No newline at end of file +export default DeletionConfirmationDialog; diff --git a/app/src/components/ExampleStory.js b/app/src/components/ExampleStory.js index cddde83..4490729 100644 --- a/app/src/components/ExampleStory.js +++ b/app/src/components/ExampleStory.js @@ -1,97 +1,96 @@ -import React, { Component } from "react"; -import { connect } from "react-redux"; +import React, { Component } from 'react'; +import { connect } from 'react-redux'; import Typography from '@material-ui/core/Typography'; import { IntentBalloon, UtterFirstBalloon, UtterBalloon } from '../styles/exampleBalloon'; import { message } from '../utils/messages'; const styles = { - title: { - alignSelf: 'center', - margin: '14px', - }, - container: { - display: 'flex', - flexDirection: 'column', - minHeight: "calc(100vh - 74px - 72px)", - borderLeft: "solid 1px #ddd", - alignItems: 'flex-start', - width: '100%', - } -} + title: { + alignSelf: 'center', + margin: '14px', + }, + container: { + display: 'flex', + flexDirection: 'column', + minHeight: 'calc(100vh - 74px - 72px)', + borderLeft: 'solid 1px #ddd', + alignItems: 'flex-start', + width: '100%', + }, +}; class ExampleStory extends Component { - exampleUtter(item, index) { - let examples = item.example.map((example, ex_index) => { - if (ex_index === 0 || item.example.length <= 1) { - return ( - - {example} - - ) - } else { - return ( - < UtterBalloon key={'example_' + index + ex_index} > - {example} - - ) - } - }) - - return examples; - } - - exampleSimpleUtter(item, index) { - const examples = item.example.map((example, ex_index) => - - {example} - - ) - return examples; - } - - exampleIntent(item, index) { + exampleUtter(item, index) { + const examples = item.example.map((example, ex_index) => { + if (ex_index === 0 || item.example.length <= 1) { return ( - - {item.example}? - + + {example} + ); - } + } + return ( + + {example} + + ); + }); - getExamples() { + return examples; + } - let last_item = {}; - let content = this.props.content; + exampleSimpleUtter(item, index) { + const examples = item.example.map((example, ex_index) => ( + + {example} + + )); + return examples; + } - for (let i = 0, size = content.length; i < size; i++) { - if (last_item.type === "utter") { - content[i] = { ...content[i], sequence: true }; - } else if (content[i].sequence) { - content[i].sequence = false; - } + exampleIntent(item, index) { + return ( + + + {item.example} + ? + + + ); + } - last_item = content[i]; - } + getExamples() { + let last_item = {}; + const { content } = this.props; - return content.map((item, index) => { - let element; - if (item.type === "intent") { element = this.exampleIntent(item, index) } - else if (item.sequence) { element = this.exampleSimpleUtter(item, index) } - else { element = this.exampleUtter(item, index) }; - return element; - }) - } + for (let i = 0, size = content.length; i < size; i++) { + if (last_item.type === 'utter') { + content[i] = { ...content[i], sequence: true }; + } else if (content[i].sequence) { + content[i].sequence = false; + } - render() { - return ( -
- - {this.props.content.length !== 0 ? "Exemplo:" : message.no_examples} - - {this.getExamples()} -
- ); + last_item = content[i]; } + + return content.map((item, index) => { + let element; + if (item.type === 'intent') { element = this.exampleIntent(item, index); } else if (item.sequence) { element = this.exampleSimpleUtter(item, index); } else { element = this.exampleUtter(item, index); } + return element; + }); + } + + render() { + return ( +
+ + {this.props.content.length !== 0 ? 'Exemplo:' : message.no_examples} + + {this.getExamples()} +
+ ); + } } -const mapStateToProps = state => { return { ...state.story } }; +const mapStateToProps = (state) => ({ ...state.story }); -export default connect(mapStateToProps)(ExampleStory); \ No newline at end of file +export default connect(mapStateToProps)(ExampleStory); diff --git a/app/src/components/IntentForm.js b/app/src/components/IntentForm.js index 0affcfd..8b3ad6d 100644 --- a/app/src/components/IntentForm.js +++ b/app/src/components/IntentForm.js @@ -1,37 +1,37 @@ -import { connect } from "react-redux"; +import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; -import React, { Component } from "react"; +import React, { Component } from 'react'; import Grid from '@material-ui/core/Grid'; import DeleteIcon from '@material-ui/icons/Delete'; import TextField from '@material-ui/core/TextField'; import IconButton from '@material-ui/core/IconButton'; import InputAdornment from '@material-ui/core/InputAdornment'; import Typography from '@material-ui/core/Typography'; -import SnackbarDelete from './DeleteSnackbar' +import SnackbarDelete from './DeleteSnackbar'; -import { Creators as IntentAction } from "../ducks/intents"; +import { Creators as IntentAction } from '../ducks/intents'; const style = { new_question: { - opacity: "0.2", - position: "relative", - cursor: "pointer", - border: "solid 1px #000", - borderRadius: "4px", - padding: "10px 0 10px 14px", - } -} + opacity: '0.2', + position: 'relative', + cursor: 'pointer', + border: 'solid 1px #000', + borderRadius: '4px', + padding: '10px 0 10px 14px', + }, +}; class IntentForm extends Component { constructor(props) { super(props); this.state = { undo_delete: false, - there_is_auto_focus: false - } + there_is_auto_focus: false, + }; - this.handleSnackbarClick = this.handleSnackbarClick.bind(this) + this.handleSnackbarClick = this.handleSnackbarClick.bind(this); } handleDelete(intent_index) { @@ -47,7 +47,7 @@ class IntentForm extends Component { handleClick(key = 'Enter') { if (key === 'Enter') { - this.props.addIntent() + this.props.addIntent(); this.setState({ there_is_auto_focus: true }); } } @@ -59,34 +59,32 @@ class IntentForm extends Component { setIntentContents() { let samples = []; if (this.props.content !== undefined) { - samples = (this.props.content).map((sample, sample_index) => { - return ( -
  • - - - { this.handleClick(event.key) }} - autoFocus={this.state.there_is_auto_focus} - onChange={(e) => this.props.setIntentContent(sample_index, e.target.value)} - InputProps={{ - endAdornment: ?, - }} - /> - - - this.handleDelete(sample_index)}> - - - + samples = (this.props.content).map((sample, sample_index) => ( +
  • + + + { this.handleClick(event.key); }} + autoFocus={this.state.there_is_auto_focus} + onChange={(e) => this.props.setIntentContent(sample_index, e.target.value)} + InputProps={{ + endAdornment: ?, + }} + /> + + + this.handleDelete(sample_index)}> + + -
  • - ) - }) + + + )); } return samples; @@ -100,15 +98,17 @@ class IntentForm extends Component {
      {this.setIntentContents()}
    - + -
    { this.handleClick() }} +
    { this.handleClick(); }} > Nova pergunta
    @@ -123,8 +123,8 @@ class IntentForm extends Component { } } -const mapStateToProps = state => { return { ...state.intent } }; +const mapStateToProps = (state) => ({ ...state.intent }); -const mapDispatchToProps = dispatch => bindActionCreators(IntentAction, dispatch); +const mapDispatchToProps = (dispatch) => bindActionCreators(IntentAction, dispatch); export default connect(mapStateToProps, mapDispatchToProps)(IntentForm); diff --git a/app/src/components/ItemsList.js b/app/src/components/ItemsList.js index 4e3c52c..ed4bde1 100644 --- a/app/src/components/ItemsList.js +++ b/app/src/components/ItemsList.js @@ -1,43 +1,44 @@ -import React, { Component } from "react"; +import React, { Component } from 'react'; import Typography from '@material-ui/core/Typography'; -import { List, ListItem, ListItemIcon, ListItemText, styled } from '@material-ui/core'; -import { message } from "../utils/messages"; -import { setHighlight } from "../utils/utils"; +import { + List, ListItem, ListItemIcon, ListItemText, styled, +} from '@material-ui/core'; +import { message } from '../utils/messages'; +import { setHighlight } from '../utils/utils'; const StyledListItem = styled(ListItem)({ - backgroundColor: "transparent", - borderRadius: "12px 0 0 12px", + backgroundColor: 'transparent', + borderRadius: '12px 0 0 12px', - "&:hover": { - backgroundColor: "rgba(246,249,249,0.6)", //primary.light $40% + '&:hover': { + backgroundColor: 'rgba(246,249,249,0.6)', // primary.light $40% }, - "&.Mui-selected": { - color: "#f15035", //secondary - backgroundColor: "#f6f9f9", //primary.light - "&:hover": { - backgroundColor: "#f6f9f9" //primary.light - } + '&.Mui-selected': { + color: '#f15035', // secondary + backgroundColor: '#f6f9f9', // primary.light + '&:hover': { + backgroundColor: '#f6f9f9', // primary.light + }, }, - "& .MuiListItemIcon-root": { - fill: "#4b3953", //primary - "&.Mui-selected": { - fill: "#f15035", //secondary - } + '& .MuiListItemIcon-root': { + fill: '#4b3953', // primary + '&.Mui-selected': { + fill: '#f15035', // secondary + }, + }, + '&.Mui-selected .MuiListItemIcon-root': { + fill: '#f15035', // secondary }, - "&.Mui-selected .MuiListItemIcon-root": { - fill: "#f15035", //secondary - } }); export default class ItemList extends Component { - getItemsList(items, icon, highlighted_text, selected_item_position) { const new_items = items.map((item, index) => ( this.handleListItemClick(item, index)} > @@ -59,9 +60,9 @@ export default class ItemList extends Component { getErrorMessage() { return ( -
  • - {message.no_result} -
  • +
  • + {message.no_result} +
  • ); } diff --git a/app/src/components/ListFilter.js b/app/src/components/ListFilter.js index 37da849..3d8cc00 100644 --- a/app/src/components/ListFilter.js +++ b/app/src/components/ListFilter.js @@ -1,35 +1,35 @@ -import React, { Component } from "react"; +import React, { Component } from 'react'; import Typography from '@material-ui/core/Typography'; import TextField from '@material-ui/core/TextField'; import Divider from '@material-ui/core/Divider'; -import ItemsList from "./ItemsList"; import SearchIcon from '@material-ui/icons/Search'; import CloseIcon from '@material-ui/icons/Close'; +import ItemsList from './ItemsList'; const style = { filter_items_container: { - padding: "12px 8px", - //position: "relative", - //background: "yellow", - //bottom: 0 + padding: '12px 8px', + // position: "relative", + // background: "yellow", + // bottom: 0 }, list_container: { - height: "calc(100vh - 74px - 64px - 80px - 10px)", - paddingLeft: "24px", - overflowY: "auto" - } -} + height: 'calc(100vh - 74px - 64px - 80px - 10px)', + paddingLeft: '24px', + overflowY: 'auto', + }, +}; export default class ListFilter extends Component { constructor(props) { super(props); - this.state = { value: "" }; + this.state = { value: '' }; } filterItems(items) { if (items !== undefined) { - return items.filter(item => (item.name).includes(this.state.value)); + return items.filter((item) => (item.name).includes(this.state.value)); } return []; } @@ -44,18 +44,18 @@ export default class ListFilter extends Component { getFilterIcon() { if ((this.state.value).trim().length === 0) { - return + return ; } return ( this.cleanFilter()} - style={{ cursor: "pointer" }} + style={{ cursor: 'pointer' }} /> - ) + ); } cleanFilter() { - this.setState({ value: "" }); + this.setState({ value: '' }); } render() { @@ -88,6 +88,6 @@ export default class ListFilter extends Component { />
    - ) + ); } -} \ No newline at end of file +} diff --git a/app/src/components/MenuNavbar.js b/app/src/components/MenuNavbar.js index 35d184d..091be69 100644 --- a/app/src/components/MenuNavbar.js +++ b/app/src/components/MenuNavbar.js @@ -1,50 +1,51 @@ import React from 'react'; import { Link } from 'react-router-dom'; +import { + Tab, Tabs, AppBar, Toolbar, +} from '@material-ui/core'; +import { makeStyles, withStyles } from '@material-ui/core/styles'; +import Button from '@material-ui/core/Button'; import StoryIcon from '../icons/StoryIcon'; import UtterIcon from '../icons/UtterIcon'; import IntentIcon from '../icons/IntentIcon'; -import { Tab, Tabs } from '@material-ui/core'; -import { makeStyles, withStyles } from '@material-ui/core/styles'; import AppIcon from '../icons/AppIcon'; -import Button from '@material-ui/core/Button'; import { message } from '../utils/messages.js'; -import { AppBar, Toolbar } from '@material-ui/core'; -import { DOWNLOAD_URL} from '../utils/url_routes.js'; -const useStyles = makeStyles(theme => ({ +import { DOWNLOAD_URL } from '../utils/url_routes.js'; + +const useStyles = makeStyles((theme) => ({ root: { flexGrow: 1, marginBottom: 2, }, tabWrapper: { - flexDirection: "row", - justifyContent: "space-around", + flexDirection: 'row', + justifyContent: 'space-around', }, })); -const StyledTab = withStyles(theme => ({ +const StyledTab = withStyles((theme) => ({ root: { - fontStyle: "italic", + fontStyle: 'italic', fontSize: 14, - textTransform: "uppercase", + textTransform: 'uppercase', fontWeight: theme.typography.fontWeightRegular, color: theme.palette.primary.light, '& svg': { - display: "none", + display: 'none', }, '&$selected': { fontWeight: theme.typography.fontWeightMedium, '& svg': { - display: "inline", + display: 'inline', fill: theme.palette.primary.light, }, }, }, selected: {}, wrapper: {}, -}))(props => ); - +}))((props) => ); export default function MenuNavbar() { const classes = useStyles(); @@ -53,39 +54,42 @@ export default function MenuNavbar() { function handleChange(event, newValue) { const url = window.location.pathname; if (newValue !== undefined) { - setValue(newValue) + setValue(newValue); } else { if (url === '/' || url.includes('/stories/')) { return 0; - } else if (url.includes('/intents/')) { + } if (url.includes('/intents/')) { return 1; - } else if (url.includes('/utters/')) { + } if (url.includes('/utters/')) { return 2; } } } return ( - - - handleChange(undefined, 0)} to="/"> - - - - } label="Diálogos" to="/" component={Link} /> - } label="Perguntas" to="/intents/new" component={Link} /> - } label="Respostas" to="/utters/new" component={Link} /> - - - - + + + handleChange(undefined, 0)} to="/"> + + + + } label="Diálogos" to="/" component={Link} /> + } label="Perguntas" to="/intents/new" component={Link} /> + } label="Respostas" to="/utters/new" component={Link} /> + + + + ); } diff --git a/app/src/components/NameField.js b/app/src/components/NameField.js index 870f610..fb0a77d 100644 --- a/app/src/components/NameField.js +++ b/app/src/components/NameField.js @@ -1,59 +1,59 @@ -import React, { Component } from "react"; +import React, { Component } from 'react'; import TextField from '@material-ui/core/TextField'; -import { message } from "../utils/messages"; +import { message } from '../utils/messages'; class NameField extends Component { - isRepeatedName(items, name) { - if (items !== undefined) { - let founded = items.find((item) => ( - (item.name === name) && - (item.id !== this.props.item_id) - )); - - return (founded !== undefined ? message.repeated_name : ""); - } + isRepeatedName(items, name) { + if (items !== undefined) { + const founded = items.find((item) => ( + (item.name === name) + && (item.id !== this.props.item_id) + )); + + return (founded !== undefined ? message.repeated_name : ''); } + } - hasSpecialCharacteres(name) { - let helper_text = ""; - let regex = /^[\w\d_]+$/; + hasSpecialCharacteres(name) { + let helper_text = ''; + const regex = /^[\w\d_]+$/; - if (!regex.test(name) && name.length > 0) { - helper_text = message.no_special_char; - } - - return helper_text; + if (!regex.test(name) && name.length > 0) { + helper_text = message.no_special_char; } - setName(items, name) { - let helper_text = this.hasSpecialCharacteres(name); - if (helper_text.length!==0) { - name = name.substr(0, name.length - 1); - } else { - helper_text = this.isRepeatedName(items, name); - } + return helper_text; + } - this.props.setItemName(name, helper_text); + setName(items, name) { + let helper_text = this.hasSpecialCharacteres(name); + if (helper_text.length !== 0) { + name = name.substr(0, name.length - 1); + } else { + helper_text = this.isRepeatedName(items, name); } - render() { - return ( -
    - this.setName(this.props.items, e.target.value)} - /> -
    - ) - } + this.props.setItemName(name, helper_text); + } + + render() { + return ( +
    + this.setName(this.props.items, e.target.value)} + /> +
    + ); + } } export default NameField; diff --git a/app/src/components/Snackbar.js b/app/src/components/Snackbar.js index 9326b84..6c622e5 100644 --- a/app/src/components/Snackbar.js +++ b/app/src/components/Snackbar.js @@ -1,24 +1,22 @@ - import Snackbar from '@material-ui/core/Snackbar'; -import SnackbarContent from "./CustomSnackbar" -import React from "react"; +import React from 'react'; +import SnackbarContent from './CustomSnackbar'; -const MessageSnackbar = ({ notification_text, handleClose, variant = "success" }) => { - return ( - handleClose()}> - handleClose()} - /> - - ) -} -export default MessageSnackbar; \ No newline at end of file +const MessageSnackbar = ({ notification_text, handleClose, variant = 'success' }) => ( + handleClose()} + > + handleClose()} + /> + +); +export default MessageSnackbar; diff --git a/app/src/components/StoryCard.js b/app/src/components/StoryCard.js index 0f784d5..60c0ceb 100644 --- a/app/src/components/StoryCard.js +++ b/app/src/components/StoryCard.js @@ -1,69 +1,68 @@ -import { Link } from 'react-router-dom' -import React, { Component } from "react"; +import { Link } from 'react-router-dom'; +import React, { Component } from 'react'; import { Card } from '@material-ui/core'; +import Typography from '@material-ui/core/Typography'; import UtterIcon from '../icons/UtterIcon'; import IntentIcon from '../icons/IntentIcon'; -import Typography from '@material-ui/core/Typography'; -import { setHighlight } from "../utils/utils"; +import { setHighlight } from '../utils/utils'; const styles = { - intent: { - color: '#4b3953', - fontWeight: 'bold', - margin: '0px 0px 2px 0px' - }, - utter: { - color: '#f26a53', - margin: '2px 0px 2px 12px' - }, - intent_icon: { - fill: '#4b3953', - marginRight: 8, - verticalAlign: 'middle', - }, - utter_icon: { - fill: '#f26a53', - marginRight: 8, - verticalAlign: 'middle', - }, - card: { - background: 'white', - margin: '0 8px 16px 8px', - breakInside: 'avoid-column', - padding: '16px' - }, -} + intent: { + color: '#4b3953', + fontWeight: 'bold', + margin: '0px 0px 2px 0px', + }, + utter: { + color: '#f26a53', + margin: '2px 0px 2px 12px', + }, + intent_icon: { + fill: '#4b3953', + marginRight: 8, + verticalAlign: 'middle', + }, + utter_icon: { + fill: '#f26a53', + marginRight: 8, + verticalAlign: 'middle', + }, + card: { + background: 'white', + margin: '0 8px 16px 8px', + breakInside: 'avoid-column', + padding: '16px', + }, +}; export default class StoryCard extends Component { - getContent(content) { - let list = content.map((item, index) => { - if (item.type === "intent") { - return ( - - - {setHighlight(item.name, this.props.highlighted_text)} - - ) - } - else { - return ( - - - {setHighlight(item.name, this.props.highlighted_text)} - - ) - } - }) - return list; - } - - render() { + getContent(content) { + const list = content.map((item, index) => { + if (item.type === 'intent') { return ( - - - {this.getContent(this.props.story.content)} - - + + + {setHighlight(item.name, this.props.highlighted_text)} + ); - } + } + + return ( + + + {setHighlight(item.name, this.props.highlighted_text)} + + ); + }); + return list; + } + + render() { + return ( + + + {this.getContent(this.props.story.content)} + + + ); + } } diff --git a/app/src/components/StoryList.js b/app/src/components/StoryList.js index e77ba31..b622ca5 100644 --- a/app/src/components/StoryList.js +++ b/app/src/components/StoryList.js @@ -1,180 +1,182 @@ -import { connect } from "react-redux"; -import React, { Component } from "react"; +import { connect } from 'react-redux'; +import React, { Component } from 'react'; import { bindActionCreators } from 'redux'; -import UtterIcon from '../icons/UtterIcon'; -import { message } from "../utils/messages"; -import IntentIcon from '../icons/IntentIcon'; import { Grid, Card } from '@material-ui/core'; import DeleteIcon from '@material-ui/icons/Delete'; import IconButton from '@material-ui/core/IconButton'; import Typography from '@material-ui/core/Typography'; -import SnackbarDelete from '../components/DeleteSnackbar'; -import { Creators as StoryAction } from "../ducks/stories"; -import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd"; +import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd'; +import UtterIcon from '../icons/UtterIcon'; +import { message } from '../utils/messages'; +import IntentIcon from '../icons/IntentIcon'; +import SnackbarDelete from './DeleteSnackbar'; +import { Creators as StoryAction } from '../ducks/stories'; const styles = { - intent_icon: { - fill: '#4b3953', - }, - utter_icon: { - fill: '#f26a53', - }, - card_intent: { - border: '1px solid #4b3953', - color: '#4b3953', - boxShadow: 'none', - padding: "12px 12px 6px", - - }, - card_utter: { - border: '1px solid #f26a53', - color: '#f26a53', - marginLeft: '24px', - boxShadow: 'none', - padding: "12px 12px 6px", - } -} + intent_icon: { + fill: '#4b3953', + }, + utter_icon: { + fill: '#f26a53', + }, + card_intent: { + border: '1px solid #4b3953', + color: '#4b3953', + boxShadow: 'none', + padding: '12px 12px 6px', + + }, + card_utter: { + border: '1px solid #f26a53', + color: '#f26a53', + marginLeft: '24px', + boxShadow: 'none', + padding: '12px 12px 6px', + }, +}; const grid = 8; const getItemStyle = (isDragging, draggableStyle) => ({ - userSelect: "none", - padding: grid * 2, - margin: `0 0 ${grid}px 0`, - display: 'flex', - background: 'white', + userSelect: 'none', + padding: grid * 2, + margin: `0 0 ${grid}px 0`, + display: 'flex', + background: 'white', - ...draggableStyle + ...draggableStyle, }); const getUtterStyle = (isDragging, draggableStyle) => ({ - ...getItemStyle(isDragging, draggableStyle), - ...styles.card_utter -}) + ...getItemStyle(isDragging, draggableStyle), + ...styles.card_utter, +}); const getIntentStyle = (isDragging, draggableStyle) => ({ - ...getItemStyle(isDragging, draggableStyle), - ...styles.card_intent -}) - + ...getItemStyle(isDragging, draggableStyle), + ...styles.card_intent, +}); -const getListStyle = isDraggingOver => ({ - background: isDraggingOver ? "#f6f9f9" : "white", - padding: grid, - width: "420px", +const getListStyle = (isDraggingOver) => ({ + background: isDraggingOver ? '#f6f9f9' : 'white', + padding: grid, + width: '420px', }); class StoryList extends Component { - constructor(props) { - super(props); - this.onDragEnd = this.onDragEnd.bind(this); - this.state = { - undo_delete: false - } - this.handleSnackbarClick = this.handleSnackbarClick.bind(this) - } - - getIcon(type) { - return type === "intent" ? : - } - - onDragEnd(result) { - if (!result.destination) { - return; - } - this.props.reorderContent(result.source.index, result.destination.index) + constructor(props) { + super(props); + this.onDragEnd = this.onDragEnd.bind(this); + this.state = { + undo_delete: false, + }; + this.handleSnackbarClick = this.handleSnackbarClick.bind(this); + } + + getIcon(type) { + return type === 'intent' ? : ; + } + + onDragEnd(result) { + if (!result.destination) { + return; } - - getDrag(provided, snapshot) { - return ( -
    + {this.props.content.map((item, content_position) => ( + + {(provided, snapshot) => ( +
    - {this.props.content.map((item, content_position) => ( - - {(provided, snapshot) => ( -
    - - - - - - {this.getIcon(item.type)} - - - {item.name} - - - - - - this.handleDelete(content_position)}> - - - - -
    - )} -
    - ))} -
    - ) - } - - getContent() { - if (this.props.content.length !== 0) { - return ( -
    - - - {(provided, snapshot) => this.getDrag(provided, snapshot)} - - -
    - ) - - } else { - return
    {message.no_dialogs}
    - } - } - handleSnackbarClick(value) { - this.setState({ undo_delete: value }); - } - handleDelete(content_position) { - this.handleSnackbarClick(true); - this.props.deleteContent(content_position); - } - - render() { - return ( -
    - {this.getContent()} - - -
    - ); + {...provided.draggableProps} + {...provided.dragHandleProps} + > + + + + + + {this.getIcon(item.type)} + + + {item.name} + + + + + + this.handleDelete(content_position)} + > + + + + +
    + )} + + ))} + + ); + } + + getContent() { + if (this.props.content.length !== 0) { + return ( +
    + + + {(provided, snapshot) => this.getDrag(provided, snapshot)} + + +
    + ); } + return
    {message.no_dialogs}
    ; + } + + handleSnackbarClick(value) { + this.setState({ undo_delete: value }); + } + + handleDelete(content_position) { + this.handleSnackbarClick(true); + this.props.deleteContent(content_position); + } + + render() { + return ( +
    + {this.getContent()} + + +
    + ); + } } -const mapStateToProps = state => { return { ...state.story } }; +const mapStateToProps = (state) => ({ ...state.story }); -const mapDispatchToProps = dispatch => bindActionCreators(StoryAction, dispatch); +const mapDispatchToProps = (dispatch) => bindActionCreators(StoryAction, dispatch); export default connect(mapStateToProps, mapDispatchToProps)(StoryList); diff --git a/app/src/components/StorySnackbar.js b/app/src/components/StorySnackbar.js index a0ec388..957247d 100644 --- a/app/src/components/StorySnackbar.js +++ b/app/src/components/StorySnackbar.js @@ -1,24 +1,21 @@ - import Snackbar from '@material-ui/core/Snackbar'; -import SnackbarContent from "./CustomSnackbar" -import React from "react"; +import React from 'react'; +import SnackbarContent from './CustomSnackbar'; -const MessageSnackbar = ({ notification_text, handleClose, variant = "success" }) => { - return ( - - handleClose()} - /> - - ) -} -export default MessageSnackbar; \ No newline at end of file +const MessageSnackbar = ({ notification_text, handleClose, variant = 'success' }) => ( + + handleClose()} + /> + +); +export default MessageSnackbar; diff --git a/app/src/components/ToolbarName.js b/app/src/components/ToolbarName.js index 3ccb835..73e55ff 100644 --- a/app/src/components/ToolbarName.js +++ b/app/src/components/ToolbarName.js @@ -1,6 +1,4 @@ -import NameField from './NameField.js' -import { Done } from '../styles/button'; -import React, { Component } from "react"; +import React, { Component } from 'react'; import Grid from '@material-ui/core/Grid'; import Menu from '@material-ui/core/Menu'; import Button from '@material-ui/core/Button'; @@ -10,129 +8,132 @@ import IconButton from '@material-ui/core/IconButton'; import MoreVertIcon from '@material-ui/icons/MoreVert'; import InfoIcon from '@material-ui/icons/InfoOutlined'; import Tooltip from '@material-ui/core/Tooltip'; +import { Done } from '../styles/button'; +import NameField from './NameField.js'; const style = { - toolbar: { - background: "#f6f9f9", - padding: "4px" - }, -} + toolbar: { + background: '#f6f9f9', + padding: '4px', + }, +}; -const options = ['Apagar'] +const options = ['Apagar']; export default class ToolbarName extends Component { - constructor(props) { - super(props); - this.state = { - anchorEl: null, - open: false, - } - } + constructor(props) { + super(props); + this.state = { + anchorEl: null, + open: false, + }; + } - getMoreOptions() { - return ( - this.handleMenuClick(e, false)} - > - { - options.map(option => ( - this.handleDelete()} - > - {option} - + getMoreOptions() { + return ( + this.handleMenuClick(e, false)} + > + { + options.map((option) => ( + this.handleDelete()} + > + {option} + )) } - - ); - } + + ); + } - handleMenuClick(event, is_open) { - if (is_open) { - this.setState({ - anchorEl: event.currentTarget, - open: is_open - }); - } else { - this.setState({ - anchorEl: null, - open: is_open - }); - } + handleMenuClick(event, is_open) { + if (is_open) { + this.setState({ + anchorEl: event.currentTarget, + open: is_open, + }); + } else { + this.setState({ + anchorEl: null, + open: is_open, + }); } + } - handleClick() { - this.props.saveData(this.props.item); - } + handleClick() { + this.props.saveData(this.props.item); + } - handleDelete() { - this.props.deleteItem(this.props.item.id); - this.setState({ open: false }); - } + handleDelete() { + this.props.deleteItem(this.props.item.id); + this.setState({ open: false }); + } - getDeleteOption() { - if (this.props.item.id !== '') { - return ( - this.handleMenuClick(e, true)} - > - - - ) - } + getDeleteOption() { + if (this.props.item.id !== '') { + return ( + this.handleMenuClick(e, true)} + > + + + ); } + } - render() { - return ( - - - - {this.props.story ? null : ( - - )} - - - {this.props.story ? null : ( - {this.props.name_good_pratice}}> - - - - - )} - - - - + render() { + return ( + + + + {this.props.story ? null : ( + + )} + + + {this.props.story ? null : ( + {this.props.name_good_pratice}}> + + + + + )} + + + + - {this.getDeleteOption()} - {this.getMoreOptions()} - - - ) - } + {this.getDeleteOption()} + {this.getMoreOptions()} + + + ); + } } diff --git a/app/src/ducks/index.js b/app/src/ducks/index.js index 7c4ce85..d97402f 100644 --- a/app/src/ducks/index.js +++ b/app/src/ducks/index.js @@ -1,19 +1,18 @@ import thunk from 'redux-thunk'; -import { combineReducers } from 'redux' -import { createStore, applyMiddleware } from 'redux'; +import { combineReducers, createStore, applyMiddleware } from 'redux'; -import utterReducer from './utters' -import storyReducer from './stories' -import intentReducer from './intents' +import utterReducer from './utters'; +import storyReducer from './stories'; +import intentReducer from './intents'; function configureStore() { return createStore( combineReducers({ intent: intentReducer, utter: utterReducer, - story: storyReducer + story: storyReducer, }), - applyMiddleware(thunk) + applyMiddleware(thunk), ); } diff --git a/app/src/ducks/intents.js b/app/src/ducks/intents.js index 1eb3ed0..56b0a60 100644 --- a/app/src/ducks/intents.js +++ b/app/src/ducks/intents.js @@ -1,203 +1,181 @@ import axios from 'axios'; +import { createActions, createReducer } from 'reduxsauce'; import { message } from '../utils/messages'; import { Intent } from '../utils/DataFormat.js'; import { INTENT_URL } from '../utils/url_routes.js'; -import { createActions, createReducer } from 'reduxsauce'; const INITIAL_STATE = { - intents: [], - mode: 'Intent', - name: '', - helper_text: '', - old_name: '', - notification_text: '', - content: [''], - old_content: [''], + intents: [], + mode: 'Intent', + name: '', + helper_text: '', + old_name: '', + notification_text: '', + content: [''], + old_content: [''], }; export const addIntent = (state = INITIAL_STATE) => { - let new_intent = [...state.content]; - new_intent.push('') - - return { - ...state, - content: new_intent, - old_content: [...new_intent] - }; -} + const new_intent = [...state.content]; + new_intent.push(''); + + return { + ...state, + content: new_intent, + old_content: [...new_intent], + }; +}; export const setIntentContent = (state = INITIAL_STATE, action) => { - let content = [...state.content]; - content[action.intent_position] = action.text + const content = [...state.content]; + content[action.intent_position] = action.text; - return { - ...state, - content: content - }; -} + return { + ...state, + content, + }; +}; export const deleteIntentContent = (state = INITIAL_STATE, action) => { - let content = [...state.content] - let old_item_history = [...state.content] - - content.splice(action.intent_position, 1); - - return { - ...state, - content: content, - old_content: old_item_history - }; -} - -export const undoDeleteIntentContent = (state = INITIAL_STATE) => { - return { - ...state, - content: [...state.old_content] - } -} + const content = [...state.content]; + const old_item_history = [...state.content]; -export const selectIntent = (state = INITIAL_STATE, action) => { - let selected_item = action.item; - let selected_item_position = action.item_position; - - if (selected_item_position < 0) { - state.intents.find((item, index) => { - selected_item_position = index; - return (item.id === action.item.id || item.name === action.item.name); - }); - } + content.splice(action.intent_position, 1); + + return { + ...state, + content, + old_content: old_item_history, + }; +}; + +export const undoDeleteIntentContent = (state = INITIAL_STATE) => ({ + ...state, + content: [...state.old_content], +}); - return { - ...state, - id: selected_item.id, - name: selected_item.name, - old_name: selected_item.name, - selected_item_position: selected_item_position, - content: [...selected_item.samples], - old_content: [...selected_item.samples], - helper_text: '' - }; -} +export const selectIntent = (state = INITIAL_STATE, action) => { + const selected_item = action.item; + let selected_item_position = action.item_position; + + if (selected_item_position < 0) { + state.intents.find((item, index) => { + selected_item_position = index; + return (item.id === action.item.id || item.name === action.item.name); + }); + } + + return { + ...state, + id: selected_item.id, + name: selected_item.name, + old_name: selected_item.name, + selected_item_position, + content: [...selected_item.samples], + old_content: [...selected_item.samples], + helper_text: '', + }; +}; export const createNewIntent = (state = INITIAL_STATE) => { - const new_intent = new Intent(); - - return { - ...state, - id: new_intent.id, - selected_item_position: -1, - name: new_intent.name, - old_name: new_intent.name, - content: [...new_intent.samples], - old_content: [...new_intent.samples] - }; -} - -export const setIntentName = (state = INITIAL_STATE, action) => { - return { - ...state, - name: action.name, - helper_text: action.helper_text - }; -} - -export const notifyAction = (state = INITIAL_STATE, action) => { - return { - ...state, - notification_text: action.text - }; -} - -export const getIntents = (state = INITIAL_STATE, action) => { - return { - ...state, - intents: action.intents - }; -} - -export const createOrUpdateItem = (mode = 'post', new_item, message = '') => { - return async (dispatch) => { - try { - const mode_url = (mode === 'post') ? INTENT_URL : INTENT_URL + new_item.id; - let intent; - await axios[mode](mode_url, new_item) - .then((resp) => { - intent = resp.data; - }) - - await dispatch(Creators.getIntents()); - await dispatch(Creators.selectIntent(intent.id, -1)); - - dispatch(Creators.notifyAction(message)); - } catch (error) { - throw (error); - } - } + const new_intent = new Intent(); + + return { + ...state, + id: new_intent.id, + selected_item_position: -1, + name: new_intent.name, + old_name: new_intent.name, + content: [...new_intent.samples], + old_content: [...new_intent.samples], + }; }; -export const { Types, Creators } = createActions({ - addIntent: [], - createNewIntent: [], - notifyAction: ['text'], - undoDeleteIntentContent: [], - setIntentName: ['name', 'helper_text'], - deleteIntentContent: ['intent_position'], - setIntentContent: ['intent_position', 'text'], - selectIntent: (id = '', item_position = -1) => { - return async (dispatch) => { - try { - const response = await axios.get(INTENT_URL + id); - await dispatch({ type: Types.SELECT_INTENT, item: response.data, item_position: item_position }); - } catch (error) { - throw (error); - } - } - }, - getIntents: () => { - return async (dispatch) => { - try { - const response = await axios.get(INTENT_URL); - await dispatch({ type: Types.GET_INTENTS, intents: response.data }); - } catch (error) { - throw (error); - } - } - }, - saveData: (item) => { - return async (dispatch) => { - if (item.id === '' || item.id === undefined) { - dispatch(createOrUpdateItem('post', item, message.intent.created)); - } else { - dispatch(createOrUpdateItem('put', item, message.intent.updated)); - } - } - }, - deleteIntent: (delete_intent_id) => { - return async (dispatch) => { - try { - await axios.delete(INTENT_URL + delete_intent_id); - await dispatch(Creators.getIntents()); - await dispatch(Creators.notifyAction(message.intent.deleted)); - await dispatch(Creators.createNewIntent()) - - } catch (error) { - throw (error); - } - } - } -}) +export const setIntentName = (state = INITIAL_STATE, action) => ({ + ...state, + name: action.name, + helper_text: action.helper_text, +}); -export default createReducer(INITIAL_STATE, { - [Types.ADD_INTENT]: addIntent, - [Types.GET_INTENTS]: getIntents, - [Types.SELECT_INTENT]: selectIntent, - [Types.NOTIFY_ACTION]: notifyAction, - [Types.SET_INTENT_NAME]: setIntentName, - [Types.CREATE_NEW_INTENT]: createNewIntent, - [Types.SET_INTENT_CONTENT]: setIntentContent, - [Types.DELETE_INTENT_CONTENT]: deleteIntentContent, - [Types.UNDO_DELETE_INTENT_CONTENT]: undoDeleteIntentContent, +export const notifyAction = (state = INITIAL_STATE, action) => ({ + ...state, + notification_text: action.text, +}); + +export const getIntents = (state = INITIAL_STATE, action) => ({ + ...state, + intents: action.intents, }); +export const createOrUpdateItem = (mode = 'post', new_item, message = '') => async (dispatch) => { + try { + const mode_url = (mode === 'post') ? INTENT_URL : INTENT_URL + new_item.id; + let intent; + await axios[mode](mode_url, new_item) + .then((resp) => { + intent = resp.data; + }); + + await dispatch(Creators.getIntents()); + await dispatch(Creators.selectIntent(intent.id, -1)); + + dispatch(Creators.notifyAction(message)); + } catch (error) { + throw (error); + } +}; +export const { Types, Creators } = createActions({ + addIntent: [], + createNewIntent: [], + notifyAction: ['text'], + undoDeleteIntentContent: [], + setIntentName: ['name', 'helper_text'], + deleteIntentContent: ['intent_position'], + setIntentContent: ['intent_position', 'text'], + selectIntent: (id = '', item_position = -1) => async (dispatch) => { + try { + const response = await axios.get(INTENT_URL + id); + await dispatch({ type: Types.SELECT_INTENT, item: response.data, item_position }); + } catch (error) { + throw (error); + } + }, + getIntents: () => async (dispatch) => { + try { + const response = await axios.get(INTENT_URL); + await dispatch({ type: Types.GET_INTENTS, intents: response.data }); + } catch (error) { + throw (error); + } + }, + saveData: (item) => async (dispatch) => { + if (item.id === '' || item.id === undefined) { + dispatch(createOrUpdateItem('post', item, message.intent.created)); + } else { + dispatch(createOrUpdateItem('put', item, message.intent.updated)); + } + }, + deleteIntent: (delete_intent_id) => async (dispatch) => { + try { + await axios.delete(INTENT_URL + delete_intent_id); + await dispatch(Creators.getIntents()); + await dispatch(Creators.notifyAction(message.intent.deleted)); + await dispatch(Creators.createNewIntent()); + } catch (error) { + throw (error); + } + }, +}); +export default createReducer(INITIAL_STATE, { + [Types.ADD_INTENT]: addIntent, + [Types.GET_INTENTS]: getIntents, + [Types.SELECT_INTENT]: selectIntent, + [Types.NOTIFY_ACTION]: notifyAction, + [Types.SET_INTENT_NAME]: setIntentName, + [Types.CREATE_NEW_INTENT]: createNewIntent, + [Types.SET_INTENT_CONTENT]: setIntentContent, + [Types.DELETE_INTENT_CONTENT]: deleteIntentContent, + [Types.UNDO_DELETE_INTENT_CONTENT]: undoDeleteIntentContent, +}); diff --git a/app/src/ducks/stories.js b/app/src/ducks/stories.js index 9c57474..5852760 100644 --- a/app/src/ducks/stories.js +++ b/app/src/ducks/stories.js @@ -1,275 +1,244 @@ - -import axios from "axios"; +import axios from 'axios'; +import { createActions, createReducer } from 'reduxsauce'; import { Story } from '../utils/DataFormat'; import { message } from '../utils/messages'; -import { createActions, createReducer } from 'reduxsauce'; import { INTENT_URL, UTTER_URL, STORY_URL } from '../utils/url_routes.js'; const INITIAL_STATE = { - utters: [], - intents: [], - stories: [], - content: [], - loading: true, - name: "", - old_content: [], - story_id: "", - notification_text: "", - content_text_validation: "" + utters: [], + intents: [], + stories: [], + content: [], + loading: true, + name: '', + old_content: [], + story_id: '', + notification_text: '', + content_text_validation: '', }; function createArrayObjCopyOf(samples = []) { - return samples.map(text => { return { ...text } }); + return samples.map((text) => ({ ...text })); } -export const getIntents = (state = INITIAL_STATE, action) => { - return { - ...state, - intents: action.intents - }; -} +export const getIntents = (state = INITIAL_STATE, action) => ({ + ...state, + intents: action.intents, +}); -export const getUtters = (state = INITIAL_STATE, action) => { - return { - ...state, - utters: action.utters - }; -} +export const getUtters = (state = INITIAL_STATE, action) => ({ + ...state, + utters: action.utters, +}); -export const getStories = (state = INITIAL_STATE, action) => { - return { - ...state, - stories: action.stories, - loading: false - }; -} +export const getStories = (state = INITIAL_STATE, action) => ({ + ...state, + stories: action.stories, + loading: false, +}); -export const getStory = (state = INITIAL_STATE, action) => { - return { - ...state, - name: action.story.name, - story_id: action.story.id, - content: action.story.content, - old_content: action.story.content - }; -} +export const getStory = (state = INITIAL_STATE, action) => ({ + ...state, + name: action.story.name, + story_id: action.story.id, + content: action.story.content, + old_content: action.story.content, +}); export const validationContent = (content) => { - let intent_intent = true; + let intent_intent = true; - for (let i = 1, size = content.length; i < size; i++) { - if (content[i - 1].type === 'intent' && (content[i].type === 'intent')) { - intent_intent = false; - } else if (content[size - 1].type === 'intent') { - intent_intent = false; - } + for (let i = 1, size = content.length; i < size; i++) { + if (content[i - 1].type === 'intent' && (content[i].type === 'intent')) { + intent_intent = false; + } else if (content[size - 1].type === 'intent') { + intent_intent = false; } + } - if (!intent_intent) { - return message.story.two_intents; - } else if (content.length !== 0 && content[0].type !== 'intent') { - return message.story.first_element; - } + if (!intent_intent) { + return message.story.two_intents; + } if (content.length !== 0 && content[0].type !== 'intent') { + return message.story.first_element; + } - return ''; -} + return ''; +}; export const reorderContent = (state = INITIAL_STATE, action) => { - const result = createArrayObjCopyOf(state.content); - const [removed] = result.splice(action.start_index, 1); - result.splice(action.end_index, 0, removed); - - const text = validationContent(result); - - return { - ...state, - content: result, - content_text_validation: text, - old_content: createArrayObjCopyOf(state.content) - } -} + const result = createArrayObjCopyOf(state.content); + const [removed] = result.splice(action.start_index, 1); + result.splice(action.end_index, 0, removed); + + const text = validationContent(result); + + return { + ...state, + content: result, + content_text_validation: text, + old_content: createArrayObjCopyOf(state.content), + }; +}; export const deleteContent = (state = INITIAL_STATE, action) => { - let new_content = createArrayObjCopyOf(state.content); - new_content.splice(action.content_position, 1); + const new_content = createArrayObjCopyOf(state.content); + new_content.splice(action.content_position, 1); - const text = validationContent(new_content); + const text = validationContent(new_content); - return { - ...state, - content: new_content, - content_text_validation: text, - old_content: createArrayObjCopyOf(state.content) - } -} + return { + ...state, + content: new_content, + content_text_validation: text, + old_content: createArrayObjCopyOf(state.content), + }; +}; export const undoDeleteContent = (state = INITIAL_STATE) => { - const text = validationContent(state.old_content); - - return { - ...state, - content_text_validation: text, - content: createArrayObjCopyOf(state.old_content) - } -} + const text = validationContent(state.old_content); -export const notifyAction = (state = INITIAL_STATE, action) => { - return { - ...state, - notification_text: action.text - }; -} + return { + ...state, + content_text_validation: text, + content: createArrayObjCopyOf(state.old_content), + }; +}; -export const notifyContentTextValidation = (state = INITIAL_STATE, action) => { - return { - ...state, - content_text_validation: action.text - }; -} +export const notifyAction = (state = INITIAL_STATE, action) => ({ + ...state, + notification_text: action.text, +}); -export const addToStory = (state = INITIAL_STATE, action) => { - let new_content = createArrayObjCopyOf(state.content); - new_content.push({ ...action.item, type: action.mode }); - const text = validationContent(new_content); +export const notifyContentTextValidation = (state = INITIAL_STATE, action) => ({ + ...state, + content_text_validation: action.text, +}); - return { - ...state, - content: new_content, - content_text_validation: text, - old_content: createArrayObjCopyOf(state.content), - } -} +export const addToStory = (state = INITIAL_STATE, action) => { + const new_content = createArrayObjCopyOf(state.content); + new_content.push({ ...action.item, type: action.mode }); + const text = validationContent(new_content); + + return { + ...state, + content: new_content, + content_text_validation: text, + old_content: createArrayObjCopyOf(state.content), + }; +}; export const createNewStory = (state = INITIAL_STATE) => { - const new_story = new Story(); - - return { - ...state, - name: new_story.name, - notification_text: '', - story_id: new_story.id, - content: createArrayObjCopyOf(new_story.content), - old_content: createArrayObjCopyOf(new_story.content) - }; -} + const new_story = new Story(); + + return { + ...state, + name: new_story.name, + notification_text: '', + story_id: new_story.id, + content: createArrayObjCopyOf(new_story.content), + old_content: createArrayObjCopyOf(new_story.content), + }; +}; -export const createOrUpdateItem = (mode = 'post', new_item, message = "") => { - return async (dispatch) => { - try { - const mode_url = (mode === 'post') ? STORY_URL : STORY_URL + new_item.id; - const response = await axios[mode](mode_url, new_item); - await dispatch(Creators.getStory(response.data.id)); - await dispatch(Creators.notifyAction(message)); - } catch (error) { - throw (error); - } - } +export const createOrUpdateItem = (mode = 'post', new_item, message = '') => async (dispatch) => { + try { + const mode_url = (mode === 'post') ? STORY_URL : STORY_URL + new_item.id; + const response = await axios[mode](mode_url, new_item); + await dispatch(Creators.getStory(response.data.id)); + await dispatch(Creators.notifyAction(message)); + } catch (error) { + throw (error); + } }; export const { Types, Creators } = createActions({ - createNewStory: [], - undoDeleteContent: [], - notifyAction: ['text'], - addToStory: ['item', 'mode'], - deleteContent: ['content_position'], - notifyContentTextValidation: ['text'], - reorderContent: ['start_index', 'end_index'], - addIntent: (intent) => { - return async (dispatch) => { - try { - const response = await axios.get(INTENT_URL + intent.id + '/example'); - await dispatch({ type: Types.ADD_TO_STORY, item: response.data, mode: "intent" }); - } catch (error) { - throw (error); - } - } - }, - addUtter: (utter) => { - return async (dispatch) => { - try { - const response = await axios.get(UTTER_URL + utter.id + '/example'); - await dispatch({ type: Types.ADD_TO_STORY, item: response.data, mode: "utter" }); - } catch (error) { - throw (error); - } - } - }, - getIntents: () => { - return async (dispatch) => { - try { - const response = await axios.get(INTENT_URL); - await dispatch({ type: Types.GET_INTENTS, intents: response.data }); - } catch (error) { - throw (error); - } - } - }, - getUtters: () => { - return async (dispatch) => { - try { - const response = await axios.get(UTTER_URL); - await dispatch({ type: Types.GET_UTTERS, utters: response.data }); - } catch (error) { - throw (error); - } - } - }, - saveData: (item) => { - return async (dispatch) => { - if ((item.id === "" || item.id === undefined)) { - dispatch(createOrUpdateItem('post', item, message.story.created)); - } else { - dispatch(createOrUpdateItem('put', item, message.story.updated)); - } - } - }, - getStories: (value = '') => { - return async (dispatch) => { - try { - const response = await axios.get(STORY_URL + '?filter=' + value); - await dispatch({ type: Types.GET_STORIES, stories: response.data }); - } catch (error) { - throw (error); - } - } - }, - getStory: (id = '') => { - return async (dispatch) => { - try { - if (id !== '') { - const response = await axios.get(STORY_URL + id); - await dispatch({ type: Types.GET_STORY, story: response.data }); - } - } catch (error) { - throw (error); - } - } - }, - deleteStory: (id) => { - return async (dispatch) => { - try { - if (id !== '') { - await axios.delete(STORY_URL + id); - await dispatch(Creators.notifyAction(message.story.deleted)); - } - } catch (error) { - throw (error); - } - } + createNewStory: [], + undoDeleteContent: [], + notifyAction: ['text'], + addToStory: ['item', 'mode'], + deleteContent: ['content_position'], + notifyContentTextValidation: ['text'], + reorderContent: ['start_index', 'end_index'], + addIntent: (intent) => async (dispatch) => { + try { + const response = await axios.get(`${INTENT_URL + intent.id}/example`); + await dispatch({ type: Types.ADD_TO_STORY, item: response.data, mode: 'intent' }); + } catch (error) { + throw (error); + } + }, + addUtter: (utter) => async (dispatch) => { + try { + const response = await axios.get(`${UTTER_URL + utter.id}/example`); + await dispatch({ type: Types.ADD_TO_STORY, item: response.data, mode: 'utter' }); + } catch (error) { + throw (error); + } + }, + getIntents: () => async (dispatch) => { + try { + const response = await axios.get(INTENT_URL); + await dispatch({ type: Types.GET_INTENTS, intents: response.data }); + } catch (error) { + throw (error); + } + }, + getUtters: () => async (dispatch) => { + try { + const response = await axios.get(UTTER_URL); + await dispatch({ type: Types.GET_UTTERS, utters: response.data }); + } catch (error) { + throw (error); + } + }, + saveData: (item) => async (dispatch) => { + if ((item.id === '' || item.id === undefined)) { + dispatch(createOrUpdateItem('post', item, message.story.created)); + } else { + dispatch(createOrUpdateItem('put', item, message.story.updated)); + } + }, + getStories: (value = '') => async (dispatch) => { + try { + const response = await axios.get(`${STORY_URL}?filter=${value}`); + await dispatch({ type: Types.GET_STORIES, stories: response.data }); + } catch (error) { + throw (error); + } + }, + getStory: (id = '') => async (dispatch) => { + try { + if (id !== '') { + const response = await axios.get(STORY_URL + id); + await dispatch({ type: Types.GET_STORY, story: response.data }); + } + } catch (error) { + throw (error); + } + }, + deleteStory: (id) => async (dispatch) => { + try { + if (id !== '') { + await axios.delete(STORY_URL + id); + await dispatch(Creators.notifyAction(message.story.deleted)); + } + } catch (error) { + throw (error); } + }, }); export default createReducer(INITIAL_STATE, { - [Types.GET_STORY]: getStory, - [Types.GET_UTTERS]: getUtters, - [Types.GET_STORIES]: getStories, - [Types.GET_INTENTS]: getIntents, - [Types.ADD_TO_STORY]: addToStory, - [Types.NOTIFY_ACTION]: notifyAction, - [Types.DELETE_CONTENT]: deleteContent, - [Types.REORDER_CONTENT]: reorderContent, - [Types.CREATE_NEW_STORY]: createNewStory, - [Types.UNDO_DELETE_CONTENT]: undoDeleteContent, - [Types.NOTIFY_CONTENT_TEXT_VALIDATION]: notifyContentTextValidation, + [Types.GET_STORY]: getStory, + [Types.GET_UTTERS]: getUtters, + [Types.GET_STORIES]: getStories, + [Types.GET_INTENTS]: getIntents, + [Types.ADD_TO_STORY]: addToStory, + [Types.NOTIFY_ACTION]: notifyAction, + [Types.DELETE_CONTENT]: deleteContent, + [Types.REORDER_CONTENT]: reorderContent, + [Types.CREATE_NEW_STORY]: createNewStory, + [Types.UNDO_DELETE_CONTENT]: undoDeleteContent, + [Types.NOTIFY_CONTENT_TEXT_VALIDATION]: notifyContentTextValidation, }); diff --git a/app/src/ducks/utters.js b/app/src/ducks/utters.js index 1799a34..d541d8a 100644 --- a/app/src/ducks/utters.js +++ b/app/src/ducks/utters.js @@ -1,240 +1,221 @@ import axios from 'axios'; +import { createActions, createReducer } from 'reduxsauce'; import { Utter } from '../utils/DataFormat.js'; import { message } from '../utils/messages.js'; import { UTTER_URL } from '../utils/url_routes.js'; -import { createActions, createReducer } from 'reduxsauce'; const INITIAL_STATE = { - mode: "Utter", - name: "", - helper_text: "", - old_name: "", - notification_text: "", - content: [[""]], - old_content: [[""]], - multiple_alternatives: false, + mode: 'Utter', + name: '', + helper_text: '', + old_name: '', + notification_text: '', + content: [['']], + old_content: [['']], + multiple_alternatives: false, }; function createArrayCopyOf(items) { - if (items !== undefined) { - return items.map(utter => utter.map(text => text)); - } - return items; + if (items !== undefined) { + return items.map((utter) => utter.map((text) => text)); + } + return items; } export const addUtterContent = (state = INITIAL_STATE) => { - let new_utter = createArrayCopyOf(state.content); - - if (state.multiple_alternatives) { - new_utter.push(['']); - } else { - new_utter[0].push(''); - } - - return { - ...state, - content: new_utter, - old_content: createArrayCopyOf(new_utter) - }; -} + const new_utter = createArrayCopyOf(state.content); + + if (state.multiple_alternatives) { + new_utter.push(['']); + } else { + new_utter[0].push(''); + } + + return { + ...state, + content: new_utter, + old_content: createArrayCopyOf(new_utter), + }; +}; export const setUtterContent = (state = INITIAL_STATE, action) => { - let content = createArrayCopyOf(state.content); - content[action.utter_position][action.text_position] = action.text + const content = createArrayCopyOf(state.content); + content[action.utter_position][action.text_position] = action.text; - return { - ...state, - content: content - }; -} + return { + ...state, + content, + }; +}; export const deleteUtterContent = (state = INITIAL_STATE, action) => { - let content = createArrayCopyOf(state.content) - let old_utter_history = createArrayCopyOf(state.content) - - content[action.utter_position].splice(action.text_position, 1); - if (content[action.utter_position].length === 0) { - content.splice(action.utter_position, 1); - } - - return { - ...state, - content: content, - old_content: old_utter_history - }; -} + const content = createArrayCopyOf(state.content); + const old_utter_history = createArrayCopyOf(state.content); + + content[action.utter_position].splice(action.text_position, 1); + if (content[action.utter_position].length === 0) { + content.splice(action.utter_position, 1); + } + + return { + ...state, + content, + old_content: old_utter_history, + }; +}; -export const undoDeleteUtterContent = (state = INITIAL_STATE) => { - return { - ...state, - content: createArrayCopyOf(state.old_content) - } -} +export const undoDeleteUtterContent = (state = INITIAL_STATE) => ({ + ...state, + content: createArrayCopyOf(state.old_content), +}); export const selectUtter = (state = INITIAL_STATE, action) => { - let selected_item = action.item; - let selected_item_position = action.item_position; - - if (selected_item_position < 0) { - state.utters.find((item, index) => { - selected_item_position = index; - return (item.id === action.item.id || item.name === action.item.name); - }); - } - - return { - ...state, - helper_text: "", - id: selected_item.id, - name: selected_item.name, - old_name: selected_item.name, - selected_item_position: selected_item_position, - content: createArrayCopyOf(selected_item.alternatives), - old_content: createArrayCopyOf(selected_item.alternatives), - multiple_alternatives: selected_item.multiple_alternatives, - }; -} + const selected_item = action.item; + let selected_item_position = action.item_position; + + if (selected_item_position < 0) { + state.utters.find((item, index) => { + selected_item_position = index; + return (item.id === action.item.id || item.name === action.item.name); + }); + } + + return { + ...state, + helper_text: '', + id: selected_item.id, + name: selected_item.name, + old_name: selected_item.name, + selected_item_position, + content: createArrayCopyOf(selected_item.alternatives), + old_content: createArrayCopyOf(selected_item.alternatives), + multiple_alternatives: selected_item.multiple_alternatives, + }; +}; export const createNewUtter = (state = INITIAL_STATE) => { - const new_utter = new Utter(); - - return { - ...state, - helper_text: "", - id: new_utter.id, - name: new_utter.name, - old_name: new_utter.name, - selected_item_position: -1, - multiple_alternatives: new_utter.multiple_alternatives, - content: createArrayCopyOf(new_utter.alternatives), - old_content: createArrayCopyOf(new_utter.alternatives), - }; -} + const new_utter = new Utter(); + + return { + ...state, + helper_text: '', + id: new_utter.id, + name: new_utter.name, + old_name: new_utter.name, + selected_item_position: -1, + multiple_alternatives: new_utter.multiple_alternatives, + content: createArrayCopyOf(new_utter.alternatives), + old_content: createArrayCopyOf(new_utter.alternatives), + }; +}; -export const setUtterName = (state = INITIAL_STATE, action) => { - return { - ...state, - name: action.name, - helper_text: action.helper_text - }; -} +export const setUtterName = (state = INITIAL_STATE, action) => ({ + ...state, + name: action.name, + helper_text: action.helper_text, +}); -export const notifyAction = (state = INITIAL_STATE, action) => { - return { - ...state, - notification_text: action.text - }; -} +export const notifyAction = (state = INITIAL_STATE, action) => ({ + ...state, + notification_text: action.text, +}); -export const getUtters = (state = INITIAL_STATE, action) => { - return { - ...state, - utters: action.utters - }; -} +export const getUtters = (state = INITIAL_STATE, action) => ({ + ...state, + utters: action.utters, +}); export const changeUtterForm = (state = INITIAL_STATE, action) => { - let texts = []; - let new_alternatives = []; + const texts = []; + let new_alternatives = []; + + action.content.forEach((i) => { + i.forEach((j) => texts.push(j)); + }); + + if (action.multiple_alternatives) { + new_alternatives = texts.map((text) => [text]); + } else { + new_alternatives = [texts.map((text) => text)]; + } + + return { + ...state, + content: new_alternatives, + multiple_alternatives: action.multiple_alternatives, + }; +}; - action.content.forEach(i => { - i.forEach(j => texts.push(j)) - }) +export const createOrUpdateItem = (mode = 'post', new_item, message = '') => async (dispatch) => { + try { + const mode_url = (mode === 'post') ? UTTER_URL : UTTER_URL + new_item.id; + let utter; + await axios[mode](mode_url, new_item) + .then((resp) => { + utter = resp.data; + }); + await dispatch(Creators.getUtters()); + await dispatch(Creators.selectUtter(utter.id, -1)); + + await dispatch(Creators.notifyAction(message)); + } catch (error) { + throw (error); + } +}; - if (action.multiple_alternatives) { - new_alternatives = texts.map(text => [text]); - } else { - new_alternatives = [texts.map(text => text)]; +export const { Types, Creators } = createActions({ + createNewUtter: [], + addUtterContent: [], + notifyAction: ['text'], + undoDeleteUtterContent: [], + setUtterName: ['name', 'helper_text'], + deleteUtterContent: ['utter_position', 'text_position'], + setUtterContent: ['text', 'utter_position', 'text_position'], + changeUtterForm: ['content', 'multiple_alternatives'], + selectUtter: (id = '', item_position = '') => async (dispatch) => { + try { + const response = await axios.get(UTTER_URL + id); + await dispatch({ type: Types.SELECT_UTTER, item: response.data, item_position }); + } catch (error) { + throw (error); } - - return { - ...state, - content: new_alternatives, - multiple_alternatives: action.multiple_alternatives + }, + getUtters: () => async (dispatch) => { + try { + const response = await axios.get(UTTER_URL); + await dispatch({ type: Types.GET_UTTERS, utters: response.data }); + } catch (error) { + throw (error); } -} - -export const createOrUpdateItem = (mode = 'post', new_item, message = "") => { - return async (dispatch) => { - try { - const mode_url = (mode === 'post') ? UTTER_URL : UTTER_URL + new_item.id; - let utter; - await axios[mode](mode_url, new_item) - .then((resp) => { - utter = resp.data; - }) - await dispatch(Creators.getUtters()); - await dispatch(Creators.selectUtter(utter.id, -1)); - - await dispatch(Creators.notifyAction(message)); - } catch (error) { - throw (error); - } + }, + saveData: (item) => async (dispatch) => { + if (item.id === '' || item.id === undefined) { + dispatch(createOrUpdateItem('post', item, message.utter.created)); + } else { + dispatch(createOrUpdateItem('put', item, message.utter.updated)); } -}; - -export const { Types, Creators } = createActions({ - createNewUtter: [], - addUtterContent: [], - notifyAction: ['text'], - undoDeleteUtterContent: [], - setUtterName: ['name', 'helper_text'], - deleteUtterContent: ['utter_position', 'text_position'], - setUtterContent: ['text', 'utter_position', 'text_position'], - changeUtterForm: ['content', 'multiple_alternatives'], - selectUtter: (id = "", item_position = "") => { - return async (dispatch) => { - try { - const response = await axios.get(UTTER_URL + id); - await dispatch({ type: Types.SELECT_UTTER, item: response.data, item_position: item_position }); - } catch (error) { - throw (error); - } - } - }, - getUtters: () => { - return async (dispatch) => { - try { - const response = await axios.get(UTTER_URL); - await dispatch({ type: Types.GET_UTTERS, utters: response.data }); - } catch (error) { - throw (error); - } - } - }, - saveData: (item) => { - return async (dispatch) => { - if (item.id === "" || item.id === undefined) { - dispatch(createOrUpdateItem('post', item, message.utter.created)); - } else { - dispatch(createOrUpdateItem('put', item, message.utter.updated)); - } - } - }, - deleteUtter: (delete_id) => { - return async (dispatch) => { - try { - await axios.delete(UTTER_URL + delete_id); - await dispatch(Creators.getUtters()); - await dispatch(Creators.notifyAction(message.utter.deleted)); - await dispatch(Creators.createNewUtter()) - - } catch (error) { - throw (error); - } - } + }, + deleteUtter: (delete_id) => async (dispatch) => { + try { + await axios.delete(UTTER_URL + delete_id); + await dispatch(Creators.getUtters()); + await dispatch(Creators.notifyAction(message.utter.deleted)); + await dispatch(Creators.createNewUtter()); + } catch (error) { + throw (error); } -}) + }, +}); export default createReducer(INITIAL_STATE, { - [Types.GET_UTTERS]: getUtters, - [Types.SELECT_UTTER]: selectUtter, - [Types.NOTIFY_ACTION]: notifyAction, - [Types.SET_UTTER_NAME]: setUtterName, - [Types.CREATE_NEW_UTTER]: createNewUtter, - [Types.SET_UTTER_CONTENT]: setUtterContent, - [Types.CHANGE_UTTER_FORM]: changeUtterForm, - [Types.ADD_UTTER_CONTENT]: addUtterContent, - [Types.DELETE_UTTER_CONTENT]: deleteUtterContent, - [Types.UNDO_DELETE_UTTER_CONTENT]: undoDeleteUtterContent, + [Types.GET_UTTERS]: getUtters, + [Types.SELECT_UTTER]: selectUtter, + [Types.NOTIFY_ACTION]: notifyAction, + [Types.SET_UTTER_NAME]: setUtterName, + [Types.CREATE_NEW_UTTER]: createNewUtter, + [Types.SET_UTTER_CONTENT]: setUtterContent, + [Types.CHANGE_UTTER_FORM]: changeUtterForm, + [Types.ADD_UTTER_CONTENT]: addUtterContent, + [Types.DELETE_UTTER_CONTENT]: deleteUtterContent, + [Types.UNDO_DELETE_UTTER_CONTENT]: undoDeleteUtterContent, }); diff --git a/app/src/icons/AppIcon.js b/app/src/icons/AppIcon.js index 6bcf20e..10b3b25 100644 --- a/app/src/icons/AppIcon.js +++ b/app/src/icons/AppIcon.js @@ -1,6 +1,6 @@ -import React from "react"; +import React from 'react'; -const SvgAppIcon = props => ( +const SvgAppIcon = (props) => ( ( +const SvgIntentIcon = (props) => ( ( ); -export default SvgIntentIcon; \ No newline at end of file +export default SvgIntentIcon; diff --git a/app/src/icons/StoryIcon.js b/app/src/icons/StoryIcon.js index 4efc179..c29523d 100644 --- a/app/src/icons/StoryIcon.js +++ b/app/src/icons/StoryIcon.js @@ -1,6 +1,6 @@ -import React from "react"; +import React from 'react'; -const SvgStoryIcon = props => ( +const SvgStoryIcon = (props) => ( ( ); -export default SvgStoryIcon; \ No newline at end of file +export default SvgStoryIcon; diff --git a/app/src/icons/UtterIcon.js b/app/src/icons/UtterIcon.js index 05a349e..1e43e85 100644 --- a/app/src/icons/UtterIcon.js +++ b/app/src/icons/UtterIcon.js @@ -1,6 +1,6 @@ -import React from "react"; +import React from 'react'; -const SvgUtterIcon = props => ( +const SvgUtterIcon = (props) => ( ( ); -export default SvgUtterIcon; \ No newline at end of file +export default SvgUtterIcon; diff --git a/app/src/index.js b/app/src/index.js index 7af3a91..326d199 100644 --- a/app/src/index.js +++ b/app/src/index.js @@ -1,48 +1,47 @@ import React from 'react'; import ReactDOM from 'react-dom'; -import { Provider } from "react-redux"; -import configureStore from "./ducks/index"; +import { Provider } from 'react-redux'; +import { MuiThemeProvider, createMuiTheme } from '@material-ui/core'; +import configureStore from './ducks/index'; import App from './pages/App'; import * as serviceWorker from './serviceWorker'; -import { MuiThemeProvider, createMuiTheme } from '@material-ui/core'; - const theme = createMuiTheme({ palette: { background: { - paper: "#dae8ea", - default: "#fcfcfc" + paper: '#dae8ea', + default: '#fcfcfc', }, primary: { - light: "#f6f9f9", - main: "#4b3953", - contrastText: "#fff" + light: '#f6f9f9', + main: '#4b3953', + contrastText: '#fff', }, secondary: { - light: "#fef4f3", - main: "#f15035", - contrastText: "#fff" + light: '#fef4f3', + main: '#f15035', + contrastText: '#fff', }, error: { - main: "#AF0C00", - contrastText: "#fff" + main: '#AF0C00', + contrastText: '#fff', }, text: { - primary: "rgba(0, 0, 0, 0.87)", - hint: "rgba(0, 0, 0, 0.38)" - } + primary: 'rgba(0, 0, 0, 0.87)', + hint: 'rgba(0, 0, 0, 0.38)', + }, }, typography: { h4: { fontStyle: 'Roboto-Regular', fontSize: 34, - color: '#000000' + color: '#000000', }, h5: { fontStyle: 'Roboto-Regular', fontSize: 24, - color: '#000000' + color: '#000000', }, h6: { fontStyle: 'Roboto-Regular', @@ -54,76 +53,75 @@ const theme = createMuiTheme({ AppbarMenuActive: { fontStyle: 'Roboto-Bold-Italic', fontSize: 16, - color: '#f15035' + color: '#f15035', }, AppbarMenuHover: { fontStyle: 'Roboto-Bold-Italic', fontSize: 16, - color: '#dae8ea' + color: '#dae8ea', }, AppbarMenuIdle: { fontStyle: 'Roboto-Regular-Italic', fontSize: 16, - color: '#dae8ea' + color: '#dae8ea', }, body1Dark: { fontStyle: 'Roboto-Regular', fontSize: 16, - color: '#000000' + color: '#000000', }, body1Light: { fontStyle: 'Roboto-Regular', fontSize: 16, - color: '#ffffff' + color: '#ffffff', }, buttonAccent: { fontStyle: 'Roboto-Medium', fontSize: 14, - color: '#f15035' + color: '#f15035', }, buttonDarkCenter: { fontStyle: 'Roboto-Medium', fontSize: 14, - color: '#ffffff' + color: '#ffffff', }, buttonDarkLeft: { fontStyle: 'Roboto-Medium', fontSize: 14, - color: '#000000' + color: '#000000', }, buttonLightLeft: { fontStyle: 'Roboto-Medium', fontSize: 14, - color: '#ffffff' + color: '#ffffff', }, body2Accent: { fontStyle: 'Roboto-Regular', fontSize: 14, - color: '#f15035' + color: '#f15035', }, body2Dark: { fontStyle: 'Roboto-Regular', fontSize: 14, - color: '#000000' + color: '#000000', }, body2Light: { fontStyle: 'Roboto-Regular', fontSize: 14, - color: '#ffffff' + color: '#ffffff', }, Subheader: { fontStyle: 'Roboto-Regular', fontSize: 14, - color: '#4b3953' + color: '#4b3953', }, Caption: { fontStyle: 'Roboto-Regular', fontSize: 12, - color: '#000000' - } - } -}) - + color: '#000000', + }, + }, +}); ReactDOM.render( @@ -131,7 +129,7 @@ ReactDOM.render( , - document.getElementById('root') + document.getElementById('root'), ); serviceWorker.unregister(); diff --git a/app/src/pages/App.js b/app/src/pages/App.js index 5e07cc6..ab728a8 100644 --- a/app/src/pages/App.js +++ b/app/src/pages/App.js @@ -1,23 +1,23 @@ -import "./App.css" +import './App.css'; import React from 'react'; -import UtterPage from "./UtterPage"; +import { BrowserRouter as Router, Route } from 'react-router-dom'; +import UtterPage from './UtterPage'; import IntentPage from './IntentPage'; import StoriesPage from './StoriesPage'; import StoryEditPage from './StoryEditPage'; -import MenuNavbar from "../components/MenuNavbar"; -import { BrowserRouter as Router, Route } from 'react-router-dom'; +import MenuNavbar from '../components/MenuNavbar'; function App() { return ( -
    +
    -