MUI GridActionsCellItem as prop - reactjs

I created a ListView component for my admin page which is responsible for showing, editing and deleting data. I would like to add extra features for some of the pages. I'm using the MUI DataGrid component.
In the ListView DataGrid I have the "actions" column:
field: "manage",
headerName: "Manage",
sortable: false,
type: "actions",
getActions: (params) => [
<GridActionsCellItem
icon={<DeleteIcon/>}
onClick={() => {
setCurrent(params.row["id"])
setDeletePopupOpen(true)
}}
label="Törlés"
showInMenu={true}
/>,
<GridActionsCellItem
icon={<EditIcon/>}
onClick={() => {
setCurrent(params.row["id"])
setEditPopupOpen(true)
}}
label="Szerkesztés"
showInMenu={true}
/>
],
For example from the reservations page I would like to add an extra GridActionsCellItem so I added this to the getActions list:
extraColActions.map(action =>
<GridActionsCellItem
icon={action.icon}
onClick={() => {action.onClick(params.row['id'])}}
label={action.label}
showInMenu={true}
/>)
Now I have these two errors:
Uncaught TypeError: Cannot read properties of undefined (reading 'showInMenu')
The above error occurred in the component
The extraColActions is a prop to the ListView component, and I need that because I want to use the params variable to keep track of the row I click.
From the parent (reservations) component I have this list:
const extraColActions = [
{
icon: <CheckIcon/>,
onClick: (id) => {
// setAcceptReservationOpen(true)
console.log(id)
},
label: "Foglalás elfogadása",
},
]

Related

AntD Tree: need help! can't pass react element as icon OR title for antd tree

I'm using the AntD tree and I have a react element that I want to pass as either an icon or a title because it has custom styling. Due to it being IP I can't share too much code, but my question is:
how can I pass a react element (see below i.e. generic name) as either a title or icon and have antD tree render it?
i.e. this is what I want to pass as a prop to the icon or title
import React from 'react';
const genericName = (props) => {
// code uses props to get some infor for Color
// cant share code due to proprietary reasons
// but it is not needed for this question
const colorHTML = getColor(Color);
return (
<div>
<div className={`colors from`}>${colorHTML}</div>
{pin}
</div>
);
};
export default genericName;
in my console you can see node.icon is a typeof react.element. I want to target that and just pass the prop into antD tree as either title or icon
i.e.
return (
<Tree
icon={node.icon}
/>
)
I've searched and similar answers were given before antD forbid the use of children and strictly allows treeData. All examples I see only use strings in titles/icons, but since antD documentation is very limited, I need to know if my use case is possible. Right now, for the life of me I can't understand why it doesn't populate.
Thank you in advance.
It should definitely work to put a JSX component as title within treeData. Take a look at this snippet, I added a Icon here in one of the titles:
import React from 'react'
import { RightCircleOutlined } from '#ant-design/icons'
type Props = {}
import { Tree } from 'antd';
import type { DataNode, TreeProps } from 'antd/es/tree';
const treeData: DataNode[] = [
{
title: <span>{<RightCircleOutlined />} parent</span>, //icon added here
key: '0-0',
children: [
{
title: 'parent 1-0',
key: '0-0-0',
disabled: true,
children: [
{
title: 'leaf',
key: '0-0-0-0',
disableCheckbox: true,
},
{
title: 'leaf',
key: '0-0-0-1',
},
],
},
{
title: 'parent 1-1',
key: '0-0-1',
children: [{ title: <span style={{ color: '#1890ff' }}>sss</span>, key: '0-0-1-0' }],
},
],
},
];
const Demo: React.FC = () => {
const onSelect: TreeProps['onSelect'] = (selectedKeys, info) => {
console.log('selected', selectedKeys, info);
};
const onCheck: TreeProps['onCheck'] = (checkedKeys, info) => {
console.log('onCheck', checkedKeys, info);
};
return (
<Tree
checkable
defaultExpandedKeys={['0-0-0', '0-0-1']}
defaultSelectedKeys={['0-0-0', '0-0-1']}
defaultCheckedKeys={['0-0-0', '0-0-1']}
onSelect={onSelect}
onCheck={onCheck}
treeData={treeData}
/>
);
};
export default Demo;

I don't get the expected value of a react props in child component

I'm trying to manage some clients in a react js application (that I'm maintaining), it was first written in classes components but I'm now adding a functional child component and im not sure if this is the source of the problem or not (react-table examples only use functional component)
I have a main component that will do the data GET from a rest API and save it in state "entries" then I passe it to a child component as a props to render the data in a react-table, the problem is in this section as I have some buttons to edit and delete the data in react-modal, when I try access the props.entries after the buttons clicks I have an empty array of props.entries.
Here's the sandbox of the issue : https://codesandbox.io/s/stale-prop-one-forked-r6cevx?file=/src/App.js
I did a console.log when the delete button is clicked, and you can see that en entries array is empty.
You need to pass the showEditModal & showEditModal in useMemo dependency array. Since you dependency array is empty, when you click on edit or delete, it just points to the old function reference and it have the old entries value.
You can check the entries values by console.log.
Hope this solve your problem
const showEditModal = useCallback(
(client_id) => {
const tmpClient = props.entries.filter(function (el) {
return el._id === client_id;
})[0];
setClient(tmpClient);
setEditModal(true);
console.log('aaa', props);
console.log(client_id);
console.log(props.entries);
console.log(tmpClient);
},
[props.entries]
);
const showDeleteModal = useCallback(
(client_id) => {
console.log('showDeleteModal entries : ', entries);
const tmpClient = entries.filter(function (el) {
return el._id === client_id;
})[0];
setClient(tmpClient);
setDeleteModal(true);
console.log('Delete', entries);
console.log(client_id);
console.log(tmpClient);
},
[props.entries]
);
const columns = React.useMemo(
() => [
{
Header: 'fact',
accessor: 'fact'
},
{
Header: 'Actions',
accessor: 'length',
Cell: ({ cell }) => (
<>
{cell.row.values.length}
<Tooltip title='Supprimer' placement='top'>
<IconButton
variant='outlined'
id={cell.row.values._id}
onClick={() => showDeleteModal(cell.row.values.length)}
>
<DeleteIcon />
</IconButton>
</Tooltip>
<Tooltip title='Modifier' placement='top'>
<IconButton
variant='outlined'
id={cell.row.values.length}
onClick={() => showEditModal(cell.row.values.length)}
>
<EditIcon />
</IconButton>
</Tooltip>
</>
)
}
],
[showEditModal, showDeleteModal]
);

