mirror of
https://github.com/xpipe-io/xpipe.git
synced 2026-05-03 19:30:31 +00:00
Fixes
This commit is contained in:
@@ -2,6 +2,8 @@ package io.xpipe.app.action;
|
||||
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.SimpleComp;
|
||||
import io.xpipe.app.core.AppFont;
|
||||
import io.xpipe.app.core.AppFontSizes;
|
||||
import io.xpipe.app.hub.action.BatchStoreAction;
|
||||
import io.xpipe.app.hub.action.MultiStoreAction;
|
||||
import io.xpipe.app.hub.action.StoreAction;
|
||||
@@ -73,6 +75,7 @@ public class ActionConfirmComp extends SimpleComp {
|
||||
grid.add(value, 1, row);
|
||||
row++;
|
||||
}
|
||||
AppFontSizes.lg(grid);
|
||||
return grid;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package io.xpipe.app.action;
|
||||
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import io.xpipe.app.hub.action.BatchStoreAction;
|
||||
import io.xpipe.app.hub.action.MultiStoreAction;
|
||||
import io.xpipe.app.hub.action.StoreAction;
|
||||
@@ -41,8 +43,10 @@ public class ActionJacksonMapper {
|
||||
var object = (ObjectNode) tree;
|
||||
var ref = tree.get("ref");
|
||||
|
||||
var mapper = JacksonMapper.newMapper().enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
|
||||
|
||||
if (ref != null && !ref.isArray() && StoreAction.class.isAssignableFrom(clazz.get())) {
|
||||
var action = JacksonMapper.getDefault().treeToValue(tree, clazz.get());
|
||||
var action = mapper.treeToValue(tree, clazz.get());
|
||||
return (T) action;
|
||||
}
|
||||
|
||||
@@ -56,7 +60,7 @@ public class ActionJacksonMapper {
|
||||
object.remove("ref");
|
||||
for (JsonNode batchRef : ref) {
|
||||
object.set("ref", batchRef);
|
||||
var action = JacksonMapper.getDefault().treeToValue(object, clazz.get());
|
||||
var action = mapper.treeToValue(object, clazz.get());
|
||||
batchActions.add((StoreAction<DataStore>) action);
|
||||
}
|
||||
return (T) BatchStoreAction.builder().actions(batchActions).build();
|
||||
@@ -66,7 +70,7 @@ public class ActionJacksonMapper {
|
||||
if (makeMulti) {
|
||||
object.remove("ref");
|
||||
object.set("refs", ref);
|
||||
var action = JacksonMapper.getDefault().treeToValue(object, clazz.get());
|
||||
var action = mapper.treeToValue(object, clazz.get());
|
||||
return (T) action;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package io.xpipe.app.action;
|
||||
|
||||
import io.xpipe.app.beacon.AppBeaconServer;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.SimpleComp;
|
||||
import io.xpipe.app.comp.base.ButtonComp;
|
||||
@@ -8,6 +9,7 @@ import io.xpipe.app.comp.base.TextFieldComp;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.util.*;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.scene.layout.Region;
|
||||
@@ -31,6 +33,7 @@ public class ActionShortcutComp extends SimpleComp {
|
||||
var options = new OptionsBuilder();
|
||||
options.nameAndDescription("actionDesktopShortcut").addComp(createDesktopComp());
|
||||
options.nameAndDescription("actionUrlShortcut").addComp(createUrlComp());
|
||||
options.nameAndDescription("actionApiCall").addComp(createApiComp());
|
||||
// options.nameAndDescription("actionMacro")
|
||||
// .addComp(createMacroComp());
|
||||
return options.build();
|
||||
@@ -80,6 +83,26 @@ public class ActionShortcutComp extends SimpleComp {
|
||||
return group;
|
||||
}
|
||||
|
||||
private Comp<?> createApiComp() {
|
||||
var url = "curl -X POST \"http://localhost:" + AppBeaconServer.get().getPort() + "/action\" ...";
|
||||
var text = AppI18n.observable("actionApiUrl", url);
|
||||
var prop = new SimpleStringProperty();
|
||||
prop.bind(text);
|
||||
|
||||
var copyButton = new ButtonComp(null, new FontIcon("mdi2c-clipboard-multiple-outline"), () -> {
|
||||
if (action.getValue() instanceof SerializableAction sa) {
|
||||
ClipboardHelper.copyUrl(sa.toNode().toPrettyString());
|
||||
}
|
||||
})
|
||||
.grow(false, true)
|
||||
.tooltipKey("copyBody");
|
||||
var field = new TextFieldComp(prop, true);
|
||||
field.grow(true, false);
|
||||
field.apply(struc -> struc.get().setEditable(false));
|
||||
var group = new InputGroupComp(List.of(field, copyButton));
|
||||
return group;
|
||||
}
|
||||
|
||||
private Comp<?> createMacroComp() {
|
||||
var button = new ButtonComp(
|
||||
AppI18n.observable("createMacro"), new FontIcon("mdi2c-clipboard-multiple-outline"), onCreateMacro);
|
||||
|
||||
@@ -6,6 +6,7 @@ import io.xpipe.app.browser.file.BrowserEntry;
|
||||
import io.xpipe.app.browser.file.BrowserFileSystemTabModel;
|
||||
import io.xpipe.app.core.AppLayoutModel;
|
||||
import io.xpipe.app.hub.action.StoreAction;
|
||||
import io.xpipe.core.store.FileEntry;
|
||||
import io.xpipe.core.store.FilePath;
|
||||
import io.xpipe.core.store.FileSystemStore;
|
||||
|
||||
@@ -44,7 +45,7 @@ public abstract class BrowserAction extends StoreAction<FileSystemStore> {
|
||||
if (isFile) {
|
||||
return files.getFirst().getParent();
|
||||
} else {
|
||||
var dir = files.getFirst().getParent();
|
||||
var dir = files.getFirst();
|
||||
if (!model.getFileSystem().directoryExists(dir)) {
|
||||
throw new IllegalArgumentException("Directory does not exist: " + dir);
|
||||
}
|
||||
@@ -84,6 +85,11 @@ public abstract class BrowserAction extends StoreAction<FileSystemStore> {
|
||||
return be.get();
|
||||
}
|
||||
|
||||
var current = model.getCurrentDirectory();
|
||||
if (current != null && filePath.equals(current.getPath())) {
|
||||
return new BrowserEntry(current, model.getFileList());
|
||||
}
|
||||
|
||||
return null;
|
||||
})
|
||||
.filter(browserEntry -> browserEntry != null)
|
||||
|
||||
@@ -48,8 +48,8 @@ public class ApplyFileEditActionProvider implements ActionProvider {
|
||||
@Override
|
||||
public Map<String, String> toDisplayMap() {
|
||||
var map = new LinkedHashMap<String, String>();
|
||||
map.put("action", getDisplayName());
|
||||
map.put("target", target);
|
||||
map.put("Action", getDisplayName());
|
||||
map.put("Target", target);
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,14 +50,14 @@ public class TransferFilesActionProvider implements ActionProvider {
|
||||
@Override
|
||||
public Map<String, String> toDisplayMap() {
|
||||
var map = new LinkedHashMap<String, String>();
|
||||
map.put("action", getDisplayName());
|
||||
map.put("Action", getDisplayName());
|
||||
map.put(
|
||||
"sources",
|
||||
"Sources",
|
||||
operation.getFiles().stream()
|
||||
.map(fileEntry -> fileEntry.getName())
|
||||
.collect(Collectors.joining("\n")));
|
||||
map.put("target", DataStorage.get().getStoreEntryDisplayName(target.get()));
|
||||
map.put("targetDirectory", operation.getTarget().getPath().toString());
|
||||
map.put("Target system", DataStorage.get().getStoreEntryDisplayName(target.get()));
|
||||
map.put("Target directory", operation.getTarget().getPath().toString());
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
@@ -75,6 +75,19 @@ public final class BrowserFileListComp extends SimpleComp {
|
||||
sizeCol.textProperty().bind(AppI18n.observable("size"));
|
||||
sizeCol.setCellValueFactory(param -> new ReadOnlyStringWrapper(
|
||||
param.getValue().getRawFileEntry().resolved().getSize()));
|
||||
sizeCol.setComparator((size1, size2) -> {
|
||||
if (size1 == null && size2 == null) return 0;
|
||||
if (size1 == null) return -1;
|
||||
if (size2 == null) return 1;
|
||||
|
||||
try {
|
||||
long long1 = Long.parseLong(size1);
|
||||
long long2 = Long.parseLong(size2);
|
||||
return Long.compare(long1, long2);
|
||||
} catch (NumberFormatException e) {
|
||||
return size1.compareTo(size2);
|
||||
}
|
||||
});
|
||||
sizeCol.setCellFactory(col -> new FileSizeCell());
|
||||
sizeCol.setResizable(false);
|
||||
sizeCol.setReorderable(false);
|
||||
|
||||
@@ -15,6 +15,7 @@ import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.util.LabelGraphic;
|
||||
import io.xpipe.app.util.OptionsBuilder;
|
||||
import io.xpipe.core.process.OsType;
|
||||
import io.xpipe.core.store.FileKind;
|
||||
import io.xpipe.core.store.FilePath;
|
||||
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
@@ -66,8 +67,11 @@ public class NewItemMenuProvider implements BrowserMenuBranchProvider {
|
||||
return;
|
||||
}
|
||||
|
||||
var fixedFiles = entries.stream().map(browserEntry -> browserEntry.getRawFileEntry().getKind() == FileKind.DIRECTORY ?
|
||||
browserEntry.getRawFileEntry().getPath() : browserEntry.getRawFileEntry().getPath().getParent())
|
||||
.toList();
|
||||
var builder = NewFileActionProvider.Action.builder();
|
||||
builder.initEntries(model, entries);
|
||||
builder.initFiles(model, fixedFiles);
|
||||
builder.name(name.getValue());
|
||||
builder.build().executeAsync();
|
||||
});
|
||||
@@ -102,8 +106,11 @@ public class NewItemMenuProvider implements BrowserMenuBranchProvider {
|
||||
return;
|
||||
}
|
||||
|
||||
var fixedFiles = entries.stream().map(browserEntry -> browserEntry.getRawFileEntry().getKind() == FileKind.DIRECTORY ?
|
||||
browserEntry.getRawFileEntry().getPath() : browserEntry.getRawFileEntry().getPath().getParent())
|
||||
.toList();
|
||||
var builder = NewDirectoryActionProvider.Action.builder();
|
||||
builder.initEntries(model, entries);
|
||||
builder.initFiles(model, fixedFiles);
|
||||
builder.name(name.getValue());
|
||||
builder.build().executeAsync();
|
||||
});
|
||||
@@ -143,8 +150,11 @@ public class NewItemMenuProvider implements BrowserMenuBranchProvider {
|
||||
return;
|
||||
}
|
||||
|
||||
var fixedFiles = entries.stream().map(browserEntry -> browserEntry.getRawFileEntry().getKind() == FileKind.DIRECTORY ?
|
||||
browserEntry.getRawFileEntry().getPath() : browserEntry.getRawFileEntry().getPath().getParent())
|
||||
.toList();
|
||||
var builder = NewLinkActionProvider.Action.builder();
|
||||
builder.initEntries(model, entries);
|
||||
builder.initFiles(model, fixedFiles);
|
||||
builder.name(linkName.getValue());
|
||||
builder.target(FilePath.of(target.getValue()));
|
||||
builder.build().executeAsync();
|
||||
|
||||
@@ -26,7 +26,9 @@ public class ShellSession extends Session {
|
||||
|
||||
try {
|
||||
shellControl.start();
|
||||
startAliveListener();
|
||||
if (shellControl.getShellDialect().getDumbMode().supportsAnyPossibleInteraction()) {
|
||||
startAliveListener();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
try {
|
||||
stop();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package io.xpipe.app.hub.action;
|
||||
|
||||
import io.xpipe.app.action.*;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.app.storage.DataStoreEntry;
|
||||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
import io.xpipe.core.store.DataStore;
|
||||
@@ -21,6 +22,13 @@ public final class BatchStoreAction<T extends DataStore> extends SerializableAct
|
||||
|
||||
private final List<StoreAction<T>> actions;
|
||||
|
||||
@Override
|
||||
public String getShortcutName() {
|
||||
var names = actions.size() > 3 ? actions.size() + "..." : actions.stream().map(a -> DataStorage.get().getStoreEntryDisplayName(a.getRef().get())).collect(
|
||||
Collectors.joining(", "));
|
||||
return names + " (" + getDisplayName() + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeImpl() throws Exception {
|
||||
for (AbstractAction action : actions) {
|
||||
|
||||
@@ -3,6 +3,7 @@ package io.xpipe.app.hub.action;
|
||||
import io.xpipe.app.action.ActionJacksonMapper;
|
||||
import io.xpipe.app.action.SerializableAction;
|
||||
import io.xpipe.app.action.StoreContextAction;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.app.storage.DataStoreEntry;
|
||||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
import io.xpipe.core.store.DataStore;
|
||||
@@ -15,6 +16,7 @@ import lombok.experimental.SuperBuilder;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@SuperBuilder
|
||||
public abstract class MultiStoreAction<T extends DataStore> extends SerializableAction implements StoreContextAction {
|
||||
@@ -22,6 +24,13 @@ public abstract class MultiStoreAction<T extends DataStore> extends Serializable
|
||||
@Getter
|
||||
protected final List<DataStoreEntryRef<T>> refs;
|
||||
|
||||
@Override
|
||||
public String getShortcutName() {
|
||||
var names = refs.size() > 3 ? refs.size() + "..." : refs.stream().map(ref -> DataStorage.get().getStoreEntryDisplayName(ref.get())).collect(
|
||||
Collectors.joining(", "));
|
||||
return names + " (" + getDisplayName() + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean beforeExecute() {
|
||||
for (DataStoreEntryRef<T> ref : refs) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package io.xpipe.app.hub.action.impl;
|
||||
|
||||
import io.xpipe.app.action.AbstractAction;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.ext.ShellStore;
|
||||
import io.xpipe.app.hub.action.BatchHubProvider;
|
||||
@@ -16,6 +17,8 @@ import javafx.beans.value.ObservableValue;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import lombok.extern.jackson.Jacksonized;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ScanHubBatchProvider implements BatchHubProvider<ShellStore> {
|
||||
|
||||
@Override
|
||||
@@ -50,6 +53,11 @@ public class ScanHubBatchProvider implements BatchHubProvider<ShellStore> {
|
||||
return "scanStoreBatch";
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractAction createBatchAction(List<DataStoreEntryRef<ShellStore>> dataStoreEntryRefs) {
|
||||
return Action.builder().refs(dataStoreEntryRefs).build();
|
||||
}
|
||||
|
||||
@Jacksonized
|
||||
@SuperBuilder
|
||||
public static class Action extends MultiStoreAction<ShellStore> {
|
||||
|
||||
@@ -110,11 +110,8 @@ public class StoreCreationMenu {
|
||||
}
|
||||
|
||||
Platform.runLater(() -> {
|
||||
StoreCreationDialog.showCreation(
|
||||
defaultProvider != null
|
||||
? DataStoreProviders.byId(defaultProvider).orElseThrow()
|
||||
: null,
|
||||
category);
|
||||
var onlyItem = menu.getItems().getFirst();
|
||||
onlyItem.fire();
|
||||
});
|
||||
|
||||
// Fix weird JavaFX NPE
|
||||
|
||||
@@ -183,9 +183,6 @@ public class StoreEntryListStatusBarComp extends SimpleComp {
|
||||
var l = new ArrayList<>(
|
||||
StoreViewState.get().getEffectiveBatchModeSelection().getList());
|
||||
var mapped = l.stream().map(w -> w.getEntry().<T>ref()).toList();
|
||||
var action = ((BatchHubProvider<T>) s).createBatchAction(mapped);
|
||||
if (action != null) {
|
||||
action.executeAsync();
|
||||
}
|
||||
((BatchHubProvider<T>) s).execute(mapped);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ public final class FilePath {
|
||||
return false;
|
||||
}
|
||||
FilePath filePath = (FilePath) o;
|
||||
return Objects.equals(value, filePath.value);
|
||||
return Objects.equals(normalize().removeTrailingSlash().value, filePath.normalize().removeTrailingSlash().value);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Vendored
+44
-34
@@ -1,44 +1,22 @@
|
||||
Note: This release includes all features for XPipe 17 with barely any testing. This means that you should not use this build for any kind of production use yet. It is mostly for internal testing.
|
||||
|
||||
XPipe 17 is a large-scale rework of many existing parts of XPipe. It focuses on fixing many longstanding issues and limitations, so that future updates can easily bring new integrations without having to deal with that baggage.
|
||||
|
||||
## File browser
|
||||
|
||||
- Actions which modify a single file will now automatically refresh the file list to show updated changes
|
||||
- There is now a new file browser action to compute directory sizes
|
||||
- The transfer speed in the file browser on Windows for multiple files has been optimized
|
||||
- Renaming a file now moves the caret to the end of the base file name
|
||||
- The file browser now works much better in small windows sizes
|
||||
- Fix size sorting using alphabetical order instead of actual size (Thanks to @RustyRaptor for the PR)
|
||||
- Fix terminal sometimes not being launched with the correct working directory of the current path
|
||||
- Fix file deletion not showing errors when the operation failed in cmd
|
||||
- Fix file renaming not working if previous rename operation was cancelled
|
||||
- Fix file transfer kill button sometimes not working when transfer was frozen
|
||||
|
||||
## Connection hub
|
||||
|
||||
Proper functionality to organize a collection of hundreds of connections was always somewhat limited until now. There is now an additional index-based organization mechanism where you can assign and move indices of connections to have them listed at a certain place in relation to other connections. This can also be combined with the existing sorting methods like time and alphabetical sorting.
|
||||
|
||||
Furthermore, there are also more improvements in the connection hub:
|
||||
- Renaming connection entries can now be done quickly from the context menu without having to open the configuration dialog
|
||||
- You can now set connection configurations to be frozen, meaning that the connection entry can't be modified or deleted. This is helpful for templating and team vault setups
|
||||
- When editing an incomplete connection configuration, the focus will automatically jump to the first incomplete/invalid value. This makes keyboard usage easier
|
||||
|
||||
## SSH
|
||||
|
||||
They are two major changes regarding SSH in this release.
|
||||
|
||||
First, there is now proper support for jump servers. While gateways worked similar to jump servers, they were a different concept and did not work for cases where the ProxyJump functionality was required. You can now configure an SSH connection in its advanced settings to be treated as a jump server. This will result in XPipe using the ProxyJump syntax when this connection is used as a gateway for other SSH connections. This works for all kinds of connections, including config connections.
|
||||
|
||||
Second, the SSH implementation for devices that don't provide a full shell, e.g. embedded devices and other limited systems, has been completely reworked. This fixes many issues where connections to such systems were not possible or failed. You can now designate an SSH connection as a limited system in its advanced settings, even without the homelab plan. This will then allow you to directly launch the connection, without any issues.
|
||||
|
||||
## Actions
|
||||
|
||||
There is now a new action system, which maps most UI actions to fixed schemas. Essentially, this means that you can now automate almost any action you can perform from the UI via desktop shortcuts, URLs, HTTP API calls, and more. You can configure action shortcuts with the new action configuration dialog and control how to call the action from it.
|
||||
|
||||
Furthermore, it is also now possible to control how all of these actions are run. For production systems, for example, you can configure that all actions that perform some kind of modification, like deleting a file, have to be confirmed first. This gives you an added layer of protection to double-check any operation before actually executing it.
|
||||
|
||||
## SSH
|
||||
|
||||
There is now proper support for jump servers. While gateways worked similar to jump servers, they were a different concept and did not work for cases where the ProxyJump functionality was required. You can now configure an SSH connection in its advanced settings to be treated as a jump server. This will result in XPipe using the ProxyJump syntax when this connection is used as a gateway for other SSH connections. This works for all kinds of connections, including config connections.
|
||||
|
||||
Furthermore, the SSH implementation for devices that don't provide a full shell, e.g. embedded devices and other limited systems, has been completely reworked. This fixes many issues where connections to such systems were not possible or failed. You can now designate an SSH connection as a limited system in its advanced settings, even without the homelab plan. This will then allow you to directly launch the connection, without any issues.
|
||||
|
||||
## VNC
|
||||
|
||||
Up until now, the internal VNC implementation of XPipe did a somewhat acceptable job for most connections. However, it is not able to match dedicated VNC clients when it comes to more advanced features and authentication methods. There's simply not Le development capacity to maintain all of these additional VNC features. For this reason, there is now support to also use an external VNC client with XPipe, it just as with any other tool integrations.
|
||||
Up until now, the internal VNC implementation of XPipe did a somewhat acceptable job for most connections. However, it is not able to match dedicated VNC clients when it comes to more advanced features and authentication methods. There's simply not the development capacity to maintain all of these additional VNC features. For this reason, there is now support to also use an external VNC client with XPipe, just as with any other tool integrations.
|
||||
|
||||
The current integrations include:
|
||||
- TigerVNC
|
||||
@@ -52,11 +30,42 @@ The current integrations include:
|
||||
|
||||
XPipe adopts many of the new features of macOS 26 right away. if you are using the macOS beta, you have access to these right away.
|
||||
|
||||
The application window now uses the new Liquid Glass theming. The application icon has also been reworked with Liquid Glass in mind. There's also support for the new apple containers framework, which has just been released. Searching for available connections on the local machine will make apple containers show up if you have installed the package.
|
||||
The application window now uses the new Liquid Glass theming. The application icon has also been reworked with Liquid Glass in mind.
|
||||
|
||||
There's also support for the new apple containers framework, which has just been released. Searching for available connections on the local machine will make apple containers show up if you have installed the package.
|
||||
|
||||
## Windows ARM
|
||||
|
||||
There is now a native Windows ARM build. This release is also available in choco and winget.
|
||||
|
||||
Note that you will have to uninstall any old x64 XPipe installation for the upgrade.
|
||||
|
||||
## File browser
|
||||
|
||||
- Actions which modify a single file, e.g. a file edit, will now automatically refresh the file list to show updated changes
|
||||
- There is now a new file browser action to compute directory sizes
|
||||
- The transfer speed in the file browser on Windows for multiple files has been improved
|
||||
- Renaming a file now moves the caret to the end of the base file name
|
||||
- The file browser now works much better in small windows sizes
|
||||
- Fix size sorting using alphabetical order instead of actual size (Thanks to @RustyRaptor for the PR)
|
||||
- Fix terminal sometimes not being launched with the correct working directory of the current path
|
||||
- Fix file deletion not showing errors when the operation failed in cmd
|
||||
- Fix file renaming not working if previous rename operation was cancelled
|
||||
- Fix file transfer kill button sometimes not working when transfer was frozen
|
||||
- Fix file browser listing not working for older PowerShell systems
|
||||
|
||||
## Connection hub
|
||||
|
||||
Proper functionality to organize a collection of hundreds of connections was always somewhat limited until now. There is now an additional index-based organization mechanism where you can assign and move indices of connections to have them listed at a certain place in relation to other connections. This can also be combined with the existing sorting methods like time and alphabetical sorting.
|
||||
|
||||
Furthermore, there are also more improvements in the connection hub:
|
||||
- Renaming connection entries can now be done quickly from the context menu without having to open the configuration dialog
|
||||
- You can now set connection configurations to be frozen, meaning that the connection entry can't be modified or deleted. This is helpful for templating and team vault setups
|
||||
- When editing an incomplete connection configuration, the focus will automatically jump to the first incomplete/invalid value. This makes keyboard usage easier
|
||||
|
||||
## HTTP API
|
||||
|
||||
The HTTP API has been improved in various areas. The action system is integrated in it, meaning that you can call any action from the API. Furthermore, there are now more API endpoints for categories so that you have proper control over them as well. There is also now a way to encrypt and decrypt secrets via the API, allowing you to create connections with integrated secrets with it as well.
|
||||
The HTTP API has been improved in various areas. The action system is integrated in it, meaning that you can call any action from the API. Furthermore, there are now more API endpoints for categories so that you have proper control over them as well. There is also now a way to encrypt and decrypt secrets via the API, allowing you to create connections with integrated secrets with it as well.
|
||||
|
||||
## Other
|
||||
|
||||
@@ -68,7 +77,6 @@ The HTTP API has been improved in various areas. The action system is integrated
|
||||
- You can now specify an alternative user for shell environments to switch to via sudo
|
||||
- You can now specify a git username and password in the settings menu if your local system does not have a git client with configured credentials
|
||||
- You can now disable icon sources without having to remove them
|
||||
- There is now a native Windows ARM build. Note that you will have to uninstall any old x64 XPipe installation for the upgrade
|
||||
- Active tunnels are now periodically refreshed to check if the underlying tunnel was closed
|
||||
- Fix clipboard data of other formats, e.g. files, being cleared after expiration of a copied password
|
||||
- Fix pwsh connections on Linux/macOS freezing on sudo elevation
|
||||
@@ -78,3 +86,5 @@ The HTTP API has been improved in various areas. The action system is integrated
|
||||
- Fix text color on hover having low contrast in some themes
|
||||
- There is now support for nushell
|
||||
- Fix SSH agent variables being wrong on macOS when using homebrew ssh
|
||||
- Fix connection search freezing on Ubuntu systems with LXD snap stub installed
|
||||
|
||||
|
||||
@@ -222,6 +222,15 @@ public class RunScriptActionProviderMenu implements HubBranchProvider<ShellStore
|
||||
|
||||
@Override
|
||||
public List<HubMenuItemProvider<?>> getChildren(DataStoreEntryRef<ShellStore> store) {
|
||||
return getChildren();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends ActionProvider> getChildren(List<DataStoreEntryRef<ShellStore>> batch) {
|
||||
return getChildren();
|
||||
}
|
||||
|
||||
private List<HubMenuItemProvider<?>> getChildren() {
|
||||
if (hierarchy.isLeaf()) {
|
||||
return List.of(
|
||||
new TerminalRunActionProvider(hierarchy),
|
||||
|
||||
Generated
+7
-3
@@ -1506,11 +1506,13 @@ actionShortcuts=Action shortcuts
|
||||
actionStore=Action store
|
||||
actionStoreDescription=The store entry to run the action on
|
||||
actionStores=Action stores
|
||||
actionStoreDescriptions=The store entries to run the action on
|
||||
actionStoresDescription=The store entries to run the action on
|
||||
actionDesktopShortcut=Desktop shortcut
|
||||
actionDesktopShortcutDescription=Create a shortcut for this action on your desktop
|
||||
actionUrlShortcut=URL a shortcut
|
||||
actionUrlShortcut=URL shortcut
|
||||
actionUrlShortcutDescription=Copy a URL that can trigger this actions when opened
|
||||
actionApiCall=API request
|
||||
actionApiCallDescription=Call this action from the HTTP API
|
||||
actionMacro=Action macro
|
||||
actionMacroDescription=Create a macro with advanced functionality for this action
|
||||
createMacro=Create macro
|
||||
@@ -1538,4 +1540,6 @@ includeRoot=Include root
|
||||
excludeRoot=Exclude root
|
||||
freezeConfiguration=Freeze configuration
|
||||
unfreezeConfiguration=Unfreeze configuration
|
||||
waylandScalingTitle=Wayland scaling
|
||||
waylandScalingTitle=Wayland scaling
|
||||
actionApiUrl=$URL$ (Copy json body)
|
||||
copyBody=Copy request body
|
||||
|
||||
Reference in New Issue
Block a user