antd collapse.panel not re rendering - reactjs

I have this collapse panel in antd.
<Collapse defaultActiveKey={[1]} onChange={onChange}>
<Panel header="Billing Details" key="2" forceRender>
<BillingPanel
invoiceCycleOptions={invoiceCycleOptions}
projectData={projectData}
payModelOptions={payModelOptions}
accTypeOptions={accTypeOptions}
onDateChange={onDateChange}
isEditMode={isEditMode}
isPopulated={isPopulated}
prjStartDate={prjStartDate}
/>
</Panel>
<Panel header="Other Details" key="3" forceRender>
<OtherDetailsPanel
csmOptions={csmOptions}
projectData={projectData}
csm={csm}
onPrimaryCsmSelect={onPrimaryCsmSelect}
accountantOptions={accountantOptions?.map(
(option) => option?.name
)}
isEditMode={isEditMode}
secondaryCsmoptions={secondaryCsmoptions}
setShow={setShow}
setDocument={setDocument}
show={show}
salesPersonOptions={salesPersonOptions}
setIsValidSize={setIsValidSize}
isValidSize={isValidSize}
leadSourceOptions={leadSourceOptions}
marketingChannelOptions={marketingChannelOptions}
activeBillingOptions={activeBillingOptions}
activeBilling={activeBilling}
form={form}
selectedCsm={selectedCsm}
primaryCsm={primaryCsm}
secondaryCsmList={secondaryCsmList}
/>
</Panel>
</Collapse>
when projectData changes, the panel with the header "Other Details" does not re render. I am getting updated projectData in this component but not in the OtherDetailsPanel component. Can anyone help me?

Related

How to use custom isOpen with a chakra component