Update state of a react component when language is changed

I have created a custom table component I forked from ant design. I reuse it in all my components, It takes an array of all columns and renders it. I pass columns as a prop called initialColumns.
My issue is whenever the user changes the language, the table contents is re rendering but not the columns which I passed, they don't get translated, How would I force a rerender when the language is changed.
custom table component
const TableComponent = (props) => {
const { initialColumns, dataSource, handleClick } = props
return ( <Table
columns={colmenu.visibleColumns}
dataSource={dataSource}
size="small"
pagination={{
pageSizeOptions: ['10', '20', '50'],
showSizeChanger: true,
}}
/>)
}
Parent component, here I call my TableComponent as pass it columns
It looks something like this:
const columns = [
{
title: t.status,
dataIndex: 'status',
key: 'status',
sorter: (a, b) => a.status.localeCompare(b.status),
...GetColumnSearchProps(['status']),
className: 'text-center',
checked: true,
},
.
.
.
.
here is how I get the translated files
const { messages: t } = useIntl()
and this is the render method:
<TableComponent
initialColumns={columns}
dataSource={data}
handleClick={addModal}
title="AABC"
/>
So how would I update the initialColumns prop when the language is changed?

How to disable the button once clicked in antd table?

Getting the table values through props. The claim update function is working fine, but the record still there. once I refresh or select another tab only after that the claimed record will be removed.
{
title: 'Action',
dataIndex: 'action',
render: (text, record) =>
<Button class="claimBom-btn" onClick={(e) => this.handleClaim(e,text, record)} ><Icon type="plus-circle" />Claim</Button>
}
This the button call for all record in the table
Just pass along the button state in the datasource.
When it is clicked mutate the datasource.
const [datasource, setDatasource] = useState([
{
disabled: false,
// others properties
}
]);
// On button click find the data and change disabled property
const onClick = (id) => {
const source = datasource.find(source => source.id === id);
source.disabled = true;
setDatasource(datasource);
}
{
title: 'Action',
dataIndex: 'action',
render: (text, record) =>
<Button disabled={text.disabled} class="claimBom-btn" onClick={(e) => this.handleClaim(e,text, record)} ><Icon type="plus-circle" />Claim</Button>
}
You can simply pass the disabled prop to the button accordingly. When calling this.handleClaim, set a state of which button should be disabled while handling, and pass that as a disabled prop to the button.

Unable to overwrite css top property in prime react menu component

I'm trying to get rid of the space as shown in the image below:
I'm using the Menu component of primereact from this documentation
Here's my constructor code for reference:
constructor() {
super();
this.state = {
items: [
{
label: 'First Services',
items: [
{label: 'firstitem',
command: (event) => {window.open('http://someurl','_blank');}},
{label: 'firstitemname',
command: (event) => {window.open('http://someurl#get-firstitemname','_blank');}},
{label: 'firstcategoryname',
command: (event) => {window.open('http://someurl#get-firstcategoryname','_blank');}},
]
},
{
label: 'Second Services',
items: [
{label: 'testforuser ',
command: (event) => {window.open('http://someurl#get-testforuser','_blank');}},
{label: 'testforproject',
command: (event) => {window.open('http://someurl#get-testforproject','_blank');}},
{label: 'testforprotocol ',
command: (event) => {window.open('http://someurl#get-testforprotocol','_blank');}}
]
},
{
label: 'Workflows ',
items: [
{label: 'Workflow for User ',
command: (event) => {window.open('http://someurl#workflow-section','_blank');}}
]
},
]
};
}
And here's my Menu and Button component defined:
<Menu
model={this.state.items}
popup={true}
style={{fontSize:'16px'},{width:'12%'}}
ref={el => this.menu = el}
/>
<Button
label="My DropDown Menu"
icon="pi pi-bars"
style={{width:'12%'},{backgroundColor:'#000000'}}
onClick={
(event)=>this.menu.toggle(event)
}
/>
I figured out the reason why there's space between the Button and the Menu. When I right clicked on the MY DROPDOWN MENU and selected Inspect Element Q on my Firefox browser, I saw the following-the css top property is set to 118.5px. :
I'm trying to overwrite the top property and change it to 60px from 118.5px. For that I tried modifying my code like this:
<Menu
model={this.state.items}
popup={true}
style={{fontSize:'16px'},{width:'12%'},{marginTop:'60px'}}
ref={el => this.menu = el}
/>
But it ended up showing as a separate property like this:
How can I modify top property?
Top and margin-top are 2 different things in CSS.
style={{
top:'60px'
}}
CSS: Top vs Margin-top
First check what classes are being used by the primereact menu, using console, then make a .css file and import into your .js file. Write the same name of the class as you found out using console and then override the properties you want. Then run your app again. It should work. P.S. I tried this before and this worked for me.

Resources