mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-17 18:21:26 +00:00
split up check view:
- checkListController is responsible for selecting and (batch)running checks - checkDetailController is responsible for displaying results
This commit is contained in:
@@ -25,7 +25,7 @@
|
||||
<project.jdk.version>16</project.jdk.version>
|
||||
|
||||
<!-- cryptomator dependencies -->
|
||||
<cryptomator.cryptofs.version>2.1.0-beta4</cryptomator.cryptofs.version>
|
||||
<cryptomator.cryptofs.version>2.1.0-beta5</cryptomator.cryptofs.version>
|
||||
<cryptomator.integrations.version>1.0.0-beta2</cryptomator.integrations.version>
|
||||
<cryptomator.integrations.win.version>1.0.0-beta2</cryptomator.integrations.win.version>
|
||||
<cryptomator.integrations.mac.version>1.0.0-beta2</cryptomator.integrations.mac.version>
|
||||
|
||||
@@ -12,7 +12,7 @@ public enum FxmlFile {
|
||||
ERROR("/fxml/error.fxml"), //
|
||||
FORGET_PASSWORD("/fxml/forget_password.fxml"), //
|
||||
HEALTH_START("/fxml/health_start.fxml"), //
|
||||
HEALTH_CHECK("/fxml/health_check.fxml"), //
|
||||
HEALTH_CHECK("/fxml/health_check_list.fxml"), //
|
||||
LOCK_FORCED("/fxml/lock_forced.fxml"), //
|
||||
LOCK_FAILED("/fxml/lock_failed.fxml"), //
|
||||
MAIN_WINDOW("/fxml/main_window.fxml"), //
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package org.cryptomator.ui.health;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Suppliers;
|
||||
import dagger.Lazy;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javafx.concurrent.Service;
|
||||
import javafx.concurrent.Task;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class BatchService extends Service<Void> {
|
||||
|
||||
private final Iterator<HealthCheckTask> remainingTasks;
|
||||
|
||||
@Inject
|
||||
public BatchService(Iterable<HealthCheckTask> tasks) {
|
||||
this.remainingTasks = tasks.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Task<Void> createTask() {
|
||||
Preconditions.checkState(remainingTasks.hasNext(), "No remaining tasks");
|
||||
return remainingTasks.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void succeeded() {
|
||||
if (remainingTasks.hasNext()) {
|
||||
this.restart();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,99 +8,56 @@ import org.cryptomator.ui.common.FxController;
|
||||
import javax.inject.Inject;
|
||||
import javafx.beans.binding.Binding;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.ReadOnlyBooleanProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
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.TableColumn;
|
||||
import javafx.scene.control.TableView;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
@HealthCheckScoped
|
||||
public class CheckController implements FxController {
|
||||
public class CheckDetailController implements FxController {
|
||||
|
||||
private final HealthCheckSupervisor supervisor;
|
||||
private final HealthReportWriteTask reportWriter;
|
||||
private final ExecutorService executorService;
|
||||
private final ObjectProperty<HealthCheckTask> selectedTask;
|
||||
private final Binding<ObservableList<DiagnosticResult>> selectedResults;
|
||||
private final OptionalBinding<Worker.State> selectedTaskState;
|
||||
private final Binding<String> selectedTaskName;
|
||||
private final Binding<String> selectedTaskDescription;
|
||||
private final ReadOnlyBooleanProperty running;
|
||||
|
||||
/* FXML */
|
||||
public ListView<HealthCheckTask> checksListView;
|
||||
public TableView<DiagnosticResult> resultsTableView;
|
||||
public TableColumn<DiagnosticResult, String> resultDescriptionColumn;
|
||||
public TableColumn<DiagnosticResult, String> resultSeverityColumn;
|
||||
|
||||
|
||||
@Inject
|
||||
public CheckController(HealthCheckSupervisor supervisor, HealthReportWriteTask reportWriteTask, ExecutorService executorService) {
|
||||
this.supervisor = supervisor;
|
||||
this.reportWriter = reportWriteTask;
|
||||
this.executorService = executorService;
|
||||
this.selectedTask = new SimpleObjectProperty<>();
|
||||
public CheckDetailController(ObjectProperty<HealthCheckTask> selectedTask) {
|
||||
this.selectedResults = EasyBind.wrapNullable(selectedTask).map(HealthCheckTask::results).orElse(FXCollections.emptyObservableList());
|
||||
this.selectedTaskState = EasyBind.wrapNullable(selectedTask).mapObservable(HealthCheckTask::stateProperty);
|
||||
this.selectedTaskName = EasyBind.wrapNullable(selectedTask).map(HealthCheckTask::getTitle).orElse("");
|
||||
this.selectedTaskDescription = EasyBind.wrapNullable(selectedTask).map(task -> task.getCheck().toString()).orElse("");
|
||||
this.running = supervisor.runningProperty();
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void initialize() {
|
||||
checksListView.setItems(FXCollections.observableArrayList(supervisor.getTasks()));
|
||||
checksListView.setCellFactory(ignored -> new CheckListCell());
|
||||
checksListView.getSelectionModel().select(0);
|
||||
selectedTask.bind(checksListView.getSelectionModel().selectedItemProperty());
|
||||
|
||||
resultsTableView.itemsProperty().bind(selectedResults);
|
||||
resultDescriptionColumn.setCellValueFactory(cellFeatures -> new SimpleStringProperty(cellFeatures.getValue().toString()));
|
||||
resultSeverityColumn.setCellValueFactory(cellFeatures -> new SimpleStringProperty(cellFeatures.getValue().getServerity().name()));
|
||||
executorService.execute(supervisor);
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void cancelCheck() {
|
||||
assert running.get();
|
||||
supervisor.cancel(true);
|
||||
}
|
||||
/* Getter/Setter */
|
||||
|
||||
|
||||
@FXML
|
||||
public void exportResults() {
|
||||
executorService.execute(reportWriter);
|
||||
}
|
||||
|
||||
/* Getter&Setter */
|
||||
|
||||
public boolean isRunning() {
|
||||
return running.get();
|
||||
}
|
||||
|
||||
public ReadOnlyBooleanProperty runningProperty() {
|
||||
return running;
|
||||
public String getSelectedTaskName() {
|
||||
return selectedTaskName.getValue();
|
||||
}
|
||||
|
||||
public Binding<String> selectedTaskNameProperty() {
|
||||
return selectedTaskName;
|
||||
}
|
||||
|
||||
public String isSelectedTaskName() {
|
||||
return selectedTaskName.getValue();
|
||||
public String getSelectedTaskDescription() {
|
||||
return selectedTaskDescription.getValue();
|
||||
}
|
||||
|
||||
public Binding<String> selectedTaskDescriptionProperty() {
|
||||
return selectedTaskDescription;
|
||||
}
|
||||
|
||||
public String isSelectedTaskDescription() {
|
||||
return selectedTaskDescription.getValue();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package org.cryptomator.ui.health;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.tobiasdiez.easybind.EasyBind;
|
||||
import com.tobiasdiez.easybind.optional.OptionalBinding;
|
||||
import dagger.Lazy;
|
||||
import org.cryptomator.cryptofs.health.api.DiagnosticResult;
|
||||
import org.cryptomator.ui.common.FxController;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javafx.beans.binding.Binding;
|
||||
import javafx.beans.binding.BooleanBinding;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
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.TableColumn;
|
||||
import javafx.scene.control.TableView;
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
@HealthCheckScoped
|
||||
public class CheckListController implements FxController {
|
||||
|
||||
private final ObservableList<HealthCheckTask> tasks;
|
||||
private final HealthReportWriteTask reportWriter;
|
||||
private final ExecutorService executorService;
|
||||
private final ObjectProperty<HealthCheckTask> selectedTask;
|
||||
private final SimpleObjectProperty<Worker<?>> runningTask;
|
||||
private final Binding<Boolean> running;
|
||||
private final BooleanBinding anyCheckSelected;
|
||||
|
||||
/* FXML */
|
||||
public ListView<HealthCheckTask> checksListView;
|
||||
|
||||
@Inject
|
||||
public CheckListController(Lazy<Collection<HealthCheckTask>> tasks, HealthReportWriteTask reportWriteTask, ObjectProperty<HealthCheckTask> selectedTask, ExecutorService executorService) {
|
||||
this.tasks = FXCollections.observableArrayList(tasks.get());
|
||||
this.reportWriter = reportWriteTask;
|
||||
this.executorService = executorService;
|
||||
this.selectedTask = selectedTask;
|
||||
this.runningTask = new SimpleObjectProperty<>();
|
||||
this.running = EasyBind.wrapNullable(runningTask).map(Worker::isRunning).orElse(false);
|
||||
this.anyCheckSelected = selectedTask.isNotNull();
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void initialize() {
|
||||
checksListView.setItems(tasks);
|
||||
checksListView.setCellFactory(ignored -> new CheckListCell());
|
||||
selectedTask.bind(checksListView.getSelectionModel().selectedItemProperty());
|
||||
}
|
||||
|
||||
@FXML
|
||||
public synchronized void runSelectedChecks() {
|
||||
Preconditions.checkState(runningTask.get() == null);
|
||||
var batch = new BatchService(checksListView.getSelectionModel().getSelectedItems());
|
||||
batch.setExecutor(executorService);
|
||||
batch.start();
|
||||
runningTask.set(batch);
|
||||
}
|
||||
|
||||
@FXML
|
||||
public synchronized void runAllChecks() {
|
||||
Preconditions.checkState(runningTask.get() == null);
|
||||
var batch = new BatchService(checksListView.getItems());
|
||||
batch.setExecutor(executorService);
|
||||
batch.start();
|
||||
runningTask.set(batch);
|
||||
}
|
||||
|
||||
@FXML
|
||||
public synchronized void cancelCheck() {
|
||||
Preconditions.checkState(runningTask.get() != null);
|
||||
runningTask.get().cancel();
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void exportResults() {
|
||||
executorService.execute(reportWriter);
|
||||
}
|
||||
|
||||
/* Getter/Setter */
|
||||
|
||||
public boolean isRunning() {
|
||||
return running.getValue();
|
||||
}
|
||||
|
||||
public Binding<Boolean> runningProperty() {
|
||||
return running;
|
||||
}
|
||||
|
||||
public boolean isAnyCheckSelected() {
|
||||
return anyCheckSelected.get();
|
||||
}
|
||||
|
||||
public BooleanBinding anyCheckSelectedProperty() {
|
||||
return anyCheckSelected;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,11 +20,13 @@ import org.cryptomator.ui.keyloading.KeyLoadingStrategy;
|
||||
import org.cryptomator.ui.mainwindow.MainWindow;
|
||||
|
||||
import javax.inject.Provider;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.stage.Modality;
|
||||
import javafx.stage.Stage;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
@@ -40,12 +42,6 @@ abstract class HealthCheckModule {
|
||||
return new AtomicReference<>();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@HealthCheckScoped
|
||||
static Runnable provideMasterkeyDestructor(AtomicReference<Masterkey> masterkeyRef) {
|
||||
return () -> Optional.ofNullable(masterkeyRef.getAndSet(null)).ifPresent(Masterkey::destroy);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@HealthCheckScoped
|
||||
static AtomicReference<VaultConfig> provideVaultConfigRef() {
|
||||
@@ -54,15 +50,21 @@ abstract class HealthCheckModule {
|
||||
|
||||
@Provides
|
||||
@HealthCheckScoped
|
||||
static Collection<HealthCheck> provideSelectedHealthChecks() {
|
||||
return new ArrayList<>();
|
||||
static Collection<HealthCheck> provideAvailableHealthChecks() {
|
||||
return HealthCheck.allChecks();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@HealthCheckScoped
|
||||
static ObjectProperty<HealthCheckTask> provideSelectedHealthCheckTask() {
|
||||
return new SimpleObjectProperty<>();
|
||||
}
|
||||
|
||||
/* Only inject with Lazy-Wrapper!*/
|
||||
@Provides
|
||||
@HealthCheckScoped
|
||||
static Collection<HealthCheckTask> provideSelectedHealthCheckTasks(Collection<HealthCheck> selectedHealthChecks, @HealthCheckWindow Vault vault, AtomicReference<Masterkey> masterkeyRef, AtomicReference<VaultConfig> vaultConfigRef, SecureRandom csprng) {
|
||||
return selectedHealthChecks.stream().map(check -> new HealthCheckTask(vault.getPath(), vaultConfigRef.get(), masterkeyRef.get(), csprng, check)).toList();
|
||||
static Collection<HealthCheckTask> provideAvailableHealthCheckTasks(Collection<HealthCheck> availableHealthChecks, @HealthCheckWindow Vault vault, AtomicReference<Masterkey> masterkeyRef, AtomicReference<VaultConfig> vaultConfigRef, SecureRandom csprng) {
|
||||
return availableHealthChecks.stream().map(check -> new HealthCheckTask(vault.getPath(), vaultConfigRef.get(), masterkeyRef.get(), csprng, check)).toList();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@@ -82,20 +84,26 @@ abstract class HealthCheckModule {
|
||||
@Provides
|
||||
@HealthCheckWindow
|
||||
@HealthCheckScoped
|
||||
static Stage provideStage(StageFactory factory, @MainWindow Stage owner, ResourceBundle resourceBundle, Runnable masterkeyDestructor) {
|
||||
static Stage provideStage(StageFactory factory, @MainWindow Stage owner, ResourceBundle resourceBundle, ChangeListener<Boolean> showingListener) {
|
||||
Stage stage = factory.create();
|
||||
stage.setTitle(resourceBundle.getString("health.title"));
|
||||
stage.setResizable(true);
|
||||
stage.initModality(Modality.WINDOW_MODAL);
|
||||
stage.initOwner(owner);
|
||||
stage.showingProperty().addListener((observable, wasShowing, isShowing) -> { //TODO: should we use showingProperty or onCloseRequest
|
||||
if (!isShowing) {
|
||||
masterkeyDestructor.run();
|
||||
}
|
||||
});
|
||||
stage.showingProperty().addListener(showingListener); // bind masterkey lifecycle to window
|
||||
return stage;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@HealthCheckScoped
|
||||
static ChangeListener<Boolean> provideWindowShowingChangeListener(AtomicReference<Masterkey> masterkey) {
|
||||
return (observable, wasShowing, isShowing) -> {
|
||||
if (!isShowing) {
|
||||
Optional.ofNullable(masterkey.getAndSet(null)).ifPresent(Masterkey::destroy);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Provides
|
||||
@FxmlScene(FxmlFile.HEALTH_START)
|
||||
@HealthCheckScoped
|
||||
@@ -117,7 +125,13 @@ abstract class HealthCheckModule {
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FxControllerKey(CheckController.class)
|
||||
abstract FxController bindCheckController(CheckController controller);
|
||||
@FxControllerKey(CheckListController.class)
|
||||
abstract FxController bindCheckController(CheckListController controller);
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FxControllerKey(CheckDetailController.class)
|
||||
abstract FxController bindCheckDetailController(CheckDetailController controller);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
package org.cryptomator.ui.health;
|
||||
|
||||
import dagger.Lazy;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javafx.concurrent.Task;
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
@HealthCheckScoped
|
||||
public class HealthCheckSupervisor extends Task<Void> {
|
||||
|
||||
private final ExecutorService executor;
|
||||
private final Lazy<Collection<HealthCheckTask>> lazyTasks;
|
||||
private final Runnable masterkeyDestructor;
|
||||
private final AtomicReference<HealthCheckTask> currentTask;
|
||||
private final ConcurrentLinkedQueue<HealthCheckTask> remainingTasks;
|
||||
|
||||
@Inject
|
||||
public HealthCheckSupervisor(Lazy<Collection<HealthCheckTask>> lazyTasks, Runnable masterkeyDestructor) {
|
||||
this.lazyTasks = lazyTasks;
|
||||
this.masterkeyDestructor = masterkeyDestructor;
|
||||
this.currentTask = new AtomicReference<>(null);
|
||||
this.executor = Executors.newSingleThreadExecutor();
|
||||
this.remainingTasks = new ConcurrentLinkedQueue<>();
|
||||
}
|
||||
|
||||
public Void call() {
|
||||
remainingTasks.addAll(lazyTasks.get());
|
||||
while (!remainingTasks.isEmpty()) {
|
||||
final var task = remainingTasks.remove();
|
||||
currentTask.set(task);
|
||||
executor.execute(task); //TODO: think about if we set the scheduled property for all tasks?
|
||||
try {
|
||||
task.get();
|
||||
} catch (InterruptedException e) {
|
||||
executor.shutdownNow();
|
||||
cleanup();
|
||||
;
|
||||
Thread.currentThread().interrupt(); //TODO: do we need this?
|
||||
} catch (ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
} catch (CancellationException e) {
|
||||
// ok
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cancel(boolean mayInterruptIfRunning) {
|
||||
cleanup();
|
||||
currentTask.get().cancel(mayInterruptIfRunning);
|
||||
if (mayInterruptIfRunning) {
|
||||
executor.shutdownNow();
|
||||
} else {
|
||||
executor.shutdown();
|
||||
}
|
||||
return super.cancel(mayInterruptIfRunning);
|
||||
}
|
||||
|
||||
private void cleanup() {
|
||||
remainingTasks.forEach(task -> task.cancel(false));
|
||||
remainingTasks.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void done() {
|
||||
masterkeyDestructor.run(); //TODO: if we destroy it, no check can rerun
|
||||
}
|
||||
|
||||
public Collection<HealthCheckTask> getTasks() {
|
||||
return lazyTasks.get();
|
||||
}
|
||||
}
|
||||
@@ -44,8 +44,6 @@ public class StartController implements FxController {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(StartController.class);
|
||||
|
||||
private final Stage window;
|
||||
private final Collection<HealthCheck> availableChecks;
|
||||
private final Map<HealthCheck, BooleanProperty> availableCheckListSelectProperties;
|
||||
private final Optional<VaultConfig.UnverifiedVaultConfig> unverifiedVaultConfig;
|
||||
private final KeyLoadingStrategy keyLoadingStrategy;
|
||||
private final ExecutorService executor;
|
||||
@@ -55,11 +53,6 @@ public class StartController implements FxController {
|
||||
private final Lazy<Scene> checkScene;
|
||||
|
||||
/* FXML */
|
||||
public ListView availableChecksList;
|
||||
public RadioButton customCheckSetButton;
|
||||
public RadioButton quickCheckSetButton;
|
||||
public RadioButton fullCheckSetButton;
|
||||
public ToggleGroup checksSetToggleGroup;
|
||||
|
||||
@Inject
|
||||
public StartController(@HealthCheckWindow Vault vault, @HealthCheckWindow Stage window, @HealthCheckWindow KeyLoadingStrategy keyLoadingStrategy, ExecutorService executor, AtomicReference<Masterkey> masterkeyRef, AtomicReference<VaultConfig> vaultConfigRef, Collection<HealthCheck> selectedChecks, @FxmlScene(FxmlFile.HEALTH_CHECK) Lazy<Scene> checkScene) {
|
||||
@@ -71,31 +64,6 @@ public class StartController implements FxController {
|
||||
this.vaultConfigRef = vaultConfigRef;
|
||||
this.selectedChecks = selectedChecks;
|
||||
this.checkScene = checkScene;
|
||||
this.availableChecks = HealthCheck.allChecks();
|
||||
this.availableCheckListSelectProperties = new HashMap<>();
|
||||
|
||||
availableChecks.forEach(check -> availableCheckListSelectProperties.put(check, new SimpleBooleanProperty(false)));
|
||||
}
|
||||
|
||||
public void initialize() {
|
||||
availableChecksList.setItems(FXCollections.observableList(availableChecks.stream().toList()));
|
||||
availableChecksList.setCellFactory(CheckBoxListCell.forListView(availableCheckListSelectProperties::get));
|
||||
availableChecksList.setEditable(false);
|
||||
|
||||
var availableCheckIds = availableChecks.stream().map(HealthCheck::identifier).toList();
|
||||
|
||||
if (PredefinedCheckSet.QUICK.getCheckIds().stream().anyMatch(checkId -> !availableCheckIds.contains(checkId))) {
|
||||
quickCheckSetButton.setVisible(false);
|
||||
quickCheckSetButton.setManaged(false);
|
||||
}
|
||||
if (PredefinedCheckSet.FULL.getCheckIds().stream().anyMatch(checkId -> !availableCheckIds.contains(checkId))) {
|
||||
fullCheckSetButton.setVisible(false);
|
||||
fullCheckSetButton.setManaged(false);
|
||||
}
|
||||
|
||||
quickCheckSetButton.setUserData(PredefinedCheckSet.QUICK);
|
||||
fullCheckSetButton.setUserData(PredefinedCheckSet.FULL);
|
||||
customCheckSetButton.setUserData(PredefinedCheckSet.CUSTOM);
|
||||
}
|
||||
|
||||
@FXML
|
||||
@@ -106,15 +74,6 @@ public class StartController implements FxController {
|
||||
|
||||
@FXML
|
||||
public void next() {
|
||||
switch ((PredefinedCheckSet) checksSetToggleGroup.getSelectedToggle().getUserData()) {
|
||||
case FULL -> selectedChecks.addAll(availableChecks);
|
||||
case QUICK -> selectedChecks.addAll(availableChecks.stream().filter(check -> PredefinedCheckSet.QUICK.getCheckIds().contains(check.identifier())).toList());
|
||||
case CUSTOM -> availableCheckListSelectProperties.forEach((check, selected) -> {
|
||||
if (selected.get()) {
|
||||
selectedChecks.add(check);
|
||||
}
|
||||
});
|
||||
}
|
||||
LOG.trace("StartController.next()");
|
||||
executor.submit(this::loadKey);
|
||||
}
|
||||
@@ -166,27 +125,4 @@ public class StartController implements FxController {
|
||||
return unverifiedVaultConfig.isEmpty();
|
||||
}
|
||||
|
||||
public BooleanBinding anyCheckSetSelectedProperty() {
|
||||
return checksSetToggleGroup.selectedToggleProperty().isNotNull();
|
||||
}
|
||||
|
||||
public boolean isAnyCheckSetSelected() {
|
||||
return anyCheckSetSelectedProperty().get();
|
||||
}
|
||||
|
||||
enum PredefinedCheckSet {
|
||||
QUICK(DirIdCheck.class.getCanonicalName()), //TODO: get identifier via static method?
|
||||
FULL(DirIdCheck.class.getCanonicalName()),
|
||||
CUSTOM();
|
||||
|
||||
private Collection<String> checkIds;
|
||||
|
||||
PredefinedCheckSet(String... checkIds) {
|
||||
this.checkIds = Set.of(checkIds);
|
||||
}
|
||||
|
||||
Collection<String> getCheckIds() {
|
||||
return checkIds;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.ListView?>
|
||||
<?import javafx.scene.control.TableColumn?>
|
||||
<?import javafx.scene.control.TableView?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Text?>
|
||||
<HBox xmlns:fx="http://javafx.com/fxml"
|
||||
xmlns="http://javafx.com/javafx"
|
||||
fx:controller="org.cryptomator.ui.health.CheckController"
|
||||
minWidth="400"
|
||||
maxWidth="400"
|
||||
minHeight="145"
|
||||
spacing="12">
|
||||
<padding>
|
||||
<Insets topRightBottomLeft="12"/>
|
||||
</padding>
|
||||
<children>
|
||||
<VBox minWidth="80">
|
||||
<Label fx:id="listHeading" text="Health checks"/>
|
||||
<ListView fx:id="checksListView"/>
|
||||
<Button text="%generic.button.cancel" onAction="#cancelCheck" disable="${!controller.running}" maxWidth="Infinity"/>
|
||||
<Button text="Export Results" onAction="#exportResults" disable="${controller.running}" maxWidth="Infinity"/>
|
||||
</VBox>
|
||||
<VBox spacing="6">
|
||||
<Label fx:id="checkTitle" styleClass="label-large" text="${controller.selectedTaskName}" />
|
||||
<Text fx:id="checkDescription" styleClass="label" text="${controller.selectedTaskDescription}" />
|
||||
<TableView fx:id="resultsTableView" >
|
||||
<columns>
|
||||
<TableColumn fx:id="resultDescriptionColumn" text="Info" editable="false"/>
|
||||
<TableColumn fx:id="resultSeverityColumn" text="Severity" editable="false"/>
|
||||
<!--TableColumn fx:id="resultAction" text="Action" /-->
|
||||
</columns>
|
||||
</TableView>
|
||||
</VBox>
|
||||
</children>
|
||||
</HBox>
|
||||
22
main/ui/src/main/resources/fxml/health_check_details.fxml
Normal file
22
main/ui/src/main/resources/fxml/health_check_details.fxml
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.TableColumn?>
|
||||
<?import javafx.scene.control.TableView?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Text?>
|
||||
<VBox xmlns:fx="http://javafx.com/fxml"
|
||||
xmlns="http://javafx.com/javafx"
|
||||
fx:controller="org.cryptomator.ui.health.CheckDetailController"
|
||||
spacing="6">
|
||||
<Label fx:id="checkTitle" styleClass="label-large" text="${controller.selectedTaskName}"/>
|
||||
<Text fx:id="checkDescription" styleClass="label" text="${controller.selectedTaskDescription}"/>
|
||||
<!-- TODO hide if state != succeeded: -->
|
||||
<TableView fx:id="resultsTableView">
|
||||
<columns>
|
||||
<TableColumn fx:id="resultDescriptionColumn" text="Info" editable="false"/>
|
||||
<TableColumn fx:id="resultSeverityColumn" text="Severity" editable="false"/>
|
||||
<!--TableColumn fx:id="resultAction" text="Action" /-->
|
||||
</columns>
|
||||
</TableView>
|
||||
</VBox>
|
||||
39
main/ui/src/main/resources/fxml/health_check_list.fxml
Normal file
39
main/ui/src/main/resources/fxml/health_check_list.fxml
Normal file
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.ButtonBar?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.ListView?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<VBox xmlns:fx="http://javafx.com/fxml"
|
||||
xmlns="http://javafx.com/javafx"
|
||||
fx:controller="org.cryptomator.ui.health.CheckListController"
|
||||
minWidth="400"
|
||||
maxWidth="400"
|
||||
minHeight="145"
|
||||
spacing="12">
|
||||
<padding>
|
||||
<Insets topRightBottomLeft="12"/>
|
||||
</padding>
|
||||
<children>
|
||||
<HBox>
|
||||
<VBox minWidth="80">
|
||||
<Label fx:id="listHeading" text="Health checks"/>
|
||||
<ListView fx:id="checksListView"/>
|
||||
<!-- TODO: clean up button states: -->
|
||||
<Button text="TODO: run selected" onAction="#runSelectedChecks" disable="${controller.running || !controller.anyCheckSelected}" maxWidth="Infinity"/>
|
||||
<Button text="TODO: run all" onAction="#runAllChecks" disable="${controller.running}" maxWidth="Infinity"/>
|
||||
<Button text="%generic.button.cancel" onAction="#cancelCheck" disable="${!controller.running}" maxWidth="Infinity"/>
|
||||
</VBox>
|
||||
<fx:include source="/fxml/health_check_details.fxml" visible="${controller.anyCheckSelected}" managed="${controller.anyCheckSelected}"/>
|
||||
</HBox>
|
||||
<ButtonBar buttonMinWidth="120" buttonOrder="+X">
|
||||
<buttons>
|
||||
<!-- TODO: hide/disable if no results yet -->
|
||||
<Button text="TODO Export Results" ButtonBar.buttonData="NEXT_FORWARD" disable="${controller.running}" onAction="#exportResults"/>
|
||||
</buttons>
|
||||
</ButtonBar>
|
||||
</children>
|
||||
</VBox>
|
||||
@@ -16,29 +16,18 @@
|
||||
maxWidth="400"
|
||||
minHeight="145"
|
||||
spacing="12">
|
||||
<fx:define>
|
||||
<ToggleGroup fx:id="checksSetToggleGroup"/>
|
||||
</fx:define>
|
||||
<padding>
|
||||
<Insets topRightBottomLeft="12"/>
|
||||
</padding>
|
||||
<children>
|
||||
<Label text="TODO: Invalid vault config" visible="${controller.invalidConfig}" managed="${controller.invalidConfig}"/>
|
||||
|
||||
<Label text="Please select, which check(s) should be performed:"/>
|
||||
<VBox spacing="6" disable="${controller.invalidConfig}">
|
||||
<RadioButton fx:id="quickCheckSetButton" toggleGroup="${checksSetToggleGroup}" text="Quick Check"/>
|
||||
<RadioButton fx:id="fullCheckSetButton" toggleGroup="${checksSetToggleGroup}" text="Full Check"/>
|
||||
<AnchorPane >
|
||||
<RadioButton fx:id="customCheckSetButton" toggleGroup="${checksSetToggleGroup}" text="Custom Check"/>
|
||||
<ListView fx:id="availableChecksList" AnchorPane.leftAnchor="20.0" AnchorPane.topAnchor="20.0" maxHeight="100" visible="${customCheckSetButton.selected}"/>
|
||||
</AnchorPane>
|
||||
</VBox>
|
||||
<Label text="TODO: Blabla going to health check now...:"/>
|
||||
|
||||
<ButtonBar buttonMinWidth="120" buttonOrder="+CX">
|
||||
<buttons>
|
||||
<Button text="%generic.button.cancel" ButtonBar.buttonData="CANCEL_CLOSE" cancelButton="true" onAction="#close"/>
|
||||
<Button text="%generic.button.next" ButtonBar.buttonData="NEXT_FORWARD" disable="${controller.invalidConfig || !controller.anyCheckSetSelected}" defaultButton="true" onAction="#next"/>
|
||||
<Button text="%generic.button.next" ButtonBar.buttonData="NEXT_FORWARD" disable="${controller.invalidConfig}" defaultButton="true" onAction="#next"/>
|
||||
</buttons>
|
||||
</ButtonBar>
|
||||
</children>
|
||||
|
||||
@@ -19,10 +19,10 @@ Cryptomator uses 45 third-party dependencies under the following licenses:
|
||||
- jnr-ffi (com.github.jnr:jnr-ffi:2.1.12 - http://github.com/jnr/jnr-ffi)
|
||||
- FindBugs-jsr305 (com.google.code.findbugs:jsr305:3.0.2 - http://findbugs.sourceforge.net/)
|
||||
- Gson (com.google.code.gson:gson:2.8.6 - https://github.com/google/gson/gson)
|
||||
- Dagger (com.google.dagger:dagger:2.32 - https://github.com/google/dagger)
|
||||
- error-prone annotations (com.google.errorprone:error_prone_annotations:2.3.4 - http://nexus.sonatype.org/oss-repository-hosting.html/error_prone_parent/error_prone_annotations)
|
||||
- Dagger (com.google.dagger:dagger:2.35.1 - https://github.com/google/dagger)
|
||||
- error-prone annotations (com.google.errorprone:error_prone_annotations:2.5.1 - http://nexus.sonatype.org/oss-repository-hosting.html/error_prone_parent/error_prone_annotations)
|
||||
- Guava InternalFutureFailureAccess and InternalFutures (com.google.guava:failureaccess:1.0.1 - https://github.com/google/guava/failureaccess)
|
||||
- Guava: Google Core Libraries for Java (com.google.guava:guava:30.1-jre - https://github.com/google/guava/guava)
|
||||
- Guava: Google Core Libraries for Java (com.google.guava:guava:30.1.1-jre - https://github.com/google/guava/guava)
|
||||
- Guava ListenableFuture only (com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava - https://github.com/google/guava/listenablefuture)
|
||||
- J2ObjC Annotations (com.google.j2objc:j2objc-annotations:1.3 - https://github.com/google/j2objc/)
|
||||
- Apache Commons CLI (commons-cli:commons-cli:1.4 - http://commons.apache.org/proper/commons-cli/)
|
||||
@@ -70,11 +70,11 @@ Cryptomator uses 45 third-party dependencies under the following licenses:
|
||||
- Java Native Access (net.java.dev.jna:jna:5.7.0 - https://github.com/java-native-access/jna)
|
||||
- Java Native Access Platform (net.java.dev.jna:jna-platform:5.7.0 - https://github.com/java-native-access/jna)
|
||||
MIT License:
|
||||
- java jwt (com.auth0:java-jwt:3.13.0 - https://github.com/auth0/java-jwt)
|
||||
- java jwt (com.auth0:java-jwt:3.15.0 - https://github.com/auth0/java-jwt)
|
||||
- jnr-x86asm (com.github.jnr:jnr-x86asm:1.0.2 - http://github.com/jnr/jnr-x86asm)
|
||||
- jnr-fuse (com.github.serceman:jnr-fuse:0.5.5 - https://github.com/SerCeMan/jnr-fuse)
|
||||
- zxcvbn4j (com.nulab-inc:zxcvbn:1.3.0 - https://github.com/nulab/zxcvbn4j)
|
||||
- Checker Qual (org.checkerframework:checker-qual:3.5.0 - https://checkerframework.org)
|
||||
- Checker Qual (org.checkerframework:checker-qual:3.8.0 - https://checkerframework.org)
|
||||
- SLF4J API Module (org.slf4j:slf4j-api:1.7.30 - http://www.slf4j.org)
|
||||
The BSD 2-Clause License:
|
||||
- EasyBind (com.tobiasdiez:easybind:2.1.0 - https://github.com/tobiasdiez/EasyBind)
|
||||
|
||||
Reference in New Issue
Block a user