I am relatively new to react and not sure why isOpen is not working as expected.
Please see the code below for the example that I am working with
I have a menu icon that is using isOpen to open navlinks:
const { isOpen, onOpen, onClose } = useDisclosure();
<IconButton variant={"unstyled"} bgColor={"white"} color={"black"} size={"s"} icon={isOpen ? <Hamburger size={"24"} /> : <Hamburger size={"24"} />} aria-label={"Open Menu"} display={{ md: "none" }} onClick={isOpen ? onClose : onOpen} />
{isOpen ? (
<Box color={"#b8860b"} pb={4} display={{ md: "none" }}>
<Stack as={"nav"} spacing={5}>
{Links.map(link => (
<Link key={link.name} href={link.route}>
<Flex paddingBottom="40px" h="40px" borderBottom="1px" borderColor="black" justifyContent={'left'}>
<Flex paddingLeft={"10px"} paddingTop={"3%"}> {link.icon}</Flex>
<Text p={2} color={"black"} >
{link.name}
</Text>
</Flex>
</Link>
))}
</Stack>
</Box>
) : null}
When I try using a custom isOpen to open a drawer component, i just cant get it to work..
What am I doing wrong?:
const { isOpenMenu, onOpenMenu, onCloseMenu } = useDisclosure()
<Button
bgColor={"white"}
onClick={isOpenMenu}
>
<BsCart4 size={"26px"} color={"black"} />
{cartItemCount > 0 && <Badge ml='1' fontSize='0.9em' colorScheme='green'>{cartItemCount}</Badge>}
</Button>
<Drawer
isOpen={isOpenMenu}
placement='right'
onClose={onCloseMenu}
finalFocusRef={btnRef}
>
<DrawerOverlay />
<DrawerContent>
<DrawerCloseButton />
<DrawerHeader>Create your account</DrawerHeader>
<DrawerBody>
<Input placeholder='Type here...' />
</DrawerBody>
<DrawerFooter>
<Button variant='outline' mr={3} onClick={onCloseMenu}>
Cancel
</Button>
<Button colorScheme='blue'>Save</Button>
</DrawerFooter>
</DrawerContent>
</Drawer>
```
When I use isOpen for the drawer it works fine so I thought having another isOpen but custom would open the drawer but its not working as expected.
Can someone help understand why my thinking isnt right based on how to use isOpen correctly?
It seems like only isOpen works when I switch it from using the menu bar and drawer
First of all, if you want to use custom names to the useDisclosure states, you have to set them like this:
const { isOpen: isOpenMenu, onOpen: onOpenMenu, onClose: onCloseMenu } = useDisclosure()
Also, the onClose prop of the drawer component is just a event handler, dont put your onCloseMenu function ther, just call it when you want to close the drawer, as you made on the cancel button, example:
<Button onClick={onCloseMenu} ... />

How to correctly add the Aside component to create a modal style button on the right side of my show page?

I am building a custom show page for an individual customer. Within this page I need a button that allows me to edit their points value they have. I am wanting to use the aside component that is built in react-admin but I can't seem to get it to work correctly.
I have followed the documentation to add the code for the aside component and I placed my button component within it. However it's not rendering to the page at all. I am receiving a TypeError. 'TypeError: Cannot read roperty "search" of undefined.'
const Aside = (...props) => {
const { customer_id: customer_id_string } = parse(props.location.search);
const customer_id = customer_id_string ? parseInt(customer_id_string, 10) : '';
return (
<div style={{ width: 200, margin: '1em'}}>
<Button
defaultValue={{ customer_id }}
redirect="show"
component={Link}
to={{
pathname: '/points/{{point-id}}/create',
}}
label="Add Points"
>
<Reward>Add Points</Reward>
</Button>
)
</div>
)
};
const CustomerShow = ({ classes, record, ...props }) => (
<Show aside={<Aside />} {...props}>
<TabbedShowLayout>
<Tab label="Customer Basics">
<TextField source="firstName" /><TextField source="lastName" />
<TextField source="email" />
<BooleanField source="active" />
</Tab>
<Tab label="The Rest">
<NumberField label="Points" source="points" />
<NumberField source="usedPoints" />
<NumberField source="expiredPoints" />
<NumberField source="lockedPoints" />
<BooleanField source="agreement1" />
<BooleanField source="agreement2" />
</Tab>
<Tab label="Transactions" resource="transactions" >
<ReferenceManyField
addLabel={false}
reference="transactions"
target="customerId"
pagination={<Pagination />}
perPage={10}
sort={{ field: 'createdAt', order: 'DESC' }}
><Datagrid rowClick="show" >
<DateField source="createdAt"/>
<TextField source="documentNumber"/>
<TextField source="documentType"/>
<NumberField source="grossValue"/>
<NumberField source="pointsEarned"/>
<NumberField source="pointsUsed"/>
</Datagrid>
</ReferenceManyField>
</Tab>
<Tab label="Points" resource="Points" >
<ReferenceManyField
addLabel={false}
reference="points"
target="customerId"
pagination={<Pagination />}
perPage={10}
sort={{ field: 'createdAt', order: 'DESC' }}
><Datagrid rowClick="show" >
<NumberField source="valueLocked" />
<NumberField source="valueUsed" />
<NumberField source="valueRemain" />
<NumberField source="valueExpired" />
<NumberField source="valueEarned" />
</Datagrid>
</ReferenceManyField>
</Tab>
</TabbedShowLayout>
</Show>
);
The expected results are a button on the right side of the page displaying the words "Add Points". The actual results are either a TypeError or the page renders but no button.
I figured out what I was doing wrong. I didn't have one of my sources filled out correctly. It was referencing the wrong source.

how do i open only one panel when I use mapping in react for panels

I have created a panel to map through my users and display their songs below their name.
The problem im having is that when I click on the {username} it opens all of the accordion panels. I'd like it to only open the accordion for the panel being clicked.
<PanelGroup accordion id="accordion-example">
{this.state.allUsersList.map((user, index) => (
<Panel>
<Panel.Heading>
<Panel.Title toggle >
<Button key={index} className="btn-uvideo">{user.Username}</Button>
</Panel.Title>
</Panel.Heading>
<Panel.Body collapsible>
<ListGroup>
{user.songs.map((song, index) => (
<ListGroupItem key={index}>
<Button className="btn-video" onClick={() => this.handleSongChange(song)}>
<p>{song.SongName}</p>
</Button>
</ListGroupItem>
))}
</ListGroup>
</Panel.Body>
</Panel>
))}
</PanelGroup>
I'm assuming you're using React-Bootstrap. Looks like you're missing eventKey:
A unique identifier for the Component, the eventKey makes it distinguishable from others in a set. Similar to React's key prop, in that it only needs to be unique amoungst the Components siblings, not globally.
https://react-bootstrap.github.io/components/panel/#panels-accordion
<PanelGroup accordion id="accordion-example">
<Panel eventKey="1">
...
</Panel>
<Panel eventKey="2">
...
</Panel>
<Panel eventKey="3">
...
</Panel>
</PanelGroup>
Assuming your usernames are unique you can use that value for your eventKey:
<PanelGroup accordion id="accordion-example">
{this.state.allUsersList.map((user, index) => (
<Panel eventKey={user.Username}>
...

admin-on-rest toggle menu (show / hide)

I'm using admin-on-rest in my react application as admin interface.
My problem is the menu, I'm add a DashboardMenuItem to toggle (show/hide) the menu. But I have no idea what the onClick function should look like and I find no example of this in the documentary or somewhere else.
Can anyone help me by giving an example for this?
My Code:
const Menu = ({ hasDashboard, onMenuTap, resources, translate, logout }) => (
<div style={styles.main}>
<WithPermission value='ROLE_SA'>
{hasDashboard && <DashboardMenuItem onClick={onMenuTap} />}
</WithPermission>
{resources
.filter(r => r.list)
.map(resource => (
<MenuItemLink
key={resource.name}
to={`/${resource.name}`}
primaryText={translatedResourceName(resource, translate)}
leftIcon={<resource.icon />}
onClick={onMenuTap}
/>
))}
{/* <MenuItemLink primaryText='Reports' key='reports' to={`/reports`} leftIcon={<UserIcon />} onClick={onMenuTap} /> */}
<WithPermission value='ROLE_SA'>
<SelectField floatingLabelText='Language for Datasets' onChange={LocaleSwitcher}>
<MenuItem value={'de'} primaryText='DE' />
<MenuItem value={'en'} primaryText='EN' />
</SelectField>
</WithPermission>
{logout}
<img src={Logo} style={{maxWidth: '100%', margin: '0 auto'}} />
</div>
)

Reactjs Material UI Tabs label will disappear and will retain logo for smaller screen

So I am new in using Material UI Tabs and I want the labels to disappear when the screen is resized. for example when the screen is in 500px or smaller, the logo will only retain and the label will disappear.
below is the sample code of my material ui Tabs
<Tabs onChange={this.handleChange.bind(this)} value={this.state.status}>
<Tab icon={<FontIcon className="fa fa-cogs" />} label="Process" value='orderProcessing' />
<Tab icon={<FontIcon className="fa fa-money" />} label="Paid" value='orderConfirmed' />
<Tab icon={<FontIcon className="fa fa-industry" />} label="Production" value='onProduction' />
<Tab icon={<FontIcon className="fa fa-shopping-cart" />} label="Qc and Packaging" value={3} />
<Tab icon={<FontIcon className="fa fa-cart-arrow-down" />} label="Sold" value='sold' />
<Tab icon={<FontIcon className="fa fa-ban" />} label="Cancelled" value='cancelled' />
<Tab icon={<FontIcon className="fa fa-globe" />} label="All Transactions" value='' />
</Tabs>
You can accomplish this by using this.isDeviceSize(). Here is an example:
Updated to show one tab with only a label and the other with only the icon when the screen is small. Previously both tabs removed the icons and the question was actually asking how to remove the labels. Now the example below shows how to do either.
import React from 'react'
import {Mixins, Tabs, Tab} from 'material-ui'
const {StylePropable, StyleResizable} = Mixins
import {MapsDirectionsRun} from 'material-ui/lib/svg-icons'
export default React.createClass({
propTypes: {
onChangeMuiTheme: React.PropTypes.func,
},
contextTypes: {
muiTheme: React.PropTypes.object,
},
mixins: [StylePropable, StyleResizable],
render() {
return (
<Tabs>
<Tab
label="Tab 1"
icon={this.isDeviceSize(StyleResizable.statics.Sizes.MEDIUM) ? (<MapsDirectionsRun />) : null}>
Tab 1 content
</Tab>
<Tab
label={this.isDeviceSize(StyleResizable.statics.Sizes.MEDIUM) ? "Tab 2" : null}
icon={<MapsDirectionsRun />}>
Tab 2 content
</Tab>
</Tabs>
)
}
})

Resources