Rework summary and info

This commit is contained in:
crschnick
2025-06-15 19:19:01 +00:00
parent 5b40c5cc14
commit 57aab3331f
23 changed files with 45 additions and 135 deletions
@@ -58,10 +58,6 @@ public interface DataStoreProvider {
return new SimpleBooleanProperty(false);
}
default boolean alwaysShowSummary() {
return false;
}
default void validate() {
if (getUsageCategory() == null) {
throw ExtensionException.corrupt("Provider %s does not have the usage category".formatted(getId()));
@@ -3,6 +3,7 @@ package io.xpipe.app.hub.comp;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.augment.GrowAugment;
import io.xpipe.app.core.AppFontSizes;
import io.xpipe.app.core.AppI18n;
import io.xpipe.core.process.OsType;
import javafx.beans.binding.Bindings;
@@ -35,14 +36,16 @@ public class DenseStoreEntryComp extends StoreEntryComp {
.textProperty()
.bind(Bindings.createStringBinding(
() -> {
var val = summary.getValue();
var p = getWrapper().getEntry().getProvider();
if (val != null && grid.isHover() && p.alwaysShowSummary()) {
return val;
} else if (info.getValue() == null && p.alwaysShowSummary()) {
return val;
var summaryValue = summary.getValue();
var infoValue = info.getValue();
if (summaryValue != null && infoValue != null && grid.isHover()) {
return summaryValue;
} else if (infoValue == null && summaryValue != null) {
return summaryValue;
} else if (summaryValue == null && infoValue != null) {
return infoValue;
} else {
return info.getValue();
return null;
}
},
grid.hoverProperty(),
@@ -60,7 +63,7 @@ public class DenseStoreEntryComp extends StoreEntryComp {
@Override
public int getHeight() {
return OsType.getLocal() == OsType.WINDOWS ? 38 : 37;
return 37;
}
protected Region createContent() {
@@ -2,8 +2,10 @@ package io.xpipe.app.hub.comp;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.core.AppFontSizes;
import io.xpipe.app.core.AppI18n;
import io.xpipe.core.process.OsType;
import javafx.beans.binding.Bindings;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
@@ -28,7 +30,15 @@ public class StandardStoreEntryComp extends StoreEntryComp {
private Label createSummary() {
var summary = new Label();
summary.textProperty().bind(getWrapper().getShownSummary());
summary.textProperty().bind(Bindings.createStringBinding(() -> {
var summaryValue = getWrapper().getShownSummary().getValue();
if (summaryValue != null) {
return summaryValue;
} else {
var provider = getWrapper().getEntry().getProvider();
return AppI18n.get(provider.getId() + ".displayName");
}
}));
summary.getStyleClass().add("summary");
AppFontSizes.xs(summary);
return summary;
@@ -50,26 +50,26 @@ public class StoreCreationMenu {
automatically.disableProperty().bind(disableSearch);
}
menu.getItems().add(category("addHost", "mdi2h-home-plus", DataStoreCreationCategory.HOST, "ssh"));
menu.getItems().add(categoryMenu("addHost", "mdi2h-home-plus", DataStoreCreationCategory.HOST, "ssh"));
menu.getItems().add(category("addDesktop", "mdi2c-camera-plus", DataStoreCreationCategory.DESKTOP, null));
menu.getItems().add(categoryMenu("addDesktop", "mdi2c-camera-plus", DataStoreCreationCategory.DESKTOP, null));
menu.getItems()
.add(category("addScript", "mdi2s-script-text-outline", DataStoreCreationCategory.SCRIPT, "script"));
.add(categoryMenu("addScript", "mdi2s-script-text-outline", DataStoreCreationCategory.SCRIPT, "script"));
menu.getItems().add(category("addCommand", "mdi2c-code-greater-than", DataStoreCreationCategory.COMMAND, null));
menu.getItems().add(categoryMenu("addCommand", "mdi2c-code-greater-than", DataStoreCreationCategory.COMMAND, null));
menu.getItems()
.add(category("addService", "mdi2l-link-plus", DataStoreCreationCategory.SERVICE, "customService"));
.add(categoryMenu("addService", "mdi2l-link-plus", DataStoreCreationCategory.SERVICE, "customService"));
menu.getItems()
.add(category(
.add(categoryMenu(
"addTunnel", "mdi2v-vector-polyline-plus", DataStoreCreationCategory.TUNNEL, "sshLocalTunnel"));
menu.getItems().add(category("addSerial", "mdi2s-serial-port", DataStoreCreationCategory.SERIAL, "serial"));
menu.getItems().add(categoryMenu("addSerial", "mdi2s-serial-port", DataStoreCreationCategory.SERIAL, "serial"));
menu.getItems()
.add(category(
.add(categoryMenu(
"addIdentity",
"mdi2a-account-multiple-plus",
DataStoreCreationCategory.IDENTITY,
@@ -93,29 +93,6 @@ public class StoreCreationMenu {
menu.getItems().add(actionMenu);
}
private static MenuItem category(
String name, String graphic, DataStoreCreationCategory category, String defaultProvider) {
var sub = DataStoreProviders.getAll().stream()
.filter(dataStoreProvider -> category.equals(dataStoreProvider.getCreationCategory()))
.toList();
if (sub.size() < 2) {
var item = new MenuItem();
item.setGraphic(new FontIcon(graphic));
item.textProperty().bind(AppI18n.observable(name));
item.setOnAction(event -> {
StoreCreationDialog.showCreation(
defaultProvider != null
? DataStoreProviders.byId(defaultProvider).orElseThrow()
: null,
category);
event.consume();
});
return item;
}
return categoryMenu(name, graphic, category, defaultProvider);
}
private static Menu categoryMenu(
String name, String graphic, DataStoreCreationCategory category, String defaultProvider) {
var sub = DataStoreProviders.getAll().stream()
@@ -8,9 +8,11 @@ import io.xpipe.app.comp.base.VerticalComp;
import io.xpipe.app.core.AppCache;
import io.xpipe.app.core.AppLayoutModel;
import io.xpipe.app.prefs.AppPrefs;
import javafx.beans.binding.Bindings;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ObservableValue;
import javafx.css.PseudoClass;
import javafx.geometry.Insets;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
@@ -53,6 +55,10 @@ public class StoreEntryListComp extends SimpleComp {
StoreViewState.get().getFilterString().addListener((observable, oldValue, newValue) -> {
struc.get().setVvalue(0);
});
AppPrefs.get().condenseConnectionDisplay().subscribe(dense -> {
struc.get().pseudoClassStateChanged(PseudoClass.getPseudoClass("dense"), dense);
});
});
content.styleClass("store-list-comp");
content.vgrow();
@@ -233,8 +233,7 @@ public class StoreEntryWrapper {
summary.setValue(null);
} else {
try {
summary.setValue(
entry.getProvider() != null ? entry.getProvider().summaryString(this) : null);
summary.setValue(entry.getProvider() != null ? entry.getProvider().summaryString(this) : null);
} catch (Exception ex) {
// Summary creation might fail or have a bug
ErrorEventFactory.fromThrowable(ex).handle();
@@ -36,7 +36,7 @@ public class AppPrefsSidebarComp extends SimpleComp {
AppPrefs.get().getSelectedCategory().setValue(appPrefsCategory);
})
.apply(struc -> {
struc.get().setGraphicTextGap(7);
struc.get().setGraphicTextGap(9);
struc.get().setTextAlignment(TextAlignment.LEFT);
struc.get().setAlignment(Pos.CENTER_LEFT);
AppPrefs.get().getSelectedCategory().subscribe(val -> {
@@ -41,18 +41,6 @@ public class DataStoreFormatter {
return name.substring(0, 1).toUpperCase() + name.substring(1).toLowerCase();
}
public static String toApostropheName(DataStoreEntry input) {
return toName(input, Integer.MAX_VALUE) + "'s";
}
public static String toName(DataStoreEntry input, int length) {
if (input == null) {
return "?";
}
return cut(input.getName(), length);
}
public static String split(String left, String separator, String right, int length) {
var half = (length / 2) - separator.length();
return cut(left, half) + separator + cut(right, length - half);
@@ -30,6 +30,10 @@
-fx-padding: 4 0 4 0;
}
.store-list-comp.scroll-pane:dense > .viewport .list-box-content {
-fx-spacing: 2;
}
.store-list-comp.scroll-pane {
-fx-padding: 0 0 0 2;
}
@@ -178,7 +182,7 @@
}
.store-entry-section-comp:last:sub {
-fx-padding: 0 0 3 0;
-fx-padding: 0 0 1 0;
}
.store-entry-section-comp:last:sub:expanded {
@@ -98,11 +98,6 @@ public class DesktopApplicationStoreProvider implements DataStoreProvider {
.buildDialog();
}
public String summaryString(StoreEntryWrapper wrapper) {
DesktopApplicationStore s = wrapper.getEntry().getStore().asNeeded();
return DataStoreFormatter.toApostropheName(s.getDesktop().get()) + " config";
}
@Override
public String getDisplayIconFileName(DataStore store) {
return "base:desktopApplication_icon.svg";
@@ -67,12 +67,6 @@ public class LocalIdentityStoreProvider extends IdentityStoreProvider {
.buildDialog();
}
@Override
public String summaryString(StoreEntryWrapper wrapper) {
var st = (LocalIdentityStore) wrapper.getStore().getValue();
return AppI18n.get("localIdentity");
}
@Override
public String getId() {
return "localIdentity";
@@ -44,11 +44,6 @@ public class PasswordManagerIdentityStoreProvider extends IdentityStoreProvider
.buildDialog();
}
@Override
public String summaryString(StoreEntryWrapper wrapper) {
return AppI18n.get("passwordManagerIdentity");
}
@Override
public String getId() {
return "passwordManagerIdentity";
@@ -86,11 +86,6 @@ public class ScriptGroupStoreProvider implements EnabledParentStoreProvider, Dat
return new SimpleStringProperty(scriptStore.getDescription());
}
@Override
public String summaryString(StoreEntryWrapper wrapper) {
return "Script group";
}
@Override
public String getDisplayIconFileName(DataStore store) {
return "proc:shellEnvironment_icon.svg";
@@ -202,11 +202,6 @@ public class SimpleScriptStoreProvider implements EnabledParentStoreProvider, Da
.buildDialog();
}
@Override
public boolean alwaysShowSummary() {
return true;
}
@Override
public String summaryString(StoreEntryWrapper wrapper) {
SimpleScriptStore st = wrapper.getEntry().getStore().asNeeded();
@@ -108,12 +108,6 @@ public abstract class AbstractServiceStoreProvider implements SingletonSessionSt
: List.of("" + s.getRemotePort());
}
@Override
public String summaryString(StoreEntryWrapper wrapper) {
AbstractServiceStore s = wrapper.getEntry().getStore().asNeeded();
return DataStoreFormatter.toApostropheName(s.getHost().get()) + " service";
}
@Override
public ObservableValue<String> informationString(StoreSection section) {
return Bindings.createStringBinding(
@@ -47,12 +47,6 @@ public class ServiceControlStoreProvider implements SingletonSessionStoreProvide
CustomServiceGroupStore.builder().parent(s.getHost()).build());
}
@Override
public String summaryString(StoreEntryWrapper wrapper) {
ServiceControlStore s = wrapper.getEntry().getStore().asNeeded();
return DataStoreFormatter.toApostropheName(s.getHost().get()) + " service control";
}
@Override
public ObservableValue<String> informationString(StoreSection section) {
ServiceControlStore s = section.getWrapper().getEntry().getStore().asNeeded();
@@ -90,13 +90,6 @@ public class IncusContainerStoreProvider implements ShellStoreProvider {
return q;
}
@Override
public String summaryString(StoreEntryWrapper wrapper) {
IncusContainerStore s = wrapper.getEntry().getStore().asNeeded();
return DataStoreFormatter.toApostropheName(
s.getInstall().getStore().getHost().get()) + " container";
}
@Override
public ObservableValue<String> informationString(StoreSection section) {
var c = (ContainerStoreState) section.getWrapper().getPersistentState().getValue();
@@ -56,11 +56,6 @@ public class IncusInstallStoreProvider implements DataStoreProvider {
return s.getHost().get();
}
public String summaryString(StoreEntryWrapper wrapper) {
IncusInstallStore s = wrapper.getEntry().getStore().asNeeded();
return DataStoreFormatter.toApostropheName(s.getHost().get()) + " containers";
}
@Override
public ObservableValue<String> informationString(StoreSection section) {
return BindingsHelper.map(section.getWrapper().getPersistentState(), o -> {
@@ -56,11 +56,6 @@ public class LxdCmdStoreProvider implements DataStoreProvider {
return s.getHost().get();
}
public String summaryString(StoreEntryWrapper wrapper) {
LxdCmdStore s = wrapper.getEntry().getStore().asNeeded();
return DataStoreFormatter.toApostropheName(s.getHost().get()) + " containers";
}
@Override
public ObservableValue<String> informationString(StoreSection section) {
return BindingsHelper.map(section.getWrapper().getPersistentState(), o -> {
@@ -85,13 +85,6 @@ public class LxdContainerStoreProvider implements ShellStoreProvider {
return q;
}
@Override
public String summaryString(StoreEntryWrapper wrapper) {
LxdContainerStore s = wrapper.getEntry().getStore().asNeeded();
return DataStoreFormatter.toApostropheName(
s.getCmd().getStore().getHost().get()) + " container";
}
@Override
public ObservableValue<String> informationString(StoreSection section) {
var c = (ContainerStoreState) section.getWrapper().getPersistentState().getValue();
@@ -56,11 +56,6 @@ public class PodmanCmdStoreProvider implements DataStoreProvider {
return s.getHost().get();
}
public String summaryString(StoreEntryWrapper wrapper) {
PodmanCmdStore s = wrapper.getEntry().getStore().asNeeded();
return DataStoreFormatter.toApostropheName(s.getHost().get()) + " containers";
}
@Override
public ObservableValue<String> informationString(StoreSection section) {
return BindingsHelper.map(section.getWrapper().getPersistentState(), o -> {
@@ -85,13 +85,6 @@ public class PodmanContainerStoreProvider implements ShellStoreProvider {
return new GuiDialog(q, val);
}
@Override
public String summaryString(StoreEntryWrapper wrapper) {
PodmanContainerStore s = wrapper.getEntry().getStore().asNeeded();
return DataStoreFormatter.toApostropheName(
s.getCmd().getStore().getHost().get()) + " container";
}
@Override
public ObservableValue<String> informationString(StoreSection section) {
var c = (ContainerStoreState) section.getWrapper().getPersistentState().getValue();
+2 -1
View File
@@ -960,7 +960,8 @@ gitVaultIdentityStrategyDescription=If you chose to use an SSH git URL as the re
dockerContainers=Docker containers
dockerCmd.displayName=docker CLI client
dockerCmd.displayDescription=Access Docker containers via the docker CLI client
wslCmd.displayName=wsl client
#force
wslCmd.displayName=WSL install
wslCmd.displayDescription=Access WSL instances via the wsl CLI client
k8sCmd.displayName=kubectl client
k8sCmd.displayDescription=Access Kubernetes clusters via kubectl