<div>
<Button onClick={() => this.setState({ show: true })}>Open</Button>
<Modal
show={this.state.show}
onHide={() => this.setState({ show: false })}
animation={true}
>
<Modal.Header closeButton>
<Modal.Title>Modal</Modal.Title>
</Modal.Header>
<Modal.Body>
<TimePicker open getPopupContainer={triggerNode => triggerNode.parentNode}/>
<div style={{ height: '370px' }} />
</Modal.Body>
</Modal>
</div>
With animation enabled, it becomes https://i.imgur.com/0r1aULs.png
Without animation: https://i.imgur.com/YTdF8rT.png
Any clue how to fix it?
Related
This question expands on my problem which got partially solved here. I have two components, ApplicationOverview.js and ApplicationModal.jsx and I want to dynamically add div panels to the ApplicationOverview.js Component from the Modal. In the Modal I have two input fields and I can add an image, which will be displayed on the div after I clicked on the 'Add' button. This is what the Modal looks like and this is what I am trying to achieve with n number of panels. (Note that the first 3 panels are hard coded)
So far, I can add a single div panel to my page, but whenever I try to add another one, it just changes the text of the panel that I just added. I am currently just toggling the visibility of that single div I am adding with a boolean (as you can see on the bottom of ApplicationOverview.js), but I can't figure out how I'd add multiple divs from my Modal to the page. Also, when I close the Modal but type something into the input fields, the text on the added div will still change without clicking on 'Add' beforehand.
ApplicationModal.jsx:
import React from "react";
var name = "";
var comment = "";
var filename = "";
const ApplicationModal = ({
setOpen,
setState,
setStateComment,
setFile,
file,
setBool,
}) => {
React.useEffect(() => {
function handleEscapeKey(event) {
if (event.code === "Escape") {
setOpen(false);
}
}
document.addEventListener("keydown", handleEscapeKey);
return () => document.removeEventListener("keydown", handleEscapeKey);
});
const handleComment = (e) => {
setStateComment(e.target.value);
};
const handleChange = (e) => {
setState(e.target.value);
};
const addNewApplication = () => {
setBool(true);
setOpen(false);
};
function openDialog() {
document.getElementById("inputUpload").click();
}
function loadFile(e) {
console.log(e.target.files);
setFile(URL.createObjectURL(e.target.files[0]));
}
document.addEventListener("click", function (e) {});
return (
<React.Fragment>
<div className="modalDark" style={{ paddingRight: "250px" }}>
<div class="modal-dialog">
<div class="modal-content" style={{ width: "800px" }}>
<div class="modal-close">
<div class="module-button" style={{ left: "750px" }}>
<button
class="btn btn-link "
onClick={() => setOpen(false)}
></button>
<div class="button-animation"></div>
<div class="button-content new">
<i class="icon icon-dc_close"></i>
</div>
</div>
</div>
<div class="modal-header">
<h3>Add new Application</h3>
</div>
<div class="modal-body">
<div
class="module-input form-group has-placeholder"
data-plugin="moduleInput"
style={{ bottom: "60px", width: "350px" }}
>
<label for="demo-default">Customer Name</label>
<div class="input-animation-wrapper">
<input
type="text"
id="demo-default"
class="form-control "
maxLength="42"
placeholder="[Application Name]"
onChange={(e) => handleChange(e)}
/>
<div class="input-animation"></div>
</div>
</div>
<div
class="module-textarea form-group floating-label has-placeholder"
data-plugin="moduleInput"
style={{ bottom: "60px" }}
>
<label for="demo-3">Customer Short text</label>
<div class="input-animation-wrapper" style={{ width: "350px" }}>
<textarea
id="demo-3"
class="form-control"
rows="9"
placeholder="Short description of Customer; max. 280 characters"
maxLength={180}
onChange={(e) => handleComment(e)}
style={{ width: "350px" }}
></textarea>
<div class="label-area"></div>
<div class="input-animation"></div>
</div>
</div>
<img
class="image"
alt="Customer Logo"
id="logo"
src={file}
style={{
left: "420px",
bottom: "280px",
position: "absolute",
height: "250px",
}}
/>
<div
class="module-button"
style={{
left: "500px",
bottom: "200px",
position: "absolute",
zIndex: "1",
}}
>
<button
type="file"
class="btn btn-light"
onClick={() => openDialog()}
id="fileUpload"
>
<input
type="file"
hidden={true}
accept="image/*"
id="inputUpload"
onChange={(e) => loadFile(e)}
></input>
</button>
<div class="button-animation"> </div>
<div class="button-content">
<span class="content-text">Upload Logo</span>
</div>
</div>
<div
class="module-button"
style={{ bottom: "50px", width: "100px", textAlign: "center" }}
>
<button
type="button"
class="btn btn-secondary btn"
onClick={() => addNewApplication()}
id="adding"
></button>
<div class="button-animation"></div>
<div class="button-content">
<span class="content-text">Add</span>
</div>
</div>
</div>
</div>
</div>
</div>
</React.Fragment>
);
};
export default ApplicationModal;
export { name, comment, filename };
ApplicationOverview.js:
import React from "react";
import "../Overview.css";
import ApplicationModal from "../components/ApplicationModal.jsx";
var id = 0;
const ApplicationOverview = () => {
const [open, setOpen] = React.useState(false);
const [state, setState] = React.useState("");
const [stateComment, setStateComment] = React.useState("");
const [file, setFile] = React.useState("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3f/Placeholder_view_vector.svg/681px-Placeholder_view_vector.svg.png");
const [bool, setBool] = React.useState(false);
function addID()
{
id++;
console.log(id)
return id;
}
return (
<div id="wrapper">
{open && <ApplicationModal setOpen={setOpen} setState={setState} file={file} setBool={setBool} setFile={setFile} setStateComment={setStateComment} />}
<div class="component-headline">
<h4 style={{ color: "gray", display: "inline" }}>
Application overview
</h4>
<div
class="module-button"
style={{
backgroundColor: "rgb(18,205,212,255)",
borderRadius: "12px",
marginLeft: "1032px",
}}
onClick={() => setOpen(true)}
>
<button type="button" class="btn btn-secondary"></button>
<div class="button-animation"></div>
<div
class="button-content"
style={{
backgroundColor: "rgb(18,205,212,255)",
borderRadius: "12px",
}}
>
<span class="content-text" style={{ color: "black" }}>
Add Application
</span>
</div>
</div>
</div>
<hr style={{ marginTop: "-20px" }} />
<div class="center-content" id="center">
<div class="overview-box">
<img
class="image"
src="https://st.depositphotos.com/1968353/2535/i/600/depositphotos_25357041-stock-photo-close-up-of-machine-gears.jpg"
alt="car"
/>
<div class="box-content">
<h3 class="overview-h3">Press</h3>
<p class="overview-p">This Application is used for maintenance</p>
<h3 class="overview-h3-second">Connected Products</h3>
<h1 class="overview-h1-second">
?/?
<p class="overview-p-second">Online</p>
</h1>
<div class="module-button" id="configure">
<button type="button" class="btn btn-secondary"></button>
<div class="button-animation"></div>
<div class="button-content">
<span class="content-text">Configure</span>
</div>
</div>
</div>
</div>
<div class="overview-box">
<img
class="image"
src="https://st.depositphotos.com/1968353/2535/i/600/depositphotos_25357041-stock-photo-close-up-of-machine-gears.jpg"
alt="car"
/>
<div class="box-content">
<h3 class="overview-h3">Tooling Machine</h3>
<p class="overview-p">
This Application is used for drilling records
</p>
<h3 class="overview-h3-second">Connected Products</h3>
<h1 class="overview-h1-second">
?/?
<p class="overview-p-second">Online</p>
</h1>
<div class="module-button" id="configure">
<button type="button" class="btn btn-secondary"></button>
<div class="button-animation"></div>
<div class="button-content">
<span class="content-text">Configure</span>
</div>
</div>
</div>
</div>
<div class="overview-box">
<img
class="image"
src="https://st.depositphotos.com/1968353/2535/i/600/depositphotos_25357041-stock-photo-close-up-of-machine-gears.jpg"
alt="car"
/>
<div class="box-content">
<h3 class="overview-h3">Storing Unit</h3>
<p class="overview-p">
This Application is used for store parameters
</p>
<h3 class="overview-h3-second">Connected Products</h3>
<h1 class="overview-h1-second">
?/?
<p class="overview-p-second">Online</p>
</h1>
<div class="module-button" id="configure">
<button type="button" class="btn btn-secondary"></button>
<div class="button-animation"></div>
<div class="button-content">
<span class="content-text">Configure</span>
</div>
</div>
</div>
</div>
{(stateComment || state) && bool && <div class='overview-box' id={addID()}> <img class='image' src={file} alt='car'/> <div class='box-content'><h3 class='overview-h3' id='new-headline'>{state}</h3> <p class='overview-p'>{stateComment}</p><h3 class='overview-h3-second'>Connected Products</h3><h1 class='overview-h1-second'> ?/? <p class='overview-p-second'>Online</p> </h1> <div class='module-button' id='configure'> <button type='button' class='btn btn-secondary'></button> <div class='button-animation'></div> <div class='button-content'> <span class='content-text'>Configure</span> </div> </div> </div> </div> }
</div>
</div>
);
};
export default ApplicationOverview;
So if I understand your problem is that you have a modal and when you fill the modal and send add it will add the text and images to ApplicationOverview. I think you want to be able to do that several times. You want your users to be able to complete the modal again and again so it keep adding at the bottom of the ApplicationOverview.
So you need your ApplicationModal to have its own state.
const [modalState, setModalState] = useState("");
const [modalCommentState, setCommentModalState] = useState("");
const [modalFile, setModalFile] = useState("");
so your handler function should be
const handleComment = (e) => {
setCommentModalState(e.target.value);
};
const handleChange = (e) => {
setModalState(e.target.value);
};
function loadFile(e) {
setModalFile(URL.createObjectURL(e.target.files[0]));
}
Your submit function
const addNewApplication = () => {
setOpen(false);
setStates( oldArray => [...oldArray, {
state:modalState,
stateComment:modalCommentState,
file: modalFile } ]);
};
in the ApplicationOverview.js
const [states, setStates] = useState([]);
in your HTML section you loop through the state with a map
{ states.map((state)=> {
return (
<div class='overview-box' id={addID()}>
<img class='image' src={state.file} alt='car'/>
<div class='box-content'>
<h3 class='overview-h3' id='new-headline'>{state.state}</h3>
<p class='overview-p'>{state.stateComment}</p>
<h3 class='overview-h3-second'>Connected Products</h3>
<h1 class='overview-h1-second'> ?/? <p class='overview-p-second'>Online</p></h1>
<div class='module-button' id='configure'>
<button type='button' class='btn btn-secondary'></button>
<div class='button-animation'></div>
<div class='button-content'>
<span class='content-text'>Configure</span>
</div>
</div>
</div>
</div>
})}
So everytime the user submit the modal it will get added to the array of states and it will be display in the ApplicationOverview
How can I get a flex container on a same line rather than taking up a whole new row like when I have a logo on the left end of the page and wants to add a flex container to its right but even when I use inline-flex it still takes up a whole new row and I'm not very sure how I can implement the way Ive in my mind. I've attached a pic for reference regarding the same. Also I"m using tailwind css to style in a react based project so my code has elements that require other routings and paths to be viewed properly but the html part of the code is what I have attached below along with the styling I used.
How I intend to implement but instead how its being implemented
<div>
<body class="box-border m-0 p-0">
<header>
{user?(
<div>
<Link to="/main"><img class="ml-4 mt-8 w-48 bg-yellow-600" src={WorxaImg} alt="logo" /></Link>
<div class="inline-flex bg-red-700 flex-wrap w-[320px] gap-5">
<div class="self-start ">
<input class="bg-green-600 ml-4 w-[10vw] " type="text" placeholder="Search" value={value} onChange={onChange}/> {/* <label>Location {location}</label> */} {/* <button onClick={()=> onSearch(value)} className="ui primary button">search</button> */}
</div>
<div>
<select class="ml-6 mr-20" type="text" placeholder="Location" name='location' id='location' value={location} onChange={onChangeLocation}>
<option value="">Select your option</option>
{ locations.map((location,i)=>{ return(
<option>{location.city}</option>
) }) }
</select>
</div>
{jobs .filter((item) => { const searchTerm = value.toLowerCase(); const fullName = item.catogory.toLowerCase(); return ( searchTerm && fullName.startsWith(searchTerm) && fullName !== searchTerm ); }) .slice(0, 10) .map((item) => (
<Link to={ '/main/'+item.catogory}> {item.catogory}
<div onClick={()=> onSearch(item.catogory)} key={item.catogory}>
<Link to={ '/main/'+item.catogory}> {item.catogory}</Link>
</div>
</Link>
))} {worker .filter((item) => { const searchTerm = value.toLowerCase(); const fullName = item.name.toLowerCase(); return ( searchTerm && fullName.startsWith(searchTerm) && fullName !== searchTerm ); }) .slice(0, 10) .map((item) => (
<Link to={ '/main/'+item.job+ '/'+item._id}>
<div onClick={()=> onSearch(item.name)} key={item.name}>
<Link to={ '/main/'+item.job+ '/'+item._id}> {item.name},{item.job}{item.sjob!=='none'?','+item.sjob:''}</Link>
</div>
</Link>
))}
<div>
<Link to='/registerworker'><i>{(user.type==="employee")?(<div >Update Worker</div>):(<div class="bg-pink-700"> Test</div>)}</i></Link>
</div>
<div>
<button class="bg-yellow-600" onClick={onLogout}>
<i>Sign out</i>
</button>
</div>
<div>
<Link to='/profile'><i class="bg-green-700">Profile</i></Link>
</div>
</div>
</div>
Try to use flex flex-row to outermost div but inside of <body>.
Below is the code, see whether it works or not for you.
<div>
<body class="box-border m-0 p-0">
<header>
{user?(
<div class="flex flex-row space-x-5">
<Link to="/main"><img class="ml-4 mt-8 w-48 bg-yellow-600" src="http://commondatastorage.googleapis.com/codeskulptor-aets/week5-triangle.png" alt="logo" /></Link>
<div class="flex bg-red-700 flex-wrap w-[320px] gap-5">
<div class="self-start">
<input class="bg-green-600 ml-4 w-[10vw] " type="text" placeholder="Search" value={value} onChange={onChange}/> {/* <label>Location {location}</label> */} {/* <button onClick={()=> onSearch(value)} className="ui primary button">search</button> */}
</div>
<div>
<select class="ml-6 mr-20" type="text" placeholder="Location" name='location' id='location' value={location} onChange={onChangeLocation}>
<option value="">Select your option</option>
{ locations.map((location,i)=>{ return(
<option>{location.city}</option>
) }) }
</select>
</div>
{jobs .filter((item) => { const searchTerm = value.toLowerCase(); const fullName = item.catogory.toLowerCase(); return ( searchTerm && fullName.startsWith(searchTerm) && fullName !== searchTerm ); }) .slice(0, 10) .map((item) => (
<Link to={ '/main/'+item.catogory}> {item.catogory}
<div onClick={()=> onSearch(item.catogory)} key={item.catogory}>
<Link to={ '/main/'+item.catogory}> {item.catogory}</Link>
</div>
</Link>
))} {worker .filter((item) => { const searchTerm = value.toLowerCase(); const fullName = item.name.toLowerCase(); return ( searchTerm && fullName.startsWith(searchTerm) && fullName !== searchTerm ); }) .slice(0, 10) .map((item) => (
<Link to={ '/main/'+item.job+ '/'+item._id}>
<div onClick={()=> onSearch(item.name)} key={item.name}>
<Link to={ '/main/'+item.job+ '/'+item._id}> {item.name},{item.job}{item.sjob!=='none'?','+item.sjob:''}</Link>
</div>
</Link>
))}
<div>
<Link to='/registerworker'><i>{(user.type==="employee")?(<div >Update Worker</div>):(<div class="bg-pink-700"> Test</div>)}</i></Link>
</div>
<div>
<button class="bg-yellow-600" onClick={onLogout}>
<i>Sign out</i>
</button>
</div>
<div>
<Link to='/profile'><i class="bg-green-700">Profile</i></Link>
</div>
</div>
</div>
</header>
</body>
</div>
The issue: My first table bugtracker_table on dashboard.js works fine when I submit data to it but my second table ticket_table on projects.js do not submit values even though it's pretty much the same code.
I even have the terminal that says: Executing (default): INSERT INTO ticket_table (id,ticket_title,ticket_description,type_menu,priority_menu,status_menu,createdAt,updatedAt) VALUES (DEFAULT,?,?,?,?,?,?,?);
But there is no data in table.
Dashboard.js
import React, { useState, useEffect } from "react";
import { DataTable } from "primereact/datatable";
import { Column } from "primereact/column";
import { Button } from "primereact/button";
// import ButtonDemo from './ButtonDemo';
import { Chart } from "primereact/chart";
import { InputText } from "primereact/inputtext";
import { InputTextarea } from "primereact/inputtextarea";
import { Modal, ModalFooter, ModalHeader } from "react-bootstrap";
import axios from "axios";
import { useHistory, Link } from "react-router-dom";
// import { Media } from "react-bootstrap/Media"
// import ProjectsTable from "./Tables/ProjectsTable";
// import TicketsPieChart from "./Tables/TicketsPieChart"
// import API from
//project table
//eslint-disable no-unused-vars
const TableDemo = () => {
// const toggle = () => {setShow(!show);}
const [project_name, setProjectName] = useState("");
const [description, setDescription] = useState("");
const [projects, setProjects] = useState([]);
const history = useHistory();
const projectsToShow = projects.map((project) => {
return {
...project,
project_name: <Link to={`/projects/${project.id}`}>{project.project_name}</Link>,
};
});
useEffect(() => {
getProjects();
}, []);
const getProjects = async () => {
const response = await axios.get("http://localhost:5002/bugtracker_table");
setProjects(response.data);
};
const saveProject = async (e) => {
e.preventDefault();
await axios.post("http://localhost:5002/bugtracker_table", {
project_name: project_name,
description: description,
});
history.push("/");
};
const [show, setShow] = useState(false);
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
return (
<>
<div className="grid table-demo">
<div className="col-12">
<div className="card">
<h5>Projects</h5>
<div>
<Button label="New Project" className="p-button-rounded mr-2 mb-2 npbutton" onClick={handleShow} />
</div>
<Modal className="modal" show={show} onHide={handleClose}>
<form onSubmit={saveProject}>
<div className="grid p-fluid">
<div className="col-12 md:col-6">
<div className="card">
<Button icon="pi pi-times" className="p-button-rounded p-button-danger p-button-text mr-2 mb-2 x-button" onClick={handleClose}></Button>
<ModalHeader>
<h5>Projects</h5>
</ModalHeader>
<div className="grid formgrid">
<div className="col-12 mb-2 lg:col-4 lg:mb-0">
<InputText value={project_name} onChange={(e) => setProjectName(e.target.value)} type="text" placeholder="Enter project name"></InputText>
</div>
</div>
<h5>Project Description</h5>
<InputTextarea value={description} onChange={(e) => setDescription(e.target.value)} type="text" placeholder="Enter project description" autoResize rows="3" cols="30" />
<ModalFooter>
<Button label="Submit" className="p-button-rounded p-button-success mr-2 mb-2 success" />
{/* <Button onClick={handleClose}>Close</Button> */}
</ModalFooter>
</div>
</div>
</div>
</form>
</Modal>
{/* // <Link to="/ticketlist" className="col-12"> */}
<div>
{/* // className="card"></Link> */}
<DataTable
// sortMode="single" sortField="representative.name"
value={projectsToShow}
sortOrder={1}
scrollable
scrollHeight="400px"
responsiveLayout="scroll"
>
<Column field="project_name" header="Project Name" style={{ minWidth: "200px" }}></Column>
<Column field="description" header="Description" style={{ minWidth: "350px" }}></Column>
<Column field="createdAt" header="Created On" style={{ minWidth: "150px" }}></Column>
{projects.map((project, index) => (
<tr key={project.id}>
<td>{index + 1}</td>
<td>{project.description}</td>
<td>{project.createdAt}</td>
</tr>
))}
</DataTable>
</div>
</div>
</div>
<div className="grid p-fluid">
<div className="col-12 lg:col-6">
<div className="card flex flex-column align-items-center">
<h5>Tickets by Type</h5>
<Chart type="pie" focus={"type"} />
</div>
</div>
</div>
<div className="grid p-fluid">
<div className="col-12 lg:col-6">
<div className="card flex flex-column align-items-center">
<h5>Tickets by Priority</h5>
<Chart type="pie" focus={"priority"} />
</div>
</div>
</div>
<div className="grid p-fluid">
<div className="col-12 lg:col-6">
<div className="card flex flex-column align-items-center">
<h5>Tickets by Status</h5>
<Chart type="pie" focus={"status"} />
</div>
</div>
</div>
</div>
</>
);
};
export default React.memo(TableDemo);
Projects.js
import React, { useState, useEffect } from "react";
import { Column } from "primereact/column";
import { DataTable } from "primereact/datatable";
import { Button } from "primereact/button";
import { Modal, ModalFooter, ModalHeader } from "react-bootstrap";
import { InputText } from "primereact/inputtext";
import { InputTextarea } from "primereact/inputtextarea";
// import { InputNumber } from "primereact/inputnumber";
import { Dropdown } from "primereact/dropdown";
import axios from "axios";
const Projectz = () => {
const [ticket_title, setTicketTitle] = useState("");
const [ticket_description, setTicketDescription] = useState("");
// const [time_takes, setTimeTakes] = useState("");
const [type_menu, setTypeMenu] = useState("");
const [priority_menu, setPriorityMenu] = useState("");
const [status_menu, setStatusMenu] = useState("");
const [projects, setProjects] = useState([]);
useEffect(() => {
getProjects();
}, []);
const getProjects = async () => {
const response = await axios.get("http://localhost:5002/ticket_table");
setProjects(response.data);
};
const saveProject = async (e) => {
e.preventDefault();
await axios.post("http://localhost:5002/ticket_table", {
ticket_title: ticket_title,
ticket_description: ticket_description,
// time_takes: time_takes,
type_menu: type_menu,
priority_menu: priority_menu,
status_menu: status_menu,
});
};
const dropdownValues1 = [
{ name: "Issue", code: "ISS" },
{ name: "Bug", code: "BUG" },
{ name: "Error", code: "ERR" },
{ name: "Other", code: "OTH" },
];
const dropdownValues2 = [
{ name: "Low", code: "LOW" },
{ name: "Medium", code: "MED" },
{ name: "High", code: "HI" },
{ name: "Immediate", code: "IMM" },
];
const dropdownValues3 = [
{ name: "New", code: "NEW" },
{ name: "Open", code: "OP" },
{ name: "In Progress", code: "IP" },
{ name: "Resolved", code: "RES" },
{ name: "Additional Info Required", code: "AIR" },
];
const [show, setShow] = useState(false);
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
return (
<>
<div className="grid table-demo">
<div className="col-12">
<div className="card">
<h5>Tickets</h5>
<div>
<Button label="New Ticket" className="p-button-rounded mr-2 mb-2 npbutton" onClick={handleShow} />
</div>
<Modal className="modal" show={show} onHide={handleClose}>
<form onSubmit={saveProject}>
<div className="grid p-fluid">
<div className="col-12 md:col-6">
<div className="card">
<ModalHeader>
<h5>Create Ticket</h5>
</ModalHeader>
<div className="grid formgrid">
<div className="col-12 mb-2 lg:col-4 lg:mb-0">
<InputText value={ticket_title} onChange={(e) => setTicketTitle(e.target.value)} type="text" placeholder="Enter ticket title"></InputText>
</div>
</div>
<h5>Ticket Description</h5>
<InputTextarea value={ticket_description} onChange={(e) => setTicketDescription(e.target.value)} type="text" placeholder="Enter ticket description" autoResize rows="3" cols="30" />
{/* <h5>Time Estimate (Hours)</h5> */}
{/* <InputNumber value={time_takes} onValueChange={(e) => setTimeTakes(e.value)} showButtons mode="decimal"></InputNumber> */}
<h5>Type</h5>
<Dropdown value={type_menu} onChange={(e) => setTypeMenu(e.value)} options={dropdownValues1} optionLabel="name" placeholder="Select" />
<h5>Priority</h5>
<Dropdown value={priority_menu} onChange={(e) => setPriorityMenu(e.value)} options={dropdownValues2} optionLabel="name" placeholder="Select" />
<h5>Status</h5>
<Dropdown value={status_menu} onChange={(e) => setStatusMenu(e.value)} options={dropdownValues3} optionLabel="name" placeholder="Select" />
<ModalFooter>
<Button label="Submit" className="p-button-rounded p-button-success mr-2 mb-2 success" />
<Button onClick={handleClose}>Close</Button>
</ModalFooter>
</div>
</div>
</div>
</form>
</Modal>
<div>
<DataTable
// sortMode="single" sortField="representative.name"
sortOrder={1}
scrollable
scrollHeight="400px"
responsiveLayout="scroll"
>
<Column field="ticket_title" header="Ticket Title" style={{ minWidth: "200px" }}></Column>
<Column field="description" header="Description" style={{ minWidth: "350px" }}></Column>
<Column field="status" header="Status" style={{ minWidth: "200" }}></Column>
<Column field="createdAt" header="Date" style={{ minWidth: "200px" }}></Column>
</DataTable>
</div>
</div>
</div>
</div>
<div className="grid table-demo">
<div className="col-12">
<div className="card">
<h5>Ticket Info</h5>
<div>
<DataTable
// value={projects}
// sortMode="single" sortField="representative.name"
// sortOrder={1}
// scrollable
// scrollHeight="400px"
// responsiveLayout="scroll"
>
{projects.map((project, index) => (
<tr key={project.id}>
<td>{index + 1}</td>
<td>{project.ticket_title}</td>
<td>{project.ticket_description}</td>
{/* <td>{ticket.time_takes}</td> */}
<td>{project.type_menu}</td>
<td>{project.priority_menu}</td>
<td>{project.status_menu}</td>
</tr>
))}
</DataTable>
</div>
</div>
</div>
</div>
</>
);
};
export default React.memo(Projectz);
Intended function: Projects names pulled from MySQL database that are listed in table column, will be a link to /projects page listing related unique information.
What is actually happening: Project names that are pulled from MySQL database that are listed in table column, are not links.
See pics for details: https://imgur.com/a/jp1JvV0
Dashboard.js
import React, { useState, useEffect } from "react";
import { DataTable } from "primereact/datatable";
import { Column } from "primereact/column";
import { Button } from "primereact/button";
// import ButtonDemo from './ButtonDemo';
import { Chart } from "primereact/chart";
import { InputText } from "primereact/inputtext";
import { InputTextarea } from "primereact/inputtextarea";
import { Modal, ModalFooter, ModalHeader } from "react-bootstrap";
import axios from "axios";
import { useHistory, Link } from "react-router-dom";
// import { Media } from "react-bootstrap/Media"
// import ProjectsTable from "./Tables/ProjectsTable";
// import TicketsPieChart from "./Tables/TicketsPieChart"
// import API from
//project table
//eslint-disable no-unused-vars
const TableDemo = () => {
// const toggle = () => {setShow(!show);}
const [project_name, setProjectName] = useState("");
const [description, setDescription] = useState("");
const [projects, setProjects] = useState([]);
const history = useHistory();
useEffect(() => {
getProjects();
}, []);
const getProjects = async () => {
const response = await axios.get("http://localhost:5002/bugtracker_table");
setProjects(response.data);
};
const saveProject = async (e) => {
e.preventDefault();
await axios.post("http://localhost:5002/bugtracker_table", {
project_name: project_name,
description: description,
});
history.push("/");
};
const [show, setShow] = useState(false);
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
return (
<>
<div className="grid table-demo">
<div className="col-12">
<div className="card">
<h5>Projects</h5>
<div>
<Button label="New Project" className="p-button-rounded mr-2 mb-2 npbutton" onClick={handleShow} />
</div>
<Modal className="modal" show={show} onHide={handleClose}>
<form onSubmit={saveProject}>
<div className="grid p-fluid">
<div className="col-12 md:col-6">
<div className="card">
<ModalHeader>
<h5>Projects</h5>
</ModalHeader>
<div className="grid formgrid">
<div className="col-12 mb-2 lg:col-4 lg:mb-0">
<InputText value={project_name} onChange={(e) => setProjectName(e.target.value)} type="text" placeholder="Enter project name"></InputText>
</div>
</div>
<h5>Project Description</h5>
<InputTextarea value={description} onChange={(e) => setDescription(e.target.value)} type="text" placeholder="Enter project description" autoResize rows="3" cols="30" />
<ModalFooter>
<Button label="Submit" className="p-button-rounded p-button-success mr-2 mb-2" />
<Button onClick={handleClose}>Close</Button>
</ModalFooter>
</div>
</div>
</div>
</form>
</Modal>
{/* // <Link to="/ticketlist" className="col-12"> */}
<div>
{/* // className="card"></Link> */}
<DataTable
// sortMode="single" sortField="representative.name"
value={projects}
sortOrder={1}
scrollable
scrollHeight="400px"
responsiveLayout="scroll"
>
<Column field="project_name" header="Project Name" style={{ minWidth: "200px" }}></Column>
{/* <Column field="ticket_title" header="Ticket Title" style={{ minWidth: "200px" }}></Column> */}
<Column field="description" header="Description" style={{ minWidth: "350px" }}></Column>
<Column field="status" header="Status" style={{ minWidth: "200" }}></Column>
<Column field="createdAt" header="Date" style={{ minWidth: "200px" }}></Column>
{projects.map((project, index) => (
<tr key={project.id}>
<td>{index + 1}</td>
<td>
<Link to={`/projects/${project.id}`}>{project.project_name}</Link>
</td>
<td>{project.description}</td>
<td>{project.createdAt}</td>\{" "}
</tr>
))}
</DataTable>
</div>
</div>
</div>
<div className="grid p-fluid">
<div className="col-12 lg:col-6">
<div className="card flex flex-column align-items-center">
<h5>Tickets by Type</h5>
<Chart type="pie" focus={"type"} />
</div>
</div>
</div>
<div className="grid p-fluid">
<div className="col-12 lg:col-6">
<div className="card flex flex-column align-items-center">
<h5>Tickets by Priority</h5>
<Chart type="pie" focus={"priority"} />
</div>
</div>
</div>
<div className="grid p-fluid">
<div className="col-12 lg:col-6">
<div className="card flex flex-column align-items-center">
<h5>Tickets by Status</h5>
<Chart type="pie" focus={"status"} />
</div>
</div>
</div>
</div>
</>
);
};
export default React.memo(TableDemo);
You could do a map to the projects array into a new variable before passing it to the Datatable value parameter
const projectsToShow = projects.map(project => {
return {
...project,
project_name: <Link to={`/projects/${project.id}`}>{project.project_name}</Link>
}
})
then the DataTable can handle the display with projectsToShow instead of project
<DataTable
...
value={projectsToShow}
...
>
I am trying to compose a navbar inside the AppBar in material-ui. I have the following code.
Currently, using #material-ui/core version 3.9.2.
class Header extends Component {
handleMenuOpen = ev => {
this.setState({ anchorAccountMenu: ev.currentTarget });
}
handleMenuClose = ev => {
this.setState({ anchorAccountMenu: null });
}
menuGotoUrl = siteUrl => ev => {
console.log(siteUrl);
this.props.history.push(siteUrl);
this.handleMenuClose(ev);
}
render() {
let { classes } = this.props;
let { anchorAccountMenu } = this.state;
const user = UserService.currentUser();
let userFirstChar = user.name.charAt(0).toUpperCase();
return (<AppBar><Toolbar>
{ /* Some more content here... */ }
<Button onClick={ this.handleMenuOpen }>
<span className={ classes.nameInButton }>{ `${user.name}` }</span>
<Avatar className={ classes.avatar }>{ userFirstChar }</Avatar>
</Button>
<Menu
id="user-menu" anchorEl={ anchorAccountMenu }
getContentAnchorEl= { null }
disableAutoFocusItem={ true }
anchorOrigin={{ vertical: "bottom", horizontal: "right" }}
transformOrigin={{ vertical: "top", horizontal: "right" }}
open={ !!anchorAccountMenu } onClose={ this.handleMenuClose }>
<MenuItem onClick={ this.menuGotoUrl("/profile/edit") }>
<ListItemIcon className={ classes.menuIcon }>
<Icon className="far fa-fw fa-user" />
</ListItemIcon>
<ListItemText inset primary="Profile" />
</MenuItem>
<MenuItem onClick={ this.handleLogout }>
<ListItemIcon className={ classes.menuIcon }>
<Icon className="fas fa-fw fa-sign-out-alt" />
</ListItemIcon>
<ListItemText inset primary="Logout" />
</MenuItem>
</Menu>
</Toolbar></AppBar>)
}
}
export default withRouter(withStyles(styles)(Header));
The problem is when I select the profile menuItem, it returns me error, instead of navigate to /profile/edit via react-routes-dom and close the menu.
Error:
react-dom.development.js:57 Uncaught Invariant Violation: Unable to find node on an unmounted component.
at invariant (webpack-internal:///./node_modules/react-dom/cjs/react-dom.development.js:57:19)
at findCurrentFiberUsingSlowPath (webpack-internal:///./node_modules/react-dom/cjs/react-dom.development.js:4395:31)
at findCurrentHostFiber (webpack-internal:///./node_modules/react-dom/cjs/react-dom.development.js:4407:27)
at findHostInstanceWithWarning (webpack-internal:///./node_modules/react-dom/cjs/react-dom.development.js:21470:25)
at Object.findDOMNode (webpack-internal:///./node_modules/react-dom/cjs/react-dom.development.js:22022:18)
at ref (webpack-internal:///./node_modules/#material-ui/core/MenuList/MenuList.js:203:46)
...
...
What am I missing here? Thanks.
I finally solve it by placing <Menu/> with <MenuList />. Not sure how's it different internally. This is also the alternative of building menu from material-ui from the doc.
Specifically, this is what I do:
render() {
let { classes } = this.props;
let { anchorAccountMenu } = this.state;
const user = UserService.currentUser();
let userFirstChar = user.name.charAt(0).toUpperCase();
return (<AppBar><Toolbar>
{ /* Some more content here... */ }
<Button onClick={ this.handleMenuOpen }>
<span className={ classes.nameInButton }>{ `${user.name}` }</span>
<Avatar className={ classes.avatar }>{ userFirstChar }</Avatar>
</Button>
<Popper open={ !!anchorAccountMenu } anchorEl={ anchorAccountMenu }
transition disablePortal>{ ({ TransitionProps }) => (
<Grow {...TransitionProps} id="menu-item-grow"
style={{ transformOrigin: 'center top' }}
><Paper><ClickAwayListener onClickAway={ this.handleMenuClose }>
<MenuList>
<MenuItem onClick={ this.menuGotoUrl("/profile/edit") }>
<ListItemIcon className={ classes.menuIcon }>
<Icon className="far fa-fw fa-user" />
</ListItemIcon>
<ListItemText inset primary="Profile" />
</MenuItem>
<MenuItem onClick={ this.handleLogout }>
<ListItemIcon className={ classes.menuIcon }>
<Icon className="fas fa-fw fa-sign-out-alt" />
</ListItemIcon>
<ListItemText inset primary="Logout" />
</MenuItem>
</MenuList>
</ClickAwayListener></Paper></Grow>
) }</Popper>
</Toolbar></AppBar>)
}
}