Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dark Mode & UI Overhauls #152

Open
wants to merge 72 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
a09f9d8
gitignore data/archive/*
Ilverism Jun 19, 2024
24f7bf4
Any Event filtering for trends / severities / flights
Ilverism Jul 3, 2024
4cbcd98
Include Event.java change
Ilverism Jul 3, 2024
ed7bb8a
Rework Import rows visuals
Ilverism Jul 9, 2024
12b45e0
Upload summary changes, Navbar icons
Ilverism Jul 12, 2024
4aa90dd
Fix navbar active page name highlighting
Ilverism Jul 12, 2024
789653d
Import badge formatting, Navbar background highlights on hover
Ilverism Jul 16, 2024
023897e
Missing color variable usage
Ilverism Jul 16, 2024
7ec3391
Change Uploads UI to match Imports, Fixes in waiting.html
Ilverism Jul 17, 2024
22cbc48
Prepare to merge with Flight Updates
Ilverism Jul 26, 2024
7cb508d
Categorized CSS
Ilverism Aug 12, 2024
3eaa535
Top level HTML background and page load color fix
Ilverism Aug 12, 2024
e3e2f39
Change PostUploads access requirement 'Upload' -> 'View'
Ilverism Aug 12, 2024
d755dc2
Dark Mode Toggle Button + Logic
Ilverism Aug 12, 2024
4e04a7a
Disable Confirm Modal 'submitMethod' call if not defined
Ilverism Aug 12, 2024
4537ac9
Move Upload Flights button to the Paginator dock
Ilverism Aug 12, 2024
4170252
Fix Imports Paginator dock
Ilverism Aug 12, 2024
eb92c68
Remove unneeded buttons from TTF Header (additional layout changes in…
Ilverism Aug 12, 2024
6ae0d18
Event Definitions table UI improvements
Ilverism Aug 12, 2024
4ffda72
Disable Empty Filters
Ilverism Aug 12, 2024
c49d792
Flights Page UI overhaul
Ilverism Aug 12, 2024
e95e736
Time Header buttons in one larger container
Ilverism Aug 12, 2024
75fd951
Flight Tags fixes (incomplete)
Ilverism Aug 12, 2024
6ec7d8c
Minor Manage Tail Numbers UI changes
Ilverism Aug 12, 2024
5506062
Summary Page minor UI changes
Ilverism Aug 12, 2024
da12495
Paginator Sorter ellipses
Ilverism Aug 12, 2024
37185bf
Event Manager table UI update
Ilverism Aug 12, 2024
ad6fc1d
Paginator changes, Flight upload 'triggerInput' method moved to Pagin…
Ilverism Aug 12, 2024
0ed97c1
Manage Fleet UI made consistent with My Preferences UI
Ilverism Aug 12, 2024
6b3c578
Misc. Minor UI changes and Sticky Navbar headers
Ilverism Aug 12, 2024
0c0f9e2
gitignore data/*
Ilverism Aug 12, 2024
eb28995
Update scrollbar for Event Definitions page
Ilverism Aug 12, 2024
7eefde4
Rework AirSync Upload Regiment (#146)
jkarns275 Jun 21, 2024
5d7e89c
Unsubcribe Links for Email Preferences (#144)
Ilverism Aug 13, 2024
806ca6d
Fix empty default severity columns (#147)
Ilverism Aug 13, 2024
955dc44
Fix Upload access for Users with 'View' perms (#148)
Ilverism Aug 13, 2024
c524a2d
Remove RuntimeGlobals import
Ilverism Aug 14, 2024
ac00bd1
Replace anti-flashbang inlined code with CSS and JS files
Ilverism Aug 14, 2024
9648bd8
tabs -> spaces
Ilverism Aug 14, 2024
58bfbe1
Remove package and webpack from gitignore
Ilverism Aug 14, 2024
248ac51
Add missing HMTL preload headers
Ilverism Aug 16, 2024
f4cd970
More compressed dark mode background
Ilverism Aug 16, 2024
3a1933c
Rework AirSync Upload Regiment (#146)
jkarns275 Jun 21, 2024
db3aace
Unsubcribe Links for Email Preferences (#144)
Ilverism Aug 13, 2024
8b9e63b
Fix empty default severity columns (#147)
Ilverism Aug 13, 2024
78918d4
Fix Upload access for Users with 'View' perms (#148)
Ilverism Aug 13, 2024
0c177ec
Prepare to merge with Flight Updates
Ilverism Jul 26, 2024
d15c8ae
Move Upload Flights button to the Paginator dock
Ilverism Aug 12, 2024
a03e257
Paginator changes, Flight upload 'triggerInput' method moved to Pagin…
Ilverism Aug 12, 2024
4f17217
Remove duplicate Paginator variable declaration
Ilverism Aug 16, 2024
96f32f8
gitignore data/*
Ilverism Aug 16, 2024
21d95b1
Fix button access on Uploads page for users with View and Upload priv…
Ilverism Aug 16, 2024
7da394f
Hide the Upload/Delete buttons for users with View access
Ilverism Aug 26, 2024
072038e
Enabled upload button for all users with upload permissions (managers…
jkarns275 Aug 22, 2024
a296a51
Merge branch 'main' into aidan_cu/fix_upload_button_access
jkarns275 Sep 10, 2024
7d81c9a
SendEmail System.out.println -> LOG.info
Ilverism Sep 11, 2024
0979959
Rearrange some functions & rename some variables
Ilverism Sep 11, 2024
2aff62b
Undo webpack config change
Ilverism Sep 11, 2024
eda975f
Environment variable for email base URL
Ilverism Sep 12, 2024
ad5c5c8
Enabled upload button for all users with upload permissions (managers…
jkarns275 Aug 22, 2024
f162eb4
Pass existing connections into email functions when possible (#155)
Ilverism Sep 3, 2024
709b4db
Indicate missing Flight Info on Flights page
Ilverism Oct 23, 2024
1472284
Merge branch 'main' into aidan_cu/imports_interface_updates
Ilverism Oct 23, 2024
d915541
Merge remote-tracking branch 'origin/main' into aidan_cu/imports_inte…
Ilverism Oct 23, 2024
dd0f951
Merge branch 'aidan_cu/imports_interface_updates' of https://github.c…
Ilverism Oct 23, 2024
f72280c
Reconcile Orange/Blue Fixes & ANY Event color changes in Trends
Ilverism Oct 23, 2024
9286e0f
Merge branch 'aidan_cu/imports_interface_updates' into aidan_cu/dark_…
Ilverism Oct 23, 2024
d1cb6f7
Dashed lines fix for Trends , ANY Event , Percentage of Flights graph
Ilverism Oct 24, 2024
20640de
Migrate Event Sevierites ANY Event fixes
Ilverism Oct 24, 2024
00a4c27
Uploads page delete & download buttons OCD fix
Ilverism Oct 24, 2024
c060fb5
Merge remote-tracking branch 'origin/aidan_cu/fix_upload_button_acces…
Ilverism Oct 29, 2024
67ea41d
Reverse percentage graph ordering so blue bars appear above orange ones
Ilverism Oct 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 18 additions & 16 deletions src/main/java/org/ngafid/SendEmail.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ public class SendEmail {

private static final Logger LOG = Logger.getLogger(SendEmail.class.getName());

private static final String baseURL = "https://ngafid.org";
//private static final String baseURL = "https://ngafidbeta.rit.edu";
private static final String baseURLFallback = "https://ngafid.org";
private static final String baseURLEnvironment = System.getenv("NGAFID_BASE_URL");
private static final String baseURL = Objects.requireNonNullElse(baseURLEnvironment, baseURLFallback);
private static final String unsubscribeURLTemplate = (baseURL + "/email_unsubscribe?id=__ID__&token=__TOKEN__");
private static final java.sql.Date lastTokenFree = new java.sql.Date(0);
private static final int EMAIL_UNSUBSCRIBE_TOKEN_EXPIRATION_MONTHS = 3;
Expand All @@ -45,6 +46,7 @@ public class SendEmail {
static {

String enabled = System.getenv("NGAFID_EMAIL_ENABLED");
LOG.info("Email base URL: " + baseURL);

if (enabled != null && enabled.toLowerCase().equals("false")) {
LOG.info("Emailing has been disabled");
Expand All @@ -69,9 +71,9 @@ public class SendEmail {

String NGAFID_ADMIN_EMAILS = System.getenv("NGAFID_ADMIN_EMAILS");
adminEmails = new ArrayList<String>(Arrays.asList(NGAFID_ADMIN_EMAILS.split(";")));
System.out.println("import emails will always also be sent to the following admin emails:");
LOG.info("import emails will always also be sent to the following admin emails:");
for (String adminEmail : adminEmails) {
System.out.println("\t'" + adminEmail + "'");
LOG.info("\t'" + adminEmail + "'");
}

try {
Expand Down Expand Up @@ -139,16 +141,16 @@ private static class SMTPAuthenticator extends javax.mail.Authenticator {
public SMTPAuthenticator(String username, String password) {
this.username = username;
this.password = password;
System.out.println("Created authenticator with username: '" + this.username + "' and password: '" + this.password + "'");
LOG.info("Created authenticator with username: '" + this.username + "' and password: '" + this.password + "'");
}

public PasswordAuthentication getPasswordAuthentication() {
System.out.println("Attempting to authenticate with username: '" + this.username + "' and password: '" + this.password + "'");
LOG.info("Attempting to authenticate with username: '" + this.username + "' and password: '" + this.password + "'");
return new PasswordAuthentication(this.username, this.password);
}

public boolean isValid() {
System.out.println("Checking if valid with username: '" + this.username + "' and password: '" + this.password + "'");
LOG.info("Checking if valid with username: '" + this.username + "' and password: '" + this.password + "'");
return !(this.username == null || this.password == null);
}

Expand Down Expand Up @@ -259,7 +261,7 @@ public static void sendEmail(ArrayList<String> toRecipients, ArrayList<String> b
SMTPAuthenticator auth = new SMTPAuthenticator(username, password);

if (!emailEnabled) {
System.out.println("Emailing has been disabled, not sending email");
LOG.info("Emailing has been disabled, not sending email");
return;
}

Expand All @@ -270,10 +272,10 @@ public static void sendEmail(ArrayList<String> toRecipients, ArrayList<String> b

if (auth.isValid()) {

System.out.println("emailing to " + String.join(", ", toRecipients));
System.out.println("BCCing to " + String.join(", ", bccRecipients));
System.out.println("subject: '" + subject);
System.out.println("body: '" + body);
LOG.info("emailing to " + String.join(", ", toRecipients));
LOG.info("BCCing to " + String.join(", ", bccRecipients));
LOG.info("subject: '" + subject);
LOG.info("body: '" + body);


// Sender's email ID needs to be mentioned
Expand Down Expand Up @@ -318,7 +320,7 @@ public static void sendEmail(ArrayList<String> toRecipients, ArrayList<String> b
boolean embedUnsubscribeURL = true;
if (EmailType.isForced(emailType)) {

System.out.println("Delivering FORCED email type: " + emailType);
LOG.info("Delivering FORCED email type: " + emailType);
embedUnsubscribeURL = false;

} else if (!UserEmailPreferences.getEmailTypeUserState(toRecipient, emailType)) { //Check whether or not the emailType is enabled for the user
Expand Down Expand Up @@ -354,7 +356,7 @@ public static void sendEmail(ArrayList<String> toRecipients, ArrayList<String> b
message.setRecipient(Message.RecipientType.TO, new InternetAddress(toRecipient));

// Send the message to the current recipient
System.out.println("sending message!");
LOG.info("Sending email message!");
Transport.send(message);

}
Expand All @@ -377,12 +379,12 @@ public static void sendEmail(ArrayList<String> toRecipients, ArrayList<String> b
message.setContent(body, "text/html; charset=utf-8");

// Send the message to the current BCC recipients
System.out.println("sending message (BCC)!");
LOG.info("Sending email message (BCC)!");
Transport.send(message);

}

System.out.println("Sent messages successfully....");
LOG.info("Sent email messages successfully...");

} catch (MessagingException mex) {
mex.printStackTrace();
Expand Down
1 change: 1 addition & 0 deletions src/main/java/org/ngafid/WebServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ public static void main(String[] args) {
Spark.post("/protected/monthly_event_counts", new PostMonthlyEventCounts(gson));
Spark.get("/protected/severities", new GetSeverities(gson));
Spark.post("/protected/severities", new PostSeverities(gson));
Spark.post("/protected/all_severities", new PostAllSeverities(gson));

Spark.get("/protected/event_statistics", new GetEventStatistics(gson));
Spark.get("/protected/waiting", new GetWaiting(gson));
Expand Down
41 changes: 23 additions & 18 deletions src/main/java/org/ngafid/accounts/UserEmailPreferences.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,17 @@

public class UserEmailPreferences {

private int userId;
private HashMap<String, Boolean> emailTypesUser;
private String[] emailTypesKeys;

private static final Logger LOG = Logger.getLogger(UserEmailPreferences.class.getName());

private static HashMap<Integer, User> users = new HashMap<>();
private static HashMap<String, Integer> userIDs = new HashMap<>();
private static HashMap<String, HashMap<String, Boolean>> emailTypesUsers = new HashMap<>();

private static final Logger LOG = Logger.getLogger(UserEmailPreferences.class.getName());

private int userId;
private HashMap<String, Boolean> emailTypesUser;
private String[] emailTypesKeys;


public UserEmailPreferences(int userId, HashMap<String, Boolean> emailTypesUser) {
Expand All @@ -47,31 +49,30 @@ public UserEmailPreferences(int userId, HashMap<String, Boolean> emailTypesUser)
this.emailTypesKeys = keysRecent;
}

public static void addUser(Connection connection, User user) throws SQLException {
public static void addUser(Connection connection, User userTarget) throws SQLException {

int userID = user.getId();
String userEmail = user.getEmail();
int userTargetID = userTarget.getId();
String userEmail = userTarget.getEmail();

//user email --> userId
userIDs.put(userEmail, userID);
userIDs.put(userEmail, userTargetID);

//userId --> User
users.put(userID, user);

emailTypesUsers.put( user.getEmail(), user.getUserEmailPreferences(connection).getEmailTypesUser() );
users.put(userTargetID, userTarget);

}
emailTypesUsers.put(
userTarget.getEmail(),
userTarget.getUserEmailPreferences(connection).getEmailTypesUser()
);

public static User getUser(int userId) {
return users.get(userId);
}

public static int getUserIDFromEmail(String userEmail) {
return userIDs.get(userEmail);
public static User getUser(int userTargetID) {
return users.get(userTargetID);
}

public HashMap<String, Boolean> getEmailTypesUser() {
return emailTypesUser;
public static int getUserIDFromEmail(String userTargetEmail) {
return userIDs.get(userTargetEmail);
}

public static boolean getEmailTypeUserState(String email, EmailType emailType) {
Expand All @@ -96,4 +97,8 @@ public static boolean getEmailTypeUserState(String email, EmailType emailType) {

}

public HashMap<String, Boolean> getEmailTypesUser() {
return emailTypesUser;
}

}
21 changes: 17 additions & 4 deletions src/main/java/org/ngafid/events/Event.java
Original file line number Diff line number Diff line change
Expand Up @@ -369,11 +369,24 @@ public static HashMap<String, ArrayList<Event>> getEvents(Connection connection,
eventsByAirframe.put(airframe, new ArrayList<Event>());
}

String query = "SELECT id FROM event_definitions WHERE (fleet_id = 0 OR fleet_id = ?) AND name LIKE ? ORDER BY name";
String query;
PreparedStatement preparedStatement;

if (eventName.equals("ANY Event")) {

LOG.info("[EX] Getting ALL events for fleet with ID: " + fleetId);

query = "SELECT id FROM event_definitions WHERE fleet_id = 0 OR fleet_id = ? ORDER BY name";
preparedStatement = connection.prepareStatement(query);
preparedStatement.setInt(1, fleetId);

} else {
query = "SELECT id FROM event_definitions WHERE (fleet_id = 0 OR fleet_id = ?) AND name LIKE ? ORDER BY name";
preparedStatement = connection.prepareStatement(query);
preparedStatement.setInt(1, fleetId);
preparedStatement.setString(2, eventName);
}

PreparedStatement preparedStatement = connection.prepareStatement(query);
preparedStatement.setInt(1, fleetId);
preparedStatement.setString(2, eventName);

LOG.info(preparedStatement.toString());
ResultSet resultSet = preparedStatement.executeQuery();
Expand Down
7 changes: 4 additions & 3 deletions src/main/java/org/ngafid/routes/GetUpload.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,10 @@ public Object handle(Request request, Response response) throws SQLException {
return "Upload not found";
}

if (!user.hasUploadAccess(upload.getFleetId())) {
LOG.severe("INVALID ACCESS: user did not have upload or manager access this fleet.");
Spark.halt(401, "User did not have access to delete this upload.");
//Verify that a user has access to the download the uploaded file (requires View Access)
if (!user.hasViewAccess(upload.getFleetId())) {
LOG.severe("INVALID ACCESS: user did not have view, upload, or manager access this fleet.");
Spark.halt(401, "User did not have access to download the uploaded file.");
return null;
}

Expand Down
2 changes: 2 additions & 0 deletions src/main/java/org/ngafid/routes/GetUploads.java
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ public Object handle(Request request, Response response) {

scopes.put("uploads_js", "var uploads = JSON.parse('" + gson.toJson(other_uploads) + "'); var pending_uploads = JSON.parse('" + gson.toJson(pending_uploads) + "');");

scopes.put("user_js", "var user = JSON.parse('" + gson.toJson(user) + "');");

StringWriter stringOut = new StringWriter();
mustache.execute(new PrintWriter(stringOut), scopes).flush();
resultString = stringOut.toString();
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/org/ngafid/routes/Navbar.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ public static String getJavascript(Request request) {
+ "var modifyTailsAccess = " + modifyTailsAccess + ";"
+ "var unconfirmedTailsCount = " + unconfirmedTailsCount + ";"
+ "var airSyncEnabled = " + airSyncEnabled + ";"
+ "var uploader = " + hasUploadAccess + ";";
+ "var isUploader = " + hasUploadAccess + ";";

}
}
89 changes: 89 additions & 0 deletions src/main/java/org/ngafid/routes/PostAllSeverities.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package org.ngafid.routes;

import java.time.LocalDate;

import java.util.List;
import java.util.ArrayList;
import java.util.logging.Logger;
import java.util.HashMap;


import java.sql.Connection;
import java.sql.SQLException;

import com.google.gson.Gson;

import spark.Route;
import spark.Request;
import spark.Response;
import spark.Session;
import spark.Spark;

import org.ngafid.Database;
import org.ngafid.WebServer;
import org.ngafid.accounts.User;
import org.ngafid.events.Event;
import org.ngafid.events.EventStatistics;
import org.ngafid.common.*;

public class PostAllSeverities implements Route {
private static final Logger LOG = Logger.getLogger(PostAllSeverities.class.getName());
private Gson gson;

public PostAllSeverities(Gson gson) {
this.gson = gson;
LOG.info("post " + this.getClass().getName() + " initalized");
}


@Override
public Object handle(Request request, Response response) {
LOG.info("handling " + this.getClass().getName() + " route");

String startDate = request.queryParams("startDate");
String endDate = request.queryParams("endDate");
String eventNames = request.queryParams("eventNames");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would making these JSON parameters simplify the code below?

String tagName = request.queryParams("tagName");
final Session session = request.session();
User user = session.attribute("user");
int fleetId = user.getFleetId();

//check to see if the user has upload access for this fleet.
if (!user.hasViewAccess(fleetId)) {
LOG.severe("INVALID ACCESS: user did not have access view imports for this fleet.");
Spark.halt(401, "User did not have access to view imports for this fleet.");
return null;
}

try {

Connection connection = Database.getConnection();
String[] eventNamesArray = eventNames.split(",");
HashMap<String, HashMap<String, ArrayList<Event>> > eventMap = new HashMap<>();

for (String eventName : eventNamesArray) {

//Remove leading and trailing quotes
eventName = eventName.replace("\"", "");

//Remove brackets
eventName = eventName.replace("[", "");
eventName = eventName.replace("]", "");

//Remove trailing spaces
eventName = eventName.trim();

if (eventName.equals("ANY Event"))
continue;

HashMap<String, ArrayList<Event>> events = Event.getEvents(connection, fleetId, eventName, LocalDate.parse(startDate), LocalDate.parse(endDate), tagName);
eventMap.put(eventName, events);
}

return gson.toJson(eventMap);

} catch (SQLException e) {
return gson.toJson(new ErrorResponse(e));
}
}
}
2 changes: 1 addition & 1 deletion src/main/java/org/ngafid/routes/PostUploads.java
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,4 @@ public Object handle(Request request, Response response) {
return gson.toJson(new ErrorResponse(e));
}
}
}
}
3 changes: 2 additions & 1 deletion src/main/javascript/cesium_buttons.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ class CesiumButtons extends React.Component {
<div className="col form-row input-group m-0 p-0" style={{
position: "center", display: 'flex',
justifyContent: 'center',
alignItems: 'center',
alignItems: 'flex-start',
margin: "0"
}}>
<div className="input-group-prepend p-0">
<button id={"cesiumViewButton" + this.props.location} className="btn btn-sm btn-primary"
Expand Down
7 changes: 5 additions & 2 deletions src/main/javascript/confirm_modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ class ConfirmModal extends React.Component {

this.state = {
title : "",
message : ""
message : "",
submitMethod : null
};
}

Expand All @@ -29,7 +30,9 @@ class ConfirmModal extends React.Component {

modalClicked() {
console.log("modal submit clicked!");
this.state.submitMethod();

if (this.state.submitMethod != null)
this.state.submitMethod();
}

render() {
Expand Down
Loading
Loading