【发布时间】:2021-03-26 22:46:09
【问题描述】:
尝试为 FormRow 函数设置 onChange 事件处理程序时出现图示错误。最终需要存储来自 Que Reset Time、Service Level threshold 和 Short Abandoned Threshold 的用户数据。 Queuecontainer 是使用编辑器创建容器表单的主类。
QuesContainer.js
import React from 'react';
import Editor from './Editor';
import LoginForm from '../LoginForm';
import axios from 'axios';
export default class QueuesContainer extends React.Component {
constructor(props) {
super(props);
this.state = {
workspaceSID: '',
apiKey: '',
apiSecret: '',
queues: [],
name: '',
}
this.listQueues = this.listQueues.bind(this);
this.setCredentials = this.setCredentials.bind(this);
this.getCredentials = this.getCredentials.bind(this);
this.setQueues = this.setQueues.bind(this);
this.handleChange = this.handleChange.bind(this);
}
/*
handleChange(target) {
this.setState({ [target.id]: target.value });
}
*/
//Added by JR for Save Function
handleChange(event){
console.log("From handle change", event);
this.setState({ name: event.target.value })
}
/*
handleSubmit(event) {
event.preventDefault();
this.props.login(this.state.workspaceSID, this.state.apiKey, this.state.apiSecret);
}
*/
handleSubmit(event) {
event.preventDefault();
var text = this.state.text;
console.log("form testing value output:");
}
setCredentials(workspaceSID, apiKey, apiSecret) {
this.setState({ workspaceSID: workspaceSID });
this.setState({ apiKey: apiKey });
this.setState({ apiSecret: apiSecret });
}
getCredentials() {
return this.state;
}
setQueues(queues) {
this.setState({ queues: queues });
}
getConfig(apiKey, apiSecret) {
return axios.get(`https://flex-api.twilio.com/v1/Configuration`, {
auth: {
username: apiKey,
password: apiSecret
},
});
}
//Added by JR used to post configuration
postConfig(apiKey, apiSecret, params) {
return axios.post(`https://flex-api.twilio.com/v1/Configuration`, {
auth: {
username: apiKey,
password: apiSecret
},
});
}
listQueues(workspaceSID, apiKey, apiSecret) {
this.setCredentials(workspaceSID, apiKey, apiSecret);
const queuesPromise = axios.get(`https://taskrouter.twilio.com/v1/Workspaces/${workspaceSID}/TaskQueues?PageSize=1000&Page=0`, {
auth: {
username: apiKey,
password: apiSecret
},
});
const channelsPromise = axios.get(`https://taskrouter.twilio.com/v1/Workspaces/${workspaceSID}/TaskChannels?PageSize=1000&Page=0`, {
auth: {
username: apiKey,
password: apiSecret
},
});
const configPromise = this.getConfig(apiKey, apiSecret);
Promise.all([queuesPromise, channelsPromise, configPromise])
.then((values) => {
console.log(values);
const twilioQueues = values[0].data.task_queues;
const twilioChannels = values[1].data.channels;
// const config = values[2].data.queue_stats_configuration;
const voice = twilioChannels.find(channel => {
console.log(channel)
return channel.unique_name === 'voice'
});
const chat = twilioChannels.find(channel => {
console.log(channel)
return channel.unique_name === 'chat'
});
const email = twilioChannels.find(channel => {
console.log(channel)
return channel.unique_name === 'email'
});
const channels = [voice, chat, email];
const queues = twilioQueues.map(q => {
const queue = {
queue_sid: q.sid,
friendly_name: q.friendly_name,
channels
}
return queue;
});
this.setQueues(queues);
});
}
//onChange={this.handleInputChange.bind(this)}
render() {
const { name } = this.state
return (
<div>
<p> Test Value is : {name} </p>
<LoginForm login={this.listQueues} buttonText='Load Queues' />
<Editor onSubmit={this.handleSubmit} onChange={this.handleChange} data={this.state.queues} credentials={this.getCredentials} setData={this.setQueues} />
</div>
);
}
}
Editor.js
import React from 'react';
import MaterialTable from 'material-table'
import Button from '@material-ui/core/Button';
import TextField from '@material-ui/core/TextField';
import Grid from '@material-ui/core/Grid';
import axios from 'axios';
import { waitForDomChange } from '@testing-library/react';
export default class Editor extends React.Component {
constructor(props) {
super(props);
this.state = {
open: false,
queue: {},
columns: [
{ title: 'Queue Name', field: 'friendly_name', editable: 'never' },
{ title: 'Channel', field: 'channel_friendly_name', editable: 'never' },
{ title: 'Reset Timezone', field: 'channel_reset_timezone' },
{ title: 'Reset Time', field: 'channel_reset_time' },
{ title: 'Service Level Threshold', field: 'channel_service_level_threshold', type: 'numeric' },
{ title: 'Short Abandoned Threshold', field: 'channel_service_level_threshold', type: 'numeric' },
]
}
this.handleClose = this.handleClose.bind(this);
// this.handleSave = this.handleSave.bind(this);
}
handleClose(xxx) {
console.log('this happening');
console.log(xxx);
this.setState({ open: true });
}
/*
handleSave(event) {
console.log('Saving user input data');
console.log(event);
this.setState({ value: event.target.value});
}
*/
render() {
console.log('hey ho');
console.group(this.props.data);
const queues = this.props.data.map(q => {
const channel = q.channels.find(c => c.unique_name === 'voice');
q.channel_friendly_name = channel.friendly_name;
q.channel_reset_time = channel.reset_time;
q.channel_reset_timezone = channel.reset_timezone;
q.channel_service_level_threshold = channel.service_level_threshold;
q.channel_service_level_threshold = channel.service_level_threshold;
return q;
})
return (
<div>
<MaterialTable
title='Queue SLA'
columns={this.state.columns}
data={queues}
options={{
pageSize: 25,
pageSizeOptions: [25, 100, 500, 1000]
}}
detailPanel={rowData => {
//Modified by JR for Save Function
return FormContainer(rowData, this.props.credentials().apiKey,
this.props.credentials().apiSecret, this.handleChange);
}}
/>
</div>
);
}
}
function FormRow(data, handleChange) {
const queue = data.data;
const channels = queue.channels;
return (
channels.map((channel, index) => (
<Grid container item sm={12} spacing={3}>
<Grid item sm={2}>
<TextField
autoFocus
margin="dense"
id="channel_name"
label="Channel"
type="text"
value={channel.friendly_name}
fullWidth
disabled
/>
</Grid>
<Grid item sm={2}>
<TextField
autoFocus
margin="dense"
id="reset_timezone"
label="Reset Timezone"
type="text"
value="GMT"
fullWidth
disabled
/>
</Grid>
<Grid item sm={2}>
<TextField
autoFocus
margin="dense"
id="service_level_threshold"
label="Service Level Threshold"
value={channel.service_level_threshold}
onChange={handleChange}
type="text"
fullWidth
/>
</Grid>
<Grid item sm={2}>
<TextField
autoFocus
margin="dense"
id="short_abandoned_threshold"
label="Short Abandoned Threshold"
value={channel.short_abandoned_threshold}
onChange={handleChange}
type="text"
fullWidth
/>
</Grid>
</Grid>
))
);
}
//Modified by JR for Save Function
function FormContainer(data, apiKey, apiSecret, props, handleChange) {
console.log('what');
console.log(data);
console.log('JSON what');
console.log(JSON.stringify(data));
const queue = data;
// const queue = data.data;
const channels = queue.channels;
const cancel = () => {
console.log('cancel');
}
const save = () => {
//Modified by JR for Save Function
console.log('save');
console.log(data);
console.log(JSON.stringify(data));
console.log('SaveButtonClicked');
waitForDomChange();
console.log(data);
console.log(JSON.stringify(data));
savebuttonclicked(queue, apiKey, apiSecret);
console.log('Props Information');
console.log(props);
console.log('Save Sucessful');
}
return (
<div>
<Grid container>
<Grid item sm={1}></Grid>
<Grid container item sm={11} spacing={3}>
<FormRow data={queue}
formOnChange={handleChange}/>
</Grid>
<Grid
container
direction="row"
justify="flex-end"
alignItems="center"
>
<Grid item sm={1}></Grid>
<Grid item sm={11} spacing={3} justify="flex-end"
alignItems="center">
<Grid item sm={2}>
<TextField
autoFocus
margin="dense"
id="reset_time"
label="Queue Reset Time"
type="text"
value={channels.reset_time}
onChange={handleChange}
fullWidth
/>
</Grid>
<Button variant="outlined" onClick={cancel} color="secondary">Cancel</Button>
<Button variant="outlined" onClick={save} color="primary">Save</Button>
</Grid>
</Grid>
</Grid>
</div>
);
}
//Add by JR for Save Function
function savebuttonclicked(data, apiKey, apiSecret) {
const workspace = workspaces[0];
console.log('Test');
alert(JSON.stringify(data));
console.log(JSON.stringify(data));
var params = [];
for (const [index, value] of data.channels.entries()) {
params.push({
'url': data.channels[index].url,
'unique_name': data.channels[index].unique_name,
'account_sid': data.channels[index].account_sid,
'channel_reset_time': data.channels[index].channel_reset_time,
'channel_reset_timezone': data.channels[index].channel_reset_timezone,
'channel_service_level_threshold': data.channels[index].channel_service_level_threshold
})
}
alert(JSON.stringify(params));
console.log('Parms for API post:');
console.log(JSON.stringify(params));
/*
* Loop for API call for each URL in created JSON
*
for (const [index, value] of params.entries())
{
axios.post(params[index].url, params[index], {
auth: {
username: apiKey,
password: apiSecret,
}
})
}
*/
axios.get(workspace.apiURL, {
auth: {
username: apiKey,
password: apiSecret,
},
})
.then(function (response) {
alert('Save Sucessful.')
alert(JSON.stringify(response))
console.log('success');
console.log(response.headers);
})
.catch(function (error) {
alert('Error Occured.')
alert(error)
console.log('Error');
console.log(error);
});
}
应用修复后,这是一个新错误:
TypeError:无法读取未定义 FormRow 的属性“通道” C:/Users/drago/Source/Repos/twilio-flex-editor/src/queues/Editor.js:99 96 | 97 |函数FormRow({数据,handleChange}){98 |常量队列 =数据。数据; > 99 |常量频道 = queue.channels; 100 | 101 | 102 |查看编译 ▶ 18 个堆栈帧被折叠。
【问题讨论】:
标签: javascript reactjs grid onchange