fixed PR #15 comments
This commit is contained in:
@@ -65,8 +65,8 @@ constants.stringConstraints = {
|
|||||||
|
|
||||||
constants.answerType = {
|
constants.answerType = {
|
||||||
PREDEFINED: 0,
|
PREDEFINED: 0,
|
||||||
EXTERNAL_SOURCE_WP_JSON : 1,
|
EXTERNAL_SOURCE_WP_TITLES : 1,
|
||||||
EXTERNAL_SOURCE_RSS : 2
|
EXTERNAL_SOURCE_WP_NEWS : 2
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = constants;
|
module.exports = constants;
|
||||||
|
|||||||
@@ -3,14 +3,6 @@ let Parser = require ('rss-parser');
|
|||||||
|
|
||||||
let parser = new Parser ();
|
let parser = new Parser ();
|
||||||
|
|
||||||
getDataFromRSSFeed = function (url) {
|
|
||||||
//let feed = await parser.parseURL(url);
|
|
||||||
//console.log(feed.title);
|
|
||||||
//feed.items.forEach(item => {
|
|
||||||
// console.log(item.title + ':' + item.link)
|
|
||||||
//});
|
|
||||||
}
|
|
||||||
|
|
||||||
getDataFromWPJSON = function (sourceUrl, page = 1, maxPosts = 10) {
|
getDataFromWPJSON = function (sourceUrl, page = 1, maxPosts = 10) {
|
||||||
return new Promise ((resolve, reject) => {
|
return new Promise ((resolve, reject) => {
|
||||||
var options = {
|
var options = {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ let predefinedSourceHelper = require ('../helpers/externalSource');
|
|||||||
|
|
||||||
var handlers = {};
|
var handlers = {};
|
||||||
var destinationEmail;
|
var destinationEmail;
|
||||||
|
let skillName;
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
run: function (req, res) {
|
run: function (req, res) {
|
||||||
@@ -33,6 +34,7 @@ module.exports = {
|
|||||||
.then (activeSkill => {
|
.then (activeSkill => {
|
||||||
handlers = {};
|
handlers = {};
|
||||||
destinationEmail = activeSkill.contactEmail;
|
destinationEmail = activeSkill.contactEmail;
|
||||||
|
skillName = activeSkill.invocationName;
|
||||||
|
|
||||||
let listOfPossibleQuestions = '';
|
let listOfPossibleQuestions = '';
|
||||||
activeSkill.intents.forEach (intent => {
|
activeSkill.intents.forEach (intent => {
|
||||||
@@ -77,7 +79,7 @@ module.exports = {
|
|||||||
reject: null
|
reject: null
|
||||||
}
|
}
|
||||||
|
|
||||||
let answer = new Promise((resolve,reject)=>{
|
let answerPromise = new Promise ((resolve, reject) => {
|
||||||
answerPromiseProps = {
|
answerPromiseProps = {
|
||||||
resolve:resolve,
|
resolve:resolve,
|
||||||
reject:reject
|
reject:reject
|
||||||
@@ -88,30 +90,32 @@ module.exports = {
|
|||||||
case constants.answerType.PREDEFINED:
|
case constants.answerType.PREDEFINED:
|
||||||
answerPromiseProps.resolve(intent.answer);
|
answerPromiseProps.resolve(intent.answer);
|
||||||
break;
|
break;
|
||||||
case constants.answerType.EXTERNAL_SOURCE_WP_JSON:
|
case constants.answerType.EXTERNAL_SOURCE_WP_TITLES:
|
||||||
predefinedSourceHelper.getAnswerFromWP(intent.externalAnswerSource).then(answer=>{
|
predefinedSourceHelper.getAnswerFromWP(intent.externalAnswerSource).then(answer=>{
|
||||||
answerPromiseProps.resolve(answer);
|
answerPromiseProps.resolve(answer);
|
||||||
}).catch(error=>{
|
}).catch(error=>{
|
||||||
answerPromiseProps.reject(error);
|
answerPromiseProps.reject(error);
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case constants.answerType.EXTERNAL_SOURCE_RSS:
|
case constants.answerType.EXTERNAL_SOURCE_WP_NEWS:
|
||||||
answer = 'Not implemented yet'
|
answer = 'Not implemented yet'
|
||||||
answerPromiseProps.resolve(answer);
|
answerPromiseProps.resolve(answer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
answer.then(answer=>{
|
answerPromise
|
||||||
this.response
|
.then (answer => {
|
||||||
.speak (answer)
|
this.response
|
||||||
.listen (constants.voiceResponseStrings.GENERIC_CONTINUE); //Phrase from listen doesn't work !!!
|
.speak (answer)
|
||||||
this.emit (':responseReady');
|
.listen (constants.voiceResponseStrings.GENERIC_CONTINUE); //Phrase from listen doesn't work !!!
|
||||||
}).catch(error=>{
|
this.emit (':responseReady');
|
||||||
this.response
|
})
|
||||||
.speak (error)
|
.catch (error => {
|
||||||
.listen (constants.voiceResponseStrings.GENERIC_CONTINUE); //Phrase from listen doesn't work !!!
|
this.response
|
||||||
this.emit (':responseReady');
|
.speak (error)
|
||||||
});
|
.listen (constants.voiceResponseStrings.GENERIC_CONTINUE); //Phrase from listen doesn't work !!!
|
||||||
|
this.emit (':responseReady');
|
||||||
|
});
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -213,7 +217,7 @@ module.exports = {
|
|||||||
if (this.attributes['LaunchRequestYesNo']) {
|
if (this.attributes['LaunchRequestYesNo']) {
|
||||||
this.attributes['LaunchRequestYesNo'] = false;
|
this.attributes['LaunchRequestYesNo'] = false;
|
||||||
}
|
}
|
||||||
this.response.speak ('Thank you for using Saburly');
|
this.response.speak (`Thank you for using ${skillName}`);
|
||||||
this.emit (':responseReady');
|
this.emit (':responseReady');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -253,30 +253,21 @@ class App extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Check for same question variants and same question name in other intents
|
//Check for same question variants and same question name in other intents
|
||||||
|
//all intents with the same intentName, or some of the questions are the same
|
||||||
|
//will be kept in filteredIntents. After filterring, there should be only one
|
||||||
|
//intent left, the selected one
|
||||||
|
|
||||||
|
let filteredIntents = this.state.allIntents.filter(intent=>{
|
||||||
|
let result = (selectedIntent.intentName === intent.intentName);
|
||||||
|
let filteredQuestions = intent.questions.filter(question=>{
|
||||||
|
return (selectedIntent.questions.indexOf(question)!==-1);
|
||||||
|
});
|
||||||
|
return (result || filteredQuestions.length > 0);
|
||||||
|
});
|
||||||
|
|
||||||
for (let i = 0; i < this.state.allIntents.length; i++) {
|
if (filteredIntents.length > 1){
|
||||||
if (i !== this.state.selectedIndex) {
|
Popup.alert('Question name or question variant already exists');
|
||||||
if (selectedIntent.intentName === this.state.allIntents[i].intentName) {
|
return;
|
||||||
Popup.alert ('Question name already exists');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let j = 0; j < selectedIntent.questions.length; j++) {
|
|
||||||
for (let k = 0; k < this.state.allIntents[i].questions.length; k++) {
|
|
||||||
if (
|
|
||||||
selectedIntent.questions[j] ===
|
|
||||||
this.state.allIntents[i].questions[k]
|
|
||||||
) {
|
|
||||||
Popup.alert (
|
|
||||||
'Question variant already exists (in question :' +
|
|
||||||
this.state.allIntents[i].intentName +
|
|
||||||
')'
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let newAllIntentsJSON = JSON.stringify (this.state.allIntents);
|
let newAllIntentsJSON = JSON.stringify (this.state.allIntents);
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import {Button, SelectionControlGroup} from 'react-md';
|
import {Button} from 'react-md';
|
||||||
import Modal from './modal/Modal';
|
import AnswerSourceForm from './helper/AnswerSourceForm';
|
||||||
import {
|
import '../css/components/IntentDetails.css';
|
||||||
ANSWER_TYPE
|
|
||||||
} from '../config/constants';
|
|
||||||
|
|
||||||
class AnswerSource extends Component {
|
class AnswerSource extends Component {
|
||||||
constructor (props) {
|
constructor (props) {
|
||||||
@@ -30,67 +28,27 @@ class AnswerSource extends Component {
|
|||||||
|
|
||||||
onSave(){
|
onSave(){
|
||||||
this.onClose();
|
this.onClose();
|
||||||
this.props.onSaveHandle(this.state.answerType);
|
this.props.onSaveAnswerType(this.state.answerType);
|
||||||
}
|
}
|
||||||
|
|
||||||
onSourceChange(value, event){
|
onSourceChange(value, event){
|
||||||
this.setState({answerType:parseInt(value)});
|
this.setState({answerType:parseInt(value,10)});
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
let modal;
|
let modal;
|
||||||
if (this.state.isModalOpen) {
|
if (this.state.isModalOpen) {
|
||||||
modal = (
|
modal = <AnswerSourceForm
|
||||||
<Modal
|
isModalOpen={this.state.isModalOpen}
|
||||||
title="Answer type"
|
answerType={this.state.answerType}
|
||||||
actions={[
|
onSave={this.onSave.bind(this)}
|
||||||
<Button
|
onClose={this.onClose.bind(this)}
|
||||||
flat
|
onSourceChange={this.onSourceChange.bind(this)}
|
||||||
swapTheming
|
/>
|
||||||
onClick={this.onClose.bind (this)}
|
|
||||||
key="cancel"
|
|
||||||
>
|
|
||||||
Cancel
|
|
||||||
</Button>,
|
|
||||||
<Button
|
|
||||||
flat
|
|
||||||
primary
|
|
||||||
swapTheming
|
|
||||||
key="save"
|
|
||||||
onClick={this.onSave.bind(this)}
|
|
||||||
>
|
|
||||||
Save
|
|
||||||
</Button>,
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<SelectionControlGroup
|
|
||||||
id="answer-source"
|
|
||||||
name="answer-source"
|
|
||||||
type="radio"
|
|
||||||
label="Import answer from:"
|
|
||||||
onChange={this.onSourceChange.bind(this)}
|
|
||||||
controls={[
|
|
||||||
{
|
|
||||||
label: 'Predefined answer',
|
|
||||||
value: '0'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'WordPress titles',
|
|
||||||
value: '1',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'RSS feed - latest',
|
|
||||||
value: '2',
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
defaultValue={String(this.state.answerType)}
|
|
||||||
/>
|
|
||||||
</Modal>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Button flat primary swapTheming onClick={this.onOpen.bind (this)}>
|
<Button flat primary onClick={this.onOpen.bind (this)}>
|
||||||
Answer type
|
Answer type
|
||||||
</Button>
|
</Button>
|
||||||
{modal}
|
{modal}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import {
|
|||||||
INTENT_EXPLANATION_MAX_LENGTH,
|
INTENT_EXPLANATION_MAX_LENGTH,
|
||||||
ANSWER_TYPE,
|
ANSWER_TYPE,
|
||||||
} from '../config/constants';
|
} from '../config/constants';
|
||||||
|
import AnswerTextBox from './helper/AnswerTextBox.js';
|
||||||
|
|
||||||
class IntentDetails extends Component {
|
class IntentDetails extends Component {
|
||||||
constructor (props) {
|
constructor (props) {
|
||||||
@@ -20,13 +21,10 @@ class IntentDetails extends Component {
|
|||||||
this.addQuestion = this.addQuestion.bind (this);
|
this.addQuestion = this.addQuestion.bind (this);
|
||||||
this.deleteQuestion = this.deleteQuestion.bind (this);
|
this.deleteQuestion = this.deleteQuestion.bind (this);
|
||||||
this.handleQuestionEdit = this.handleQuestionEdit.bind (this);
|
this.handleQuestionEdit = this.handleQuestionEdit.bind (this);
|
||||||
this.handleAnswerEdit = this.handleAnswerEdit.bind (this);
|
|
||||||
this.handleAnswerSourceEdit = this.handleAnswerSourceEdit.bind (this);
|
|
||||||
this.handleIntentNameEdit = this.handleIntentNameEdit.bind (this);
|
this.handleIntentNameEdit = this.handleIntentNameEdit.bind (this);
|
||||||
this.handleIntentExplanationEdit = this.handleIntentExplanationEdit.bind (
|
this.handleIntentExplanationEdit = this.handleIntentExplanationEdit.bind (
|
||||||
this
|
this
|
||||||
);
|
);
|
||||||
this.handleExternalSourceSave = this.handleExternalSourceSave.bind (this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps (props) {
|
componentWillReceiveProps (props) {
|
||||||
@@ -34,43 +32,6 @@ class IntentDetails extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
let answerBox;
|
|
||||||
switch (this.state.intent.answerType) {
|
|
||||||
case ANSWER_TYPE.PREDEFINED:
|
|
||||||
answerBox = (
|
|
||||||
<div className="QuestionBox">
|
|
||||||
<TextField
|
|
||||||
id="intent answer"
|
|
||||||
lineDirection="center"
|
|
||||||
label="Answer"
|
|
||||||
placeholder="Answer"
|
|
||||||
maxLength={ANSWER_MAX_LENGTH}
|
|
||||||
className="md-cell md-cell--bottom IntentDetailsInputBoxes"
|
|
||||||
onChange={this.handleAnswerEdit}
|
|
||||||
value={this.state.intent.answer}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case ANSWER_TYPE.EXTERNAL_SOURCE_WP_JSON:
|
|
||||||
case ANSWER_TYPE.EXTERNAL_SOURCE_RSS:
|
|
||||||
answerBox = (
|
|
||||||
<div className="QuestionBox">
|
|
||||||
<TextField
|
|
||||||
id="intent answer"
|
|
||||||
lineDirection="center"
|
|
||||||
label="Answer source"
|
|
||||||
placeholder="Answer source"
|
|
||||||
maxLength={ANSWER_MAX_LENGTH}
|
|
||||||
className="md-cell md-cell--bottom IntentDetailsInputBoxes"
|
|
||||||
onChange={this.handleAnswerSourceEdit}
|
|
||||||
value={this.state.intent.externalAnswerSource}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="RightPanelBox">
|
<div className="RightPanelBox">
|
||||||
<div className="QuestionBox">
|
<div className="QuestionBox">
|
||||||
@@ -140,11 +101,17 @@ class IntentDetails extends Component {
|
|||||||
add
|
add
|
||||||
</Button>
|
</Button>
|
||||||
<AnswerSource
|
<AnswerSource
|
||||||
className="QuestionTypeButton"
|
className="AnswerTypeButton"
|
||||||
onSaveHandle={this.handleExternalSourceSave}
|
onSaveAnswerType={this.handleExternalSourceSave.bind(this)}
|
||||||
answerType={this.state.intent.answerType}
|
answerType={this.state.intent.answerType}
|
||||||
/>
|
/>
|
||||||
{answerBox}
|
<AnswerTextBox
|
||||||
|
answerType={this.state.intent.answerType}
|
||||||
|
externalAnswerSource={this.state.intent.externalAnswerSource}
|
||||||
|
handleAnswerSourceEdit={this.handleAnswerSourceEdit.bind(this)}
|
||||||
|
handleAnswerEdit={this.handleAnswerEdit.bind(this)}
|
||||||
|
answer={this.state.intent.answer}
|
||||||
|
/>
|
||||||
<Button
|
<Button
|
||||||
className="IntentDetailsButton-firstInRow"
|
className="IntentDetailsButton-firstInRow"
|
||||||
flat
|
flat
|
||||||
|
|||||||
57
web/src/components/helper/AnswerSourceForm.js
Normal file
57
web/src/components/helper/AnswerSourceForm.js
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
import React, {Component} from 'react';
|
||||||
|
import {Button, SelectionControlGroup} from 'react-md';
|
||||||
|
import Modal from './Modal';
|
||||||
|
|
||||||
|
class AnswerSourceForm extends Component{
|
||||||
|
|
||||||
|
render(){
|
||||||
|
return(
|
||||||
|
<Modal
|
||||||
|
title="Answer type"
|
||||||
|
actions={[
|
||||||
|
<Button
|
||||||
|
flat
|
||||||
|
swapTheming
|
||||||
|
onClick={this.props.onClose.bind (this)}
|
||||||
|
key="cancel"
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</Button>,
|
||||||
|
<Button
|
||||||
|
flat
|
||||||
|
primary
|
||||||
|
swapTheming
|
||||||
|
key="save"
|
||||||
|
onClick={this.props.onSave.bind(this)}
|
||||||
|
>
|
||||||
|
Save
|
||||||
|
</Button>,
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<SelectionControlGroup
|
||||||
|
id="answer-source"
|
||||||
|
name="answer-source"
|
||||||
|
type="radio"
|
||||||
|
label="Import answer from:"
|
||||||
|
onChange={this.props.onSourceChange.bind(this)}
|
||||||
|
controls={[
|
||||||
|
{
|
||||||
|
label: 'Predefined answer',
|
||||||
|
value: '0'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'WordPress titles',
|
||||||
|
value: '1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'WordPress latest news',
|
||||||
|
value: '2',
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
defaultValue={String(this.props.answerType)}
|
||||||
|
/>
|
||||||
|
</Modal>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AnswerSourceForm;
|
||||||
44
web/src/components/helper/AnswerTextBox.js
Normal file
44
web/src/components/helper/AnswerTextBox.js
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
import React, {Component} from 'react';
|
||||||
|
import {TextField} from 'react-md';
|
||||||
|
import '../../css/components/IntentDetails.css';
|
||||||
|
import '../../css/Common.css';
|
||||||
|
import {
|
||||||
|
ANSWER_MAX_LENGTH,
|
||||||
|
ANSWER_TYPE,
|
||||||
|
} from '../../config/constants';
|
||||||
|
|
||||||
|
class AnswerTextBox extends Component {
|
||||||
|
|
||||||
|
render () {
|
||||||
|
//theese are defaults for ANSWER_TYPE.PREDEFINED
|
||||||
|
let labelText="Answer";
|
||||||
|
let valueText=this.props.answer;
|
||||||
|
let onChangeValue=this.props.handleAnswerEdit;
|
||||||
|
switch(this.props.answerType){
|
||||||
|
case ANSWER_TYPE.EXTERNAL_SOURCE_WP_TITLES:
|
||||||
|
case ANSWER_TYPE.EXTERNAL_SOURCE_WP_NEWS:
|
||||||
|
labelText="Answer source";
|
||||||
|
valueText=this.props.externalAnswerSource;
|
||||||
|
onChangeValue=this.props.handleAnswerSourceEdit
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return(
|
||||||
|
<div className="QuestionBox">
|
||||||
|
<TextField
|
||||||
|
id="intent answer"
|
||||||
|
lineDirection="center"
|
||||||
|
label={labelText}
|
||||||
|
placeholder={labelText}
|
||||||
|
maxLength={ANSWER_MAX_LENGTH}
|
||||||
|
className="md-cell md-cell--bottom IntentDetailsInputBoxes"
|
||||||
|
onChange={onChangeValue}
|
||||||
|
value={valueText}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AnswerTextBox;
|
||||||
@@ -24,8 +24,8 @@ export const CONTACT_SELECTED_INDEX = -3;
|
|||||||
|
|
||||||
export const ANSWER_TYPE = {
|
export const ANSWER_TYPE = {
|
||||||
PREDEFINED: 0,
|
PREDEFINED: 0,
|
||||||
EXTERNAL_SOURCE_WP_JSON : 1,
|
EXTERNAL_SOURCE_WP_TITLES : 1,
|
||||||
EXTERNAL_SOURCE_RSS : 2
|
EXTERNAL_SOURCE_WP_NEWS : 2
|
||||||
}
|
}
|
||||||
|
|
||||||
export const RESULT_CODES = {
|
export const RESULT_CODES = {
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
margin-right: 10%;
|
margin-right: 10%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.QuestionTypeButton{
|
.AnswerTypeButton{
|
||||||
float: left;
|
float: right;
|
||||||
margin-left: 30px;
|
margin-right: 30px;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user