Skip to content

Commit

Permalink
feat: remove unused reservations
Browse files Browse the repository at this point in the history
  • Loading branch information
Rob Ellison committed Nov 11, 2023
1 parent 9a0553e commit 4251b55
Show file tree
Hide file tree
Showing 7 changed files with 626 additions and 625 deletions.
4 changes: 2 additions & 2 deletions components/resourcing/DemandTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ export function DemandTable() {
const fetchData = async () => {
setIsLoading(true);
try {
const response = await fetch('/api/resourcing/resources?demand=true');
const response = await fetch('/api/resourcing/demand?demand=true');
if (!response.ok) throw new Error('Network response was not ok');
const fetchedData = await response.json();
if (fetchedData.content) {
Expand All @@ -160,7 +160,7 @@ export function DemandTable() {
}

try {
const response = await fetch('/api/resourcing/resources');
const response = await fetch('/api/resourcing/demand');
if (!response.ok) throw new Error('Network response was not ok');
const fetchedData = await response.json();
if (fetchedData.content) {
Expand Down
2 changes: 1 addition & 1 deletion components/resourcing/FileUpload.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export const FileUpload = () => {
formData.append('file', file);

try {
const response = await fetch('/api/resourcing/resources', {
const response = await fetch('/api/resourcing/demand', {
method: 'POST',
body: formData,
});
Expand Down
209 changes: 174 additions & 35 deletions components/resourcing/ResourceTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
Stack
} from '@mui/material';


import ChevronLeftIcon from '@mui/icons-material/ChevronLeft';
import ChevronRightIcon from '@mui/icons-material/ChevronRight';
import WorkOutlineIcon from '@mui/icons-material/WorkOutline';
Expand All @@ -38,48 +39,154 @@ function determineColor(daysAllocated, daysHypo) {

function UserPopup({ data, open, handleClose }) {
// Example toggles' state
const [toggle1, setToggle1] = useState(false);
const [toggle2, setToggle2] = useState(false);
const [toggle3, setToggle3] = useState(false);
const [toggleSC, setToggleSC] = useState(false);
const [toggleTIR, setToggleTIR] = useState(false);
const [toggleMH, setToggleMH] = useState(false);
const [resource, setResource] = useState(null);

const updateUser = async () => {
const recordProposal = { 'resource': data.mail, 'sc': toggleSC, 'tir': toggleTIR, 'mh': toggleMH }
console.log('updated:', recordProposal)
try {
const response = await fetch('/api/resourcing/resources', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(recordProposal),
});

if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}

const result = await response.json();
console.log(result); // Process the response as needed

} catch (error) {
console.error('There was a problem with the fetch operation:', error);
}
}

// Handle toggle change
const handleToggleChange = (toggleSetter) => (event) => {
toggleSetter(event.target.checked);
};

useEffect(() => {
if (resource) {
setToggleSC(resource.sc);
setToggleTIR(resource.tir);
setToggleMH(resource.mh);
}
}, [resource]);

useEffect(() => {
if (resource) {
updateUser();
}
}, [toggleSC, toggleTIR, toggleMH]);


useEffect(() => {
const fetchData = async () => {

try {
const response = await fetch('/api/resourcing/resources?resource=' + data.mail);
if (!response.ok) throw new Error('Network response was not ok');
const fetchedData = await response.json();
// console.log('Resource:response: ', response)


if (fetchedData.content && fetchedData.content.length > 0) {
const jsonParsedData = JSON.parse(fetchedData.content)
setResource(jsonParsedData); // Adjust according to actual API response
} else { // record doesn't exist yet
const recordProposal = { 'resource': data.mail, 'sc': false, 'tir': false, 'mh': false }

setResource(recordProposal); // Adjust according to actual API response
}


// console.log('Resource:jsonParsedData: ', jsonParsedData)


} catch (err) {
console.error('Resource:ERROR: ', err)
}
};

fetchData();
}, []);




const LoadingSkeleton = () => {
return (
<FormGroup>
{Array.from(new Array(3)).map((_, index) => (
<FormControlLabel
key={index}
control={<Skeleton variant="rectangular" width={40} height={20} />}
label={<Skeleton variant="text" width={100} />}
/>
))}
</FormGroup>
);
};

if (!resource) {
return (
<Dialog open={open} onClose={handleClose} fullWidth>
<DialogTitle>
{data.displayName || data.name} {" - " + data.jobTitle || ""}
<IconButton onClick={handleClose} sx={{ position: 'absolute', right: 8, top: 8 }}>
<CloseIcon />
</IconButton>
</DialogTitle>
<DialogContent>
<LoadingSkeleton />
</DialogContent>
</Dialog>
);
}


return (
<Dialog open={open} onClose={handleClose} fullWidth>
<DialogTitle>
{data.displayName || data.name}
{data.displayName || data.name} {" - " + data.jobTitle || ""}
<IconButton onClick={handleClose} sx={{ position: 'absolute', right: 8, top: 8 }}>
<CloseIcon />
</IconButton>
</DialogTitle>
<DialogContent>

<FormGroup>
<FormControlLabel
control={
<Switch
checked={toggle1}
onChange={handleToggleChange(setToggle1)}
checked={toggleSC}
onChange={handleToggleChange(setToggleSC)}
/>
}
label="SC Cleared"
/>
<FormControlLabel
control={
<Switch
checked={toggle2}
onChange={handleToggleChange(setToggle2)}
checked={toggleTIR}
onChange={handleToggleChange(setToggleTIR)}
/>
}
label="TIR"
/>
<FormControlLabel
control={
<Switch
checked={toggle3}
onChange={handleToggleChange(setToggle3)}
checked={toggleMH}
onChange={handleToggleChange(setToggleMH)}
/>
}
label="Mansion House"
Expand All @@ -91,7 +198,26 @@ function UserPopup({ data, open, handleClose }) {
}


function Row({ data, displayedMonths, setPopupContent, setShowPopup, placeholder }) {
function ResourceInfo({ info }) {

if (info) {
return (
<Stack
direction="row"
justifyContent="flex-start"
alignItems="center"
spacing={0.5}
>
{info.sc && <Chip size="small" label="SC" variant="outlined" />}
{info.mh && <Chip size="small" label="MH" variant="outlined" />}
{info.tir && <Chip size="small" label="TIR" variant="outlined" />}
</Stack>
)
}
}


function Row({ data, displayedMonths, setPopupContent, setShowPopup, placeholder, refreshData }) {
// console.debug('Row: ', data)
// if (placeholder) {
// console.debug('Placeholder: ', placeholder)
Expand All @@ -115,9 +241,14 @@ function Row({ data, displayedMonths, setPopupContent, setShowPopup, placeholder
justifyContent="space-between"
alignItems="center">
{data.displayName || data.name}
{data.info && <ResourceInfo info={data.info} />}
<InfoIcon onClick={handleInfoClick} />

</Stack>
{popupOpen && <UserPopup data={data} open={popupOpen} handleClose={handleClose} />}
{popupOpen && <UserPopup data={data} open={popupOpen} handleClose={() => {
handleClose();
refreshData(); // <-- Invoke refreshData after closing the popup
}} />}

</TableCell>
<TableCell style={{ whiteSpace: 'nowrap', width: 'max-content' }}>
Expand Down Expand Up @@ -225,24 +356,24 @@ export function ResourceTable({ bench = false }) {
const [months, setMonths] = useState([]);
// const [months, setMonths] = useState([]);


const refreshData = async () => {
setIsLoading(true);
try {
const response = await fetch('/api/resourcing/demand');
if (!response.ok) throw new Error('Network response was not ok');
const fetchedData = await response.json();
const jsonParsedData = JSON.parse(fetchedData.content)
setData(jsonParsedData); // Adjust according to actual API response
setMonths(Array.from(new Set(jsonParsedData.flatMap(item => item.jobs.map(b => b.month)))).sort())
setIsLoading(false);
} catch (err) {
setError(err.message);
setIsLoading(false);
}
};

useEffect(() => {
const fetchData = async () => {
setIsLoading(true);
try {
const response = await fetch('/api/resourcing/resources');
if (!response.ok) throw new Error('Network response was not ok');
const fetchedData = await response.json();
const jsonParsedData = JSON.parse(fetchedData.content)
setData(jsonParsedData); // Adjust according to actual API response
setMonths(Array.from(new Set(jsonParsedData.flatMap(item => item.jobs.map(b => b.month)))).sort())
setIsLoading(false);
} catch (err) {
setError(err.message);
setIsLoading(false);
}
};

const fetchPlaceholderData = async () => {

try {
Expand All @@ -260,7 +391,7 @@ export function ResourceTable({ bench = false }) {
}
};

fetchData();
refreshData();
fetchPlaceholderData();
}, []);

Expand Down Expand Up @@ -312,11 +443,18 @@ export function ResourceTable({ bench = false }) {
!user.jobs.some(job => job.month.startsWith(month))
);

// Condition 2: Check if days_allocated plus holiday is less than days_hypo minus 3, using 20 if days_hypo is undefined
// Condition 2: Check if days_allocated plus holiday is less than days_hypo minus 3, using 18 if days_hypo is undefined
// Only for jobs within the displayed months
const hasLessDaysAllocated = user.jobs.some(job => {
const isInDisplayedMonths = displayedMonths.some(displayedMonth => job.month.startsWith(displayedMonth));
if (!isInDisplayedMonths) {
return false; // Skip this job if it's not in one of the displayed months
}

const holiday = job.holiday || 0; // If there is no holiday, default to 0
const daysHypo = job.days_hypo || 20; // Use 20 if days_hypo is not defined
return (job.days_allocated + holiday) < (daysHypo - 3);
const daysHypo = job.days_hypo || 18; // Use 18 if days_hypo is not defined
const days_allocated = job.days_allocated || 0;
return (days_allocated + holiday) < (daysHypo - 3);
});

// Return true if either condition is met
Expand Down Expand Up @@ -455,6 +593,7 @@ export function ResourceTable({ bench = false }) {
displayedMonths={displayedMonths}
setPopupContent={setPopupContent}
setShowPopup={setShowPopup}
refreshData={refreshData}
placeholder={placeholder && placeholder[item.mail] ? placeholder[item.mail] : null}
/>

Expand All @@ -464,9 +603,9 @@ export function ResourceTable({ bench = false }) {

<Dialog fullWidth open={showPopup} onClose={() => setShowPopup(false)}>
<DialogTitle>Job Details
<IconButton onClick={() => setShowPopup(false)} sx={{ position: 'absolute', right: 8, top: 8 }}>
<CloseIcon />
</IconButton>
<IconButton onClick={() => setShowPopup(false)} sx={{ position: 'absolute', right: 8, top: 8 }}>
<CloseIcon />
</IconButton>
</DialogTitle>
<DialogContent>
{popupContent && popupContent.map(job => (
Expand Down
33 changes: 33 additions & 0 deletions lib/redis/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,39 @@ export async function cacheRead(key) {
}
}

export async function cacheMRead(keys, prefix = '') {
try {
if (!redisInstance) {
redisInstance = await createRedisInstance();
}

// Check if keys is an array and has elements
if (!Array.isArray(keys) || keys.length === 0) return null;

// Add prefix to each key if prefix is provided
const fullKeys = prefix ? keys.map(key => `${prefix}${key}`) : keys;

// Use MGET to retrieve multiple keys
const values = await redisInstance.mget(...fullKeys);

// Process the returned values
return values.map(value => {
if (value === null || value === undefined) return null;
try {
const parsedValue = JSON.parse(value);
return parsedValue.buffer ? Buffer.from(parsedValue.buffer) : parsedValue;
} catch (parseError) {
console.error("Error parsing value from Redis:", parseError);
return null;
}
});
} catch (error) {
console.error("Error during Redis read operation:", error);
return null;
}
}


// Function to write data to the cache
export async function cacheWrite(key, value, ttl = null) {
try {
Expand Down
Loading

0 comments on commit 4251b55

Please sign in to comment.