React-router4 display the name in component - reactjs

I use react-router4 and try to display the name of the corresponding label in the commented location. I don't know how to solve this problem.
Does the react-router4 offer a solution to this problem? Can anyone show me how to do it?
Navigation.js:
...
<NavigationButton to="/" label="Dashboard" exact>
<MenuItem className={classes.menuItem}
selected={this.state.selected === "Dashboard"}
onClick={() => {this.setState({selected: "Dashboard"})}}>
<ListItemIcon className={classes.icon}>
<Home/>
</ListItemIcon>
<ListItemText classes={{primary: classes.primary}} inset primary="Dashboard"/>
</MenuItem>
</NavigationButton>
<NavigationButton to="/payment" label="Payment" exact>
<MenuItem className={classes.menuItem}
selected={this.state.selected === "Payment"}
onClick={() => {this.setState({selected: "Payment"})}}>
<ListItemIcon className={classes.icon}>
<Payment/>
</ListItemIcon>
<ListItemText classes={{primary: classes.primary}} inset primary="Moje płatności"/>
</MenuItem>
</NavigationButton>
...
Header:
...
<div className={classes.root}>
<div className={classes.appFrame}>
<AppBar
className={classNames(classes.appBar, {
[classes.appBarShift]: open,
[classes[`appBarShift-left`]]: open,
})}
>
<Toolbar disableGutters={!open} className={classes.toolBar}>
<IconButton
color="inherit"
aria-label="Open drawer"
onClick={this.handleDrawerToggle}
className={classNames(classes.menuButton, open)}
>
<MenuIcon />
</IconButton>
<Typography variant="h6" color="inherit" noWrap>
{/* print "Dashboard" when I choose Dashboard, or print "Payment" when I choose payment in Navigation.js. */}
</Typography>
</Toolbar>
</AppBar>
{before}
<main
className={classNames(classes.content, classes[`content-left`], {
[classes.contentShift]: open,
[classes[`contentShift-left`]]: open,
})}
>
<div className={classes.drawerHeader} />
<Switch>
<Route exact path="/" component={DashboardComponent} />
<Route exact path="/payment" component={PaymentComponent} />
<Redirect to="/" />
</Switch>
</main>
</div>
</div>
...
I use react-router4 and try to display the name of the corresponding label in the commented location. I don't know how to solve this problem.
Does the react-router4 offer a solution to this problem? Can anyone show me how to do it?

The approach is not right to display label of current component name with react-router as this will be an issue when it's a default export without even having a name. So it would be better to maintain a const LABEL = { ... } // all label with pathname as keys
So you can match this.props.location.pathname with your LABEL const object to display it properly.
const LABEL = {
dashboard : 'Dashboard',
home: 'Home'
}
in you render:
<Typography variant="h6" color="inherit" noWrap>
{LABEL[this.props.location.pathname]}
</Typography>
I hope this would help, Ask any questions if it doesn't help

Related

Conditional rendering of parent component in React

I need to return either Porover or Card depending on the condition with the same children content. This can be done by taking the children content into a separate component and returning it like this:
true ? <Popover><ChildrenContent props={props}/></Popover>
: <Card><ChildrenContent props = {props}/></Card>
But it seems to me that this is not the best solution in this case
<Popover dataCy="complexValidation">
<Section marginBottom={3}>
</Section>
<Flex flexDirection="column" gap={3}>
{validations.map((validation) => (
<Flex.Item key={validation.text}>
<Flex alignItems="center">
<Icon name="check_circle" size="large" color={validation.isSuccess ? 'positive' : 'negative'} />
<Flex.Item>
<Typography variant="bodyText2" component="span">
{validation.text}
</Typography>
</Flex.Item>
</Flex>
</Flex.Item>
))}
</Flex>
</Popover>

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>
)

Adding specific items to a generic component in React

