Преглед на файлове

rework gui to be more wizard like:
* show first only checkbox list of checks and single run button
* then show list of check run status with results

Armin Schrenk преди 4 години
родител
ревизия
85ff7542f1

+ 1 - 0
main/ui/src/main/java/org/cryptomator/ui/controls/FontAwesome5Icon.java

@@ -9,6 +9,7 @@ public enum FontAwesome5Icon {
 	BAN("\uF05E"), //
 	BUG("\uF188"), //
 	CHECK("\uF00C"), //
+	CLOCK("\uF017"), //
 	COG("\uF013"), //
 	COGS("\uF085"), //
 	COPY("\uF0C5"), //

+ 6 - 1
main/ui/src/main/java/org/cryptomator/ui/health/CheckListCell.java

@@ -20,6 +20,9 @@ class CheckListCell extends ListCell<HealthCheckTask> {
 			item.stateProperty().addListener(this::stateChanged);
 			setGraphic(stateIcon);
 			stateIcon.setGlyph(glyphForState(item.getState()));
+			if (item.getState() == Worker.State.READY) {
+				stateIcon.setVisible(false);
+			}
 			setContentDisplay(ContentDisplay.LEFT);
 		} else {
 			setText(null);
@@ -29,12 +32,14 @@ class CheckListCell extends ListCell<HealthCheckTask> {
 
 	private void stateChanged(ObservableValue<? extends Worker.State> observable, Worker.State oldState, Worker.State newState) {
 		stateIcon.setGlyph(glyphForState(newState));
+		stateIcon.setVisible(true);
 	}
 
 	private FontAwesome5Icon glyphForState(Worker.State state) {
 		// TODO choose appropriate glyphs
 		return switch (state) {
-			case READY, SCHEDULED -> FontAwesome5Icon.ANCHOR;
+			case READY -> FontAwesome5Icon.COG; //just a placeholder
+			case SCHEDULED -> FontAwesome5Icon.CLOCK;
 			case RUNNING -> FontAwesome5Icon.SPINNER;
 			case FAILED -> FontAwesome5Icon.EXCLAMATION_TRIANGLE;
 			case CANCELLED -> FontAwesome5Icon.BAN;

+ 42 - 23
main/ui/src/main/java/org/cryptomator/ui/health/CheckListController.java

@@ -10,15 +10,22 @@ import org.slf4j.LoggerFactory;
 import javax.inject.Inject;
 import javafx.beans.binding.Binding;
 import javafx.beans.binding.BooleanBinding;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.IntegerProperty;
 import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleIntegerProperty;
 import javafx.beans.property.SimpleObjectProperty;
 import javafx.collections.FXCollections;
 import javafx.collections.ObservableList;
 import javafx.concurrent.Worker;
 import javafx.fxml.FXML;
 import javafx.scene.control.ListView;
+import javafx.scene.control.cell.CheckBoxListCell;
 import java.io.IOException;
 import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ExecutorService;
 
@@ -35,8 +42,10 @@ public class CheckListController implements FxController {
 	private final SimpleObjectProperty<Worker<?>> runningTask;
 	private final Binding<Boolean> running;
 	private final Binding<Boolean> finished;
+	private final Map<HealthCheckTask, BooleanProperty> listPickIndicators;
+	private final IntegerProperty numberOfPickedChecks;
 	private final BooleanBinding anyCheckSelected;
-	private final BooleanBinding readyToRun;
+	private final BooleanProperty showResultScreen;
 
 	/* FXML */
 	public ListView<HealthCheckTask> checksListView;
@@ -51,33 +60,35 @@ public class CheckListController implements FxController {
 		this.runningTask = new SimpleObjectProperty<>();
 		this.running = EasyBind.wrapNullable(runningTask).mapObservable(Worker::runningProperty).orElse(false);
 		this.finished = EasyBind.wrapNullable(runningTask).mapObservable(Worker::stateProperty).map(END_STATES::contains).orElse(false);
-		this.readyToRun = runningTask.isNull();
+		this.listPickIndicators = new HashMap<>();
+		this.numberOfPickedChecks = new SimpleIntegerProperty(0);
+		this.tasks.forEach(task -> {
+			var entrySelectedProp = new SimpleBooleanProperty(false);
+			entrySelectedProp.addListener((observable, oldValue, newValue) -> numberOfPickedChecks.set(numberOfPickedChecks.get() + (newValue ? 1 : -1)));
+			listPickIndicators.put(task, entrySelectedProp);
+		});
 		this.anyCheckSelected = selectedTask.isNotNull();
+		this.showResultScreen = new SimpleBooleanProperty(false);
 	}
 
 	@FXML
 	public void initialize() {
 		checksListView.setItems(tasks);
-		checksListView.setCellFactory(ignored -> new CheckListCell());
+		checksListView.setCellFactory(CheckBoxListCell.forListView(listPickIndicators::get));
 		selectedTask.bind(checksListView.getSelectionModel().selectedItemProperty());
 	}
 
 	@FXML
-	public synchronized void runSelectedChecks() {
-		startBatch(checksListView.getSelectionModel().getSelectedItems());
-	}
-
-	@FXML
-	public synchronized void runAllChecks() {
-		startBatch(checksListView.getItems());
-	}
-
-	private void startBatch(Iterable<HealthCheckTask> batch) {
+	public void runSelectedChecks() {
 		Preconditions.checkState(runningTask.get() == null);
+		var batch = checksListView.getItems().filtered(item -> listPickIndicators.get(item).get());
 		var batchService = new BatchService(batch);
 		batchService.setExecutor(executorService);
 		batchService.start();
 		runningTask.set(batchService);
+		checksListView.setCellFactory(view -> new CheckListCell());
+		showResultScreen.set(true);
+		checksListView.getSelectionModel().select(batch.getViewIndex(0));
 	}
 
 	@FXML
@@ -95,17 +106,8 @@ public class CheckListController implements FxController {
 			LOG.error("Failed to write health check report.", e);
 		}
 	}
-	/* Getter/Setter */
-
-
-	public boolean isReadyToRun() {
-		return readyToRun.get();
-	}
-
-	public BooleanBinding readyToRunProperty() {
-		return readyToRun;
-	}
 
+	/* Getter/Setter */
 	public boolean isRunning() {
 		return running.getValue();
 	}
@@ -130,4 +132,21 @@ public class CheckListController implements FxController {
 		return anyCheckSelected;
 	}
 
+	public boolean getShowResultScreen() {
+		return showResultScreen.get();
+	}
+
+	public BooleanProperty showResultScreenProperty() {
+		return showResultScreen;
+	}
+
+	public int getNumberOfPickedChecks() {
+		return numberOfPickedChecks.get();
+	}
+
+	public IntegerProperty numberOfPickedChecksProperty() {
+		return numberOfPickedChecks;
+	}
+
+
 }

+ 14 - 10
main/ui/src/main/resources/fxml/health_check_list.fxml

@@ -7,6 +7,7 @@
 <?import javafx.scene.control.ListView?>
 <?import javafx.scene.layout.HBox?>
 <?import javafx.scene.layout.VBox?>
+<?import java.lang.Integer?>
 <?import javafx.scene.layout.StackPane?>
 <VBox xmlns:fx="http://javafx.com/fxml"
 	  xmlns="http://javafx.com/javafx"
@@ -18,25 +19,28 @@
 	<padding>
 		<Insets topRightBottomLeft="12"/>
 	</padding>
+	<fx:define>
+		<Integer fx:id="ZERO" fx:value="0"/>
+	</fx:define>
 	<children>
 		<HBox spacing="12" VBox.vgrow="ALWAYS">
 			<VBox minWidth="80" spacing="6" >
 				<Label fx:id="listHeading" text="Health checks"/>
+				<!-- TODO:HEADER with select all checkbox -->
 				<ListView fx:id="checksListView" VBox.vgrow="ALWAYS"/>
 			</VBox>
-			<!-- Maybe use class Seperator ?-->
-			<VBox minWidth="300" alignment="CENTER" HBox.hgrow="ALWAYS" visible="${!controller.anyCheckSelected}" managed="${!controller.anyCheckSelected}" >
-				<Label text="TODO: Select a Check from the left list to get more info." wrapText="true" alignment="CENTER" />
-			</VBox>
-			<fx:include  source="/fxml/health_check_details.fxml" visible="${controller.anyCheckSelected}" managed="${controller.anyCheckSelected}" HBox.hgrow="ALWAYS" />
+			<StackPane visible="${controller.showResultScreen}" managed="${controller.showResultScreen}" HBox.hgrow="ALWAYS" >
+				<VBox minWidth="300" alignment="CENTER" visible="${!controller.anyCheckSelected}" managed="${!controller.anyCheckSelected}" >
+					<Label text="%health.check.result.noSelectedCheck" wrapText="true" alignment="CENTER" />
+				</VBox>
+				<fx:include  source="/fxml/health_check_details.fxml" visible="${controller.anyCheckSelected}" managed="${controller.anyCheckSelected}" />
+			</StackPane>
 		</HBox>
 		<ButtonBar buttonMinWidth="120" buttonOrder="+CX">
 			<buttons>
-				<!-- Buttons have a prefWidth to prevent uneven interface -->
-				<Button prefWidth="20" text="%generic.button.cancel" ButtonBar.buttonData="CANCEL_CLOSE" onAction="#cancelCheck" visible="${controller.running}" managed="${controller.running}" />
-				<Button prefWidth="20" text="%health.check.runAllButton" ButtonBar.buttonData="NEXT_FORWARD" onAction="#runAllChecks" visible="${controller.readyToRun &amp;&amp; !controller.anyCheckSelected}" managed="${controller.readyToRun &amp;&amp; !controller.anyCheckSelected}" />
-				<Button prefWidth="20" text="%health.check.runSingleButton" ButtonBar.buttonData="NEXT_FORWARD" onAction="#runSelectedChecks" visible="${controller.readyToRun &amp;&amp; controller.anyCheckSelected}" managed="${controller.readyToRun &amp;&amp; controller.anyCheckSelected}" />
-				<Button text="TODO Export Results" ButtonBar.buttonData="NEXT_FORWARD" disable="${!controller.finished}" visible="${!controller.readyToRun}" managed="${!controller.readyToRun}" onAction="#exportResults"/>
+				<Button text="%generic.button.cancel" ButtonBar.buttonData="CANCEL_CLOSE" onAction="#cancelCheck" disable="${!controller.running}" visible="${controller.showResultScreen}" managed="${controller.showResultScreen}" />
+				<Button text="%health.check.export" ButtonBar.buttonData="NEXT_FORWARD" defaultButton="true" disable="${!controller.finished}" visible="${controller.showResultScreen}" managed="${controller.showResultScreen}" onAction="#exportResults"/>
+				<Button text="%health.check.runBatchButton" ButtonBar.buttonData="NEXT_FORWARD" defaultButton="true" onAction="#runSelectedChecks" disable="${controller.numberOfPickedChecks == ZERO}" visible="${!controller.showResultScreen}" managed="${!controller.showResultScreen}"/>
 			</buttons>
 		</ButtonBar>
 	</children>

+ 3 - 2
main/ui/src/main/resources/i18n/strings.properties

@@ -148,8 +148,9 @@ migration.impossible.moreInfo=The vault can still be opened with an older versio
 
 # Health Check
 health.title=Vault Check
-health.check.runSingleButton=Run selected Check
-health.check.runAllButton=Run all Checks
+health.check.runBatchButton=Run selected Checks
+health.check.result.noSelectedCheck=For results select a finished check in the left list.
+health.check.export=Export Report
 
 # Preferences
 preferences.title=Preferences