Add basic tab switching
This commit is contained in:
parent
5f85f83696
commit
8cea5f006a
8 changed files with 192 additions and 88 deletions
|
@ -156,14 +156,18 @@ public class BodyTabController implements Initializable {
|
|||
|
||||
public void setState(ComposerState state) {
|
||||
// Adding URL tab's tuples
|
||||
if (state.urlStringTuples != null)
|
||||
if (state.urlStringTuples != null) {
|
||||
urlTabController.clear();
|
||||
for (FieldState fieldState : state.urlStringTuples)
|
||||
urlTabController.addField(fieldState);
|
||||
}
|
||||
|
||||
// Adding Form tab's string tuples
|
||||
if (state.formStringTuples != null)
|
||||
formDataTabController.clear();
|
||||
if (state.formStringTuples != null) {
|
||||
for (FieldState fieldState : state.formStringTuples)
|
||||
formDataTabController.addStringField(fieldState);
|
||||
}
|
||||
|
||||
// Adding Form tab's file tuples
|
||||
if (state.formFileTuples != null)
|
||||
|
@ -171,7 +175,6 @@ public class BodyTabController implements Initializable {
|
|||
formDataTabController.addFileField(fieldState);
|
||||
|
||||
setRawTab(state);
|
||||
|
||||
filePathField.setText(state.binaryFilePath);
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ import com.jfoenix.controls.JFXSnackbar;
|
|||
import com.rohitawate.everest.controllers.codearea.EverestCodeArea;
|
||||
import com.rohitawate.everest.controllers.codearea.EverestCodeArea.HighlightMode;
|
||||
import com.rohitawate.everest.controllers.state.ComposerState;
|
||||
import com.rohitawate.everest.controllers.state.DashboardState;
|
||||
import com.rohitawate.everest.controllers.state.FieldState;
|
||||
import com.rohitawate.everest.exceptions.RedirectException;
|
||||
import com.rohitawate.everest.exceptions.UnreliableResponseException;
|
||||
|
@ -314,7 +315,7 @@ public class DashboardController implements Initializable {
|
|||
default:
|
||||
loadingLayer.setVisible(false);
|
||||
}
|
||||
Services.historyManager.saveHistory(getState());
|
||||
Services.historyManager.saveHistory(getState().composer);
|
||||
} catch (MalformedURLException MURLE) {
|
||||
promptLayer.setVisible(true);
|
||||
snackbar.show("Invalid address. Please verify and try again.", 3000);
|
||||
|
@ -401,38 +402,41 @@ public class DashboardController implements Initializable {
|
|||
responseHeadersViewer.populate(response);
|
||||
}
|
||||
|
||||
private void prettifyResponseBody(EverestResponse response) {
|
||||
String type;
|
||||
|
||||
if (response.getMediaType() != null)
|
||||
type = response.getMediaType().toString();
|
||||
else
|
||||
type = null;
|
||||
|
||||
String responseBody = response.getBody();
|
||||
private void displayResponse(DashboardState state) {
|
||||
prettifyResponseBody(state.responseBody, state.responseType);
|
||||
responseBox.getChildren().remove(responseDetails);
|
||||
responseBox.getChildren().add(0, responseDetails);
|
||||
statusCode.setText(Integer.toString(state.statusCode));
|
||||
statusCodeDescription.setText(Response.Status.fromStatusCode(state.statusCode).getReasonPhrase());
|
||||
responseTime.setText(Long.toString(state.responseTime) + " ms");
|
||||
responseSize.setText(Integer.toString(state.responseSize) + " B");
|
||||
responseHeadersViewer.populate(state.responseHeaders);
|
||||
}
|
||||
|
||||
private void prettifyResponseBody(String body, String contentType) {
|
||||
visualizerTab.setDisable(true);
|
||||
visualizer.clear();
|
||||
try {
|
||||
if (type != null) {
|
||||
// Selects only the part preceding the ';', skipping the character encoding
|
||||
type = type.split(";")[0];
|
||||
|
||||
switch (type.toLowerCase()) {
|
||||
try {
|
||||
if (contentType != null) {
|
||||
// Selects only the part preceding the ';', skipping the character encoding
|
||||
contentType = contentType.split(";")[0];
|
||||
|
||||
switch (contentType.toLowerCase()) {
|
||||
case "application/json":
|
||||
responseTypeBox.setValue("JSON");
|
||||
JsonNode node = EverestUtilities.jsonMapper.readTree(responseBody);
|
||||
JsonNode node = EverestUtilities.jsonMapper.readTree(body);
|
||||
responseArea.setText(EverestUtilities.jsonMapper.writeValueAsString(node), HighlightMode.JSON);
|
||||
visualizerTab.setDisable(false);
|
||||
visualizer.populate(node);
|
||||
break;
|
||||
case "application/xml":
|
||||
responseTypeBox.setValue("XML");
|
||||
responseArea.setText(responseBody, HighlightMode.XML);
|
||||
responseArea.setText(body, HighlightMode.XML);
|
||||
break;
|
||||
case "text/html":
|
||||
responseTypeBox.setValue("HTML");
|
||||
responseArea.setText(responseBody, HighlightMode.HTML);
|
||||
responseArea.setText(body, HighlightMode.HTML);
|
||||
if (Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
|
||||
snackbar.show("Open link in browser?", "YES", 5000, e -> {
|
||||
snackbar.close();
|
||||
|
@ -448,7 +452,7 @@ public class DashboardController implements Initializable {
|
|||
break;
|
||||
default:
|
||||
responseTypeBox.setValue("PLAIN TEXT");
|
||||
responseArea.setText(responseBody, HighlightMode.PLAIN);
|
||||
responseArea.setText(body, HighlightMode.PLAIN);
|
||||
}
|
||||
} else {
|
||||
responseTypeBox.setValue("PLAIN");
|
||||
|
@ -463,6 +467,20 @@ public class DashboardController implements Initializable {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private void prettifyResponseBody(EverestResponse response) {
|
||||
String type;
|
||||
|
||||
if (response.getMediaType() != null)
|
||||
type = response.getMediaType().toString();
|
||||
else
|
||||
type = "";
|
||||
|
||||
String responseBody = response.getBody();
|
||||
|
||||
prettifyResponseBody(responseBody, type);
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void clearResponseArea() {
|
||||
responseBox.getChildren().remove(0);
|
||||
|
@ -557,8 +575,10 @@ public class DashboardController implements Initializable {
|
|||
/**
|
||||
* @return Current state of the Dashboard.
|
||||
*/
|
||||
public ComposerState getState() {
|
||||
public DashboardState getState() {
|
||||
DashboardState dashboardState = new DashboardState();
|
||||
ComposerState composerState;
|
||||
|
||||
switch (httpMethodBox.getValue()) {
|
||||
case "POST":
|
||||
case "PUT":
|
||||
|
@ -575,7 +595,26 @@ public class DashboardController implements Initializable {
|
|||
composerState.headers = headerTabController.getFieldStates();
|
||||
composerState.params = getParamFieldStates();
|
||||
|
||||
return composerState;
|
||||
dashboardState.composer = composerState;
|
||||
dashboardState.showResponse = responseArea.isVisible();
|
||||
|
||||
if (dashboardState.showResponse) {
|
||||
dashboardState.responseHeaders = headerTabController.getHeaders();
|
||||
dashboardState.statusCode = Integer.parseInt(statusCode.getText());
|
||||
|
||||
String temp = responseSize.getText();
|
||||
temp = temp.substring(0, temp.length() - 2);
|
||||
dashboardState.responseSize = Integer.parseInt(temp);
|
||||
|
||||
temp = responseTime.getText();
|
||||
temp = temp.substring(0, temp.length() - 3);
|
||||
dashboardState.responseTime = Integer.parseInt(temp);
|
||||
|
||||
dashboardState.responseBody = responseArea.getText();
|
||||
dashboardState.responseType = responseTypeBox.getValue();
|
||||
}
|
||||
|
||||
return dashboardState;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -583,7 +622,14 @@ public class DashboardController implements Initializable {
|
|||
*
|
||||
* @param state - State of the dashboard
|
||||
*/
|
||||
public void setState(ComposerState state) {
|
||||
public void setState(DashboardState state) {
|
||||
if (state.showResponse) {
|
||||
displayResponse(state);
|
||||
}
|
||||
|
||||
if (state.composer == null)
|
||||
return;
|
||||
|
||||
/*
|
||||
The only value from a set of constants in the state.json file is the httpMethod
|
||||
which, if manipulated to a non-standard value by the user, would still
|
||||
|
@ -596,7 +642,7 @@ public class DashboardController implements Initializable {
|
|||
*/
|
||||
boolean validMethod = false;
|
||||
for (String method : httpMethods) {
|
||||
if (state.httpMethod.equals(method))
|
||||
if (state.composer.httpMethod.equals(method))
|
||||
validMethod = true;
|
||||
}
|
||||
|
||||
|
@ -605,20 +651,35 @@ public class DashboardController implements Initializable {
|
|||
return;
|
||||
}
|
||||
|
||||
httpMethodBox.setValue(state.httpMethod);
|
||||
httpMethodBox.setValue(state.composer.httpMethod);
|
||||
|
||||
if (state.target != null)
|
||||
addressField.setText(state.target);
|
||||
if (state.composer.target != null)
|
||||
addressField.setText(state.composer.target);
|
||||
|
||||
if (state.headers != null)
|
||||
for (FieldState fieldState : state.headers)
|
||||
if (state.composer.headers != null) {
|
||||
headerTabController.clear();
|
||||
for (FieldState fieldState : state.composer.headers)
|
||||
headerTabController.addHeader(fieldState);
|
||||
}
|
||||
|
||||
if (state.params != null)
|
||||
for (FieldState fieldState : state.params)
|
||||
if (state.composer.params != null) {
|
||||
clearParams();
|
||||
for (FieldState fieldState : state.composer.params)
|
||||
addParamField(fieldState);
|
||||
}
|
||||
|
||||
if (!(httpMethodBox.getValue().equals("GET") || httpMethodBox.getValue().equals("DELETE")))
|
||||
bodyTabController.setState(state);
|
||||
bodyTabController.setState(state.composer);
|
||||
}
|
||||
|
||||
void clearParams() {
|
||||
if (params != null)
|
||||
params.clear();
|
||||
|
||||
if (paramsControllers != null)
|
||||
paramsControllers.clear();
|
||||
|
||||
paramsBox.getChildren().clear();
|
||||
addParamField();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -223,4 +223,22 @@ public class FormDataTabController implements Initializable {
|
|||
|
||||
return states;
|
||||
}
|
||||
|
||||
void clear() {
|
||||
if (stringMap != null)
|
||||
stringMap.clear();
|
||||
|
||||
if (fileMap != null)
|
||||
fileMap.clear();
|
||||
|
||||
if (stringControllers != null)
|
||||
stringControllers.clear();
|
||||
|
||||
if (fileControllers != null)
|
||||
fileControllers.clear();
|
||||
|
||||
fieldsBox.getChildren().clear();
|
||||
addStringField();
|
||||
addFileField();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -134,4 +134,14 @@ public class HeaderTabController implements Initializable {
|
|||
|
||||
return states;
|
||||
}
|
||||
|
||||
void clear() {
|
||||
if (headers != null)
|
||||
headers.clear();
|
||||
if (controllers != null)
|
||||
controllers.clear();
|
||||
|
||||
headersBox.getChildren().clear();
|
||||
addHeader();
|
||||
}
|
||||
}
|
|
@ -18,6 +18,7 @@ package com.rohitawate.everest.controllers;
|
|||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.rohitawate.everest.controllers.state.ComposerState;
|
||||
import com.rohitawate.everest.controllers.state.DashboardState;
|
||||
import com.rohitawate.everest.misc.EverestUtilities;
|
||||
import com.rohitawate.everest.misc.KeyMap;
|
||||
import com.rohitawate.everest.misc.Services;
|
||||
|
@ -25,6 +26,7 @@ import com.rohitawate.everest.misc.ThemeManager;
|
|||
import javafx.application.Platform;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.fxml.Initializable;
|
||||
|
@ -58,7 +60,7 @@ public class HomeWindowController implements Initializable {
|
|||
@FXML
|
||||
private VBox tabDashboardBox;
|
||||
|
||||
private HashMap<Tab, DashboardController> tabControllerMap;
|
||||
private HashMap<Tab, DashboardState> tabStateMap;
|
||||
private DashboardController dashboard;
|
||||
|
||||
@Override
|
||||
|
@ -73,7 +75,7 @@ public class HomeWindowController implements Initializable {
|
|||
}
|
||||
|
||||
// Using LinkedHashMap because they retain order
|
||||
tabControllerMap = new LinkedHashMap<>();
|
||||
tabStateMap = new LinkedHashMap<>();
|
||||
recoverState();
|
||||
|
||||
historyPaneController.addItemClickHandler(this::addTab);
|
||||
|
@ -87,6 +89,16 @@ public class HomeWindowController implements Initializable {
|
|||
Stage thisStage = (Stage) homeWindowSP.getScene().getWindow();
|
||||
thisStage.setOnCloseRequest(e -> saveState());
|
||||
});
|
||||
|
||||
homeWindowTabPane.getSelectionModel().selectedItemProperty().addListener(this::onTabSwitched);
|
||||
}
|
||||
|
||||
private void onTabSwitched(ObservableValue<? extends Tab> obs, Tab prevTab, Tab newTab) {
|
||||
DashboardState dashboardState = dashboard.getState();
|
||||
tabStateMap.replace(prevTab, dashboardState);
|
||||
|
||||
dashboardState = tabStateMap.get(newTab);
|
||||
dashboard.setState(dashboardState);
|
||||
}
|
||||
|
||||
private void setGlobalShortcuts() {
|
||||
|
@ -96,14 +108,11 @@ public class HomeWindowController implements Initializable {
|
|||
if (KeyMap.newTab.match(e)) {
|
||||
addTab();
|
||||
} else if (KeyMap.focusAddressBar.match(e)) {
|
||||
Tab activeTab = getActiveTab();
|
||||
tabControllerMap.get(activeTab).addressField.requestFocus();
|
||||
dashboard.addressField.requestFocus();
|
||||
} else if (KeyMap.focusMethodBox.match(e)) {
|
||||
Tab activeTab = getActiveTab();
|
||||
tabControllerMap.get(activeTab).httpMethodBox.show();
|
||||
dashboard.httpMethodBox.show();
|
||||
} else if (KeyMap.sendRequest.match(e)) {
|
||||
Tab activeTab = getActiveTab();
|
||||
tabControllerMap.get(activeTab).sendRequest();
|
||||
dashboard.sendRequest();
|
||||
} else if (KeyMap.toggleHistory.match(e)) {
|
||||
toggleHistoryPane();
|
||||
} else if (KeyMap.closeTab.match(e)) {
|
||||
|
@ -111,27 +120,19 @@ public class HomeWindowController implements Initializable {
|
|||
if (homeWindowTabPane.getTabs().size() == 1)
|
||||
addTab();
|
||||
homeWindowTabPane.getTabs().remove(activeTab);
|
||||
tabControllerMap.remove(activeTab);
|
||||
tabStateMap.remove(activeTab);
|
||||
} else if (KeyMap.searchHistory.match(e)) {
|
||||
historyPaneController.focusSearchField();
|
||||
} else if (KeyMap.focusParams.match(e)) {
|
||||
Tab activeTab = getActiveTab();
|
||||
DashboardController controller = tabControllerMap.get(activeTab);
|
||||
controller.requestOptionsTab.getSelectionModel().select(controller.paramsTab);
|
||||
dashboard.requestOptionsTab.getSelectionModel().select(dashboard.paramsTab);
|
||||
} else if (KeyMap.focusAuth.match(e)) {
|
||||
Tab activeTab = getActiveTab();
|
||||
DashboardController controller = tabControllerMap.get(activeTab);
|
||||
controller.requestOptionsTab.getSelectionModel().select(controller.authTab);
|
||||
dashboard.requestOptionsTab.getSelectionModel().select(dashboard.authTab);
|
||||
} else if (KeyMap.focusHeaders.match(e)) {
|
||||
Tab activeTab = getActiveTab();
|
||||
DashboardController controller = tabControllerMap.get(activeTab);
|
||||
controller.requestOptionsTab.getSelectionModel().select(controller.headersTab);
|
||||
dashboard.requestOptionsTab.getSelectionModel().select(dashboard.headersTab);
|
||||
} else if (KeyMap.focusBody.match(e)) {
|
||||
Tab activeTab = getActiveTab();
|
||||
DashboardController controller = tabControllerMap.get(activeTab);
|
||||
String httpMethod = controller.httpMethodBox.getValue();
|
||||
String httpMethod = dashboard.httpMethodBox.getValue();
|
||||
if (!httpMethod.equals("GET") && !httpMethod.equals("DELETE")) {
|
||||
controller.requestOptionsTab.getSelectionModel().select(controller.bodyTab);
|
||||
dashboard.requestOptionsTab.getSelectionModel().select(dashboard.bodyTab);
|
||||
}
|
||||
} else if (KeyMap.refreshTheme.match(e)) {
|
||||
ThemeManager.refreshTheme();
|
||||
|
@ -152,45 +153,26 @@ public class HomeWindowController implements Initializable {
|
|||
}
|
||||
|
||||
private void addTab(ComposerState composerState) {
|
||||
try {
|
||||
Tab newTab = new Tab();
|
||||
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/homewindow/Dashboard.fxml"));
|
||||
Parent dashboard = loader.load();
|
||||
DashboardController controller = loader.getController();
|
||||
Tab newTab = new Tab();
|
||||
homeWindowTabPane.getTabs().add(newTab);
|
||||
|
||||
if (composerState != null)
|
||||
controller.setState(composerState);
|
||||
StringProperty addressProperty = dashboard.addressField.textProperty();
|
||||
newTab.textProperty().bind(
|
||||
Bindings.when(addressProperty.isNotEmpty())
|
||||
.then(addressProperty)
|
||||
.otherwise("New Tab"));
|
||||
|
||||
newTab.setContent(dashboard);
|
||||
|
||||
// Binds the addressField text to the Tab text
|
||||
StringProperty addressProperty = controller.addressField.textProperty();
|
||||
newTab.textProperty().bind(
|
||||
Bindings.when(addressProperty.isNotEmpty())
|
||||
.then(addressProperty)
|
||||
.otherwise("New Tab"));
|
||||
|
||||
// Tab closing procedure
|
||||
newTab.setOnCloseRequest(e -> {
|
||||
if (homeWindowTabPane.getTabs().size() == 1)
|
||||
addTab();
|
||||
tabControllerMap.remove(newTab);
|
||||
});
|
||||
|
||||
homeWindowTabPane.getTabs().add(newTab);
|
||||
homeWindowTabPane.getSelectionModel().select(newTab);
|
||||
tabControllerMap.put(newTab, controller);
|
||||
} catch (IOException e) {
|
||||
Services.loggingService.logSevere("Could not add a new tab.", e, LocalDateTime.now());
|
||||
}
|
||||
DashboardState dashboardState = new DashboardState();
|
||||
dashboardState.composer = composerState;
|
||||
tabStateMap.put(newTab, dashboardState);
|
||||
}
|
||||
|
||||
private void saveState() {
|
||||
ArrayList<ComposerState> composerStates = new ArrayList<>();
|
||||
|
||||
// Get the states of all the tabs
|
||||
for (DashboardController controller : tabControllerMap.values())
|
||||
composerStates.add(controller.getState());
|
||||
for (DashboardState dashboardState : tabStateMap.values())
|
||||
composerStates.add(dashboardState.composer);
|
||||
|
||||
try {
|
||||
File stateFile = new File("Everest/config/state.json");
|
||||
|
|
|
@ -23,8 +23,12 @@ import javafx.scene.control.ScrollPane;
|
|||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.VBox;
|
||||
|
||||
import javax.ws.rs.core.MultivaluedHashMap;
|
||||
import java.util.HashMap;
|
||||
|
||||
class ResponseHeadersViewer extends ScrollPane {
|
||||
private VBox container;
|
||||
private MultivaluedHashMap<String, String> map;
|
||||
|
||||
ResponseHeadersViewer() {
|
||||
this.container = new VBox();
|
||||
|
@ -33,12 +37,26 @@ class ResponseHeadersViewer extends ScrollPane {
|
|||
|
||||
this.setFitToHeight(true);
|
||||
this.setFitToWidth(true);
|
||||
|
||||
map = new MultivaluedHashMap<>();
|
||||
}
|
||||
|
||||
void populate(HashMap<String, String> headers) {
|
||||
map.clear();
|
||||
headers.forEach((key, value) -> map.putSingle(key, value));
|
||||
populate();
|
||||
}
|
||||
|
||||
void populate(EverestResponse response) {
|
||||
map.clear();
|
||||
map = (MultivaluedHashMap<String, String>) response.getHeaders();
|
||||
populate();
|
||||
}
|
||||
|
||||
private void populate() {
|
||||
container.getChildren().clear();
|
||||
|
||||
response.getHeaders().forEach((key, value) -> {
|
||||
map.forEach((key, value) -> {
|
||||
Label keyLabel = new Label(key + ": ");
|
||||
keyLabel.getStyleClass().addAll("visualizerKeyLabel", "visualizerLabel");
|
||||
|
||||
|
@ -47,5 +65,6 @@ class ResponseHeadersViewer extends ScrollPane {
|
|||
|
||||
container.getChildren().add(new HBox(keyLabel, valueLabel));
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -135,4 +135,14 @@ public class URLTabController implements Initializable {
|
|||
|
||||
return states;
|
||||
}
|
||||
|
||||
void clear() {
|
||||
if (tuples != null)
|
||||
tuples.clear();
|
||||
if (controllers != null)
|
||||
controllers.clear();
|
||||
|
||||
fieldsBox.getChildren().clear();
|
||||
addField();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ public class DashboardState {
|
|||
public boolean showResponse;
|
||||
public int statusCode;
|
||||
public String responseType;
|
||||
public String responseBody;
|
||||
public int responseTime;
|
||||
public int responseSize;
|
||||
public HashMap<String, String> responseHeaders;
|
||||
|
|
Loading…
Reference in a new issue