Commit 64d9a47d authored by Venkaiah Naidu Singamchetty's avatar Venkaiah Naidu Singamchetty

Merge branch 'apiserver' into 'master'

average score and name default changed to duties modified modal

See merge request !55
parents 728a8a82 e929b2c3
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
"react-scripts": "5.0.1", "react-scripts": "5.0.1",
"redux-persist": "^6.0.0", "redux-persist": "^6.0.0",
"redux-thunk": "^3.1.0", "redux-thunk": "^3.1.0",
"uuid": "^9.0.1",
"web-vitals": "^2.1.4" "web-vitals": "^2.1.4"
}, },
"devDependencies": { "devDependencies": {
...@@ -16398,6 +16399,14 @@ ...@@ -16398,6 +16399,14 @@
"websocket-driver": "^0.7.4" "websocket-driver": "^0.7.4"
} }
}, },
"node_modules/sockjs/node_modules/uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
"bin": {
"uuid": "dist/bin/uuid"
}
},
"node_modules/source-list-map": { "node_modules/source-list-map": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
...@@ -17746,9 +17755,13 @@ ...@@ -17746,9 +17755,13 @@
} }
}, },
"node_modules/uuid": { "node_modules/uuid": {
"version": "8.3.2", "version": "9.0.1",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
"funding": [
"https://github.com/sponsors/broofa",
"https://github.com/sponsors/ctavan"
],
"bin": { "bin": {
"uuid": "dist/bin/uuid" "uuid": "dist/bin/uuid"
} }
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
"react-scripts": "5.0.1", "react-scripts": "5.0.1",
"redux-persist": "^6.0.0", "redux-persist": "^6.0.0",
"redux-thunk": "^3.1.0", "redux-thunk": "^3.1.0",
"uuid": "^9.0.1",
"web-vitals": "^2.1.4" "web-vitals": "^2.1.4"
}, },
"scripts": { "scripts": {
......
...@@ -149,7 +149,7 @@ app.post('/createActivity',async (req, res) => { ...@@ -149,7 +149,7 @@ app.post('/createActivity',async (req, res) => {
let { data } = req.body; let { data } = req.body;
//data validation //data validation
if (!_.get(data, "aName", "") || !_.get(data, "aId", "") || !_.get(data, "type", "") || !_.get(data, "score", "")) { if (!_.get(data, "aName", "") || !_.get(data, "aId", "") || !_.get(data, "type", "") || !_.get(data, "score", "") || !_.get(data,"comments","")) {
res.status(401).json({ "error": "Invalid Activity data" }); res.status(401).json({ "error": "Invalid Activity data" });
return; return;
} }
...@@ -158,10 +158,10 @@ app.post('/createActivity',async (req, res) => { ...@@ -158,10 +158,10 @@ app.post('/createActivity',async (req, res) => {
res.status(401).json({ "message": "Score Should be between 1 to 5 or -1 to -5 only" }); res.status(401).json({ "message": "Score Should be between 1 to 5 or -1 to -5 only" });
return return
} }
if(data["comments"]===undefined){ // if(data["comments"]===undefined){
res.status(401).json({ "message": "need comments field" }); // res.status(401).json({ "message": "need comments field" });
return // return
} // }
data = { ...data, "recorded_date": new Date() }; data = { ...data, "recorded_date": new Date() };
data = Object.assign(data, { "_id": new ObjectId() }) data = Object.assign(data, { "_id": new ObjectId() })
...@@ -208,15 +208,15 @@ const calculateAverage = async(query) => { ...@@ -208,15 +208,15 @@ const calculateAverage = async(query) => {
.then(async(result) => { .then(async(result) => {
let activitiesList = result.activities; let activitiesList = result.activities;
let activitiesLength = activitiesList.length; let activitiesLength = activitiesList.length;
let score = activitiesList.reduce((acc, curr) => { return acc + curr.score }, 0); let score = activitiesList.reduce((acc, curr) => { return acc + Number(curr.score) }, 0);
let averageScore = 0; let averageScore = score / activitiesLength;
score < 0 // score < 0
? (averageScore = 0) // ? (averageScore = 0)
: (averageScore = score / activitiesLength); // : (averageScore = score / activitiesLength);
if (averageScore % 1 !== 0) { // if (averageScore % 1 !== 0) {
averageScore = averageScore.toFixed(1); averageScore = Number(averageScore).toFixed(1);
} // }
await db.collection("employees") await db.collection("employees")
.updateOne(query, { $set: { score: Number(averageScore) } }) .updateOne(query, { $set: { score: Number(averageScore) } })
......
...@@ -30,7 +30,7 @@ function Accordion({ title, data ,handleAddActivity,open,handleAccordian}) { ...@@ -30,7 +30,7 @@ function Accordion({ title, data ,handleAddActivity,open,handleAccordian}) {
// },[userDetails,id]) // },[userDetails,id])
useEffect(()=>{ useEffect(()=>{
if(reports !==null){ if(reports?.length !==null){
dispatch(calculateDefaultScore(reports)) dispatch(calculateDefaultScore(reports))
dispatch(calculateInitiativeScore(reports)) dispatch(calculateInitiativeScore(reports))
} }
...@@ -46,7 +46,7 @@ function Accordion({ title, data ,handleAddActivity,open,handleAccordian}) { ...@@ -46,7 +46,7 @@ function Accordion({ title, data ,handleAddActivity,open,handleAccordian}) {
{ title: "Comments", id: "comments", width: "40%" }, { title: "Comments", id: "comments", width: "40%" },
]; ];
if(loading && title =="Default")return <Loading/> if(loading && title =="Duties")return <Loading/>
if(!loading){ if(!loading){
return ( return (
...@@ -56,11 +56,11 @@ function Accordion({ title, data ,handleAddActivity,open,handleAccordian}) { ...@@ -56,11 +56,11 @@ function Accordion({ title, data ,handleAddActivity,open,handleAccordian}) {
onClick={handleClick} onClick={handleClick}
type="button" type="button"
className="flex items-center rounded-lg w-full py-2 px-2 mt-4 font-medium rtl:text-right bg-white text-gray-500 border border-[#B7B7B7] focus:ring-4 dark:border-gray-700 hover:bg-gray-100 gap-3" data-accordion-target="#accordion-collapse-body-2" aria-expanded="false" aria-controls="accordion-collapse-body-2" > className="flex items-center rounded-lg w-full py-2 px-2 mt-4 font-medium rtl:text-right bg-white text-gray-500 border border-[#B7B7B7] focus:ring-4 dark:border-gray-700 hover:bg-gray-100 gap-3" data-accordion-target="#accordion-collapse-body-2" aria-expanded="false" aria-controls="accordion-collapse-body-2" >
<div className="w-1/2 text-start ms-2">{title}</div> <span className="w-1/2 text-start ms-2">{title}</span>
<div className="w-1/2 flex justify-between"> <span className="w-1/2 flex justify-between">
Average Score :{title === "Default" ? defaultAvgScore : initiativeAvgScore} Average Score :{title === "Duties" ? defaultAvgScore : initiativeAvgScore}
<ModalButton type={`${title === "Default" ? "default" : "initiative"}`} handleAddActivity={handleAddActivity}/> <ModalButton type={`${title === "Duties" ? "duties" : "initiative"}`} handleAddActivity={handleAddActivity}/>
</div> </span>
<svg data-accordion-icon className="w-3 h-3 rotate-180 shrink-0" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 10 6"> <svg data-accordion-icon className="w-3 h-3 rotate-180 shrink-0" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 10 6">
<path <path
stroke="currentColor" stroke="currentColor"
......
...@@ -12,7 +12,7 @@ function LeftSidebar() { ...@@ -12,7 +12,7 @@ function LeftSidebar() {
return ( return (
<div className=" w-[33%] flex flex-col px-[5px]"> <div className=" w-[33%] flex flex-col px-[5px]">
<p className="text-xl text-blue-400 font-semibold pl-4 mt-3"> <p className="text-xl text-blue-400 font-semibold">
My Reportees My Reportees
</p> </p>
{ {
...@@ -21,11 +21,11 @@ function LeftSidebar() { ...@@ -21,11 +21,11 @@ function LeftSidebar() {
{reportees?.map(({ empName, score, empId }) => ( {reportees?.map(({ empName, score, empId }) => (
<Link <Link
to={`/viewreportee/${empId}`} to={`/viewreportee/${empId}`}
className={`flex items-center hover:bg-indigo-500 hover:text bg-${Number(id) == empId ? "indigo-200" : "white" className={`flex items-center hover:bg-blue-400 hover:text-white hover:rounded-2xl bg-${Number(id) == empId ? "indigo-200" : "white"
} p-2 justify-between mb-1 w-full`} } p-2 justify-between mb-1 w-full`}
key={empId} key={empId}
> >
<img src="/man.png" width="18px" height="18px" /> {/* <img src="/man.png" width="18px" height="18px" /> */}
<p className="w-[80%] text-left">{empName}</p> <p className="w-[80%] text-left">{empName}</p>
<p className={`w-[30px] h-[30px] rounded-full flex items-center text-white justify-center ${scoreColor(score)}`}> <p className={`w-[30px] h-[30px] rounded-full flex items-center text-white justify-center ${scoreColor(score)}`}>
{score} {score}
......
This diff is collapsed.
...@@ -3,33 +3,33 @@ import Loading from "../loading Component/Loading"; ...@@ -3,33 +3,33 @@ import Loading from "../loading Component/Loading";
function Table({headers, data,loading, maxHeight}) { function Table({headers, data,loading, maxHeight}) {
if(loading) return <Loading/> if(loading) return <Loading/>
else
return ( return (
<div className={` overflow-auto sm:rounded-lg p-4 bg-gray-100`}> <div className={` overflow-auto sm:rounded-lg p-4 bg-gray-100`}>
<table className="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400 bg-transparent justify-center border-separate border-spacing-y-2"> <table className="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400 bg-transparent justify-center border-separate border-spacing-y-2">
<thead className="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-white"> <thead className="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-white">
<tr className="mb-2"> <tr className="mb-2">
{headers.map((item,index) => ( {headers?.map((item,index) => (
<th key={index} scope="col" className={`px-6 py-4 w-[${item.width}]`} > <th key={index} scope="col" className={`px-6 py-4 w-[${item.width}]`} >
{item.title} {item.title}
</th> </th>
))} ))}
</tr> </tr>
</thead> </thead>
{ (data?.length)? {
<tbody> (data?.length)?<tbody>
{ {
data?.map((item, index) => ( data?.map((item, index) => (
<tr className="bg-white dark:bg-gray-800 dark:border-gray-700 dark:text-white hover:bg-gray-50 dark:hover:bg-gray-600"> <tr key={item.id} className="bg-white dark:bg-gray-800 dark:border-gray-700 dark:text-white hover:bg-gray-50 dark:hover:bg-gray-600">
{ {
headers?.map(({render, id}) => ( headers?.map(({render, id}) => (
<td className="px-6 py-4 listData" >{render ? render(item[id]) : item[id] === "" ? "NA" : item[id] }</td> <td key={`${item.id}_${id}`} className="px-6 py-4 listData" >{render ? render(item[id]) : item[id] === "" ? "NA" : item[id] }</td>
)) ))
} }
</tr> </tr>
)) ))
} }
</tbody>:null </tbody>:null
} }
</table> </table>
{ {
......
...@@ -38,10 +38,10 @@ function Reports() { ...@@ -38,10 +38,10 @@ function Reports() {
const handleAccordian = (value) => { const handleAccordian = (value) => {
switch (value) { switch (value) {
case "Default": case "Duties":
setOpen({ ...open, "accordianOne": !open["accordianOne"], "accordianTwo": false }); setOpen({ ...open, "accordianOne": !open["accordianOne"], "accordianTwo": false });
break; break;
case "Initiative": case "Initiatives":
setOpen({ ...open, "accordianOne": false, "accordianTwo": !open["accordianTwo"] }); setOpen({ ...open, "accordianOne": false, "accordianTwo": !open["accordianTwo"] });
break; break;
default: default:
...@@ -151,14 +151,11 @@ function Reports() { ...@@ -151,14 +151,11 @@ function Reports() {
</div> </div>
</div> </div>
<div className=""> <div className="">
{/* <div className="container mx-auto mt-4 flex justify-end pe-4">
<DateRangePicker getReports={getReports} />
</div> */}
<div className=""> <div className="">
<Accordion title="Default" open={open.accordianOne} handleAccordian={handleAccordian} data={activities?.default} handleAddActivity={handleAddActivity} /> <Accordion title="Duties" open={open.accordianOne} handleAccordian={handleAccordian} data={activities?.duties} handleAddActivity={handleAddActivity} />
</div> </div>
<div className=""> <div className="">
<Accordion title="Initiative" open={open.accordianTwo} handleAccordian={handleAccordian} data={activities?.initiative} handleAddActivity={handleAddActivity} /> <Accordion title="Initiatives" open={open.accordianTwo} handleAccordian={handleAccordian} data={activities?.initiative} handleAddActivity={handleAddActivity} />
</div> </div>
</div> </div>
</div> </div>
......
...@@ -24,16 +24,25 @@ const reportSlice = createSlice({ ...@@ -24,16 +24,25 @@ const reportSlice = createSlice({
return initialState return initialState
}, },
calculateDefaultScore:(state, action)=>{ calculateDefaultScore:(state, action)=>{
const defaultItems = action.payload?.filter(item => item.type === "default"); if(action.payload===undefined){
const totalDefaultScore = defaultItems?.reduce((acc, curr) => acc+ curr.score, 0); return {...state,defaultAvgScore :0}
const defaultAvgScore = totalDefaultScore > 0 ? totalDefaultScore / defaultItems.length : 0; }else{
return {...state,defaultAvgScore :defaultAvgScore.toFixed(1)} const dutiesItems = action.payload?.filter(item => item.type === "duties");
const totalDutiesScore =dutiesItems?.length? dutiesItems?.reduce((acc, curr) => acc+ Number(curr.score), 0):0;
const defaultAvgScore =totalDutiesScore===0?0: Number(totalDutiesScore) / Number(dutiesItems?.length);
return {...state,defaultAvgScore :Number(defaultAvgScore).toFixed(1)}
}
}, },
calculateInitiativeScore:(state,action)=>{ calculateInitiativeScore:(state,action)=>{
const defaultItems = action.payload?.filter(item => item.type === "initiative"); if(action.payload===undefined){
const totalDefaultScore = defaultItems?.reduce((acc, curr) => acc+ curr.score, 0); return {...state,initiativeAvgScore:0}
const initialAvgScore = totalDefaultScore > 0 ? totalDefaultScore / defaultItems.length : 0; }
return {...state,initiativeAvgScore :initialAvgScore.toFixed(1)} else{
const initiatiesItems = action.payload?.filter(item => item.type === "initiative");
const totalInitiateScore =initiatiesItems?.length? (initiatiesItems?.reduce((acc, curr) => acc+ Number(curr.score), 0)):0;
const initialAvgScore =totalInitiateScore===0?0: Number(totalInitiateScore) / Number(initiatiesItems?.length) ;
return {...state,initiativeAvgScore :Number(initialAvgScore).toFixed(1)}
}
}, },
}, },
......
const scoreColor = (value) => { const scoreColor = (value) => {
if (value >= 0 && value < 1) { if (value < 1) {
return 'bg-red-400'; return 'bg-red-400';
} else if (value >= 1 && value < 2) { } else if (value >= 1 && value < 2) {
return 'bg-red-300'; return 'bg-red-300';
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment