Skip to content

Commit 79be28c

Browse files
authored
Merge branch 'develop' into bugfix-2660/volunteer-tracking
2 parents da6f9b9 + 2ce9eac commit 79be28c

File tree

10 files changed

+133
-72
lines changed

10 files changed

+133
-72
lines changed

server/src/main/java/com/objectcomputing/checkins/services/memberprofile/anniversaryreport/AnniversaryReportServicesImpl.java

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import com.objectcomputing.checkins.exceptions.PermissionException;
44
import com.objectcomputing.checkins.services.memberprofile.MemberProfile;
55
import com.objectcomputing.checkins.services.memberprofile.MemberProfileServices;
6-
import com.objectcomputing.checkins.services.memberprofile.currentuser.CurrentUserServices;
76
import io.micronaut.core.annotation.Nullable;
87
import jakarta.inject.Singleton;
98

@@ -18,20 +17,13 @@
1817
public class AnniversaryReportServicesImpl implements AnniversaryServices {
1918

2019
private final MemberProfileServices memberProfileServices;
21-
private final CurrentUserServices currentUserServices;
2220

23-
public AnniversaryReportServicesImpl(MemberProfileServices memberProfileServices,
24-
CurrentUserServices currentUserServices) {
21+
public AnniversaryReportServicesImpl(MemberProfileServices memberProfileServices) {
2522
this.memberProfileServices = memberProfileServices;
26-
this.currentUserServices = currentUserServices;
2723
}
2824

2925
@Override
3026
public List<AnniversaryReportResponseDTO> findByValue(@Nullable String[] months) {
31-
if (!currentUserServices.isAdmin()) {
32-
throw new PermissionException("You do not have permission to access this resource.");
33-
}
34-
3527
List<MemberProfile> memberProfileAll = new ArrayList<>();
3628
Set<MemberProfile> memberProfiles = memberProfileServices.findByValues(null, null, null, null, null, null,
3729
false);

server/src/main/java/com/objectcomputing/checkins/services/memberprofile/birthday/BirthDayServicesImpl.java

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import com.objectcomputing.checkins.exceptions.PermissionException;
44
import com.objectcomputing.checkins.services.memberprofile.MemberProfile;
55
import com.objectcomputing.checkins.services.memberprofile.MemberProfileServices;
6-
import com.objectcomputing.checkins.services.memberprofile.currentuser.CurrentUserServices;
76

87
import jakarta.inject.Singleton;
98
import java.time.LocalDate;
@@ -15,19 +14,13 @@
1514
public class BirthDayServicesImpl implements BirthDayServices{
1615

1716
private final MemberProfileServices memberProfileServices;
18-
private final CurrentUserServices currentUserServices;
1917

20-
public BirthDayServicesImpl(MemberProfileServices memberProfileServices, CurrentUserServices currentUserServices) {
18+
public BirthDayServicesImpl(MemberProfileServices memberProfileServices) {
2119
this.memberProfileServices = memberProfileServices;
22-
this.currentUserServices = currentUserServices;
2320
}
2421

2522
@Override
2623
public List<BirthDayResponseDTO> findByValue(String[] months, Integer[] daysOfMonth) {
27-
if (!currentUserServices.isAdmin()) {
28-
throw new PermissionException("You do not have permission to access this resource.");
29-
}
30-
3124
Set<MemberProfile> memberProfiles = memberProfileServices.findByValues(null, null, null, null, null, null, false);
3225
List<MemberProfile> memberProfileAll = new ArrayList<>(memberProfiles);
3326
if (months != null) {

server/src/main/resources/db/dev/R__Load_testing_data.sql

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1298,22 +1298,32 @@ INSERT INTO review_periods
12981298
VALUES
12991299
('12345678-e29c-4cf4-9ea4-6baa09405c58', 'Review Period 2', 'PLANNING', 'd1e94b60-47c4-4945-87d1-4dc88f088e57', '926a37a4-4ded-4633-8900-715b0383aecc', '2024-09-10 06:00:00', '2024-09-11 06:00:00', '2024-09-12 06:00:00', '2024-01-01 06:00:00', '2024-08-31 06:00:00');
13001300

1301+
INSERT INTO review_periods
1302+
(id, name, review_status, review_template_id, self_review_template_id, launch_date, self_review_close_date, close_date, period_start_date, period_end_date)
1303+
VALUES
1304+
('12345678-e29c-4cf4-9ea4-6baa09405c59', 'Review Period 3', 'CLOSED', 'd1e94b60-47c4-4945-87d1-4dc88f088e57', '926a37a4-4ded-4633-8900-715b0383aecc', '2024-10-01 06:00:00', '2024-10-02 06:00:00', '2024-10-03 06:00:00', '2024-01-01 06:00:00', '2024-09-30 06:00:00');
1305+
1306+
INSERT INTO review_periods
1307+
(id, name, review_status, review_template_id, self_review_template_id, launch_date, self_review_close_date, close_date, period_start_date, period_end_date)
1308+
VALUES
1309+
('12345678-e29c-4cf4-9ea4-6baa09405c5a', 'Review Period 4', 'CLOSED', 'd1e94b60-47c4-4945-87d1-4dc88f088e57', '926a37a4-4ded-4633-8900-715b0383aecc', '2024-10-01 06:00:00', '2024-10-02 06:00:00', '2024-10-03 06:00:00', '2024-01-01 06:00:00', '2024-09-30 06:00:00');
1310+
13011311
-- CAE - Self-Review feedback request, Creator: Big Boss
13021312
INSERT INTO feedback_requests
13031313
(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status, review_period_id)
13041314
VALUES
1305-
('98390c09-7121-110a-bfee-9380a470a7ef', '72655c4f-1fb8-4514-b31e-7f7e19fa9bd7', 'c7406157-a38f-4d48-aaed-04018d846727', 'c7406157-a38f-4d48-aaed-04018d846727', '926a37a4-4ded-4633-8900-715b0383aecc', '2024-09-04', '2024-09-30', '2024-09-05', 'submitted', '12345678-e29c-4cf4-9ea4-6baa09405c57');
1315+
('98390c09-7121-110a-bfee-9380a470a7ef', '72655c4f-1fb8-4514-b31e-7f7e19fa9bd7', 'c7406157-a38f-4d48-aaed-04018d846727', 'c7406157-a38f-4d48-aaed-04018d846727', '926a37a4-4ded-4633-8900-715b0383aecc', '2024-10-04', '2024-10-30', '2024-10-05', 'submitted', '12345678-e29c-4cf4-9ea4-6baa09405c59');
13061316

13071317
-- CAE - Review feedback request, Creator: Big Boss
13081318
INSERT INTO feedback_requests
13091319
(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status, review_period_id)
13101320
VALUES
1311-
('98390c09-7121-110a-bfee-9380a470a7f0', '72655c4f-1fb8-4514-b31e-7f7e19fa9bd7', 'c7406157-a38f-4d48-aaed-04018d846727', '6207b3fd-042d-49aa-9e28-dcc04f537c2d', 'd1e94b60-47c4-4945-87d1-4dc88f088e57', '2024-09-04', '2024-09-30', '2024-09-05', 'submitted', '12345678-e29c-4cf4-9ea4-6baa09405c57');
1321+
('98390c09-7121-110a-bfee-9380a470a7f0', '72655c4f-1fb8-4514-b31e-7f7e19fa9bd7', 'c7406157-a38f-4d48-aaed-04018d846727', '6207b3fd-042d-49aa-9e28-dcc04f537c2d', 'd1e94b60-47c4-4945-87d1-4dc88f088e57', '2024-10-04', '2024-10-30', '2024-10-05', 'submitted', '12345678-e29c-4cf4-9ea4-6baa09405c59');
13121322

13131323
INSERT INTO feedback_requests
13141324
(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status, review_period_id)
13151325
VALUES
1316-
('98390c09-7121-110a-bfee-9380a470a7f3', '72655c4f-1fb8-4514-b31e-7f7e19fa9bd7', 'c7406157-a38f-4d48-aaed-04018d846727', 'dfe2f986-fac0-11eb-9a03-0242ac130003', 'd1e94b60-47c4-4945-87d1-4dc88f088e57', '2024-09-04', '2024-09-30', '2024-09-05', 'submitted', '12345678-e29c-4cf4-9ea4-6baa09405c57');
1326+
('98390c09-7121-110a-bfee-9380a470a7f3', '72655c4f-1fb8-4514-b31e-7f7e19fa9bd7', 'c7406157-a38f-4d48-aaed-04018d846727', 'dfe2f986-fac0-11eb-9a03-0242ac130003', 'd1e94b60-47c4-4945-87d1-4dc88f088e57', '2024-10-04', '2024-10-30', '2024-10-05', 'submitted', '12345678-e29c-4cf4-9ea4-6baa09405c59');
13171327

13181328
INSERT INTO feedback_requests
13191329
(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status, review_period_id)
@@ -1344,7 +1354,7 @@ VALUES
13441354
INSERT INTO feedback_requests
13451355
(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status, review_period_id)
13461356
VALUES
1347-
('98390c09-7121-110a-bfee-9380a470a7f2', '72655c4f-1fb8-4514-b31e-7f7e19fa9bd7', 'c7406157-a38f-4d48-aaed-04018d846727', 'dfe2f986-fac0-11eb-9a03-0242ac130003', '1c8bc142-c447-4889-986e-42ab177da683', '2024-09-04', '2024-09-30', '2024-09-05', 'submitted', '12345678-e29c-4cf4-9ea4-6baa09405c57');
1357+
('98390c09-7121-110a-bfee-9380a470a7f2', '72655c4f-1fb8-4514-b31e-7f7e19fa9bd7', 'c7406157-a38f-4d48-aaed-04018d846727', 'dfe2f986-fac0-11eb-9a03-0242ac130003', '1c8bc142-c447-4889-986e-42ab177da683', '2024-10-04', '2024-10-30', '2024-10-05', 'submitted', '12345678-e29c-4cf4-9ea4-6baa09405c59');
13481358

13491359
---- Creator: Big Boss
13501360
INSERT INTO feedback_requests

web-ui/src/components/reviews/TeamReviews.jsx

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,10 @@ import {
6868
selectReviewPeriod,
6969
selectSupervisors,
7070
selectProfile,
71-
selectTeamMembersBySupervisorId
71+
selectTeamMembersBySupervisorId,
72+
selectHasCreateReviewAssignmentsPermission,
73+
selectHasDeleteReviewAssignmentsPermission,
74+
selectHasUpdateReviewAssignmentsPermission,
7275
} from '../../context/selectors';
7376

7477
import MemberSelector from '../member_selector/MemberSelector';
@@ -127,9 +130,11 @@ const TeamReviews = ({ onBack, periodId }) => {
127130
const location = useLocation();
128131

129132
const [openMode, setOpenMode] = useState(false);
130-
const [approvalMode, setApprovalMode] = useState(false);
133+
const [managerApprovalMode, setManagerApprovalMode] = useState(false);
134+
const [approvalState, setApprovalState] = useState(false);
131135
const [assignments, setAssignments] = useState([]);
132136
const [canUpdate, setCanUpdate] = useState(false);
137+
const [canApprove, setCanApprove] = useState(false);
133138
const [confirmApproveAllOpen, setConfirmApproveAllOpen] = useState(false);
134139
const [confirmationDialogOpen, setConfirmationDialogOpen] = useState(false);
135140
const [confirmationText, setConfirmationText] = useState('');
@@ -173,19 +178,22 @@ const TeamReviews = ({ onBack, periodId }) => {
173178
const isManager = supervisors.some(s => s.id === myId);
174179
const period = selectReviewPeriod(state, periodId);
175180
if (period) {
176-
setApprovalMode(
177-
isManager && period.reviewStatus === ReviewStatus.AWAITING_APPROVAL
178-
);
179-
setOpenMode(isManager && period.reviewStatus === ReviewStatus.OPEN);
181+
setApprovalState(period.reviewStatus === ReviewStatus.AWAITING_APPROVAL);
182+
setManagerApprovalMode(isManager && approvalState);
180183
}
181184

182-
setCanUpdate(selectHasUpdateReviewPeriodPermission(state) &&
183-
period?.reviewStatus !== ReviewStatus.OPEN);
185+
setOpenMode(period?.reviewStatus === ReviewStatus.OPEN);
186+
setCanUpdate(!openMode &&
187+
selectHasUpdateReviewPeriodPermission(state));
188+
setCanApprove(approvalState &&
189+
selectHasUpdateReviewAssignmentsPermission(state));
190+
191+
184192
}, [state]);
185193

186194
useEffect(() => {
187195
loadTeamMembers();
188-
}, [approvalMode, assignments, showAll]);
196+
}, [managerApprovalMode, assignments, showAll]);
189197

190198
const editReviewers = member => {
191199
setSelectedMember(member);
@@ -205,7 +213,7 @@ const TeamReviews = ({ onBack, periodId }) => {
205213

206214
const loadTeamMembers = () => {
207215
let source;
208-
if (!approvalMode || (isAdmin && showAll)) {
216+
if (!managerApprovalMode || (isAdmin && showAll)) {
209217
source = currentMembers;
210218
} else {
211219
// Get the direct reports of the current user who is a manager.
@@ -769,7 +777,8 @@ const TeamReviews = ({ onBack, periodId }) => {
769777
key={reviewer.id}
770778
label={openMode ? statusLabel : reviewerName}
771779
variant={variant}
772-
onDelete={canUpdate && !openMode && hasReviewer ?
780+
onDelete={!openMode && hasReviewer &&
781+
selectHasDeleteReviewAssignmentsPermission(state) ?
773782
() => deleteReviewer(member, reviewer) : null}
774783
style={{backgroundColor: backgroundColor}}
775784
/>);
@@ -901,7 +910,7 @@ const TeamReviews = ({ onBack, periodId }) => {
901910

902911
const visibleTeamMembers = () => {
903912
const query = nameQuery.trim().toLowerCase();
904-
if (!approvalMode || query.length === 0) return teamMembers;
913+
if (!managerApprovalMode || query.length === 0) return teamMembers;
905914

906915
return teamMembers.filter(member =>
907916
member.name.toLowerCase().includes(query)
@@ -962,7 +971,7 @@ const TeamReviews = ({ onBack, periodId }) => {
962971
</Alert>
963972
)}
964973

965-
{approvalMode && (
974+
{approvalState && (
966975
<div id="approval-row" style={{ display: 'flex', alignItems: 'center' }}>
967976
{/* Wrapper div for TextField and Switch */}
968977
<div style={{ display: 'flex', alignItems: 'center', flexGrow: 1 }}>
@@ -997,7 +1006,7 @@ const TeamReviews = ({ onBack, periodId }) => {
9971006
)}
9981007
</div>
9991008
{/* Button aligned to the right */}
1000-
{canUpdate && (
1009+
{canApprove && (
10011010
<div style={{ marginLeft: 'auto' }}>
10021011
<Button onClick={() => setConfirmApproveAllOpen(true)}>
10031012
Approve All
@@ -1035,7 +1044,9 @@ const TeamReviews = ({ onBack, periodId }) => {
10351044
<Typography>Reviewers:</Typography>
10361045
{renderReviewers(member)}
10371046

1038-
{canUpdate && (
1047+
{!openMode &&
1048+
selectHasCreateReviewAssignmentsPermission(state) &&
1049+
selectHasDeleteReviewAssignmentsPermission(state) && (
10391050
<IconButton
10401051
aria-label="Edit Reviewers"
10411052
onClick={() => editReviewers(member)}
@@ -1044,7 +1055,8 @@ const TeamReviews = ({ onBack, periodId }) => {
10441055
</IconButton>
10451056
)}
10461057

1047-
{canUpdate && approvalMode && (
1058+
{canApprove &&
1059+
selectHasUpdateReviewAssignmentsPermission(state) && (
10481060
<Button onClick={() => toggleApproval(member)}>
10491061
{isMemberApproved(member) ? 'Unapprove' : 'Approve'}
10501062
</Button>

web-ui/src/components/reviews/periods/ReviewPeriods.jsx

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,15 @@ const ReviewStatus = {
9999
UNKNOWN: 'UNKNOWN'
100100
};
101101

102+
// mode will be either "self" or undefined.
103+
const selfReviewMode = "self";
104+
102105
const ReviewPeriods = ({ onPeriodSelected, mode }) => {
103106
const { state, dispatch } = useContext(AppContext);
104107

105108
const [canSave, setCanSave] = useState(false);
106109
const [loading, setLoading] = useState(false);
110+
const [periods, setPeriods] = useState([]);
107111
const [periodToAdd, setPeriodToAdd] = useState({
108112
name: '',
109113
reviewStatus: ReviewStatus.PLANNING,
@@ -119,9 +123,15 @@ const ReviewPeriods = ({ onPeriodSelected, mode }) => {
119123

120124
const currentUserId = selectCurrentUserId(state);
121125
const csrf = selectCsrfToken(state);
122-
const periods = selectReviewPeriods(state);
123126
const userProfile = selectUserProfile(state);
124127

128+
useEffect(() => {
129+
setPeriods(selectReviewPeriods(state)
130+
.filter((r) => mode !== selfReviewMode ||
131+
r.reviewStatus === ReviewStatus.OPEN ||
132+
r.reviewStatus === ReviewStatus.CLOSED));
133+
}, [state, mode]);
134+
125135
useQueryParameters([
126136
{
127137
name: 'add',
@@ -255,6 +265,7 @@ const ReviewPeriods = ({ onPeriodSelected, mode }) => {
255265

256266
useEffect(() => {
257267
const getSelfReviews = async () => {
268+
setLoading(true);
258269
let reviews = {};
259270
Promise.all(
260271
periods.map(async period => {
@@ -280,7 +291,17 @@ const ReviewPeriods = ({ onPeriodSelected, mode }) => {
280291
});
281292
}
282293
})
283-
).then(() => setSelfReviews(reviews));
294+
).then(() => {
295+
// Now that we have the reviews loaded, filter out closed
296+
// self-review periods in which the current user is not involved.
297+
if (mode == selfReviewMode) {
298+
setPeriods(periods.filter((r) =>
299+
r.reviewStatus !== ReviewStatus.CLOSED ||
300+
!!reviews[r.id]));
301+
}
302+
setSelfReviews(reviews);
303+
setLoading(false);
304+
});
284305
};
285306
if (
286307
csrf &&
@@ -291,18 +312,17 @@ const ReviewPeriods = ({ onPeriodSelected, mode }) => {
291312
) {
292313
getSelfReviews();
293314
}
294-
}, [csrf, periods, currentUserId, selfReviews]);
315+
}, [csrf, periods, currentUserId, selfReviews ]);
295316

296317
const onPeriodClick = useCallback(
297318
id => {
298319
const status = selectReviewPeriod(state, id)?.reviewStatus;
299320
switch (status) {
300321
case ReviewStatus.PLANNING:
301-
onPeriodSelected(id);
302-
break;
303322
case ReviewStatus.AWAITING_APPROVAL:
304-
// TODO: Check for the required permission.
305-
onPeriodSelected(id);
323+
if (mode !== selfReviewMode) {
324+
onPeriodSelected(id);
325+
}
306326
break;
307327
case ReviewStatus.OPEN:
308328
onPeriodSelected(id);

web-ui/src/components/settings/types/boolean.jsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ import { createLabelId } from '../../../helpers/strings.js';
1515
*/
1616
const SettingsBoolean = ({ name, description, value, handleChange }) => {
1717
const labelId = createLabelId(name);
18-
18+
const checked =
19+
typeof(value) === 'boolean' ? value : value.toLowerCase() == "true";
1920
return (
2021
<div className="settings-type">
2122
<label htmlFor={labelId}>
@@ -28,7 +29,7 @@ const SettingsBoolean = ({ name, description, value, handleChange }) => {
2829
id={labelId}
2930
className="settings-control"
3031
type="checkbox"
31-
checked={value}
32+
checked={checked}
3233
onChange={handleChange}
3334
/>
3435
</div>

web-ui/src/components/volunteer/VolunteerRelationships.jsx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,17 @@ const VolunteerRelationships = ({ forceUpdate = () => {}, onlyMe = false }) => {
183183

184184
const formattedStartDate = startDate ? formatDate(new Date(startDate)) : null;
185185
const formattedEndDate = endDate ? formatDate(new Date(endDate)) : null;
186-
186+
187+
const data = {
188+
...selectedRelationship,
189+
startDate: formattedStartDate,
190+
endDate: formattedEndDate
191+
};
192+
if (!id && !data.memberId) {
193+
// For new relationships, a memberId is required.
194+
data.memberId = currentUser.id;
195+
}
196+
187197
const res = await resolve({
188198
method: id ? 'PUT' : 'POST',
189199
url: id ? `${relationshipBaseUrl}/${id}` : relationshipBaseUrl,
@@ -192,7 +202,7 @@ const VolunteerRelationships = ({ forceUpdate = () => {}, onlyMe = false }) => {
192202
Accept: 'application/json',
193203
'Content-Type': 'application/json;charset=UTF-8',
194204
},
195-
data: { ...selectedRelationship, startDate: formattedStartDate, endDate: formattedEndDate },
205+
data: data,
196206
});
197207

198208
if (res.error) return;

0 commit comments

Comments
 (0)