浏览代码

Depeding on state of selected task, show appropiate status text in check detail view

Armin Schrenk 3 年之前
父节点
当前提交
7eaade1555

+ 97 - 45
main/ui/src/main/java/org/cryptomator/ui/health/CheckDetailController.java

@@ -7,7 +7,6 @@ import org.cryptomator.ui.common.FxController;
 
 import javax.inject.Inject;
 import javafx.beans.binding.Binding;
-import javafx.beans.binding.BooleanBinding;
 import javafx.beans.property.LongProperty;
 import javafx.beans.property.ObjectProperty;
 import javafx.beans.property.SimpleLongProperty;
@@ -25,71 +24,76 @@ import java.util.Map;
 @HealthCheckScoped
 public class CheckDetailController implements FxController {
 
-	private final Map<ObservableList<DiagnosticResult>, WarnAndErrorEntry> cachedWarnAndErrorCounts;
+	private final Map<ObservableList<DiagnosticResult>, WarnAndErrorEntry> cachedWarnAndCritCounts;
 	private final Binding<ObservableList<DiagnosticResult>> results;
 	private final OptionalBinding<Worker.State> taskState;
 	private final Binding<String> taskName;
 	private final Binding<Number> taskDuration;
 	private final ResultListCellFactory resultListCellFactory;
-	private final BooleanBinding producingResults;
-	private final LongProperty numOfWarnings;
-	private final LongProperty numOfErrors;
+	private final Binding<Boolean> taskRunning;
+	private final Binding<Boolean> taskScheduled;
+	private final Binding<Boolean> taskFinished;
+	private final Binding<Boolean> taskNotStarted;
+	private final Binding<Boolean> taskSucceeded;
+	private final Binding<Boolean> taskFailed;
+	private final Binding<Boolean> taskCancelled;
+	private final LongProperty countOfWarnSeverity;
+	private final LongProperty countOfCritSeverity;
 
 	public ListView<DiagnosticResult> resultsListView;
 
 	@Inject
 	public CheckDetailController(ObjectProperty<HealthCheckTask> selectedTask, ResultListCellFactory resultListCellFactory) {
-		selectedTask.addListener(this::rebindWarnAndErrorCount);
+		selectedTask.addListener(this::rebindWarnAndCritProperties);
 		this.results = EasyBind.wrapNullable(selectedTask).map(HealthCheckTask::results).orElse(FXCollections.emptyObservableList());
 		this.taskState = EasyBind.wrapNullable(selectedTask).mapObservable(HealthCheckTask::stateProperty);
 		this.taskName = EasyBind.wrapNullable(selectedTask).map(HealthCheckTask::getTitle).orElse("");
 		this.taskDuration = EasyBind.wrapNullable(selectedTask).mapObservable(HealthCheckTask::durationInMillisProperty).orElse(-1L);
 		this.resultListCellFactory = resultListCellFactory;
-		this.producingResults = taskState.filter(this::producesResults).isPresent();
-		this.numOfWarnings = new SimpleLongProperty(0);
-		this.numOfErrors = new SimpleLongProperty(0);
-		this.cachedWarnAndErrorCounts = new IdentityHashMap<>(); //important to use an identity hashmap, because collections violate the immnutable hashkey contract
-	}
-
-	private synchronized void rebindWarnAndErrorCount(ObservableValue<? extends HealthCheckTask> observable, HealthCheckTask oldVal, HealthCheckTask newVal) {
+		this.taskRunning = EasyBind.wrapNullable(selectedTask).mapObservable(HealthCheckTask::runningProperty).orElse(false); //TODO: DOES NOT WORK
+		this.taskScheduled = taskState.map(Worker.State.SCHEDULED::equals).orElse(false);
+		this.taskNotStarted = taskState.map(Worker.State.READY::equals).orElse(false);
+		this.taskSucceeded = taskState.map(Worker.State.SUCCEEDED::equals).orElse(false);
+		this.taskFailed = taskState.map(Worker.State.FAILED::equals).orElse(false);
+		this.taskCancelled = taskState.map(Worker.State.CANCELLED::equals).orElse(false);
+		this.taskFinished = EasyBind.combine(taskSucceeded, taskFailed, taskCancelled, (a, b, c) -> a || b || c);
+		this.countOfWarnSeverity = new SimpleLongProperty(0);
+		this.countOfCritSeverity = new SimpleLongProperty(0);
+		this.cachedWarnAndCritCounts = new IdentityHashMap<>(); //important to use an identity hashmap, because collections violate the immnutable hashkey contract
+	}
+
+	private synchronized void rebindWarnAndCritProperties(ObservableValue<? extends HealthCheckTask> observable, HealthCheckTask oldVal, HealthCheckTask newVal) {
 		//create and cache properites for the newList, if not already present
 		final var listToUpdate = newVal.results();
-		cachedWarnAndErrorCounts.computeIfAbsent(listToUpdate, key -> {
+		cachedWarnAndCritCounts.computeIfAbsent(listToUpdate, key -> {
 			var warnProperty = new SimpleLongProperty(countSeverityInList(listToUpdate, DiagnosticResult.Severity.WARN));
 			var errProperty = new SimpleLongProperty(countSeverityInList(listToUpdate, DiagnosticResult.Severity.CRITICAL));
 			return new WarnAndErrorEntry(warnProperty, errProperty);
 		});
-		listToUpdate.addListener(this::updateListSpecificWarnAndErrorCount);
+		listToUpdate.addListener(this::updateListSpecificWarnAndCritCount);
 
 		//updateBindings
-		numOfErrors.bind(cachedWarnAndErrorCounts.get(listToUpdate).errorCount);
-		numOfWarnings.bind(cachedWarnAndErrorCounts.get(listToUpdate).warningCount);
+		countOfCritSeverity.bind(cachedWarnAndCritCounts.get(listToUpdate).errorCount);
+		countOfWarnSeverity.bind(cachedWarnAndCritCounts.get(listToUpdate).warningCount);
 	}
 
-	private synchronized void updateListSpecificWarnAndErrorCount(ListChangeListener.Change<? extends DiagnosticResult> c) {
-		long tmpErr = cachedWarnAndErrorCounts.get(c.getList()).errorCount.get();
-		long tmpWarn = cachedWarnAndErrorCounts.get(c.getList()).warningCount.get();
+	private synchronized void updateListSpecificWarnAndCritCount(ListChangeListener.Change<? extends DiagnosticResult> c) {
+		long tmpErr = cachedWarnAndCritCounts.get(c.getList()).errorCount.get();
+		long tmpWarn = cachedWarnAndCritCounts.get(c.getList()).warningCount.get();
 		while (c.next()) {
 			if (c.wasAdded()) {
 				tmpWarn += countSeverityInList(c.getAddedSubList(), DiagnosticResult.Severity.WARN);
 				tmpErr += countSeverityInList(c.getAddedSubList(), DiagnosticResult.Severity.CRITICAL);
 			}
 		}
-		cachedWarnAndErrorCounts.get(c.getList()).errorCount.set(tmpErr);
-		cachedWarnAndErrorCounts.get(c.getList()).warningCount.set(tmpWarn);
+		cachedWarnAndCritCounts.get(c.getList()).errorCount.set(tmpErr);
+		cachedWarnAndCritCounts.get(c.getList()).warningCount.set(tmpWarn);
 	}
 
 	private long countSeverityInList(List<? extends DiagnosticResult> list, DiagnosticResult.Severity severityToCount) {
 		return list.stream().map(DiagnosticResult::getServerity).filter(severityToCount::equals).count();
 	}
 
-	private boolean producesResults(Worker.State state) {
-		return switch (state) {
-			case SCHEDULED, RUNNING -> true;
-			case READY, SUCCEEDED, CANCELLED, FAILED -> false;
-		};
-	}
-
 	@FXML
 	public void initialize() {
 		resultsListView.itemsProperty().bind(results);
@@ -106,14 +110,6 @@ public class CheckDetailController implements FxController {
 		return taskName;
 	}
 
-	public boolean isProducingResults() {
-		return producingResults.get();
-	}
-
-	public BooleanBinding producingResultsProperty() {
-		return producingResults;
-	}
-
 	public Number getTaskDuration() {
 		return taskDuration.getValue();
 	}
@@ -122,20 +118,76 @@ public class CheckDetailController implements FxController {
 		return taskDuration;
 	}
 
-	public long getNumOfWarnings() {
-		return numOfWarnings.get();
+	public long getCountOfWarnSeverity() {
+		return countOfWarnSeverity.get();
+	}
+
+	public LongProperty countOfWarnSeverityProperty() {
+		return countOfWarnSeverity;
+	}
+
+	public long getCountOfCritSeverity() {
+		return countOfCritSeverity.get();
+	}
+
+	public LongProperty countOfCritSeverityProperty() {
+		return countOfCritSeverity;
+	}
+
+	public boolean isTaskRunning() {
+		return taskRunning.getValue();
+	}
+
+	public Binding<Boolean> taskRunningProperty() {
+		return taskRunning;
+	}
+
+	public boolean isTaskFinished() {
+		return taskFinished.getValue();
+	}
+
+	public Binding<Boolean> taskFinishedProperty() {
+		return taskFinished;
+	}
+
+	public boolean isTaskScheduled() {
+		return taskScheduled.getValue();
+	}
+
+	public Binding<Boolean> taskScheduledProperty() {
+		return taskScheduled;
+	}
+
+	public boolean isTaskNotStarted() {
+		return taskNotStarted.getValue();
+	}
+
+	public Binding<Boolean> taskNotStartedProperty() {
+		return taskNotStarted;
+	}
+
+	public boolean isTaskSucceeded() {
+		return taskSucceeded.getValue();
+	}
+
+	public Binding<Boolean> taskSucceededProperty() {
+		return taskSucceeded;
+	}
+
+	public boolean isTaskFailed() {
+		return taskFailed.getValue();
 	}
 
-	public LongProperty numOfWarningsProperty() {
-		return numOfWarnings;
+	public Binding<Boolean> taskFailedProperty() {
+		return taskFailed;
 	}
 
-	public long getNumOfErrors() {
-		return numOfErrors.get();
+	public boolean isTaskCancelled() {
+		return taskCancelled.getValue();
 	}
 
-	public LongProperty numOfErrorsProperty() {
-		return numOfErrors;
+	public Binding<Boolean> taskCancelledProperty() {
+		return taskCancelled;
 	}
 
 	private static class WarnAndErrorEntry {

+ 11 - 5
main/ui/src/main/resources/fxml/health_check_details.fxml

@@ -9,10 +9,16 @@
 	  xmlns="http://javafx.com/javafx"
 	  fx:controller="org.cryptomator.ui.health.CheckDetailController"
 	  spacing="6">
-	<FormattedLabel fx:id="checkTitle" styleClass="label-large" format="%health.check.result.header" arg1="${controller.taskName}"/>
-	<Label text="The check is currently running..." visible="${controller.producingResults}" managed="${controller.producingResults}"/>
-	<!-- TODO: what if the check was canceled? Should be indicated in ui -->
-	<FormattedLabel fx:id="checkDescription" styleClass="label" format="The check finished after %d milliseconds." arg1="${controller.taskDuration}" visible="${!controller.producingResults}" managed="${!controller.producingResults}"/>
-	<FormattedLabel2 styleClass="label" format="Found %d Warnings and %d unfixable Errors." arg1="${controller.numOfWarnings}" arg2="${controller.numOfErrors}" />
+	<FormattedLabel fx:id="checkTitle" styleClass="label-large" format="%health.check.detail.header" arg1="${controller.taskName}"/>
+
+	<Label text="%health.check.detail.taskNotStarted" visible="${controller.taskNotStarted}" managed="${controller.taskNotStarted}"/>
+	<Label text="%health.check.detail.taskRunning" visible="${controller.taskRunning}" managed="${controller.taskRunning}"/>
+	<Label text="%health.check.detail.taskScheduled" visible="${controller.taskScheduled}" managed="${controller.taskScheduled}"/>
+	<Label text="%health.check.detail.taskCancelled" visible="${controller.taskCancelled}" managed="${controller.taskCancelled}"/>
+	<Label text="%health.check.detail.taskFailed" visible="${controller.taskFailed}" managed="${controller.taskFailed}"/>
+	<FormattedLabel styleClass="label" format="%health.check.detail.taskSucceeded" arg1="${controller.taskDuration}" visible="${controller.taskSucceeded}" managed="${controller.taskSucceeded}"/>
+
+	<FormattedLabel2 styleClass="label" format="%health.check.detail.problemCount" arg1="${controller.countOfWarnSeverity}" arg2="${controller.countOfCritSeverity}" visible="${!controller.taskNotStarted}"
+					 managed="${!controller.taskNotStarted}"	/>
 	<ListView fx:id="resultsListView" VBox.vgrow="ALWAYS"/>
 </VBox>

+ 1 - 1
main/ui/src/main/resources/fxml/health_check_list.fxml

@@ -30,7 +30,7 @@
 			</VBox>
 			<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" />
+					<Label text="%health.check.detail.noSelectedCheck" wrapText="true" alignment="CENTER" />
 				</VBox>
 				<fx:include  source="/fxml/health_check_details.fxml" visible="${controller.anyCheckSelected}" managed="${controller.anyCheckSelected}" />
 			</StackPane>

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

@@ -154,8 +154,16 @@ health.start.configInvalid=Error while reading and parsing the vault configurati
 health.checkList.header=Available Checks
 health.checkList.selectAllBox=Select All
 health.check.runBatchBtn=Run selected Checks
-health.check.result.noSelectedCheck=For results select a finished check in the left list.
-health.check.result.header=Results of %s
+## Detail view
+health.check.detail.noSelectedCheck=For results select a finished check in the left list.
+health.check.detail.header=Results of %s
+health.check.detail.taskNotStarted=The check was not selected to run.
+health.check.detail.taskScheduled=The check is scheduled.
+health.check.detail.taskRunning=The check is currently running…
+health.check.detail.taskSucceeded=The check finished successfully after %d milliseconds.
+health.check.detail.taskFailed=The check exited with errors.
+health.check.detail.taskCancelled=The check was cancelled.
+health.check.detail.problemCount=Found %d Problems and %d unfixable Errors.
 health.check.exportBtn=Export Report
 health.check.fixBtn=Fix
 ## Checks