I have main and common top Navigation Bar (TopMenu) and a body that corresponds to different modules.
/* App.js */
render() {
if (this.props.appLoading) return <Container />;
return (
<Container className="App" fluid>
<TopMenu menuStyle={menuStyle} />
<BodyContainer />
</Container>
);
}
Each module has a bunch of menu items that need to be displayed on the common Top navigation when that module loads.
/* TopMenu.js */
render() {
return (
<Menu
fixed="top"
inverted
secondary
stackable
style={this.props.menuStyle}
>
<Menu.Item as={Link} to="/" header>
<Logo />
</Menu.Item>
{ /* Module 1 Menu Items */ }
{this.props.isAuthenticated && this.props.module==='market' && (
<Menu.Menu position="left">
<Menu.Item style={{ width: '30rem' }}>
<AutoCompleteContainer />
</Menu.Item>
<Menu.Item>
<Icon name="empty star" />
</Menu.Item>
<Menu.Item>
<Icon name="line chart" />
</Menu.Item>
<Menu.Item>
<Icon name="remove bookmark" />
</Menu.Item>
<Menu.Item>
<Icon name="lock" />
</Menu.Item>
</Menu.Menu>
)}
{ /* Module 2 Menu Items */ }
{ /* Module x Menu Items */ }
<Menu.Menu position="right">
{!this.props.isAuthenticated && notAuthenticatedMenuItems}
{this.props.isAuthenticated && (
<Menu.Item>
<ProfileDropdown onSignOut={this.props.onLogOut} />
</Menu.Item>
)}
</Menu.Menu>
</Menu>
);
}
}
Clearly, having a common top navigation is making it very difficult to have all the show/hide menu items related to each module in one place. This is because there will be lot of code in one file and also, the navigation will hold the logic for showing/displaying items related to each module, which is against best practices.
My question, is how can I structure the project/code, so that I reuse the common top navigation while each module loads the required menu items when that module loads? Is there a "Extension Point" concept in React where the common top navigation bar provides an extension point for the modules to plug-in their respective items.
You could make the top generic menu as a component and then pass your respective seperate menu items as children to this Navigation component
class TopMenu extends React.Component {
render() {
return (
<Menu
fixed="top"
inverted
secondary
stackable
style={this.props.menuStyle}
>
<Menu.Item as={Link} to="/" header>
<Logo />
</Menu.Item>
{this.props.children}
<Menu.Menu position="right">
{!this.props.isAuthenticated && notAuthenticatedMenuItems}
{this.props.isAuthenticated && (
<Menu.Item>
<ProfileDropdown onSignOut={this.props.onLogOut} />
</Menu.Item>
)}
</Menu.Menu>
</Menu>
);
}
}
}
and use it as
<Container className="App" fluid>
<TopMenu menuStyle={menuStyle}>
{ /* Module 1 Menu Items */ }
{this.props.isAuthenticated && this.props.module==='market' && (
<Menu.Menu position="left">
<Menu.Item style={{ width: '30rem' }}>
<AutoCompleteContainer />
</Menu.Item>
<Menu.Item>
<Icon name="empty star" />
</Menu.Item>
<Menu.Item>
<Icon name="line chart" />
</Menu.Item>
<Menu.Item>
<Icon name="remove bookmark" />
</Menu.Item>
<Menu.Item>
<Icon name="lock" />
</Menu.Item>
</Menu
</TopMenu>
<BodyContainer />
</Container>
Similarly you could use it at other places as well

Open nested menu in main menu - material-ui (react)

(I don't have enough reputation to post more than 2 links, therefore I am writitng out the URLS)
In material-ui (w*w.material-ui.com) I can program nested menus and dropdown menus. But I haven`t found an example to open the nested menus in the main menu.
With nested menus and dropdown menus the nested menus open every time as a new window beside or above the main menu. Like this example: Menu with nested menu opened to the right
But I would like to have the nested menus opened in the main menu. Like this example:
Nested menus open in main menu
Can someone please show me an example how to achieve this.
Thanks
You're using the wrong component. Use a List with ListItems that have NestedItems
<List>
<Subheader>Nested List Items</Subheader>
<ListItem primaryText="Sent mail" leftIcon={<ContentSend />} />
<ListItem primaryText="Drafts" leftIcon={<ContentDrafts />} />
<ListItem
primaryText="Inbox"
leftIcon={<ContentInbox />}
initiallyOpen={true}
primaryTogglesNestedList={true}
nestedItems={[
<ListItem
key={1}
primaryText="Starred"
leftIcon={<ActionGrade />}
/>,
<ListItem
key={2}
primaryText="Sent Mail"
leftIcon={<ContentSend />}
disabled={true}
nestedItems={[
<ListItem key={1} primaryText="Drafts" leftIcon={<ContentDrafts />} />,
]}
/>,
<ListItem
key={3}
primaryText="Inbox"
leftIcon={<ContentInbox />}
open={this.state.open}
onNestedListToggle={this.handleNestedListToggle}
nestedItems={[
<ListItem key={1} primaryText="Drafts" leftIcon={<ContentDrafts />} />,
]}
/>,
]}
/>
</List>

How to specify an anchor for material-ui card title?

I have a simple Card in material-ui:
<Card>
<CardHeader
title={this.props.series.name} />
</Card>
And I would like to have the title be a link to a URL that I pass in via a property. I looked at the JSX source for the card header, but I cannot figure out how to make this happen.
<CardHeader
avatar={
<Avatar aria-label={placeData.type} className={classes.avatar}>
<PlaceTypeIcon type={placeData.type} />
</Avatar>
}
action={
<IconButton href={gMapUrl} aria-label="maps">
<MapOutlinedIcon />
</IconButton>
}
title={placeData.title}
subheader={placeData.street}
/>
putting it in the action prop also works fine
The simplest way to do it is to just put an a tag inside the title attribute of CardHeader:
<CardHeader
action={
<IconButton>
<MoreVertIcon />
</IconButton>
}
title={
<Link to={url}>{props.name}</Link> //similarly use `a` if not using react-router
}
// For making an avatar link
avatar={
<Avatar component={Link} to={url} aria-label={props.name} className={classes.avatar}>
A
</Avatar>
}
subheader={props.subheader}
/>
There seems no provision to make header as <a> from sourcecode.
But there are some hacks which you can use to get things working
pass <a href=''> as value to that prop
listen to click event and fire transitionTo to change the route.
This here worked for me, I just put a Material UI Link inside of the CardHeader subheader.
<CardHeader
avatar={
<Avatar aria-label={placeData.type} className={classes.avatar}>
<PlaceTypeIcon type={placeData.type} />
</Avatar>
}
title={placeData.title}
subheader={
<Link className={classes.link} href={gMapUrl}>
{placeData.street}
</Link>
}
/>
If making it an <a href={} /> does not work, I am sure this will:
<Card>
<CardHeader title={this.props.series.name} onClick={this.props.series.link} style={linkStyle}/>
</Card>
And assign a custom linkStyle that would make the <CardHeader/> look like a link.
This worked for me.
<CardTitle title={renderHTML('TITLE' )}/>
You can use same method for subtitle as well.

Resources