This commit is contained in:
crschnick
2026-05-04 13:46:46 +00:00
parent 73f3fb26ce
commit 7c5f138440
21 changed files with 65 additions and 95 deletions

View File

@@ -2,7 +2,6 @@ package io.xpipe.app.ext;
import io.xpipe.app.comp.BaseRegionBuilder;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.hub.comp.StoreEntryWrapper;
import io.xpipe.app.hub.comp.StoreSection;
import io.xpipe.app.hub.comp.SystemStateComp;
@@ -16,6 +15,13 @@ public interface CountGroupStoreProvider extends DataStoreProvider {
return false;
}
@Override
default BaseRegionBuilder<?, ?> stateDisplay(StoreSection section) {
return new SystemStateComp(Bindings.createObjectBinding(() -> {
return section.getShownChildren().getList().isEmpty() ? SystemStateComp.State.OTHER : SystemStateComp.State.SUCCESS;
}, section.getShownChildren().getList()));
}
@Override
default ObservableValue<String> informationString(StoreSection section) {
return Bindings.createStringBinding(
@@ -23,16 +29,18 @@ public interface CountGroupStoreProvider extends DataStoreProvider {
var all = section.getAllChildren().getList();
var shown = section.getShownChildren().getList();
if (all.size() == 0) {
return AppI18n.get("noConnections");
return AppI18n.get("no" + getCountTranslationKey() + "s");
}
var string = all.size() == shown.size() ? all.size() : shown.size() + "/" + all.size();
return all.size() == 1
? AppI18n.get("hasConnection", string)
: AppI18n.get("hasConnections", string);
? AppI18n.get("has" + getCountTranslationKey(), string)
: AppI18n.get("has" + getCountTranslationKey() + "s", string);
},
section.getShownChildren().getList(),
section.getAllChildren().getList(),
AppI18n.activeLanguage());
}
String getCountTranslationKey();
}

View File

