Order detail component
Less than to read
In this step, we add Order detail component.
-
Add a new component for displaying order detail line by line called order-line-detail-component.js:
import * as React from 'react'; import { Sidebar, SidebarHeader } from 'carbon-react/lib/components/sidebar'; import Heading from 'carbon-react/lib/components/heading'; import Button from 'carbon-react/lib/components/button'; import Card from 'carbon-react/lib/components/card'; import { Row, Column } from 'carbon-react/lib/components/row'; import Textbox from 'carbon-react/lib/__experimental__/components/textbox'; export default class OrderLineDetailComponent extends React.Component { constructor(props) { super(props); this.state = {}; } render() { return ( <Sidebar open={ !!this.props.order } onClose={ this.props.onClose }> <SidebarHeader> <Heading title={ this.props.order.id } divider={ false } /> <Button className='se-product-details-close' iconType='close' buttonType='tertiary' onClick={ this.props.onClose } key={ this.props.order.id } size='large' >Close </Button> </SidebarHeader> <div className='se-product-details-body'> <div className='se-product-details-properties'> {this.props.order && this.props.order.lines.edges.map(line => ( <Row key={ `${line.node.lineNumber} key ${this.props.order.id}` }> <Column> <Textbox readOnly label='Line' value={ line.node.lineNumber } key={ line.node.lineNumber } /> </Column> <Column> <Textbox readOnly label='Description' value={ line.node.product.localizedDescription1 } key={ line.node.product.localizedDescription1 } /> </Column> <Column> <Textbox readOnly label={ `Price in ${this.props.order.currency.code}` } value={ Math.round(line.node.grossPrice).toFixed(2) } key={ line.node.product.grossPrice } /> </Column> <Column> <Textbox readOnly label='Quantity' value={ line.node.quantityInSalesUnitOrdered } key={ line.node.quantityInSalesUnitOrdered} /> </Column> {line.node.product.image && line.node.product.image.value && ( <Card spacing='small' cardWidth='250px' interactive={ false } className='se-product-details-card' key={ `${line.node.lineNumber} ${this.props.order.id}` } > <img alt='product' width='200px' className='se-product-details-picture' src={ `data:image;base64,${line.node.product.image.value}` } /> </Card> )} </Row> ))} </div> </div> </Sidebar> ); } }
-
Plug this component to the order-list-detail-component.js
import * as React from 'react'; import { Table, TableRow, TableCell, TableHeader } from 'carbon-react/lib/components/table'; import Button from 'carbon-react/lib/components/button'; import Loader from 'carbon-react/lib/components/loader'; import { Query } from 'react-apollo'; import OrderLineDetailComponent from './order-line-detail-component'; import { orderDetailsQuery } from '../queries'; export default class OrderListDetailComponent extends React.Component { constructor(props) { super(props); this.state = {}; } onOrderSelected = (order) => { return () => { this.setState({ orderOpen: order }); }; }; totalOrder = (line) => { const lineCost = line.map(e => e.node.grossPrice * e.node.quantityInSalesUnitOrdered); const linesTotal = lineCost.reduce((a, b) => (a + b), 0); return Math.round(linesTotal).toFixed(2); }; renderTableOrder = orders => ( <Table> <TableRow> <TableHeader>Order ID</TableHeader> <TableHeader>Order date</TableHeader> <TableHeader>Order status</TableHeader> <TableHeader>Order amount</TableHeader> <TableHeader /> </TableRow> {orders.filter((order) => { if (this.props.closedOrder === true) { return true; } return order.node.orderStatus !== 'closed'; }).map(p => ( <TableRow key={ `${p.node.id} ${p.node.orderDate}` }> <TableCell>{p.node.id}</TableCell> <TableCell>{p.node.orderDate}</TableCell> <TableCell>{p.node.orderStatus}</TableCell> <TableCell>{`${p.node.currency.code} ${this.totalOrder(p.node.lines.edges)}`}</TableCell> <TableCell> <Button iconType='info' buttonType='tertiary' onClick={ this.onOrderSelected(p.node) } key={ p.node.id } >Detail </Button> </TableCell> </TableRow> ))} </Table> ); render() { return ( <div className='se-site-details'> <Query query={ orderDetailsQuery } variables={ { soldToCustomer: `{soldToCustomer:{ code: '${this.props.selectedCustomer}' }}`, orderBy: '{ orderDate: -1 }' } } > {({ loading, data, error }) => { if (loading) return <Loader size='large' style={ { textAlign: 'center' } } />; if (error) return <div>error</div>; if (!data) return <div>no data</div>; return ( this.renderTableOrder(data.sage.x3Sales.salesOrder.edges) ); }} </Query> { this.state.orderOpen && ( <OrderLineDetailComponent order={ this.state.orderOpen } onClose={ this.onOrderSelected() } /> )} </div> ); } }
-
Then we plug the demo endpoint in webpack.config.js:
const path = require('path'); const config = require('carbon-factory/webpack.config')({ parcelifyPaths: [ path.resolve(process.cwd(), 'node_modules/carbon-react') ] }); config.devServer.proxy = [ { context: ['/demo'], secure: false, xfwd: false, target: 'https://apidemo.sagex3.com/demo/service/X3CLOUDV2_SEED/graphql', changeOrigin: true, logLevel: 'debug' } ]; module.exports = config;
-
In the end of this step we have this file structure:
Then you can run npm install then npm start to see the result :
Open a web browser and go to http://localhost:8080/ :
Select History in the Menu drop-down:
Select a customer to see the list of orders of this customer:
Click on the button Detail to show the order detail line by line:
You can also download the VSCode project at the end of this step.