Skip to content

Commit 9525260

Browse files
committed
2024-11-07 - add inactive flag to ext-recip
1 parent 3aae481 commit 9525260

File tree

6 files changed

+135
-57
lines changed

6 files changed

+135
-57
lines changed

server/src/main/java/com/objectcomputing/checkins/services/feedback_external_recipient/FeedbackExternalRecipientController.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,23 @@ public HttpResponse<FeedbackExternalRecipientResponseDTO> save(@Body @Valid @Not
5050
.headers(headers -> headers.location(URI.create("/feedback_external_recipient/" + savedFeedbackExternalRecipient.getId())));
5151
}
5252

53+
/**
54+
* Mark a feedback request external recipient as inactive
55+
*
56+
* @param id {@link UUID} ID of the external-recipient
57+
* @return {@link HttpResponse}
58+
*/
59+
@Put("/inactivate/{id}")
60+
public HttpResponse<?> inactivate(UUID id) {
61+
FeedbackExternalRecipient feedbackExternalRecipient = feedbackExternalRecipientServices.getById(id);
62+
if (feedbackExternalRecipient == null) {
63+
throw new BadArgException("Invalid external recipient ID");
64+
}
65+
feedbackExternalRecipient.setInactive(true);
66+
feedbackExternalRecipientServices.update(feedbackExternalRecipient);
67+
return HttpResponse.ok();
68+
}
69+
5370
/**
5471
* Update a feedback request external recipient
5572
*

server/src/main/java/com/objectcomputing/checkins/services/feedback_external_recipient/FeedbackExternalRecipientServices.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
public interface FeedbackExternalRecipientServices {
88
FeedbackExternalRecipient save(FeedbackExternalRecipient feedbackExternalRecipient);
99

10-
FeedbackExternalRecipient update(FeedbackExternalRecipientUpdateDTO feedbackExternalRecipientUpdateDTO);
10+
FeedbackExternalRecipient update(FeedbackExternalRecipient feedbackExternalRecipient);
1111

1212
FeedbackExternalRecipient getById(UUID id);
1313

server/src/main/java/com/objectcomputing/checkins/services/feedback_external_recipient/FeedbackExternalRecipientServicesImpl.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ public FeedbackExternalRecipient save(FeedbackExternalRecipient feedbackExternal
2121
}
2222

2323
@Override
24-
public FeedbackExternalRecipient update(FeedbackExternalRecipientUpdateDTO feedbackExternalRecipientUpdateDTO) {
25-
return null;
24+
public FeedbackExternalRecipient update(FeedbackExternalRecipient feedbackExternalRecipient) {
25+
return feedbackExternalRecipientRepository.update(feedbackExternalRecipient);
2626
}
2727

2828
@Override

web-ui/src/api/feedback.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,19 @@ export const getFeedbackRequestsByRequestees = async (
295295

296296
export const getExternalRecipients = async (cookie) => {
297297
return resolve({
298-
url: `${feedbackExternalRecipientsURL}?inactive=false`,
298+
url: `${feedbackExternalRecipientsURL}`,
299299
headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' }
300300
});
301301
};
302+
303+
export const putExternalRecipientInactivate = async (externalRecipientId, cookie) => {
304+
return resolve({
305+
method: 'PUT',
306+
url: `${feedbackExternalRecipientsURL}/inactivate/${externalRecipientId}`,
307+
headers: {
308+
'X-CSRF-Header': cookie,
309+
Accept: 'application/json',
310+
'Content-Type': 'application/json;charset=UTF-8'
311+
}
312+
});
313+
};
Lines changed: 65 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
import React, { useContext } from 'react';
22
import { styled } from '@mui/material/styles';
33
import { AppContext } from '../../context/AppContext.jsx';
4-
import { selectProfileMap } from '../../context/selectors.js';
5-
import { getAvatarURL } from '../../api/api.js';
6-
import { Box, Card, CardHeader, CardContent, Container, Typography } from '@mui/material';
4+
import { selectCsrfToken, selectProfileMap } from '../../context/selectors.js';
5+
import { Box, Card, CardHeader, CardContent, Container, Typography, IconButton, Tooltip } from '@mui/material';
76
import Avatar from '@mui/material/Avatar';
8-
import PriorityHighIcon from '@mui/icons-material/PriorityHigh';
97
import { green } from '@mui/material/colors';
108
import CheckCircleIcon from '@mui/icons-material/CheckCircle';
11-
import Divider from '@mui/material/Divider';
9+
import CloseIcon from '@mui/icons-material/Close';
1210

1311
import './FeedbackExternalRecipientCard.css';
12+
import FeedbackExternalRecipientSelector
13+
from "../feedback_external_recipient_selector/FeedbackExternalRecipientSelector.jsx";
14+
import PropTypes from "prop-types";
1415

1516
const PREFIX = 'FeedbackExternalRecipientCard';
1617
const classes = {
@@ -59,53 +60,71 @@ const StyledBox = styled(Box)({
5960
});
6061

6162
const FeedbackExternalRecipientCard = ({
62-
recipientProfile,
63-
selected,
64-
onClick
65-
}) => {
63+
recipientProfile,
64+
selected,
65+
onClick,
66+
onInactivateHandle
67+
}) => {
6668
const { state } = useContext(AppContext);
69+
const csrf = selectCsrfToken(state);
6770
const supervisorProfile = selectProfileMap(state)[recipientProfile?.supervisorid];
6871
const pdlProfile = selectProfileMap(state)[recipientProfile?.pdlId];
6972

73+
async function handleInactivate() {
74+
onInactivateHandle();
75+
}
76+
7077
return (
71-
<StyledBox display="flex" flexWrap="wrap">
72-
<Card onClick={onClick} className="member-card" selected={selected}>
73-
<CardHeader
74-
className={classes.header}
75-
title={
76-
<Typography variant="h5" component="h2">
77-
{recipientProfile?.firstName} {recipientProfile?.lastName}
78-
</Typography>
79-
}
80-
action={
81-
selected ? (
82-
<CheckCircleIcon style={{ color: green[500] }}>
83-
checkmark-image
84-
</CheckCircleIcon>
85-
) : null
86-
}
87-
disableTypography
88-
/>
89-
<CardContent>
90-
<Container fixed className="info-container">
91-
<Typography variant="body2" color="textSecondary" component="p">
92-
<a
93-
href={`mailto:${recipientProfile?.email}`}
94-
target="_blank"
95-
rel="noopener noreferrer"
96-
>
97-
{recipientProfile?.email}
98-
</a>
99-
<br />
100-
Company: {recipientProfile?.companyName}
101-
<br />
102-
</Typography>
103-
</Container>
104-
</CardContent>
105-
</Card>
106-
</StyledBox>
78+
<StyledBox display="flex" flexWrap="wrap">
79+
<Card onClick={onClick} className="member-card" selected={selected}>
80+
<CardHeader
81+
className={classes.header}
82+
title={
83+
<Typography variant="h5" component="h2">
84+
{recipientProfile?.firstName} {recipientProfile?.lastName}
85+
</Typography>
86+
}
87+
action={
88+
<>
89+
{selected ? (
90+
<CheckCircleIcon style={{ color: green[500] }}>
91+
checkmark-image
92+
</CheckCircleIcon>
93+
) : (
94+
<Tooltip title="Inactivate" arrow>
95+
<IconButton
96+
onClick={(e) => {
97+
e.stopPropagation();
98+
handleInactivate();
99+
}}
100+
>
101+
<CloseIcon />
102+
</IconButton>
103+
</Tooltip>
104+
)}
105+
</>
106+
}
107+
disableTypography
108+
/>
109+
<CardContent>
110+
<Container fixed className="info-container">
111+
<Typography variant="body2" color="textSecondary" component="p">
112+
<a
113+
href={`mailto:${recipientProfile?.email}`}
114+
target="_blank"
115+
rel="noopener noreferrer"
116+
>
117+
{recipientProfile?.email}
118+
</a>
119+
<br />
120+
Company: {recipientProfile?.companyName}
121+
<br />
122+
</Typography>
123+
</Container>
124+
</CardContent>
125+
</Card>
126+
</StyledBox>
107127
);
108-
109128
};
110129

111130
export default FeedbackExternalRecipientCard;

web-ui/src/components/feedback_external_recipient_selector/FeedbackExternalRecipientSelector.jsx

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
selectCurrentUser,
99
selectNormalizedMembers, selectFeedbackExternalRecipient
1010
} from '../../context/selectors';
11-
import {getExternalRecipients} from '../../api/feedback';
11+
import {putExternalRecipientInactivate, getExternalRecipients} from '../../api/feedback';
1212
import Typography from '@mui/material/Typography';
1313
import { TextField, Grid, InputAdornment } from '@mui/material';
1414
import { Search } from '@mui/icons-material';
@@ -159,9 +159,41 @@ const FeedbackExternalRecipientSelector = ({ changeQuery, fromQuery, forQuery, a
159159
}
160160
console.log("FeedbackExternalRecipientSelector.jsx, cardClickHandler, 02 - fromQuery: ", fromQuery);
161161
changeQuery('from', fromQuery);
162-
hasRenewedFromURL.current = false;
162+
//hasRenewedFromURL.current = false;
163163
};
164164

165+
async function externalRecipientInactivate(id) {
166+
let externalRecipientsCopy = [...externalRecipients];
167+
let indexArray = externalRecipientsCopy.findIndex(profile => profile.id === id);
168+
169+
try {
170+
const response = await putExternalRecipientInactivate(id, csrf);
171+
if (response && !response.error) {
172+
externalRecipientsCopy[indexArray].inactive = true;
173+
hasRenewedFromURL.current = false;
174+
setExternalRecipients(externalRecipientsCopy);
175+
} else {
176+
const errorMessage = 'Failed to inactivate recipient';
177+
dispatch({
178+
type: UPDATE_TOAST,
179+
payload: {
180+
severity: 'error',
181+
toast: errorMessage
182+
}
183+
});
184+
}
185+
} catch (error) {
186+
const errorMessage = ("An error occurred while inactivating the recipient: ", error);
187+
dispatch({
188+
type: UPDATE_TOAST,
189+
payload: {
190+
severity: 'error',
191+
toast: errorMessage
192+
}
193+
});
194+
}
195+
}
196+
165197
const getSelectedCards = () => {
166198
if (fromQuery) {
167199
const title = (
@@ -219,9 +251,6 @@ const FeedbackExternalRecipientSelector = ({ changeQuery, fromQuery, forQuery, a
219251
newRecipient,
220252
csrf
221253
);
222-
223-
console.log("FeedbackExternalRecipientSelector.jsx, handleNewRecipientSubmit, feedbackExternalRecipientRes: ", feedbackExternalRecipientRes);
224-
225254
if (feedbackExternalRecipientRes.error) {
226255
const errorMessage = 'Failed to save external recipient';
227256
dispatch({
@@ -286,13 +315,14 @@ const FeedbackExternalRecipientSelector = ({ changeQuery, fromQuery, forQuery, a
286315
.filter(
287316
profile =>
288317
!fromQuery ||
289-
(!fromQuery.includes(profile.id) && profile.id !== forQuery)
318+
(!fromQuery.includes(profile.id) && profile.id !== forQuery && !!!profile.inactive)
290319
)
291-
.map(profile => (
320+
.map((profile, index) => (
292321
<FeedbackExternalRecipientCard
293322
key={profile.id}
294323
recipientProfile={profile}
295324
onClick={() => cardClickHandler(profile.id)}
325+
onInactivateHandle={() => externalRecipientInactivate(profile.id)}
296326
/>
297327
))}
298328
</div>

0 commit comments

Comments
 (0)