Skip to content

Commit

Permalink
Merge pull request #1002 from WildMeOrg/issue-756-merge-individual
Browse files Browse the repository at this point in the history
Issue 756 merge individual automation and notification fixes
  • Loading branch information
naknomum authored Feb 22, 2025
2 parents 971a6f2 + 38e85ef commit bef6e05
Show file tree
Hide file tree
Showing 10 changed files with 119 additions and 67 deletions.
27 changes: 15 additions & 12 deletions frontend/src/components/navBar/MergeMessages.jsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
import React, { useState } from "react";
import BrutalismButton from "../BrutalismButton";
import { FormattedMessage } from "react-intl";
import changeIndividualMergeState from "../../models/notifications/changeIndividualMergeState";

export default function MergeMessages({
mergeData,
getAllNotifications,
setModalOpen,
}) {
const handleClick = () => {
// const result = changeIndividualMergeState(action, taskId);
// setError('Error: ' + result);
getAllNotifications();
setModalOpen(false);
const [error, setError] = useState(false);
const handleClick = async (action, taskId) => {
const result = await changeIndividualMergeState(action, taskId);
if (result.status === 200) {
getAllNotifications();
setModalOpen(false);
} else {
setError(true);
}
};

// eslint-disable-next-line no-unused-vars
const [showError, setShowError] = useState(false);
// eslint-disable-next-line no-unused-vars
const [error, setError] = useState("");

const content = mergeData?.map((data) => {
const mergePending = data.notificationType === "mergePending";
const mergeComplete = data.notificationType === "mergeComplete";
Expand Down Expand Up @@ -103,7 +103,6 @@ export default function MergeMessages({
display: "flex",
marginTop: "10px",
marginBottom: "10px",
// width: 105
}}
>
<BrutalismButton onClick={() => handleClick("ignore", data.taskId)}>
Expand Down Expand Up @@ -167,7 +166,11 @@ export default function MergeMessages({
</h4>
)}
{content}
{showError && <h6>{error}</h6>}
{error && (
<h4>
<FormattedMessage id="BEERROR_UNKNOWN" />
</h4>
)}
</div>
);
}
31 changes: 14 additions & 17 deletions frontend/src/models/notifications/changeIndividualMergeState.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
import axios from 'axios';
import axios from "axios";

export default async function changeIndividualMergeState(action, mergeId) {
let json = {};
json["mergeId"] = mergeId;
json["action"] = action;

let json = {};
json['mergeId'] = mergeId;
json['action'] = action;

console.log("Trying to change individual merge state on mergeId "+mergeId+" to "+action+".");

const response = await axios.post('/ScheduledIndividualMergeUpdate', json, {
headers: {
'Content-Type': 'application/json'
}
try {
const response = await axios.post("/ScheduledIndividualMergeUpdate", json, {
headers: {
"Content-Type": "application/json",
},
});

console.log('changeIndividualMergeState result:', response.json());

return response.json();

}
return response;
} catch (error) {
return error;
}
}
4 changes: 3 additions & 1 deletion src/main/java/org/ecocean/MarkedIndividual.java
Original file line number Diff line number Diff line change
Expand Up @@ -2599,7 +2599,9 @@ public void mergeIndividual(MarkedIndividual other, String username, Shepherd my
+ other.getIndividualID() + "' || secondaryIndividual.individualID == '" +
other.getIndividualID() + "'";
Query q = myShepherd.getPM().newQuery(filter);
Collection c = (Collection)q.execute();
Collection cTemp = (Collection)q.execute();
ArrayList<ScheduledIndividualMerge> c = new ArrayList<ScheduledIndividualMerge>(cTemp);
q.closeAll();
ArrayList<ScheduledIndividualMerge> merges = new ArrayList<ScheduledIndividualMerge>(c);
// throw out any scheduled merge related to this individual as it is now being merged.
for (ScheduledIndividualMerge merge : merges) {
Expand Down
7 changes: 3 additions & 4 deletions src/main/java/org/ecocean/StartupWildbook.java
Original file line number Diff line number Diff line change
Expand Up @@ -290,19 +290,18 @@ private static void startWildbookScheduledTaskThread(String context) {
System.out.println("[INFO]: checking for scheduled tasks to execute...");
Shepherd myShepherd = new Shepherd(context);
myShepherd.setAction("WildbookScheduledTaskThread");
myShepherd.beginDBTransaction();
try {
ArrayList<WildbookScheduledTask> scheduledTasks =
myShepherd.getAllIncompleteWildbookScheduledTasks();
ArrayList<WildbookScheduledTask> scheduledTasks = myShepherd.getAllIncompleteWildbookScheduledTasks();
for (WildbookScheduledTask scheduledTask : scheduledTasks) {
if (scheduledTask.isTaskEligibleForExecution()) {
scheduledTask.execute(myShepherd);
}
}
} catch (Exception e) {
myShepherd.rollbackAndClose();
e.printStackTrace();
}
myShepherd.closeDBTransaction();
myShepherd.rollbackAndClose();
}
}, 0, 1, TimeUnit.HOURS);
}
Expand Down
51 changes: 38 additions & 13 deletions src/main/java/org/ecocean/scheduled/ScheduledIndividualMerge.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class ScheduledIndividualMerge extends WildbookScheduledTask {

private MarkedIndividual primaryIndividual = null;
private MarkedIndividual secondaryIndividual = null;
// participant names, with Boolean list of denied state in position 0, ignored state in position 2.
// participant names, with Boolean list of denied state in position 0, ignored state in position 1.
private HashMap<String, ArrayList<Boolean> > participantsDeniedIgnored = new HashMap<>();

private List<String> participants = new ArrayList<>();
Expand All @@ -36,21 +36,22 @@ public ScheduledIndividualMerge(MarkedIndividual primaryIndividual,
+ this.scheduledTaskType + ". Failed.");
}


@Override public void execute(Shepherd myShepherd) {
try {
myShepherd.beginDBTransaction();

// if not denied by a user !
mergeIndividuals(primaryIndividual, secondaryIndividual, myShepherd);

this.setTaskComplete();
myShepherd.updateDBTransaction();

} catch (Exception e) {
myShepherd.rollbackDBTransaction();
this.setTaskIncomplete();
//rollback this Shepherd to unwind this task and re-open the Shepherd in case it is being reused by a subsequent Task
myShepherd.rollbackDBTransaction();
myShepherd.beginDBTransaction();
e.printStackTrace();
} finally {
myShepherd.updateDBTransaction();
}

}

private void mergeIndividuals(MarkedIndividual primaryIndividual,
Expand Down Expand Up @@ -113,46 +114,70 @@ public List<String> getParticipantUsernames() {
}

public void setTaskDeniedStateForUser(String username, boolean denied) {
List<Boolean> stateForUser = participantsDeniedIgnored.get(username);
ArrayList<Boolean> stateForUser = participantsDeniedIgnored.get(username);

if (stateForUser != null) {
stateForUser.add(0, denied);
}
participantsDeniedIgnored.put(username, stateForUser);
System.out.println("setTaskDeniedStateForUser:participantsDeniedIgnored:"+participantsDeniedIgnored.toString());
}

public void setTaskIgnoredStateForUser(String username, boolean ignored) {
List<Boolean> stateForUser = participantsDeniedIgnored.get(username);
ArrayList<Boolean> stateForUser = participantsDeniedIgnored.get(username);

if (stateForUser != null) {
stateForUser.add(1, ignored);
}

participantsDeniedIgnored.put(username, stateForUser);
System.out.println("setTaskIgnoredStateForUser:participantsDeniedIgnored:"+participantsDeniedIgnored.toString());
}

public boolean deniedByUser(String username) {
List<Boolean> stateForUser = participantsDeniedIgnored.get(username);

if (stateForUser == null) return Boolean.FALSE;
return stateForUser.get(0);
if (stateForUser != null && stateForUser.get(0)) {
return true;
}

return false;
}

public boolean ignoredByUser(String username) {

System.out.println("ignoredByUser: Participants: "+participants.toString());
System.out.println("ignoredByUser: Participants that denied: "+participantsDeniedIgnored.toString());

List<Boolean> stateForUser = participantsDeniedIgnored.get(username);

if (stateForUser == null) return Boolean.FALSE;
return stateForUser.get(1);
if (stateForUser != null && stateForUser.get(1)) {
return true;
}

return false;
}

public String getUsernameThatDeniedMerge() {

System.out.println("getUsernameThatDeniedMerge(): Participants: "+participants.toString());
System.out.println("getUsernameThatDeniedMerge():Participants that denied: "+participantsDeniedIgnored.toString());

for (String participant : participants) {
if (participantsDeniedIgnored.get(participant) != null &&
participantsDeniedIgnored.get(participant).get(0)) {
System.out.println("...was denied by: "+participant);
return participant;
}
}
System.out.println("...returning null.");
return null;
}

public boolean isDenied() {
System.out.println("isDenied: Participants: "+participants.toString());
System.out.println("isDenied: Participants that denied: "+participantsDeniedIgnored.toString());

return getUsernameThatDeniedMerge() != null;
}

Expand Down
10 changes: 8 additions & 2 deletions src/main/java/org/ecocean/security/Collaboration.java
Original file line number Diff line number Diff line change
Expand Up @@ -357,8 +357,14 @@ public static String getNotificationsWidgetHtml(HttpServletRequest request,
try {
ArrayList<ScheduledIndividualMerge> potentialForNotification =
myShepherd.getAllCompleteScheduledIndividualMergesForUsername(username);
ArrayList<ScheduledIndividualMerge> incomplete =
myShepherd.getAllIncompleteScheduledIndividualMerges();

System.out.println("Collaboration:potentialForNotification: "+potentialForNotification.size());

ArrayList<ScheduledIndividualMerge> incomplete = myShepherd.getAllIncompleteScheduledIndividualMerges();

System.out.println("Collaboration:incomplete: "+incomplete.size());


potentialForNotification.addAll(incomplete);
for (ScheduledIndividualMerge merge : potentialForNotification) {
if (!merge.ignoredByUser(username) && merge.isUserParticipent(username)) {
Expand Down
28 changes: 16 additions & 12 deletions src/main/java/org/ecocean/servlet/MergeIndividual.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@
import org.ecocean.security.Collaboration;

public class MergeIndividual extends HttpServlet {
Shepherd myShepherd;
PrintWriter out;
boolean locked = false;



public void init(ServletConfig config)
throws ServletException {
Expand All @@ -30,8 +29,12 @@ public void doGet(HttpServletRequest request, HttpServletResponse response)

public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

PrintWriter out = response.getWriter();
boolean locked = false;

response.setContentType("text/html");
out = response.getWriter();


String id1 = request.getParameter("id1");
String id2 = request.getParameter("id2");
Expand All @@ -40,18 +43,19 @@ public void doPost(HttpServletRequest request, HttpServletResponse response)
"<strong>Error:</strong> Missing two valid individualIDs for MergeIndividual. ";
if (id1 == null) msg += "<br>Bad id1: " + id1;
if (id2 == null) msg += "<br>Bad id2: " + id2;
errorAndClose(msg, response);
errorAndClose(msg, response,out);
return;
}
String oldName1;
String oldName2;
boolean canMergeAutomatically = false;


myShepherd = new Shepherd(request);
Shepherd myShepherd = new Shepherd(request);
myShepherd.setAction("MergeIndividual.class");

myShepherd.beginDBTransaction();
try {
myShepherd.beginDBTransaction();


MarkedIndividual mark1 = myShepherd.getMarkedIndividualQuiet(id1);
MarkedIndividual mark2 = myShepherd.getMarkedIndividualQuiet(id2);
Expand All @@ -60,7 +64,7 @@ public void doPost(HttpServletRequest request, HttpServletResponse response)
"<strong>Error:</strong> Could not find both individuals in our database. ";
if (mark1 == null) msg += "<br>could not find individual " + mark1;
if (mark2 == null) msg += "<br>could not find individual " + mark2;
errorAndClose(msg, response);
errorAndClose(msg, response,out);
myShepherd.rollbackDBTransaction();
myShepherd.closeDBTransaction();
return;
Expand Down Expand Up @@ -161,7 +165,7 @@ public void doPost(HttpServletRequest request, HttpServletResponse response)
}
} catch (Exception le) {
le.printStackTrace();
errorAndClose("An exception occurred. Please contact the admins.", response);
errorAndClose("An exception occurred. Please contact the admins.", response, out);
myShepherd.rollbackDBTransaction();
myShepherd.closeDBTransaction();
return;
Expand Down Expand Up @@ -190,11 +194,11 @@ public void doPost(HttpServletRequest request, HttpServletResponse response)
} else {
errorAndClose(
"<strong>Failure!</strong> This encounter is currently being modified by another user, or an exception occurred. Please wait a few seconds before trying to modify this encounter again.",
response);
response,out);
}
}

private void errorAndClose(String msg, HttpServletResponse response) {
private void errorAndClose(String msg, HttpServletResponse response, PrintWriter out) {
// out.println(ServletUtilities.getHeader(request));
out.println(msg);
// out.println("<p><a href=\"http://"+CommonConfiguration.getURLLocation(request)+"/encounters/encounter.jsp?number="+encNum+"\">Return to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,12 @@ public class ScheduledIndividualMergeUpdate extends HttpServlet {
if (merge != null && merge.isUserParticipent(username)) {
System.out.println("user is participant? " + merge.isUserParticipent(username));
if ("deny".equals(action)) {
//I denied it
merge.setTaskDeniedStateForUser(username, true);
//I am therefore ignoring it too
merge.setTaskIgnoredStateForUser(username, true);
//and let's call it done
merge.setTaskComplete();
myShepherd.updateDBTransaction();
System.out.println("Set ScheduledIndividual merge " + mergeId +
" to DENIED for user " + username + ".");
Expand Down
19 changes: 13 additions & 6 deletions src/main/java/org/ecocean/servlet/UserGetNotifications.java
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,14 @@ private JSONArray addAllScheduledIndividualMergeNotifications(JSONArray notifica
if (pendingMerge.isUserParticipent(username)) {
System.out.println("Is pending merge ignored by user? : " +
pendingMerge.ignoredByUser(username));
if (pendingMerge.isDenied() && !pendingMerge.ignoredByUser(username)) {
notificationArr.put(individualMergeDeniedNotification(pendingMerge, username,
myShepherd, request));
} else if (!pendingMerge.ignoredByUser(username)) {
if (!pendingMerge.isDenied() && !pendingMerge.ignoredByUser(username)) {
notificationArr.put(individualMergePendingNotification(pendingMerge, username,
myShepherd, request));
}
}
//else if (!pendingMerge.isDenied() && !pendingMerge.ignoredByUser(username)) {
// notificationArr.put(individualMergePendingNotification(pendingMerge, username,
// myShepherd, request));
//}
}
}
ArrayList<ScheduledIndividualMerge> completeMergesOwnedByUser =
Expand All @@ -117,10 +118,16 @@ private JSONArray addAllScheduledIndividualMergeNotifications(JSONArray notifica
for (ScheduledIndividualMerge completeMerge : completeMergesOwnedByUser) {
System.out.println("Is merge ignored by user? : " +
completeMerge.ignoredByUser(username));
if (!completeMerge.ignoredByUser(username)) {
if (!completeMerge.isDenied()&&!completeMerge.ignoredByUser(username)) {
notificationArr.put(individualMergeCompleteNotification(completeMerge, username,
myShepherd, request));
System.out.println("...not denied");
}
else if (completeMerge.isDenied() && !completeMerge.ignoredByUser(username)) {
notificationArr.put(individualMergeDeniedNotification(completeMerge, username,
myShepherd, request));
System.out.println("...denied");
}
}
return notificationArr;
}
Expand Down
Loading

0 comments on commit bef6e05

Please sign in to comment.