I am very new to write test cases, i tried to write test cases for my dashboard page and i am getting Cannot read property 'clientHeight' of undefined error, please see my all dashboard.js page below & my test cases file. please help me on this
getting Error in this line:
var t = window.innerHeight - document.getElementsByClassName('nep-header')[0].clientHeight - 20 + "p
My Dashboard.js page:
import { CompanyDashboard, DeleteCompanyDashboard } from "../../APICall/CompanyDashboard";
import React from "react";import { GetimageUrl } from "../../Common/UtilityFunctions";
import { Table, Modal, Button, Message } from "#maknowledgeservices/neptune";
import './Dashboard.css';
import { dateFormatConversionForSorting } from '../../Common/UtilityFunctions';
import { setTimeout } from "timers";
import Loader from '../../Components/Loader/Loader';
var successMessage = false;
var errorMessage = false;
var showing = true;
class Dashboard extends React.Component {
constructor(props) {
super(props);
this.showing = true;
setTimeout(() => {
var divsToHide = document.getElementsByClassName("nep-table-empty"); //divsToHide is an array
for (var i = 0; i < divsToHide.length; i++) {
divsToHide[i].style.visibility = "hidden"; // or
divsToHide[i].style.display = "none"; // depending on what you're doing
}
}, 10);
this.state = {
visible: false,
DeleteCompStr: "",
DeleteCompID: 0,
columnDefs: [
{
title: "Company", render: "Companyname", fixed: "left", width: 320, sorter: order => (a, b) => {
if (order === 'asc') return a.Companyname.localeCompare(b.Companyname)
return b.Companyname.localeCompare(a.Companyname)
}
},
{
title: 'Year End', width: 95, render: d => this.renderMethod(d.financeYearEndMonth + " " + d.financeYearEnd), sorter: order => (a, b) => {
if (order === 'asc') return dateFormatConversionForSorting(a.financeYearEndMonth + " " + a.financeYearEnd).localeCompare(dateFormatConversionForSorting(b.financeYearEndMonth + " " + b.financeYearEnd))
return dateFormatConversionForSorting(b.financeYearEndMonth + " " + b.financeYearEnd).localeCompare(dateFormatConversionForSorting(a.financeYearEndMonth + " " + a.financeYearEnd))
}
},
{
title: 'LTM Financials', width: 95, render: d => this.renderMethod(d.ltmMonth + " " + d.ltmYear), sorter: order => (a, b) => {
if (order === 'asc') return dateFormatConversionForSorting(a.ltmMonth + " " + a.ltmYear).localeCompare(dateFormatConversionForSorting(b.ltmMonth + " " + b.ltmYear))
return dateFormatConversionForSorting(b.ltmMonth + " " + b.ltmYear).localeCompare(dateFormatConversionForSorting(a.ltmMonth + " " + a.ltmYear))
}
},
{
title: "AccuRate", width: 95, render: s => this.StatusIndicator(s.accurate),
},
{
title: "Financial Trends", width: 95, render: s => this.StatusIndicator(s.finTrend),
},
{
title: "Newsflow Trends", width: 115,
render: (s) => (
<div style={{ cursor: "default" }}>
{this.StatusIndicator(s.newsflow)}
<a className="tooltip" style={{ float: "right" }}
onClick={this.show.bind(this, s)}
><i style={{ cursor: "pointer" }} className="icon-Delete" name="delete"
onMouseOver={({ target }) => target.style.color = '#021155'}
onMouseOut={({ target }) => target.style.color = '#75787B'} /></a>
</div>
),
}
],
companyCount: '',
rowData: [],
res: ""
}
this.show = this.show.bind(this)
}
show(selRowVal) {
this.setState({
visible: true,
})
this.DeleteCompID = selRowVal.id;
this.DeleteCompStr = selRowVal.Companyname;
}
handleOk = () => {
DeleteCompanyDashboard("DeleteCompany/" + this.DeleteCompID).then(responce => {
if (responce.data === true) {
if (successMessage === false) {
successMessage = true;
Message.success(this.DeleteCompStr + ' Company has been deleted successfully', 7, {
onClose: () => {
successMessage = false;
}
});
}
}
else {
if (errorMessage === false) {
errorMessage = true;
Message.error('Server error', 7, {
onClose: () => {
errorMessage = false;
}
});
}
}
this.componentDidMount();
this.setState({
visible: false,
});
});
}
handleCancel = () => {
this.setState({
visible: false,
})
}
renderMethod(params) {
return params.substring(3);
}
handleRemove(selectedValue) {
this.show();
}
StatusIndicator(params) {
switch (params) {
case 'Positive':
return <span style={{ color: '#388E3C' }}><img className="indicaterGap" src={GetimageUrl(params)}></img>{params}</span>
break;
case 'Negative':
return <span style={{ color: '#C62828' }}><img className="indicaterGap" src={GetimageUrl(params)}></img>{params}</span>
break;
case 'Stable':
return <span style={{ color: '#C68700' }}><img className="indicaterGap" src={GetimageUrl(params)}></img>{params}</span>
break;
case 'Neutral':
return <span style={{ color: '#C68700' }}><img className="indicaterGap" src={GetimageUrl(params)}></img>{params}</span>
break;
default:
return <span style={{ color: '#55565A' }}>{params}</span>
break;
}
}
componentDidMount() {
CompanyDashboard("GetCompany").then(responce => {
this.showing = false;
this.setState({
rowData: responce.data,
companyCount: responce.data.length === 0 || undefined ? 0 : responce.data.length
});
});
this.tableHeight();
}
componentDidUpdate(prevProps, prevState) {
if (prevState.companyCount !== this.state.companyCount) {
CompanyDashboard("GetCompany").then(responce => {
this.setState({ rowData: responce.data, companyCount: responce.data.length === 0 || undefined ? 0 : responce.data.length });
});
}
this.tableHeight();
}
tableHeight() {
var t = window.innerHeight - document.getElementsByClassName('nep-header')[0].clientHeight - 20 + "px"
var ele = document.getElementById("pr");
ele.style.height = t.toString();
}
rowClicked(e) {
setTimeout(() => {
let selectedCompany = this.state.rowData.filter(x => x.cik == e.cik);
selectedCompany = selectedCompany.map(function (obj) {
let val = obj.Companyname;
delete obj['Companyname']
obj.companyname = val;
return obj
}
);
sessionStorage.setItem("selectedCompany", JSON.stringify(selectedCompany));
const { from } = {
from: { pathname: "/company" }
};
this.props.history.push(from);
}, 300)
}
handleClick = (value = this.state.value) => {
value += Math.random() * 12
if (value >= 100) {
value = 100
this.setState({ value })
} else {
this.setState({ value }, () => {
setTimeout(this.handleClick, 320)
})
}
}
render() {
return (
<div id="pr" className="tableSpace">
<label>Companies <span className="tableSpan">({this.state.companyCount})</span></label>
<div style={{ display: (this.showing ? 'block' : 'none') }} >
<Loader />
</div>
<Table
keygen="cik"
striped
bordered
fixed="both"
className="tableClass"
bordered fixed="both"
width={1024}
columns={this.state.columnDefs}
data={this.state.rowData}
onRowClick={this.rowClicked.bind(this)}
/>
<Modal
visible={this.state.visible}
width={500}
title=" Delete Company"
onClose={this.handleCancel}
maskCloseAble={false}
footer={[
<Button key="cancel" className="nep-button nep-button-secondary" onClick={this.handleCancel}>
Cancel
</Button>,
<Button key="ok" type="primary" onClick={this.handleOk}>
Delete
</Button>,
]} >
The company <b>{this.DeleteCompStr}</b> will be permanently deleted and this action cannot be undone. <br /> Are you sure you want to proceed ?
</Modal>
</div>
);}}export default Dashboard;`
My dashbord test cases file code:
import React from 'react'
import { render, cleanup } from '#testing-library/react';
import Dashboard from "../Components/Dashboard/Dashboard"
import axios from "axios";
import { shallow } from 'enzyme'
import { Table } from "#maknowledgeservices/neptune";
afterEach(cleanup);
jest.mock('axios');
it("should render initial layout", () => {
const component = shallow(<Dashboard />);
expect(component.getElements()).toMatchSnapshot();
});
it("test to render Dashboard component", async () => {
axios.post.mockResolvedValue({ data: [{ Companyname: "xyz", accurate: "Positive", }], status: 200, statusText: "OK" });
await render(<Dashboard />, Table);
var result = render(<Dashboard />);
expect(result).toBeTruthy();
});
Related
i have a grid with kendoreact that has a dropdown in its cell. i add a pager to the dropdown. but when i click on the pages, the dropdown close.
i have the same combobox in the form and it works good.
i tried a lot and worked on the pager and combobox props. but it was useless. perhaps its a behaviour from the grid. please help
import React, { useRef } from "react";
import { ComboBox } from "#progress/kendo-react-dropdowns";
import { filterBy } from "#progress/kendo-data-query";
import { Pager } from "#progress/kendo-react-data-tools";
import {
IntlProvider,
load,
LocalizationProvider,
loadMessages,
} from "#progress/kendo-react-intl";
import faMessages from "../../../../common/fa.json";
import persianJs from "persianjs";
// import Combobox from "../../../RPKCustomComponent/Combobox";
loadMessages(faMessages, "fa-IR");
const selectField = "selected";
const expandField = "expanded";
const dataItemKey = "value";
const textField = "label";
const subItemsField = "items";
const fields = {
selectField,
expandField,
dataItemKey,
subItemsField,
};
const initialType = "numeric";
const initialPageState = {
skip: 0,
take: 10,
total: 0,
buttonCount: 5,
type: initialType,
info: true,
// pageSizes: true,
previousNext: true,
responsive: true,
};
export default class ComboBoxCell extends React.Component {
state = {
data: [],
pageState: initialPageState,
take: 10,
skip: 0,
mammad: false,
};
handlepageChange = async (event) => {
// event.syntheticEvent.isDefaultPrevented();
// await this.setState({ skip: event.skip, take: event.take, mammad: true });
await this.props.getCombo({
id: this.props.dataItem.Id,
pageIndex: event.skip/10,
pageSize: 10,
search: "",
});
this.setState({mammad:true})
};
handleChange = (e) => {
this.props.onChange({
dataItem: this.props.dataItem,
field: this.props.field,
syntheticEvent: e.syntheticEvent,
value: e.target.value,
});
this.setState({mammad:true})
};
handleOnClick = async (e) => {
setTimeout(async () => {
if (!this.props.data && this.props.getCombo) {
await this.props.getCombo(true, this.state.skip / 10, 10, "");
}
}, 0);
this.setState({mammad:true})
};
componentDidMount() {
let dropdowntree = document.getElementById(`${this.props.id}`);
if (dropdowntree) {
dropdowntree.setAttribute("name", this.props.field);
}
this.textInput = React.createRef();
if (this.props.data?.List) {
let badData = this.props.data?.List.find((item) => {
if (item.value < 0 || item.label == null || item.label == undefined) {
return item;
}
});
if (badData) {
this.props.data.List.map((item) => {
if (item.label == null || item.label == undefined) {
item.label = "";
}
});
console.log("دیتای کمبو از سمت بک مشکل داره");
}
}
if (this.props.data?.List) {
let badData = this.props.data.List.find((item) => {
if (item.value < 0 || item.label == null || item.label == undefined) {
return item;
}
});
if (badData) {
this.props.data.List.map((item) => {
if (
item.label == null ||
item.label == undefined ||
item.label == false
) {
item.label = " ";
}
});
console.log("دیتای کمبو از سمت بک مشکل داره");
}
this.props.data.List.length > 0 &&
this.props.data.List.map(
(item) =>
(item.label =
item.label.length > 0 &&
persianJs(item.label)?.arabicChar()?._str)
);
}
this.setState({
data: this.props.data?.List,
pageState: {
...this.state.pageState,
total: this.props.data?.RecordCount ?? 0,
},
});
}
filterChange = (event) => {
this.setState({
data: this.filterData(event.filter),
});
};
filterData(filter) {
if (this.props.data?.List) {
const data = this.props.data?.List?.slice();
return filterBy(data, filter);
}
}
render() {
// let test=document.getElementsByClassName("comboFooterPageNumber")[0]
// console.log(test);
// document.getElementsByClassName("comboFooterPageNumber")[0]
// .addEventListener("click",(e)=>{
// console.log(e);
// });
// document
// .getElementsByClassName(this.props?.realurl)[0]
// .addEventListener("dblclick", this.AddInCell);
// console.log(this.state.skip);
console.log(this.state.mammad);
const { dataItem, field } = this.props;
const dataValue = dataItem[field] === null ? "" : dataItem[field];
const dataLableValue =
dataItem[field] === null ? "" : dataItem[field]?.label;
let dropValue = this.props.data?.List
? this.props.data?.List.find((c) => c.value == dataValue)
: null;
let dropLabel = this.props.data?.List
? this.props.data?.List.find((c) => c.value == dataValue)?.label
: null;
const listNoDataRender = (element) => {
const noData = (
<h4
style={{
fontSize: "1em",
}}
>
<span
className="k-icon k-i-warning"
style={{
fontSize: "1.5em",
}}
/>
<br />
<br />
موردی یافت نشد!
</h4>
);
return React.cloneElement(element, { ...element.props }, noData);
};
return (
<td className="cell-input">
{dataItem.inEdit && this.props.editable ? (
<ComboBox
{...this.props}
data={this.state.data ?? []}
onChange={this.handleChange}
textField={textField}
dataItemKey={dataItemKey}
filterable={true}
opened={this.state.mammad}
closed={!this.state.mammad}
onFilterChange={this.filterChange}
required={this.props.required}
onOpen={this.handleOnClick}
value={dropValue ?? dataValue}
listNoDataRender={listNoDataRender}
ariaLabelledBy={this.props.ariaLabelledBy ?? ""}
name={this.props.field}
footer={
// (!this.props.clientSide || this.props.allowNewForm) && (
<div>
{/* {this.props.allowNewForm && (
<>
<span className="comboFooter"></span>
<p onClick={others.setshowmodal}>افزودن گزینه جدید</p>
</>
)} */}
{/* {!this.props.clientSide && ( */}
<div className="comboFooterPageNumber">
<LocalizationProvider language="fa">
<Pager
skip={this.state.skip}
take={this.state.take}
total={this.state.pageState.total}
buttonCount={this.state.pageState.buttonCount}
info={this.state.pageState.info}
type={this.state.pageState.type}
previousNext={this.state.pageState.previousNext}
onPageChange={this.handlepageChange}
ref={this.textInput}
/>
</LocalizationProvider>
</div>
{/* )} */}
</div>
// )
}
/>
) : (
dropLabel ?? dataLableValue
)}
</td>
);
}
}
Can anyone give a suggestion on how can I convert Ant Design class-based component into function-based? I am new to class-based, so it is pretty confusing for me to convert class components. Now, my application is a functional-based component. Any suggestion will be appreciated!
Transfer Component
import { Transfer, Button } from 'antd';
class App extends React.Component {
state = {
mockData: [],
targetKeys: [],
};
componentDidMount() {
this.getMock();
}
getMock = () => {
const targetKeys = [];
const mockData = [];
for (let i = 0; i < 20; i++) {
const data = {
key: i.toString(),
title: `content${i + 1}`,
description: `description of content${i + 1}`,
chosen: Math.random() * 2 > 1,
};
if (data.chosen) {
targetKeys.push(data.key);
}
mockData.push(data);
}
this.setState({ mockData, targetKeys });
};
handleChange = targetKeys => {
this.setState({ targetKeys });
};
renderFooter = (props, { direction }) => {
if (direction === 'left') {
return (
<Button size="small" style={{ float: 'left', margin: 5 }} onClick={this.getMock}>
Left button reload
</Button>
);
}
return (
<Button size="small" style={{ float: 'right', margin: 5 }} onClick={this.getMock}>
Right button reload
</Button>
);
};
render() {
return (
<Transfer
dataSource={this.state.mockData}
showSearch
listStyle={{
width: 250,
height: 300,
}}
operations={['to right', 'to left']}
targetKeys={this.state.targetKeys}
onChange={this.handleChange}
render={item => `${item.title}-${item.description}`}
footer={this.renderFooter}
/>
);
}
}
ReactDOM.render(<App />, mountNode);
in function component to define state you can use useState hook, and also instead of lifecycles such as componentDidMount, componentDidUpdate, ... you can use useEffect hook, liek this:
import {useState, useEffect} from 'react';
import { Transfer, Button } from 'antd';
function App() {
const [state, setState] = useState({
mockData: [],
targetKeys: [],
});
const getMock = () => {
const targetKeys = [];
const mockData = [];
for (let i = 0; i < 20; i++) {
const data = {
key: i.toString(),
title: `content${i + 1}`,
description: `description of content${i + 1}`,
chosen: Math.random() * 2 > 1,
};
if (data.chosen) {
targetKeys.push(data.key);
}
mockData.push(data);
}
setState({ mockData, targetKeys });
};
useEffect(()=>{
getMock();
}, [])
const handleChange = targetKeys => {
setState(prevState => ({ ...prevState, targetKeys }));
};
const renderFooter = (props, { direction }) => {
if (direction === 'left') {
return (
<Button size="small" style={{ float: 'left', margin: 5 }} onClick={getMock}>
Left button reload
</Button>
);
}
return (
<Button size="small" style={{ float: 'right', margin: 5 }} onClick={getMock}>
Right button reload
</Button>
);
};
return (
<Transfer
dataSource={state.mockData}
showSearch
listStyle={{
width: 250,
height: 300,
}}
operations={['to right', 'to left']}
targetKeys={state.targetKeys}
onChange={handleChange}
render={item => `${item.title}-${item.description}`}
footer={renderFooter}
/>
);
}
I'am using react autosuggest npm package to get the json data and display it. I want to display only 5 items. How to do it?
Form.js
import React from 'react'
import Autosuggest from 'react-autosuggest';
import cities from 'cities.json';
const getSuggestions = value => {
const inputValue = value.trim().toLowerCase();
const inputLength = inputValue.length;
// Here I get data from cities.json
return inputLength === 0 ? [] : cities.filter(lang =>
lang.name.toLowerCase().slice(0, inputLength) === inputValue
);
);
};
const getSuggestionValue = suggestion => suggestion.name;
const renderSuggestion = suggestion => (
<div>
{console.log('suggestion', suggestion)}
{suggestion.name}
</div>
);
class Form extends React.Component {
constructor() {
super();
this.state = {
value: '',
suggestions: []
};
}
onChange = (event, { newValue }) => {
this.setState({
value: newValue
});
};
onSuggestionsFetchRequested = ({ value }) => {
this.setState({
suggestions: getSuggestions(value)
});
};
onSuggestionsClearRequested = () => {
this.setState({
suggestions: []
});
};
render(){
const { value, suggestions } = this.state;
// Autosuggest will pass through all these props to the input.
const inputProps = {
placeholder: 'Search City...',
value,
onChange: this.onChange
};
return (
<div>
<Autosuggest
suggestions={suggestions}
onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
onSuggestionsClearRequested={this.onSuggestionsClearRequested}
getSuggestionValue={getSuggestionValue}
renderSuggestion={renderSuggestion}
inputProps={inputProps}
/>
<br/>
</div>
)
}
}
export default Form;
I want to render only 5 items, otherwise, computer hangs while loading huge data. Is there any other autocomplete react npm package, since I want only cities and country list. i.e when city is inputted, automatically the city name must be suggested with its relevant country.Any solution or suggestion highly appreciated. Thanks in advance
i modified you're getSuggestions() method a little i guess this should work for you.
const getSuggestions = value => {
const inputValue = value.trim().toLowerCase();
const inputLength = inputValue.length;
// Here I get data from cities.json
return inputLength === 0 ? [] : cities.filter(lang =>
lang.name.toLowerCase().slice(0, inputLength) === inputValue
).slice(0,5);
};
Use the Slice method with start index and last Index
suggestions={suggestions.slice(0, 5)}
import {
React
,Avatar
,axiosbase
} from '../../import-files';
import Autosuggest from 'react-autosuggest';
import './autosuggest.css';
import { withStyles } from '#material-ui/core/styles';
import TextField from '#material-ui/core/TextField';
import Paper from '#material-ui/core/Paper';
import MenuItem from '#material-ui/core/MenuItem';
let suggestions = [ { label: 'Afghanistan' } ];
function renderInputComponent(inputProps) {
const { classes, inputRef = () => {}, ref, ...other } = inputProps;
return (
<TextField
className={classes.textField}
fullWidth
variant="outlined"
InputProps={{
inputRef: node => {
ref(node);
inputRef(node);
},
classes: {
input: classes.input,
},
}}
{...other}
/>
);
}
function renderSuggestion(suggestion, { query, isHighlighted }) {
return (
<MenuItem selected={isHighlighted} component="div">
<div>
<strong key={String(suggestion.id)} style={{ fontWeight: 300 }}>
<span className="sugg-option">
<span className="icon-wrap">
<Avatar src={suggestion.Poster}></Avatar>
</span>
<span className="name">
{suggestion.Title}
</span>
</span>
</strong>
</div>
</MenuItem>
);
}
function initSuggestions(value) {
suggestions = value;
}
function getSuggestionValue(suggestion) {
return suggestion.Title;
}
function onSuggestionSelected(event, { suggestion, suggestionValue, suggestionIndex, sectionIndex, method }) {
console.log('HandleSuggestion() '+suggestionValue);
}
const styles = theme => ({
root: {
height: 50,
flexGrow: 1,
},
container: {
position: 'relative',
},
suggestionsContainerOpen: {
position: 'absolute',
zIndex: 998,
marginTop: theme.spacing.unit,
left: 0,
right: 0,
overflowY: 'scroll',
maxHeight:'376%'
},
suggestion: {
display: 'block',
},
suggestionsList: {
margin: 0,
padding: 0,
listStyleType: 'none',
},
divider: {
height: theme.spacing.unit * 2,
},
});
class IntegrationAutosuggest extends React.Component {
state = {
single: '',
popper: '',
suggestions: [],
};
componentDidMount() {
initSuggestions(suggestions);
}
// Filter logic
getSuggestions = async (value) => {
const inputValue = value.trim().toLowerCase();
var _filter = JSON.stringify({
filter : inputValue,
});
return await axiosbase.post(`${apiCall}`, _filter);
};
handleSuggestionsFetchRequested = ({ value }) => {
this.getSuggestions(value)
.then(data => {
if (data.Error) {
this.setState({
suggestions: []
});
} else {
const responseData = [];
data.data.itemsList.map((item, i) => {
let File = {
id: item.idEnc,
Title: item.englishFullName +' '+item.arabicFullName,
englishFullName: item.englishFullName,
arabicFullName: item.arabicFullName,
Poster: item.photoPath,
}
responseData.push(File);
});
this.setState({
suggestions: responseData
});
}
})
};
handleSuggestionsClearRequested = () => {
this.setState({
suggestions: [],
});
};
handleChange = name => (event, { newValue }) => {
this.setState({
[name]: newValue,
});
if(event.type=='click'){
if(typeof this.props.handleOrderUserFirstNameChange === "function"){
this.props.handleOrderUserFirstNameChange(newValue);
}
this.state.suggestions.filter(f=>f.Title===newValue).map((item, i) => {
//id
//Title
// Poster
if(typeof this.props.handleUserIDChange === "function"){
this.props.handleUserIDChange(item.id);
}
});
}
};
render() {
const { classes } = this.props;
// console.log('Re-render!!');
// console.log(this.props);
// console.log(this.state.suggestions);
const autosuggestProps = {
renderInputComponent,
suggestions: this.state.suggestions,
onSuggestionsFetchRequested: this.handleSuggestionsFetchRequested,
onSuggestionsClearRequested: this.handleSuggestionsClearRequested,
onSuggestionSelected: this.props.onSelect,
getSuggestionValue,
renderSuggestion,
};
return (
<div className={classes.root}>
<Autosuggest
{...autosuggestProps}
inputProps={{
classes,
placeholder: this.props.placeHolder,
value: this.state.single,
onChange: this.handleChange('single'),
}}
theme={{
container: classes.container,
suggestionsContainerOpen: classes.suggestionsContainerOpen,
suggestionsList: classes.suggestionsList,
suggestion: classes.suggestion,
}}
renderSuggestionsContainer={options => (
<Paper {...options.containerProps} square>
{options.children}
</Paper>
)}
/>
<div className={classes.divider} />
</div>
);
}
}
export default withStyles(styles)(IntegrationAutosuggest);
I'm trying to dynamically edit the cell value but some of the components are not working properly like MoodCellRenderer and NumericCellEditor. Other editor components are working fine.
Can you please help me to make it work?
import React, {Component} from "react";
import {render} from "react-dom";
import {AgGridReact} from "ag-grid-react";
import "ag-grid-enterprise";
import 'bootstrap/dist/js/bootstrap.js';
function cloneObject(obj) {
return JSON.parse(JSON.stringify(obj));
}
class Example8 extends Component {
constructor(props) {
super(props);
this.state = {
columnDefs: [{
headerName: "Value",
field: "value",
width: 100,
editable: true,
cellEditorSelector: function(params) {
if (params.data.type === 'age') return {
component: 'numericCellEditor'
};
if (params.data.type === 'gender') return {
component: 'agRichSelectCellEditor',
params: {
values: ['Male', 'Female']
}
};
if (params.data.type === 'mood') return {
component: 'moodEditor'
};
return null;
}
},
{
headerName: "Type",
field: "type",
width: 100
}
],
rowData: [{
value: 14,
type: 'age'
},
{
value: 'female',
type: 'gender'
},
{
value: "Happy",
type: 'mood'
},
{
value: 21,
type: 'age'
},
{
value: 'male',
type: 'gender'
},
{
value: "Sad",
type: 'mood'
}
],
gridOptions: {
onRowEditingStarted: function(event) {
console.log('never called - not doing row editing');
},
onRowEditingStopped: function(event) {
console.log('never called - not doing row editing');
},
onCellEditingStarted: function(event) {
console.log('cellEditingStarted');
},
onCellEditingStopped: function(event) {
console.log('cellEditingStopped');
},
components: {
genderCellRenderer: GenderCellRenderer,
numericCellEditor: NumericCellEditor,
moodCellRenderer: MoodCellRenderer,
moodEditor: MoodEditor,
countryCellRenderer: CountryCellRenderer
}
}
};
}
onGridReady = params => {
this.gridApi = params.api;
this.gridColumnApi = params.columnApi;
params.api.sizeColumnsToFit();
};
render() {
return (
<div style={{ width: "100%", height: "100%" }}>
<div
id="myGrid"
style={{
height: "100%",
width: "100%"
}}
className="ag-theme-balham"
>
<AgGridReact
columnDefs={this.state.columnDefs}
components={this.state.components}
rowData={this.state.rowData}
onGridReady={this.onGridReady}
/>
</div>
</div>
);
}
}
function getCharCodeFromEvent(event) {
event = event || window.event;
return (typeof event.which == "undefined") ? event.keyCode : event.which;
}
function isCharNumeric(charStr) {
return !!/\d/.test(charStr);
}
function isKeyPressedNumeric(event) {
var charCode = getCharCodeFromEvent(event);
var charStr = String.fromCharCode(charCode);
return isCharNumeric(charStr);
}
// simple function cellRenderer, just returns back the name of the country
function CountryCellRenderer(params) {
return params.value.name;
}
// function to act as a class
function NumericCellEditor() {}
// gets called once before the renderer is used
NumericCellEditor.prototype.init = function(params) {
// create the cell
this.eInput = document.createElement('input');
if (isCharNumeric(params.charPress)) {
this.eInput.value = params.charPress;
} else {
if (params.value !== undefined && params.value !== null) {
this.eInput.value = params.value;
}
}
var that = this;
this.eInput.addEventListener('keypress', function(event) {
if (!isKeyPressedNumeric(event)) {
that.eInput.focus();
if (event.preventDefault) event.preventDefault();
} else if (that.isKeyPressedNavigation(event)) {
event.stopPropagation();
}
});
// only start edit if key pressed is a number, not a letter
var charPressIsNotANumber = params.charPress && ('1234567890'.indexOf(params.charPress) < 0);
this.cancelBeforeStart = charPressIsNotANumber;
};
NumericCellEditor.prototype.isKeyPressedNavigation = function(event) {
return event.keyCode === 39 ||
event.keyCode === 37;
};
// gets called once when grid ready to insert the element
NumericCellEditor.prototype.getGui = function() {
return this.eInput;
};
// focus and select can be done after the gui is attached
NumericCellEditor.prototype.afterGuiAttached = function() {
this.eInput.focus();
};
// returns the new value after editing
NumericCellEditor.prototype.isCancelBeforeStart = function() {
return this.cancelBeforeStart;
};
// example - will reject the number if it contains the value 007
// - not very practical, but demonstrates the method.
NumericCellEditor.prototype.isCancelAfterEnd = function() {
var value = this.getValue();
return value.indexOf('007') >= 0;
};
// returns the new value after editing
NumericCellEditor.prototype.getValue = function() {
return this.eInput.value;
};
// any cleanup we need to be done here
NumericCellEditor.prototype.destroy = function() {
// but this example is simple, no cleanup, we could even leave this method out as it's optional
};
// if true, then this editor will appear in a popup
NumericCellEditor.prototype.isPopup = function() {
// and we could leave this method out also, false is the default
return false;
};
function GenderCellRenderer() {}
GenderCellRenderer.prototype.init = function(params) {
this.eGui = document.createElement('span');
if (params.value !== "" || params.value !== undefined || params.value !== null) {
var gender = '<img border="0" width="15" height="10" src="https://raw.githubusercontent.com/ag-grid/ag-grid/master/packages/ag-grid-docs/src/images/' + params.value.toLowerCase() + '.png">';
this.eGui.innerHTML = gender + ' ' + params.value;
}
};
GenderCellRenderer.prototype.getGui = function() {
return this.eGui;
};
function MoodCellRenderer() {}
MoodCellRenderer.prototype.init = function(params) {
this.eGui = document.createElement('span');
if (params.value !== "" || params.value !== undefined || params.value !== null) {
var imgForMood = params.value === 'Happy' ? 'https://raw.githubusercontent.com/ag-grid/ag-grid/master/packages/ag-grid-docs/src/images/smiley.png' : 'https://raw.githubusercontent.com/ag-grid/ag-grid/master/packages/ag-grid-docs/src/images/smiley-sad.png';
this.eGui.innerHTML = '<img width="20px" src="' + imgForMood + '" />';
}
};
MoodCellRenderer.prototype.getGui = function() {
return this.eGui;
};
function MoodEditor() {
this.defaultImgStyle = 'padding-left:10px; padding-right:10px; border: 1px solid transparent; padding: 4px;';
this.selectedImgStyle = 'padding-left:10px; padding-right:10px; border: 1px solid lightgreen; padding: 4px;';
}
MoodEditor.prototype.onKeyDown = function(event) {
var key = event.which || event.keyCode;
if (key == 37 || // left
key == 39) { // right
this.toggleMood();
event.stopPropagation();
}
};
MoodEditor.prototype.toggleMood = function() {
this.selectMood(this.mood === 'Happy' ? 'Sad' : 'Happy');
};
MoodEditor.prototype.init = function(params) {
this.container = document.createElement('div');
this.container.style = "border-radius: 15px; border: 1px solid grey;background: #e6e6e6;padding: 15px; text-align:center;display:inline-block;outline:none";
this.container.tabIndex = "0"; // to allow the div to capture keypresses
this.happyImg = document.createElement('img');
this.happyImg.src = 'https://raw.githubusercontent.com/ag-grid/ag-grid/master/packages/ag-grid-docs/src/images/smiley.png';
this.happyImg.style = this.defaultImgStyle;
this.sadImg = document.createElement('img');
this.sadImg.src = 'https://raw.githubusercontent.com/ag-grid/ag-grid/master/packages/ag-grid-docs/src/images/smiley-sad.png';
this.sadImg.style = this.defaultImgStyle;
this.container.appendChild(this.happyImg);
this.container.appendChild(this.sadImg);
var that = this;
this.happyImg.addEventListener('click', function(event) {
that.selectMood('Happy');
params.stopEditing();
});
this.sadImg.addEventListener('click', function(event) {
that.selectMood('Sad');
params.stopEditing();
});
this.container.addEventListener('keydown', function(event) {
that.onKeyDown(event)
});
this.selectMood(params.value);
};
MoodEditor.prototype.selectMood = function(mood) {
this.mood = mood;
this.happyImg.style = (mood === 'Happy') ? this.selectedImgStyle : this.defaultImgStyle;
this.sadImg.style = (mood === 'Sad') ? this.selectedImgStyle : this.defaultImgStyle;
};
// gets called once when grid ready to insert the element
MoodEditor.prototype.getGui = function() {
return this.container;
};
MoodEditor.prototype.afterGuiAttached = function() {
this.container.focus();
};
MoodEditor.prototype.getValue = function() {
return this.mood;
};
// any cleanup we need to be done here
MoodEditor.prototype.destroy = function() {};
MoodEditor.prototype.isPopup = function() {
return true;
};
// setup the grid after the page has finished loading
export default Example8;
import React, { Component } from 'react'
import { render } from 'react-dom'
// import { AgGridReact } from 'ag-grid-react'
import 'ag-grid-enterprise'
import 'bootstrap/dist/js/bootstrap.js'
import 'ag-grid/dist/styles/ag-grid.css'
import 'ag-grid/dist/styles/ag-theme-balham.css'
import {DataGrid} from '#cib-jpm-ui-toolkit/data-grid'
import $ from 'jquery'
function cloneObject (obj) {
return JSON.parse(JSON.stringify(obj))
}
class InvoiceTextFields extends Component {
constructor (props) {
super(props)
this.state = {
columnDefs: [
{headerName: 'Field Name', field: 'fieldName', width: 70},
{headerName: 'Extracted Taxonomy', field: 'extractedTaxonomy', width: 70},
{headerName: 'Taxonomy Data Field', field: 'taxonomyDataField', width: 70},
{
headerName: 'Corrected Texonomy',
field: 'value',
width: 70,
editable: true,
cellEditorSelector:function (params) {
if (params.data.type === 'age') {
return {
component: 'numericCellEditor'
}
}
if (params.data.type === 'examination') {
return {
component: 'agSelectCellEditor',
params: { values: extractValues(carMappings) },
valueFormatter: function (params) {
return lookupValue(carMappings, params.value)
},
valueParser: function (params) {
return lookupKey(carMappings, params.newValue)
}
}
}
if (params.data.type === 'tenor') {
return {
component: 'agSelectCellEditor',
params: { values: extractValues(tenorMappings) },
valueFormatter: function (params) {
return lookupValue(carMappings, params.value)
},
valueParser: function (params) {
return lookupKey(carMappings, params.newValue)
}
}
}
if (params.data.type === 'dateVal') {
return {
cellEditor: 'datePicker'
}
}
return null
}
}
],
// components: { datePicker: getDatePicker() },
rowData: [
{value: '28/02/2019', type: 'dateVal', fieldName:'Expiry Date'},
{value: 'YES', type: 'tenor', fieldName:'Tenor Type'},
{value: 'Vessel 1', type: 'text', fieldName:'Vessel Name'},
{value: 'Examine Document', type: 'examination', fieldName:'Examination Type'},
],
gridOptions:{
onRowEditingStarted: function (event) {
console.log('never called - not doing row editing')
},
onRowEditingStopped: function (event) {
console.log('never called - not doing row editing')
},
onCellEditingStarted: function (event) {
console.log('cellEditingStarted')
},
onCellEditingStopped: function (event) {
console.log('cellEditingStopped')
}
}
}
}
onGridReady = params => {
this.gridApi = params.api
this.gridColumnApi = params.columnApi
params.api.sizeColumnsToFit()
};
onCellClicked = (event) => {
console.log('hi: ' + event.colDef.field)
console.log('hi type: ' + event.colDef.type)
if (this.props.correctedTaxonomy === null) {
console.log('null')
}
if (this.props.correctedTaxonomy === '') {
console.log('empty')
}
if (event.colDef.field === 'value' && this.props.correctedTaxonomy !== null) {
var rowModel = this.gridApi.getModel()
var rowNode = rowModel.rowsToDisplay[event.rowIndex]
event.data.correctedText = this.props.correctedTaxonomy
rowNode.setDataValue('value', event.data.correctedText)
}
};
render () {
return (
<div style={{ width: '100%', height: '100%' }}>
<div
id='myGrid'
style={{
height: '100%',
width: '103%'
}}
className='ag-theme-balham'
>
<DataGrid
columnDefs={this.state.columnDefs}
// components={this.state.components}
rowData={this.state.rowData}
gridOptions={this.state.gridOptions}
onGridReady={this.onGridReady}
onCellClicked={this.onCellClicked.bind(this)}
/>
</div>
</div>
)
}
}
var carMappings = {
'Examine Document': 'Examine Document',
'Do not Examine': 'Do not Examine',
'Send on approval with Doc Exam': 'Send on approval with Doc Exam',
'Send on Approval Without Doc' : 'Send on Approval Without Doc ',
'Exam' : 'Exam'
}
var tenorMappings = {
'YES': 'YES',
'NO': 'NO'
}
function extractValues (mappings) {
return Object.keys(mappings)
}
function lookupValue (mappings, key) {
return mappings[key]
}
function lookupKey (mappings, name) {
for (var key in mappings) {
if (mappings.hasOwnProperty(key)) {
if (name === mappings[key]) {
return key
}
}
}
}
function getCharCodeFromEvent (event) {
event = event || window.event
return (typeof event.which === 'undefined') ? event.keyCode : event.which
}
function isCharNumeric (charStr) {
return !!/\d/.test(charStr)
}
function isKeyPressedNumeric (event) {
var charCode = getCharCodeFromEvent(event)
var charStr = String.fromCharCode(charCode)
return isCharNumeric(charStr)
}
function getDatePicker () {
console.log('in gerDatePicker...')
function Datepicker () {}
Datepicker.prototype.init = function (params) {
this.eInput = document.createElement('input')
this.eInput.value = params.value
$(this.eInput).datepicker({ dateFormat: 'dd/mm/yy' })
}
Datepicker.prototype.getGui = function () {
return this.eInput
}
Datepicker.prototype.afterGuiAttached = function () {
this.eInput.focus()
this.eInput.select()
}
Datepicker.prototype.getValue = function () {
return this.eInput.value
}
Datepicker.prototype.destroy = function () {}
Datepicker.prototype.isPopup = function () {
return false
}
return Datepicker
}
export default InvoiceTextFields
import React, { Component } from "react";
import { render } from "react-dom";
import { AgGridReact } from "ag-grid-react";
import "ag-grid-enterprise";
import 'bootstrap/dist/js/bootstrap.js';
import $ from 'jquery'
function cloneObject (obj) {
return JSON.parse(JSON.stringify(obj))
}
class InvoiceTextFields extends Component {
constructor (props) {
super(props)
this.state = {
columnDefs: [
{headerName: 'Field Name', field: 'fieldName', width: 70},
{headerName: 'Extracted Taxonomy', field: 'extractedTaxonomy', width: 70},
{headerName: 'Taxonomy Data Field', field: 'taxonomyDataField', width: 70},
{
headerName: 'Corrected Texonomy',
field: 'value',
width: 70,
editable: true,
cellEditorSelector:function (params) {
if (params.data.type === 'age') {
return {
component: 'numericCellEditor'
}
}
if (params.data.type === 'examination') {
return {
component: 'agRichSelectCellEditor',
params: { values: extractValues(carMappings) },
valueFormatter: function (params) {
return lookupValue(carMappings, params.value)
},
valueParser: function (params) {
return lookupKey(carMappings, params.newValue)
}
}
}
if (params.data.type === 'tenor') {
return {
component: 'agSelectCellEditor',
params: { values: extractValues(tenorMappings) },
valueFormatter: function (params) {
return lookupValue(carMappings, params.value)
},
valueParser: function (params) {
return lookupKey(carMappings, params.newValue)
}
}
}
if (params.data.type === 'dateVal') {
return {
cellEditor: 'datePicker'
}
}
return null
}
}
],
// components: { datePicker: getDatePicker() },
rowData: [
{value: '28/02/2019', type: 'dateVal', fieldName:'Expiry Date'},
{value: 'YES', type: 'tenor', fieldName:'Tenor Type'},
{value: 'Vessel 1', type: 'text', fieldName:'Vessel Name'},
{value: 'Examine Document', type: 'examination', fieldName:'Examination Type'},
],
gridOptions:{
onRowEditingStarted: function (event) {
console.log('never called - not doing row editing')
},
onRowEditingStopped: function (event) {
console.log('never called - not doing row editing')
},
onCellEditingStarted: function (event) {
console.log('cellEditingStarted')
},
onCellEditingStopped: function (event) {
console.log('cellEditingStopped')
}
}
}
}
onGridReady = params => {
this.gridApi = params.api
this.gridColumnApi = params.columnApi
params.api.sizeColumnsToFit()
};
onCellClicked = (event) => {
console.log('hi: ' + event.colDef.field)
console.log('hi type: ' + event.colDef.type)
if (this.props.correctedTaxonomy === null) {
console.log('null')
}
if (this.props.correctedTaxonomy === '') {
console.log('empty')
}
if (event.colDef.field === 'value' && this.props.correctedTaxonomy !== null) {
var rowModel = this.gridApi.getModel()
var rowNode = rowModel.rowsToDisplay[event.rowIndex]
event.data.correctedText = this.props.correctedTaxonomy
rowNode.setDataValue('value', event.data.correctedText)
}
};
render () {
return (
<div style={{ width: '100%', height: '100%' }}>
<div
id='myGrid'
style={{
height: '100%',
width: '103%'
}}
className='ag-theme-balham'
>
<AgGridReact
columnDefs={this.state.columnDefs}
// components={this.state.components}
rowData={this.state.rowData}
gridOptions={this.state.gridOptions}
onGridReady={this.onGridReady}
// onCellClicked={this.onCellClicked.bind(this)}
/>
</div>
</div>
)
}
}
var carMappings = {
'Examine Document': 'Examine Document',
'Do not Examine': 'Do not Examine',
'Send on approval with Doc Exam': 'Send on approval with Doc Exam',
'Send on Approval Without Doc' : 'Send on Approval Without Doc ',
'Exam' : 'Exam'
}
var tenorMappings = {
'YES': 'YES',
'NO': 'NO'
}
function extractValues (mappings) {
return Object.keys(mappings)
}
function lookupValue (mappings, key) {
return mappings[key]
}
function lookupKey (mappings, name) {
for (var key in mappings) {
if (mappings.hasOwnProperty(key)) {
if (name === mappings[key]) {
return key
}
}
}
}
function getCharCodeFromEvent (event) {
event = event || window.event
return (typeof event.which === 'undefined') ? event.keyCode : event.which
}
function isCharNumeric (charStr) {
return !!/\d/.test(charStr)
}
function isKeyPressedNumeric (event) {
var charCode = getCharCodeFromEvent(event)
var charStr = String.fromCharCode(charCode)
return isCharNumeric(charStr)
}
function getDatePicker () {
console.log('in gerDatePicker...')
function Datepicker () {}
Datepicker.prototype.init = function (params) {
this.eInput = document.createElement('input')
this.eInput.value = params.value
$(this.eInput).datepicker({ dateFormat: 'dd/mm/yy' })
}
Datepicker.prototype.getGui = function () {
return this.eInput
}
Datepicker.prototype.afterGuiAttached = function () {
this.eInput.focus()
this.eInput.select()
}
Datepicker.prototype.getValue = function () {
return this.eInput.value
}
Datepicker.prototype.destroy = function () {}
Datepicker.prototype.isPopup = function () {
return false
}
return Datepicker
}
export default InvoiceTextFields
So after looking over many different questions asking the about this warning, I have found that there is not one single reason why this would be occurring making it difficult to infer a solution on my own code.
So here is my code incase anyone has another pair of eyes they can put on it and spot maybe why i would be getting this error.
This error occurs when not on first arrival of the component but after leaving and returning to it again.
I have a smart container and a dumb component set up so here is the container:
import React, { PropTypes } from 'react';
import { connect } from 'react-redux';
import { listOrders, listUseCases } from '../../actions/order';
import { storeWithExpiration } from '../../utils/common.js';
import OrdersIndex from './OrdersIndex';
export class OrdersIndexContainer extends React.Component {
static propTypes = {
account: PropTypes.object.isRequired,
orders: PropTypes.object.isRequired,
platformMap: PropTypes.object.isRequired,
progress: PropTypes.number,
listOrdersAction: PropTypes.func.isRequired,
listUseCasesAction: PropTypes.func.isRequired,
};
render() {
const { orders, platformMap, progress } = this.props;
return (
<div>
<OrdersIndex
orders={ orders }
platformMap={ platformMap }
progress={ progress }
/>
</div>
);
}
renderOrderIndex = () => {
}
componentWillMount = () => {
const { account, listOrdersAction, listUseCasesAction } = this.props;
const token = storeWithExpiration.get('token');
listOrdersAction(token);
listUseCasesAction(account.id, token);
}
}
function mapStateToProps(state) {
const { account, orderList, progress } = state;
const orders = orderList.get('orders');
const platformMap = orderList.get('platformMap');
return { account, platformMap, orders, progress };
}
export default connect(mapStateToProps, {
listOrdersAction: listOrders,
listUseCasesAction: listUseCases,
})(OrdersIndexContainer);
And here is the dumb component:
import React, { PropTypes } from 'react';
import { Link } from 'react-router';
import ReactDataGrid from 'react-data-grid';
import { Toolbar } from 'react-data-grid/addons';
import { Data } from 'react-data-grid/addons';
import moment from 'moment';
import { SIMPLE_DATE_FORMAT } from '../../config/app_config';
// import OrderWrapFormatter from './OrderWrapFormatter';
const TABLE_COLUMNS = [
{ key: 'cNumber', name: 'Customer #', width: 125 },
{ key: 'name', name: 'Name', width: 150 },
{ key: 'orderNumber', name: 'Order #', width: 90 },
{ key: 'platform', name: 'Platform' },
{ key: 'useCase', name: 'Use Case'/* , formatter: OrderWrapFormatter */ },
{ key: 'list', name: 'List' },
{ key: 'sku', name: 'SKU' },
{ key: 'startDate', name: 'Start Date' },
{ key: 'endDate', name: 'End Date' },
];
export default class OrdersIndex extends React.Component {
static propTypes = {
orders: PropTypes.object.isRequired,
platformMap: PropTypes.object.isRequired,
progress: PropTypes.number,
};
state = {
rows: [],
originalRows: [],
columns: TABLE_COLUMNS,
sortColumn: null,
sortDirection: null,
filters: {},
}
renderRows = (orders) => {
const _rows = [];
orders.map((o) => {
_rows.push({
key: o.order.id,
id: o.order.id,
cNumber: o.order.providerCustomerNumber,
name: o.order.company.name,
orderNumber: o.order.providerOrderNumber,
platform: o.platformUseCases[0].platform.description,
useCase: this.renderMulti(o.platformUseCases, 'useCase', 'description'),
list: this.renderMulti(o.listSKUs, 'dataSet', 'name'),
sku: this.renderMulti(o.listSKUs, 'fieldSet', 'name'),
startDate: moment(o.order.startDate).format(SIMPLE_DATE_FORMAT),
endDate: moment(o.order.endDate).format(SIMPLE_DATE_FORMAT),
});
return _rows;
});
return this.setState({
rows: _rows,
originalRows: _rows.slice(),
});
}
getRows = () => {
return Data.Selectors.getRows(this.state);
}
rowGetter = (rowIdx) => {
const rows = this.getRows();
return rows[rowIdx];
}
getSize = () => {
return this.getRows().length;
}
renderMulti = (multi, itemName, subItemName) => {
const objectArray = multi.map((object) => {
return object[itemName][subItemName];
});
return objectArray.join('\n');
}
handleGridSort = (sortColumn, sortDirection) => {
const { originalRows, rows } = this.state;
const comparer = (a, b) => {
if (sortDirection === 'ASC') {
return (a[sortColumn] > b[sortColumn]) ? 1 : -1;
}
else if (sortDirection === 'DESC') {
return (a[sortColumn] < b[sortColumn]) ? 1 : -1;
}
};
const newRows = sortDirection === 'NONE' ? originalRows.slice() : rows.sort(comparer);
this.setState({
rows: newRows,
});
}
handleRowUpdated = (e) => {
// merge updated row with current row and rerender by setting state
const { rows } = this.state;
Object.assign(rows[e.rowIdx], e.updated);
this.setState({
...rows,
});
}
handleFilterChange = (filter) => {
const { filters } = this.state;
const newFilters = Object.assign({}, filters);
if (filter.filterTerm) {
newFilters[filter.column.key] = filter;
}
else {
delete newFilters[filter.column.key];
}
this.setState({
filters: newFilters,
});
}
onClearFilters = () => {
// all filters removed
this.setState({
filters: {},
});
}
// Creates appropriate warnings to prevent entering
// the order form if the account is missing information
renderNotice = (message, buttonMessage, route) => {
return (
<div className="alert alert-warning">
<strong>Notice:</strong>
<p>{ message }</p>
<p>
<Link
to={ route }
className="btn btn-warning"
>
<i className='fa fa-plus'></i>
{ buttonMessage }
</Link>
</p>
</div>
);
}
render() {
const { platformMap, progress } = this.props;
const platformMessage = 'Your account is not associated with any platform use cases.' +
'You must select at least one use case before creating new orders.';
const platformButton = 'Add Use Cases';
const platformRoute = '/products';
return (
<div className="container">
<div className="row">
<div className="col-sm-12 col-md-8">
<h1>Orders</h1>
</div>
<div className="col-sm-12 col-md-4">
<span className="pull-right">
<Link
to="/orders/create/1"
className="btn btn-primary"
disabled
>
<i className='fa fa-plus'></i>Create New Order
</Link>
</span>
</div>
</div>
{ platformMap.size === 0 && progress === 0 ?
this.renderNotice(platformMessage, platformButton, platformRoute) : null }
<div className="row">
{ progress === 0 ?
<div className="col-md-12">
{ this.renderTable() }
</div> : null }
</div>
</div>
);
}
renderTable = () => {
const { orders } = this.props;
const { columns } = this.state;
return (
<div>
{ orders.size === 0 || orders === undefined ?
<p>Your account has no orders</p> :
<ReactDataGrid
onGridSort={ this.handleGridSort }
rowKey="key"
id="key"
columns={ columns }
rowGetter={ this.rowGetter }
rowsCount={ this.getSize() }
onRowUpdated={ this.handleRowUpdated }
toolbar={ <Toolbar enableFilter /> }
onAddFilter={ this.handleFilterChange }
onClearFilters={ this.onClearFilters }
minHeight={ 500 }
filterRowsButtonText="Search By Field"
/>
}
</div>
);
}
componentWillMount = () => {
const { orders } = this.props;
const columnArray =
TABLE_COLUMNS.map((c) => {
const copy = Object.assign({}, c);
copy.filterable = true;
copy.locked = true;
if (copy.key !== 'useCase') {
copy.sortable = true;
}
return copy;
});
this.setState({
columns: columnArray,
});
this.renderRows(orders);
}
componentWillReceiveProps = (nextProps) => {
const { orders } = nextProps;
if (orders.size > 0) {
this.renderRows(orders);
}
}
}
I understand this might be a lot but I cannot for the life of me determine what could be the cause. Thanks to anyone who takes a look.