Skip to content

Commit 675e9e5

Browse files
committed
Merge branch 'develop' into bugfix-2831/console-errors
2 parents 68a34b2 + 6975f56 commit 675e9e5

File tree

8 files changed

+114
-39
lines changed

8 files changed

+114
-39
lines changed

server/src/main/java/com/objectcomputing/checkins/services/pulseresponse/PulseResponseServicesImpl.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,9 @@ public Set<PulseResponse> findByFields(UUID teamMemberId, LocalDate dateFrom, Lo
133133
// The current user can view the pulse response if they are the team member who submitted the pulse response
134134
// or if they are the supervisor of the team member who submitted the pulse response
135135
private boolean canViewDueToReportingHierarchy(PulseResponse pulse, UUID currentUserId) {
136-
return pulse.getTeamMemberId().equals(currentUserId) ||
137-
isSubordinateTo(pulse.getTeamMemberId(), currentUserId);
136+
UUID id = pulse.getTeamMemberId();
137+
return id != null &&
138+
(id.equals(currentUserId) || isSubordinateTo(id, currentUserId));
138139
}
139140

140141
private boolean isSubordinateTo(UUID reportMember, UUID currentUserId) {

server/src/test/java/com/objectcomputing/checkins/services/fixture/PulseResponseFixture.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,9 @@ default PulseResponse createADefaultPulseResponse(MemberProfile memberprofile) {
1010
return getPulseResponseRepository().save(new PulseResponse(0, 0, LocalDate.now(),
1111
memberprofile.getId(), "internalfeelings", "externalfeelings"));
1212
}
13+
14+
default PulseResponse createADefaultAnonymousPulseResponse() {
15+
return getPulseResponseRepository().save(new PulseResponse(0, 0, LocalDate.now(),
16+
null, "internalfeelings", "externalfeelings"));
17+
}
1318
}

server/src/test/java/com/objectcomputing/checkins/services/pulseresponse/PulseResponseControllerTest.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,22 @@ void testGetFindByfindBySubmissionDateBetween() {
286286
assertEquals(Set.of(pulseResponse), response.body());
287287
}
288288

289+
@Test
290+
void testAnonymousGetFindByfindBySubmissionDateBetween() {
291+
MemberProfile memberProfile = createADefaultMemberProfile();
292+
293+
PulseResponse pulseResponse = createADefaultAnonymousPulseResponse();
294+
295+
LocalDate testDateFrom = LocalDate.of(2019, 1, 1);
296+
LocalDate testDateTo = Util.MAX.toLocalDate();
297+
298+
final HttpRequest<?> request = HttpRequest.GET(String.format("/?dateFrom=%tF&dateTo=%tF", testDateFrom, testDateTo)).basicAuth(memberProfile.getWorkEmail(), ADMIN_ROLE);
299+
final HttpResponse<Set<PulseResponse>> response = client.toBlocking().exchange(request, Argument.setOf(PulseResponse.class));
300+
301+
assertEquals(HttpStatus.OK, response.getStatus());
302+
assertEquals(Set.of(pulseResponse), response.body());
303+
}
304+
289305
@Test
290306
void testGetFindById() {
291307

web-ui/src/components/private-note/PrivateNote.jsx

Lines changed: 60 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,12 @@ import {
1212
selectIsPDL,
1313
selectIsAdmin,
1414
selectCheckin,
15-
selectProfile
15+
selectProfile,
16+
selectCanViewPrivateNotesPermission,
17+
selectCanCreatePrivateNotesPermission,
18+
selectCanUpdatePrivateNotesPermission,
1619
} from '../../context/selectors';
20+
import { UPDATE_TOAST } from '../../context/actions';
1721
import { debounce } from 'lodash/function';
1822
import { Editor } from '@tinymce/tinymce-react';
1923
import LockIcon from '@mui/icons-material/Lock';
@@ -49,19 +53,36 @@ const PrivateNote = () => {
4953

5054
useEffect(() => {
5155
async function getPrivateNotes() {
52-
setIsLoading(true);
53-
try {
54-
let res = await getPrivateNoteByCheckinId(checkinId, csrf);
55-
if (res.error) throw new Error(res.error);
56-
const currentNote =
57-
res.payload && res.payload.data && res.payload.data.length > 0
58-
? res.payload.data[0]
59-
: null;
60-
if (currentNote) {
61-
setNote(currentNote);
62-
} else if (currentUserId === pdlId) {
63-
if (!noteRef.current.some(id => id === checkinId)) {
64-
noteRef.current.push(checkinId);
56+
if (selectCanViewPrivateNotesPermission(state)) {
57+
setIsLoading(true);
58+
try {
59+
let res = await getPrivateNoteByCheckinId(checkinId, csrf);
60+
if (res.error) throw new Error(res.error);
61+
const currentNote =
62+
res.payload && res.payload.data && res.payload.data.length > 0
63+
? res.payload.data[0]
64+
: null;
65+
if (currentNote) {
66+
setNote(currentNote);
67+
} else if (currentUserId === pdlId) {
68+
if (!noteRef.current.some(id => id === checkinId) &&
69+
selectCanCreatePrivateNotesPermission(state)) {
70+
noteRef.current.push(checkinId);
71+
res = await createPrivateNote(
72+
{
73+
checkinid: checkinId,
74+
createdbyid: currentUserId,
75+
description: ''
76+
},
77+
csrf
78+
);
79+
noteRef.current = noteRef.current.filter(id => id !== checkinId);
80+
if (res.error) throw new Error(res.error);
81+
if (res && res.payload && res.payload.data) {
82+
setNote(res.payload.data);
83+
}
84+
}
85+
} else if (selectCanCreatePrivateNotesPermission(state)) {
6586
res = await createPrivateNote(
6687
{
6788
checkinid: checkinId,
@@ -70,37 +91,45 @@ const PrivateNote = () => {
7091
},
7192
csrf
7293
);
73-
noteRef.current = noteRef.current.filter(id => id !== checkinId);
7494
if (res.error) throw new Error(res.error);
7595
if (res && res.payload && res.payload.data) {
7696
setNote(res.payload.data);
7797
}
7898
}
79-
} else {
80-
res = await createPrivateNote(
81-
{
82-
checkinid: checkinId,
83-
createdbyid: currentUserId,
84-
description: ''
85-
},
86-
csrf
87-
);
88-
if (res.error) throw new Error(res.error);
89-
if (res && res.payload && res.payload.data) {
90-
setNote(res.payload.data);
91-
}
99+
} catch (e) {
100+
console.error("getPrivateNotes: " + e);
92101
}
93-
} catch (e) {
94-
console.error("getPrivateNotes: " + e);
102+
setIsLoading(false);
95103
}
96-
setIsLoading(false);
97104
}
98105
if (csrf) {
99106
getPrivateNotes();
100107
}
101108
}, [csrf, checkinId, currentUserId, pdlId]);
102109

103110
const handleNoteChange = (content, delta, source, editor) => {
111+
if (note == null) {
112+
window.snackDispatch({
113+
type: UPDATE_TOAST,
114+
payload: {
115+
severity: 'error',
116+
toast: selectCanCreatePrivateNotesPermission(state)
117+
? 'No private note was created'
118+
: 'No permission to create private notes'
119+
}
120+
});
121+
return;
122+
}
123+
if (!selectCanUpdatePrivateNotesPermission(state)) {
124+
window.snackDispatch({
125+
type: UPDATE_TOAST,
126+
payload: {
127+
severity: 'error',
128+
toast: 'No permission to update private notes'
129+
}
130+
});
131+
return;
132+
}
104133
if (Object.keys(note).length === 0 || !csrf || currentCheckin?.completed) {
105134
return;
106135
}

web-ui/src/context/reducer.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,11 @@ export const reducer = (state, action) => {
6868
state.userProfile.memberProfile.bioText = action.payload;
6969
break;
7070
case ADD_CHECKIN:
71-
state.checkins = [...state.checkins, action.payload];
71+
if (state?.checkins?.length > 0) {
72+
state.checkins = [...state.checkins, action.payload];
73+
} else {
74+
state.checkins = [action.payload];
75+
}
7276
break;
7377
case UPDATE_CHECKINS:
7478
if (state?.checkins?.length > 0) {

web-ui/src/context/selectors.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,18 @@ export const selectCanUpdateCheckinsPermission = hasPermission(
198198
'CAN_UPDATE_CHECKINS'
199199
);
200200

201+
export const selectCanViewPrivateNotesPermission = hasPermission(
202+
'CAN_VIEW_PRIVATE_NOTE'
203+
);
204+
205+
export const selectCanCreatePrivateNotesPermission = hasPermission(
206+
'CAN_CREATE_PRIVATE_NOTE'
207+
);
208+
209+
export const selectCanUpdatePrivateNotesPermission = hasPermission(
210+
'CAN_UPDATE_PRIVATE_NOTE'
211+
);
212+
201213
export const selectIsPDL = createSelector(
202214
selectUserProfile,
203215
userProfile =>

web-ui/src/pages/CheckinsPage.jsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
selectCheckinsForMember,
1616
selectCanViewCheckinsPermission,
1717
selectCanUpdateCheckinsPermission,
18+
selectCanViewPrivateNotesPermission,
1819
} from '../context/selectors';
1920
import { getCheckins, createNewCheckin } from '../context/thunks';
2021
import { UPDATE_CHECKIN, UPDATE_TOAST } from '../context/actions';
@@ -92,6 +93,7 @@ const CheckinsPage = () => {
9293
const isPdl = selectIsPDL(state);
9394

9495
const canViewPrivateNote =
96+
selectCanViewPrivateNotesPermission(state) &&
9597
(isAdmin || selectedProfile?.pdlId === currentUserId) &&
9698
currentUserId !== memberId;
9799

web-ui/src/pages/ErrorBoundaryPage.jsx

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,21 @@ const ErrorFallback = ({ error }) => {
4040
//before upload to server
4141
let sanitizeBody = sanitizeQuillElements(body);
4242
let res = await newGitHubIssue(sanitizeBody, title, csrf);
43-
if (res && res.payload) {
43+
if (res?.error) {
44+
window.snackDispatch({
45+
type: UPDATE_TOAST,
46+
payload: {
47+
severity: 'error',
48+
toast: res.error.message,
49+
}
50+
});
51+
} else if (res?.payload?.data) {
4452
setLink(res.payload.data[0].html_url);
4553
window.snackDispatch({
4654
type: UPDATE_TOAST,
4755
payload: {
48-
severity: !res.error ? 'success' : 'error',
49-
toast: !res.error
50-
? `New issue ${title} created! Gratzie &#128512`
51-
: res.error.message
56+
severity: 'success',
57+
toast: `New issue ${title} created! Gratzie &#128512`,
5258
}
5359
});
5460
}

0 commit comments

Comments
 (0)