@@ -116,7 +116,7 @@ public interface DataStoreProvider {
return true;
}
default BaseRegionBuilder<?, ?> stateDisplay(StoreEntryWrapper w) {
default BaseRegionBuilder<?, ?> stateDisplay(StoreSection section) {
return RegionBuilder.empty();
}

View File

@@ -28,10 +28,10 @@ public interface SingletonSessionStoreProvider extends DataStoreProvider {
return StoreEntryComp.create(sec, t, preferLarge);
}
default BaseRegionBuilder<?, ?> stateDisplay(StoreEntryWrapper w) {
default BaseRegionBuilder<?, ?> stateDisplay(StoreSection section) {
return new SystemStateComp(Bindings.createObjectBinding(
() -> {
SingletonSessionStore<?> s = w.getEntry().getStore().asNeeded();
SingletonSessionStore<?> s = section.getWrapper().getEntry().getStore().asNeeded();
if (!supportsSession(s)) {
return SystemStateComp.State.SUCCESS;
}
@@ -42,7 +42,7 @@ public interface SingletonSessionStoreProvider extends DataStoreProvider {
return s.isSessionRunning() ? SystemStateComp.State.SUCCESS : SystemStateComp.State.FAILURE;
},
w.getCache()));
section.getWrapper().getCache()));
}
default StoreToggleComp createToggleComp(StoreSection sec) {

View File

@@ -23,7 +23,7 @@ public class DenseStoreEntryComp extends StoreEntryComp {
information.getStyleClass().add("information");
var state = getWrapper().getEntry().getProvider() != null
? getWrapper().getEntry().getProvider().stateDisplay(getWrapper())
? getWrapper().getEntry().getProvider().stateDisplay(section)
: RegionBuilder.empty();
information.setGraphic(state.build());

View File

@@ -122,7 +122,7 @@ public class StandardStoreEntryComp extends StoreEntryComp {
information.getStyleClass().add("information");
var state = getWrapper().getEntry().getProvider() != null
? getWrapper().getEntry().getProvider().stateDisplay(getWrapper())
? getWrapper().getEntry().getProvider().stateDisplay(section)
: RegionBuilder.empty();
information.setGraphic(state.build());

View File

@@ -181,6 +181,7 @@ public class RemoteDesktopWindow {
public void close(RemoteDesktopDockEntry entry, boolean closeWindowIfNeeded) {
model.closeWindow(entry);
if (closeWindowIfNeeded) {
updateState();
closeIfNecessary();
}
}

View File

@@ -121,7 +121,7 @@ public class DesktopApplicationStoreProvider implements DataStoreProvider {
}
@Override
public BaseRegionBuilder<?, ?> stateDisplay(StoreEntryWrapper w) {
public BaseRegionBuilder<?, ?> stateDisplay(StoreSection section) {
return new SystemStateComp(SystemStateComp.State.SUCCESS);
}

View File

@@ -17,7 +17,7 @@ import lombok.SneakyThrows;
import java.util.List;
public class AbstractHostStoreProvider implements DataStoreProvider {
public class AbstractHostStoreProvider implements CountGroupStoreProvider {
@Override
public DocumentationLink getHelpLink() {
@@ -29,11 +29,6 @@ public class AbstractHostStoreProvider implements DataStoreProvider {
return 2;
}
@Override
public BaseRegionBuilder<?, ?> stateDisplay(StoreEntryWrapper w) {
return new SystemStateComp(new SimpleObjectProperty<>(SystemStateComp.State.SUCCESS));
}
@Override
public DataStoreCreationCategory getCreationCategory() {
return DataStoreCreationCategory.HOST;
@@ -44,28 +39,6 @@ public class AbstractHostStoreProvider implements DataStoreProvider {
return DataStoreUsageCategory.GROUP;
}
@Override
public ObservableValue<String> informationString(StoreSection section) {
return Bindings.createStringBinding(
() -> {
var all = section.getAllChildren().getList();
var shown = section.getShownChildren().getList();
if (shown.size() == 0) {
return null;
}
var string = all.size() == shown.size() ? all.size() : shown.size() + "/" + all.size();
return all.size() > 0
? (all.size() == 1
? AppI18n.get("hostHasConnection", string)
: AppI18n.get("hostHasConnections", string))
: AppI18n.get("hostNoConnections");
},
section.getShownChildren().getList(),
section.getAllChildren().getList(),
AppI18n.activeLanguage());
}
@SneakyThrows
@Override
public GuiDialog guiDialog(StoreCreationModel model, Property<DataStore> store) {
@@ -124,4 +97,9 @@ public class AbstractHostStoreProvider implements DataStoreProvider {
public List<Class<?>> getStoreClasses() {
return List.of(AbstractHostStore.class);
}
@Override
public String getCountTranslationKey() {
return "Connection";
}
}

View File

@@ -2,7 +2,6 @@ package io.xpipe.ext.base.identity;
import io.xpipe.app.comp.BaseRegionBuilder;
import io.xpipe.app.ext.*;
import io.xpipe.app.hub.comp.StoreEntryWrapper;
import io.xpipe.app.hub.comp.StoreSection;
import io.xpipe.app.hub.comp.SystemStateComp;
import io.xpipe.app.util.DocumentationLink;
@@ -28,7 +27,7 @@ public abstract class IdentityStoreProvider implements DataStoreProvider {
}
@Override
public BaseRegionBuilder<?, ?> stateDisplay(StoreEntryWrapper w) {
public BaseRegionBuilder<?, ?> stateDisplay(StoreSection section) {
return new SystemStateComp(new SimpleObjectProperty<>(SystemStateComp.State.SUCCESS));
}

View File

@@ -44,7 +44,7 @@ public class ScriptCollectionSourceStoreProvider implements DataStoreProvider {
}
@Override
public BaseRegionBuilder<?, ?> stateDisplay(StoreEntryWrapper w) {
public BaseRegionBuilder<?, ?> stateDisplay(StoreSection section) {
return new SystemStateComp(new SimpleObjectProperty<>(SystemStateComp.State.SUCCESS));
}

View File

@@ -70,7 +70,7 @@ public class ScriptStoreProvider implements DataStoreProvider {
}
@Override
public BaseRegionBuilder<?, ?> stateDisplay(StoreEntryWrapper w) {
public BaseRegionBuilder<?, ?> stateDisplay(StoreSection section) {
return new SystemStateComp(new SimpleObjectProperty<>(SystemStateComp.State.SUCCESS));
}

View File

@@ -2,6 +2,7 @@ package io.xpipe.ext.base.service;
import io.xpipe.app.comp.BaseRegionBuilder;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.ext.CountGroupStoreProvider;
import io.xpipe.app.ext.DataStore;
import io.xpipe.app.ext.DataStoreProvider;
import io.xpipe.app.ext.DataStoreUsageCategory;
@@ -13,18 +14,18 @@ import javafx.beans.binding.Bindings;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ObservableValue;
public abstract class AbstractServiceGroupStoreProvider implements DataStoreProvider {
public abstract class AbstractServiceGroupStoreProvider implements CountGroupStoreProvider {
@Override
public String getCountTranslationKey() {
return "Service";
}
@Override
public DocumentationLink getHelpLink() {
return DocumentationLink.SERVICES;
}
@Override
public BaseRegionBuilder<?, ?> stateDisplay(StoreEntryWrapper w) {
return new SystemStateComp(new SimpleObjectProperty<>(SystemStateComp.State.SUCCESS));
}
@Override
public DataStoreUsageCategory getUsageCategory() {
return DataStoreUsageCategory.GROUP;
@@ -36,27 +37,6 @@ public abstract class AbstractServiceGroupStoreProvider implements DataStoreProv
return s.getParent().get();
}
@Override
public ObservableValue<String> informationString(StoreSection section) {
return Bindings.createStringBinding(
() -> {
var all = section.getAllChildren().getList();
var shown = section.getShownChildren().getList();
if (shown.size() == 0) {
return null;
}
var string = all.size() == shown.size() ? all.size() : shown.size() + "/" + all.size();
return all.size() > 0
? (all.size() == 1 ? AppI18n.get("hasService", string) : AppI18n.get("hasServices", string))
: AppI18n.get("noServices");
},
section.getShownChildren().getList(),
section.getAllChildren().getList(),
AppI18n.activeLanguage());
}
@Override
public String getDisplayIconFileName(DataStore store) {
return "base:serviceGroup_icon.svg";
}

View File

@@ -145,14 +145,14 @@ public abstract class AbstractServiceStoreProvider implements SingletonSessionSt
}
@Override
public BaseRegionBuilder<?, ?> stateDisplay(StoreEntryWrapper w) {
public BaseRegionBuilder<?, ?> stateDisplay(StoreSection section) {
return new SystemStateComp(Bindings.createObjectBinding(
() -> {
if (!w.getEntry().getValidity().isUsable()) {
if (!section.getWrapper().getEntry().getValidity().isUsable()) {
return SystemStateComp.State.OTHER;
}
AbstractServiceStore s = w.getEntry().getStore().asNeeded();
AbstractServiceStore s = section.getWrapper().getEntry().getStore().asNeeded();
if (!s.requiresTunnel()) {
return SystemStateComp.State.SUCCESS;
@@ -164,7 +164,7 @@ public abstract class AbstractServiceStoreProvider implements SingletonSessionSt
return s.isSessionRunning() ? SystemStateComp.State.SUCCESS : SystemStateComp.State.FAILURE;
},
w.getCache()));
section.getWrapper().getCache()));
}
protected String formatService(AbstractServiceStore s) {

View File

@@ -4,7 +4,6 @@ import io.xpipe.app.browser.BrowserFullSessionModel;
import io.xpipe.app.comp.BaseRegionBuilder;
import io.xpipe.app.ext.*;
import io.xpipe.app.hub.comp.OsLogoComp;
import io.xpipe.app.hub.comp.StoreEntryWrapper;
import io.xpipe.app.hub.comp.StoreSection;
import io.xpipe.app.hub.comp.SystemStateComp;
import io.xpipe.app.process.SystemState;
@@ -49,8 +48,8 @@ public interface ShellStoreProvider extends DataStoreProvider {
};
}
default BaseRegionBuilder<?, ?> stateDisplay(StoreEntryWrapper w) {
return new OsLogoComp(w, SystemStateComp.State.shellState(w));
default BaseRegionBuilder<?, ?> stateDisplay(StoreSection section) {
return new OsLogoComp(section.getWrapper(), SystemStateComp.State.shellState(section.getWrapper()));
}
@Override

View File

@@ -21,8 +21,8 @@ import java.util.List;
public class IncusContainerStoreProvider implements ShellStoreProvider {
public BaseRegionBuilder<?, ?> stateDisplay(StoreEntryWrapper w) {
return new OsLogoComp(w, BindingsHelper.map(w.getPersistentState(), o -> {
public BaseRegionBuilder<?, ?> stateDisplay(StoreSection section) {
return new OsLogoComp(section.getWrapper(), BindingsHelper.map(section.getWrapper().getPersistentState(), o -> {
var state = (ContainerStoreState) o;
var cs = state.getContainerState();
if (cs != null && cs.toLowerCase().contains("stopped")) {

View File

@@ -33,8 +33,8 @@ public class IncusInstallStoreProvider implements DataStoreProvider {
return StoreEntryComp.create(sec, nonRunning, preferLarge);
}
public BaseRegionBuilder<?, ?> stateDisplay(StoreEntryWrapper w) {
return new SystemStateComp(BindingsHelper.map(w.getPersistentState(), o -> {
public BaseRegionBuilder<?, ?> stateDisplay(StoreSection section) {
return new SystemStateComp(BindingsHelper.map(section.getWrapper().getPersistentState(), o -> {
var state = (IncusInstallStore.State) o;
if (state.isReachable()) {
return SystemStateComp.State.SUCCESS;
@@ -59,7 +59,7 @@ public class IncusInstallStoreProvider implements DataStoreProvider {
public ObservableValue<String> informationString(StoreSection section) {
return BindingsHelper.map(section.getWrapper().getPersistentState(), o -> {
var state = (IncusInstallStore.State) o;
return state.isReachable() ? "incus v" + state.getServerVersion() : "Connection failed";
return state.isReachable() ? "Incus v" + state.getServerVersion() : "Connection failed";
});
}

View File

@@ -33,8 +33,8 @@ public class LxdCmdStoreProvider implements DataStoreProvider {
return StoreEntryComp.create(sec, nonRunning, preferLarge);
}
public BaseRegionBuilder<?, ?> stateDisplay(StoreEntryWrapper w) {
return new SystemStateComp(BindingsHelper.map(w.getPersistentState(), o -> {
public BaseRegionBuilder<?, ?> stateDisplay(StoreSection section) {
return new SystemStateComp(BindingsHelper.map(section.getWrapper().getPersistentState(), o -> {
var state = (LxdCmdStore.State) o;
if (state.isReachable()) {
return SystemStateComp.State.SUCCESS;
@@ -59,7 +59,7 @@ public class LxdCmdStoreProvider implements DataStoreProvider {
public ObservableValue<String> informationString(StoreSection section) {
return BindingsHelper.map(section.getWrapper().getPersistentState(), o -> {
var state = (LxdCmdStore.State) o;
return state.isReachable() ? "lxd v" + state.getServerVersion() : "Connection failed";
return state.isReachable() ? "LXD v" + state.getServerVersion() : "Connection failed";
});
}

View File

@@ -21,8 +21,8 @@ import java.util.List;
public class LxdContainerStoreProvider implements ShellStoreProvider {
public BaseRegionBuilder<?, ?> stateDisplay(StoreEntryWrapper w) {
return new OsLogoComp(w, BindingsHelper.map(w.getPersistentState(), o -> {
public BaseRegionBuilder<?, ?> stateDisplay(StoreSection section) {
return new OsLogoComp(section.getWrapper(), BindingsHelper.map(section.getWrapper().getPersistentState(), o -> {
var state = (ContainerStoreState) o;
var cs = state.getContainerState();
if (cs != null && cs.toLowerCase().contains("stopped")) {

View File

@@ -5,7 +5,6 @@ import io.xpipe.app.ext.DataStore;
import io.xpipe.app.ext.DataStoreProvider;
import io.xpipe.app.ext.DataStoreUsageCategory;
import io.xpipe.app.hub.comp.StoreEntryComp;
import io.xpipe.app.hub.comp.StoreEntryWrapper;
import io.xpipe.app.hub.comp.StoreSection;
import io.xpipe.app.hub.comp.StoreToggleComp;
import io.xpipe.app.hub.comp.SystemStateComp;
@@ -33,8 +32,8 @@ public class PodmanCmdStoreProvider implements DataStoreProvider {
return StoreEntryComp.create(sec, nonRunning, preferLarge);
}
public BaseRegionBuilder<?, ?> stateDisplay(StoreEntryWrapper w) {
return new SystemStateComp(BindingsHelper.map(w.getPersistentState(), o -> {
public BaseRegionBuilder<?, ?> stateDisplay(StoreSection section) {
return new SystemStateComp(BindingsHelper.map(section.getWrapper().getPersistentState(), o -> {
var state = (PodmanCmdStore.State) o;
if (state.isRunning()) {
return SystemStateComp.State.SUCCESS;

View File

@@ -88,8 +88,8 @@ public class PodmanContainerStoreProvider implements ShellStoreProvider {
return List.of(PodmanContainerStore.class);
}
public BaseRegionBuilder<?, ?> stateDisplay(StoreEntryWrapper w) {
return new OsLogoComp(w, BindingsHelper.map(w.getPersistentState(), o -> {
public BaseRegionBuilder<?, ?> stateDisplay(StoreSection section) {
return new OsLogoComp(section.getWrapper(), BindingsHelper.map(section.getWrapper().getPersistentState(), o -> {
var state = (ContainerStoreState) o;
var cs = state.getContainerState();
if (cs != null && cs.toLowerCase().contains("exited")) {

View File

@@ -767,6 +767,12 @@ hasService=$COUNT$ available service
noConnections=No available connections
hasConnections=$COUNT$ available connections
hasConnection=$COUNT$ available connection
noShells=No available shells
hasShells=$COUNT$ available shells
hasShell=$COUNT$ available shell
noPorts=No available ports
hasPorts=$COUNT$ available ports
hasPort=$COUNT$ available ports
openHttp=Open HTTP service
openHttps=Open HTTPS service
noScriptsAvailable=No enabled and compatible scripts available
@@ -1749,9 +1755,9 @@ abstractHostAddressDescription=The address of the host
abstractHostGateway=Gateway
abstractHostGatewayDescription=The optional gateway system through which to reach this host
abstractHostConvert=Convert to abstract host entry
hostNoConnections=No available connections
hostHasConnections=$COUNT$ available connections
hostHasConnection=$COUNT$ available connection
noHosts=No available hosts
hasHosts=$COUNT$ available hosts
hasHost=$COUNT$ available hosts
largeFileWarningTitle=Large file edit
largeFileWarningContent=The file you want to edit is quite large with $SIZE$. Do you really want to open this file in your text editor?
rdpAskpassUser=RDP username for host $HOST$