Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nisum-scorecard
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Venkaiah Naidu Singamchetty
nisum-scorecard
Commits
b192a207
Commit
b192a207
authored
Mar 16, 2024
by
Venkaiah Naidu Singamchetty
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
loading added
parent
e89390d0
Changes
15
Show whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
138 additions
and
169 deletions
+138
-169
Loade1.gif
public/Loade1.gif
+0
-0
Loader2.gif
public/Loader2.gif
+0
-0
server.js
server.js
+45
-110
index.jsx
src/components/accordion/index.jsx
+45
-37
DateRangePicker.jsx
src/components/dateRangePicker/DateRangePicker.jsx
+2
-1
index.jsx
src/components/leftSidebar/index.jsx
+8
-5
Loade1.gif
src/components/loading Component/Loade1.gif
+0
-0
Loading.jsx
src/components/loading Component/Loading.jsx
+18
-0
Spin1.png
src/components/loading Component/Spin1.png
+0
-0
index.jsx
src/components/table/index.jsx
+3
-2
index.jsx
src/pages/dashboard/index.jsx
+7
-5
index.jsx
src/pages/reports/index.jsx
+3
-5
reportSlice.js
src/redux/reducers/reportSlice.js
+3
-3
clearStore.js
src/utils/clearStore.js
+2
-0
constants.js
src/utils/constants.js
+2
-1
No files found.
public/Loade1.gif
0 → 100644
View file @
b192a207
489 KB
public/Loader2.gif
0 → 100644
View file @
b192a207
187 KB
server.js
View file @
b192a207
...
...
@@ -19,8 +19,8 @@ connectToDb((err) => {
});
//to get all the employees data
app
.
get
(
"/employees"
,
(
req
,
res
)
=>
{
db
.
collection
(
"employees"
)
app
.
get
(
"/employees"
,
async
(
req
,
res
)
=>
{
await
db
.
collection
(
"employees"
)
.
find
()
.
toArray
()
.
then
((
result
)
=>
{
...
...
@@ -30,9 +30,9 @@ app.get("/employees", (req, res) => {
});
//to get only individual employee data
app
.
get
(
"/employee/:id"
,
(
req
,
res
)
=>
{
app
.
get
(
"/employee/:id"
,
async
(
req
,
res
)
=>
{
let
Id
=
parseInt
(
req
.
params
.
id
);
db
.
collection
(
"employees"
)
await
db
.
collection
(
"employees"
)
.
findOne
({
empId
:
Id
},
{
projection
:
{
_id
:
false
}
})
.
then
((
result
)
=>
{
if
(
!
result
)
...
...
@@ -44,8 +44,6 @@ app.get("/employee/:id", (req, res) => {
});
//login Check
//require empId
//example {empId:41689}
app
.
post
(
'/login'
,
async
(
req
,
res
)
=>
{
const
{
empId
}
=
req
.
body
;
try
{
...
...
@@ -66,8 +64,8 @@ app.post('/login', async (req, res) => {
//to get activities to display
app
.
get
(
"/activities"
,
(
req
,
res
)
=>
{
db
.
collection
(
"activities_master"
)
app
.
get
(
"/activities"
,
async
(
req
,
res
)
=>
{
await
db
.
collection
(
"activities_master"
)
.
find
()
.
toArray
()
.
then
((
result
)
=>
{
...
...
@@ -84,7 +82,7 @@ Example of post Data
,"page":1,"perPage":10,
"searchText":"eng"
}*/
app
.
post
(
"/getreportees"
,
(
req
,
res
)
=>
{
app
.
post
(
"/getreportees"
,
async
(
req
,
res
)
=>
{
let
reporteesArray
=
req
.
body
.
reportees
||
[];
let
sortBy
=
req
.
body
.
sort
?
req
.
body
.
sort
.
type
||
"_id"
:
"_id"
;
let
sortByOrder
=
req
.
body
.
sort
?
parseInt
(
req
.
body
.
sort
.
order
)
||
1
:
1
;
...
...
@@ -115,7 +113,7 @@ app.post("/getreportees", (req, res) => {
};
aggre
.
push
({
$facet
:
facet
});
aggre
.
push
({
$unwind
:
{
path
:
"$totalCount"
}
});
db
.
collection
(
"employees"
)
await
db
.
collection
(
"employees"
)
.
aggregate
(
aggre
)
.
toArray
()
.
then
((
result
)
=>
{
...
...
@@ -132,7 +130,7 @@ app.post("/getreportees", (req, res) => {
//Example of post Data
/*
{
"empId":
41689
,
"empId":
10000
,
"data":{
"aName":"Approval of timesheet",
"aId":"D001",
...
...
@@ -142,135 +140,72 @@ app.post("/getreportees", (req, res) => {
}
}
*/
// app.post('/createActivity',async (req, res) => {
// const empId = req.body.empId;
// if (!empId) {
// res.status(401).json({ "message": "Employee id is missing" });
// return
// } else {
// let { data } = req.body;
// //data validation
// if (!_.get(data, "aName", "") || !_.get(data, "aId", "") || !_.get(data, "type", "") || !_.get(data, "score", "")) {
// res.status(401).json({ "error": "Invalid Activity data" });
// return;
// }
// if (data.score === (0 || -0) || data.score > 5 || data.score < -5) {
// res.status(401).json({ "message": "Score Should be between 1 to 5 or -1 to -5 only" });
// return
// }
// if(data["comments"]===undefined){
// res.status(401).json({ "message": "need comments field" });
// return
// }
// data = { ...data, "recorded_date": new Date() };
// data = Object.assign(data, { "_id": new ObjectId() })
// let query = { empId: empId };
// await db.collection('performance_master').findOne(query).then(async(result) => {
// if (result) {
// await db.collection('performance_master').updateOne(query, { $push: { "activities": data } })
// .then(async (updateRes) => {
// await calculateAverage(query);
// res.status(201).json({ "reuslt": updateRes });
// })
// .catch((error) => {
// res.json({ "error": error });
// });
// } else {
// let insertData = { empId: empId, activities: [] };
// insertData.activities.push(data);
// await db.collection('performance_master').insertOne(insertData).then(async (result) => {
// await calculateAverage(query);
// res.status(201).json({ "result": result });
// }).catch((error) => {
// res.json({ "message": error })
// })
// }
// }).catch((error) => {
// console.log(error)
// res.send(query)
// })
// }
// })
app
.
post
(
'/createActivity'
,
async
(
req
,
res
)
=>
{
app
.
post
(
'/createActivity'
,
async
(
req
,
res
)
=>
{
const
empId
=
req
.
body
.
empId
;
if
(
!
empId
)
{
res
.
status
(
401
).
json
({
"message"
:
"Employee id is missing"
});
return
;
return
}
else
{
let
{
data
}
=
req
.
body
;
// Data validation
if
(
data
===
undefined
||
typeof
data
.
aName
!==
'string'
||
data
.
aName
.
trim
()
===
''
||
typeof
data
.
aId
!==
'string'
||
data
.
aId
.
trim
()
===
''
||
typeof
data
.
type
!==
'string'
||
data
.
type
.
trim
()
===
''
||
typeof
data
.
score
!==
'number'
)
{
//data validation
if
(
!
_
.
get
(
data
,
"aName"
,
""
)
||
!
_
.
get
(
data
,
"aId"
,
""
)
||
!
_
.
get
(
data
,
"type"
,
""
)
||
!
_
.
get
(
data
,
"score"
,
""
))
{
res
.
status
(
401
).
json
({
"error"
:
"Invalid Activity data"
});
return
;
}
if
(
data
.
score
===
0
||
data
.
score
===
-
0
||
data
.
score
>
5
||
data
.
score
<
-
5
)
{
res
.
status
(
401
).
json
({
"message"
:
"Score
s
hould be between 1 to 5 or -1 to -5 only"
});
return
;
if
(
data
.
score
===
(
0
||
-
0
)
||
data
.
score
>
5
||
data
.
score
<
-
5
)
{
res
.
status
(
401
).
json
({
"message"
:
"Score
S
hould be between 1 to 5 or -1 to -5 only"
});
return
}
if
(
data
.
comments
===
undefined
)
{
res
.
status
(
401
).
json
({
"message"
:
"Need comments field"
});
return
;
if
(
data
[
"comments"
]
===
undefined
){
res
.
status
(
401
).
json
({
"message"
:
"need comments field"
});
return
}
data
=
{
...
data
,
"recorded_date"
:
new
Date
()
};
data
=
Object
.
assign
(
data
,
{
"_id"
:
new
ObjectId
()
})
;
data
=
Object
.
assign
(
data
,
{
"_id"
:
new
ObjectId
()
})
let
query
=
{
empId
:
empId
};
await
db
.
collection
(
'performance_master'
).
findOne
(
query
).
then
(
async
(
result
)
=>
{
await
db
.
collection
(
'performance_master'
).
findOne
(
query
).
then
(
async
(
result
)
=>
{
if
(
result
)
{
await
db
.
collection
(
'performance_master'
).
updateOne
(
query
,
{
$push
:
{
"activities"
:
data
}
})
.
then
(
async
(
updateRes
)
=>
{
await
calculateAverage
(
result
);
// Pass result instead of query
res
.
status
(
201
).
json
({
"result"
:
updateRes
});
await
calculateAverage
(
query
);
res
.
status
(
201
).
json
({
"reuslt"
:
updateRes
});
})
.
catch
((
error
)
=>
{
res
.
json
({
"error"
:
error
});
});
}
else
{
let
insertData
=
{
empId
:
empId
,
activities
:
[]
};
insertData
.
activities
.
push
(
data
);
await
db
.
collection
(
'performance_master'
).
insertOne
(
insertData
).
then
(
async
(
result
)
=>
{
await
calculateAverage
(
result
);
// Pass result instead of query
await
calculateAverage
(
query
);
res
.
status
(
201
).
json
({
"result"
:
result
});
}).
catch
((
error
)
=>
{
res
.
json
({
"message"
:
error
});
});
res
.
json
({
"message"
:
error
})
})
}
}).
catch
((
error
)
=>
{
console
.
log
(
error
);
res
.
send
(
error
);
});
}
});
console
.
log
(
error
)
res
.
send
(
query
)
})
}
})
//calculating average score and updating into employees data
const
calculateAverage
=
(
query
)
=>
{
return
new
Promise
(
(
res
,
rej
)
=>
{
db
.
collection
(
"performance_master"
)
const
calculateAverage
=
async
(
query
)
=>
{
return
await
new
Promise
(
async
(
res
,
rej
)
=>
{
await
db
.
collection
(
"performance_master"
)
.
findOne
(
query
)
.
then
((
result
)
=>
{
.
then
(
async
(
result
)
=>
{
let
activitiesList
=
result
.
activities
;
let
activitiesLength
=
activitiesList
.
length
;
let
score
=
activitiesList
.
reduce
((
acc
,
curr
)
=>
{
return
acc
+
curr
.
score
},
0
);
...
...
@@ -283,7 +218,7 @@ const calculateAverage = (query) => {
averageScore
=
averageScore
.
toFixed
(
1
);
}
db
.
collection
(
"employees"
)
await
db
.
collection
(
"employees"
)
.
updateOne
(
query
,
{
$set
:
{
score
:
Number
(
averageScore
)
}
})
.
then
((
result
)
=>
{
res
(
result
);
...
...
@@ -304,7 +239,7 @@ const calculateAverage = (query) => {
"toDate":"2024-03-14"
}
*/
app
.
post
(
"/getActivities"
,
(
req
,
res
)
=>
{
app
.
post
(
"/getActivities"
,
async
(
req
,
res
)
=>
{
let
{
empId
,
fromDate
,
toDate
,
today
}
=
req
.
body
;
if
(
!
empId
||
typeof
empId
==
"string"
)
{
res
.
status
(
401
).
json
({
message
:
"Employee id is missing / EmpId should be string only"
});
...
...
@@ -330,7 +265,7 @@ app.post("/getActivities", (req, res) => {
$lte
:
moment
().
toDate
(),
};
}
db
.
collection
(
"performance_master"
)
await
db
.
collection
(
"performance_master"
)
.
findOne
(
query
)
.
then
((
results
)
=>
{
res
.
status
(
201
).
json
(
results
);
...
...
src/components/accordion/index.jsx
View file @
b192a207
...
...
@@ -7,16 +7,18 @@ import { useEffect } from "react";
import
{
useParams
}
from
'react-router'
import
{
fetchReportees
}
from
"../../redux/reducers/reporteesSlice"
;
import
{
calculateDefaultScore
,
calculateInitiativeScore
}
from
"../../redux/reducers/reportSlice"
;
import
Loading
from
"../loading Component/Loading"
;
function
Accordion
({
title
,
data
,
handleAddActivity
,
open
,
handleAccordian
})
{
const
dispatch
=
useDispatch
()
const
{
id
}
=
useParams
()
const
{
reports
,
defaultAvgScore
,
initiativeAvgScore
}
=
useSelector
((
state
)
=>
state
.
reports
);
const
{
reports
,
defaultAvgScore
,
initiativeAvgScore
,
loading
}
=
useSelector
((
state
)
=>
state
.
reports
);
const
userDetails
=
useSelector
((
state
)
=>
state
.
userDetails
);
useEffect
(()
=>
{
if
(
userDetails
.
user
!==
null
){
const
data
=
{
reportees
:
userDetails
.
user
.
reportees
,
sort
:
{
type
:
"empId"
,
order
:
1
},
...
...
@@ -24,10 +26,11 @@ function Accordion({ title, data ,handleAddActivity,open,handleAccordian}) {
perPage
:
10
,
}
dispatch
(
fetchReportees
(
data
))
}
},[
userDetails
,
id
])
useEffect
(()
=>
{
if
(
reports
!=
[]
){
if
(
reports
!=
=
null
){
dispatch
(
calculateDefaultScore
(
reports
))
dispatch
(
calculateInitiativeScore
(
reports
))
}
...
...
@@ -42,6 +45,10 @@ function Accordion({ title, data ,handleAddActivity,open,handleAccordian}) {
{
title
:
"Score"
,
id
:
"score"
,
width
:
"10%"
,
render
:
(
value
)
=>
<
div
className=
"w-[35px] bg-blue-200 rounded-md text-center p-[4px]"
>
{
value
}
</
div
>
},
{
title
:
"Comments"
,
id
:
"comments"
,
width
:
"40%"
},
];
if
(
loading
&&
title
==
"Default"
)
return
<
Loading
/>
if
(
!
loading
){
return
(
<
div
className=
"px-4"
>
...
...
@@ -68,10 +75,11 @@ function Accordion({ title, data ,handleAddActivity,open,handleAccordian}) {
className=
{
`${!open && "hidden"} mt-2`
}
aria
-
labelledby=
"accordion-collapse-heading-2"
>
<
Table
headers=
{
headers
}
data=
{
data
}
maxHeight=
{
10
}
/>
<
Table
headers=
{
headers
}
loading=
{
loading
}
data=
{
data
}
maxHeight=
{
10
}
/>
</
div
>
</
div
>
);
}
}
export
default
Accordion
;
src/components/dateRangePicker/DateRangePicker.jsx
View file @
b192a207
...
...
@@ -6,7 +6,6 @@ const DateRangePicker = ({getReports}) => {
const
[
value
,
setValue
]
=
useState
({
startDate
:
""
,
endDate
:
""
});
const
handleStartChange
=
(
newValue
)
=>
{
...
...
@@ -17,7 +16,9 @@ const DateRangePicker = ({getReports}) => {
}
useEffect
(()
=>
{
if
(
value
.
startDate
!==
""
&
value
.
endDate
!==
""
){
getReports
(
value
.
startDate
?
value
.
startDate
:
null
,
value
.
endDate
?
value
.
endDate
:
null
)
}
},[
value
])
return
(
...
...
src/components/leftSidebar/index.jsx
View file @
b192a207
...
...
@@ -2,19 +2,20 @@ import React,{useEffect,useState} from "react";
import
{
Link
}
from
"react-router-dom"
;
import
{
useSelector
}
from
"react-redux"
;
import
{
useParams
}
from
"react-router-dom"
;
import
Loading
from
"../loading Component/Loading"
;
function
LeftSidebar
()
{
const
reportees
=
useSelector
((
state
)
=>
state
.
reportees
.
reportees
);
const
{
reportees
,
loading
}
=
useSelector
((
state
)
=>
state
.
reportees
);
const
{
id
}
=
useParams
()
// const [refresh,setRefresh]=useState(false)
// useEffect(()=>{ setRefresh(!refresh)},[reportees])
return
(
<
div
className=
"mt-2 w-[30%] flex flex-col px-[5px]"
>
<
p
className=
"text-xl text-blue-400 font-semibold pl-4 mt-3"
>
My Reportees
</
p
>
{
(
loading
)?
<
Loading
/>:
<
div
className=
"p-2 bg-[#E9EDEE] mt-4 max-h-[80vh] overflow-auto"
>
{
reportees
?.
map
(({
empName
,
score
,
empId
})
=>
(
<
Link
...
...
@@ -32,6 +33,8 @@ function LeftSidebar() {
</
Link
>
))
}
</
div
>
}
</
div
>
);
}
...
...
src/components/loading Component/Loade1.gif
0 → 100644
View file @
b192a207
489 KB
src/components/loading Component/Loading.jsx
0 → 100644
View file @
b192a207
import
React
,
{
memo
}
from
'react'
;
import
Loader1
from
'./Loade1.gif'
import
Spin
from
'./Spin1.png'
const
Loading
=
memo
(()
=>
{
return
(
<
div
className=
'w-100'
>
<
p
className=
'text-blue-500 flex justify-center items-center h-full mt-28'
>
<
img
src=
{
Spin
}
alt=
"Loading"
width=
{
100
}
height=
{
100
}
/>
{
/* loading */
}
</
p
>
</
div
>
);
});
export
default
Loading
;
\ No newline at end of file
src/components/loading Component/Spin1.png
0 → 100644
View file @
b192a207
168 KB
src/components/table/index.jsx
View file @
b192a207
import
React
from
"react"
;
import
Loading
from
"../loading Component/Loading"
;
function
Table
({
headers
,
data
,
maxHeight
})
{
function
Table
({
headers
,
data
,
loading
,
maxHeight
})
{
if
(
loading
)
return
<
Loading
/>
return
(
<
div
className=
{
` overflow-x-auto sm:rounded-lg p-4 max-h-[${maxHeight}vh]`
}
>
<
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"
>
...
...
src/pages/dashboard/index.jsx
View file @
b192a207
import
React
,
{
useEffect
}
from
"react"
;
import
React
,
{
useEffect
,
useState
}
from
"react"
;
import
{
Link
,
useNavigate
}
from
"react-router-dom"
;
import
{
useDispatch
,
useSelector
}
from
"react-redux"
;
import
{
fetchReportees
}
from
"../../redux/reducers/reporteesSlice"
;
...
...
@@ -7,9 +7,10 @@ import Table from '../../components/table';
function
Dashboard
()
{
const
dispatch
=
useDispatch
();
const
navigate
=
useNavigate
();
const
reportees
=
useSelector
((
state
)
=>
state
.
reportees
.
reportees
);
const
{
reportees
,
loading
}
=
useSelector
((
state
)
=>
state
.
reportees
);
const
userDetails
=
useSelector
((
state
)
=>
state
.
userDetails
);
const
reporteIds
=
userDetails
.
user
.
reportees
||
[];
const
[
reporteIds
,
setReporteIds
]
=
useState
([]);
// userDetails.user.reportees || [];
useEffect
(()
=>
{
if
(
reporteIds
.
length
>
0
)
{
...
...
@@ -24,7 +25,8 @@ function Dashboard() {
},
[
reporteIds
]);
useEffect
(()
=>
{
if
(
userDetails
.
user
!==
null
){
if
(
userDetails
.
user
){
setReporteIds
(
userDetails
.
user
.
reportees
)
navigate
(
"/dashboard"
)
}
else
{
navigate
(
"/"
)
...
...
@@ -63,7 +65,7 @@ function Dashboard() {
return
(
<
div
>
<
Table
headers=
{
headers
}
data=
{
reportees
}
maxHeight=
{
88
}
/>
<
Table
headers=
{
headers
}
data=
{
reportees
}
loading=
{
loading
}
maxHeight=
{
88
}
/>
</
div
>
)
}
...
...
src/pages/reports/index.jsx
View file @
b192a207
...
...
@@ -15,7 +15,7 @@ function Reports() {
const
reportees
=
useSelector
((
state
)
=>
state
.
reportees
.
reportees
);
const
user
=
useSelector
((
state
)
=>
state
.
userDetails
.
user
)
const
[
empDetails
,
setEmpDetails
]
=
useState
(
null
);
const
{
reports
}
=
useSelector
((
state
)
=>
state
.
reports
);
const
{
reports
,
loading
,
error
}
=
useSelector
((
state
)
=>
state
.
reports
);
const
[
open
,
setOpen
]
=
useState
({
"accordianOne"
:
true
,
"accordianTwo"
:
false
});
...
...
@@ -28,7 +28,7 @@ function Reports() {
}
*/
const
activities
=
useMemo
(()
=>
{
if
(
reports
!==
undefined
)
{
if
(
reports
)
{
const
filtered
=
Object
.
groupBy
(
reports
,
({
type
})
=>
type
);
return
filtered
;
}
...
...
@@ -96,9 +96,6 @@ function Reports() {
})
},
[
id
,
reportees
]);
return
(
<
div
className=
"p-4"
>
<
div
className=
" bg-white p-3"
>
...
...
@@ -142,6 +139,7 @@ function Reports() {
</
div
>
</
div
>
);
// }
}
...
...
src/redux/reducers/reportSlice.js
View file @
b192a207
...
...
@@ -3,7 +3,7 @@ import { base_url } from "../../utils/constants";
import
axios
from
"axios"
;
const
initialState
=
{
reports
:
[]
,
reports
:
null
,
defaultAvgScore
:
0
,
initiativeAvgScore
:
0
,
loading
:
false
,
...
...
@@ -39,13 +39,13 @@ const reportSlice = createSlice({
},
extraReducers
:
(
builder
)
=>
{
builder
.
addCase
(
fetchReports
.
pending
,
(
state
)
=>
{
return
{...
state
,
loading
:
true
,
error
:
"
pen
ding"
}
return
{...
state
,
loading
:
true
,
error
:
"
loa
ding"
}
});
builder
.
addCase
(
fetchReports
.
fulfilled
,
(
state
,
action
)
=>
{
return
{...
state
,
loading
:
false
,
error
:
""
,
reports
:
action
.
payload
?.
activities
}
});
builder
.
addCase
(
fetchReports
.
rejected
,
(
state
,
action
)
=>
{
return
{...
state
,
loading
:
false
,
error
:
action
.
error
||
"Something went wrong!"
,
reports
:
[]
}
return
{...
state
,
loading
:
false
,
error
:
action
.
error
||
"Something went wrong!"
,
reports
:
null
}
});
},
});
...
...
src/utils/clearStore.js
View file @
b192a207
import
{
resetUser
}
from
'../redux/reducers/userSlice'
;
import
{
resetReportees
}
from
'../redux/reducers/reporteesSlice'
;
import
{
resetReports
}
from
'../redux/reducers/reportSlice'
;
const
clearStore
=
(
dispatch
)
=>
{
dispatch
(
resetUser
());
dispatch
(
resetReportees
());
dispatch
(
resetReports
())
};
export
default
clearStore
;
\ No newline at end of file
src/utils/constants.js
View file @
b192a207
// export const base_url = 'http://localhost:4000'
export
const
base_url
=
'https://nisumscorecardserverdev.netlify.app/.netlify/functions/api'
// export const base_url = 'https://nisumscorecardservertesting.netlify.app/.netlify/functions/api'
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment