Initial commit
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.SignalR.Client;
|
||||
using RobotNet10.Components.Clients;
|
||||
using RobotNet10.ScriptEngine.Shared;
|
||||
|
||||
namespace RobotNet10.ScriptEditor.Clients;
|
||||
|
||||
/// <summary>
|
||||
/// SignalR HubClient for ConsoleHub - handles console logging events.
|
||||
/// </summary>
|
||||
public class ConsoleHubClient : HubClient
|
||||
{
|
||||
public event Action<string>? ErrorReceived;
|
||||
public event Action<string>? InfoReceived;
|
||||
public event Action<string>? WarningReceived;
|
||||
|
||||
public ConsoleHubClient(NavigationManager navigationManager)
|
||||
: base(navigationManager.ToAbsoluteUri(HubEndpoints.ScriptConsoleHubPath))
|
||||
{
|
||||
Connection.On<string>("Error", message => ErrorReceived?.Invoke(message));
|
||||
Connection.On<string>("Info", message => InfoReceived?.Invoke(message));
|
||||
Connection.On<string>("Warning", message => WarningReceived?.Invoke(message));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers to receive console messages for a specific task.
|
||||
/// </summary>
|
||||
public Task RegisterTaskAsync(string name) => Connection.InvokeAsync("RegisterTask", name);
|
||||
|
||||
/// <summary>
|
||||
/// Unregisters from receiving console messages for a specific task.
|
||||
/// </summary>
|
||||
public Task UnregisterTaskAsync(string name) => Connection.InvokeAsync("UnregisterTask", name);
|
||||
|
||||
/// <summary>
|
||||
/// Registers to receive console messages for a specific mission.
|
||||
/// </summary>
|
||||
public Task RegisterMissionAsync(Guid missionId) => Connection.InvokeAsync("RegisterMission", missionId);
|
||||
|
||||
/// <summary>
|
||||
/// Unregisters from receiving console messages for a specific mission.
|
||||
/// </summary>
|
||||
public Task UnregisterMissionAsync(Guid missionId) => Connection.InvokeAsync("UnregisterMission", missionId);
|
||||
|
||||
/// <summary>
|
||||
/// Registers to receive all console messages.
|
||||
/// </summary>
|
||||
public Task RegisterAllAsync() => Connection.InvokeAsync("RegisterAll");
|
||||
|
||||
/// <summary>
|
||||
/// Unregisters from receiving all console messages.
|
||||
/// </summary>
|
||||
public Task UnregisterAllAsync() => Connection.InvokeAsync("UnregisterAll");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.SignalR.Client;
|
||||
using RobotNet10.Components.Clients;
|
||||
using RobotNet10.ScriptEngine.Shared;
|
||||
|
||||
namespace RobotNet10.ScriptEditor.Clients;
|
||||
|
||||
/// <summary>
|
||||
/// SignalR HubClient for FileManagerHub - handles file management operations.
|
||||
/// Note: Events are only triggered when other clients perform actions through Hub methods,
|
||||
/// not from FileManager class directly (FileManager doesn't have HubContext).
|
||||
/// </summary>
|
||||
public class FileManagerHubClient : HubClient
|
||||
{
|
||||
/// <summary>
|
||||
/// Triggered when edit permission is revoked (sent to the previous connection).
|
||||
/// </summary>
|
||||
public event Action<string?>? EditPermissionRevoked;
|
||||
|
||||
/// <summary>
|
||||
/// Triggered when another client saves a file.
|
||||
/// </summary>
|
||||
public event Action<string, string?>? FileSaved;
|
||||
|
||||
/// <summary>
|
||||
/// Triggered when another client creates a file.
|
||||
/// </summary>
|
||||
public event Action<string, string?>? FileCreated;
|
||||
|
||||
/// <summary>
|
||||
/// Triggered when another client creates a folder.
|
||||
/// </summary>
|
||||
public event Action<string, string?>? FolderCreated;
|
||||
|
||||
/// <summary>
|
||||
/// Triggered when another client deletes a file.
|
||||
/// </summary>
|
||||
public event Action<string, string?>? FileDeleted;
|
||||
|
||||
/// <summary>
|
||||
/// Triggered when another client deletes a folder.
|
||||
/// </summary>
|
||||
public event Action<string, string?>? FolderDeleted;
|
||||
|
||||
/// <summary>
|
||||
/// Triggered when any client creates a backup.
|
||||
/// </summary>
|
||||
public event Action<string, string?>? BackupCreated;
|
||||
|
||||
/// <summary>
|
||||
/// Triggered when any client restores a backup.
|
||||
/// </summary>
|
||||
public event Action<string, string?>? BackupRestored;
|
||||
|
||||
/// <summary>
|
||||
/// Triggered when any client deletes a backup.
|
||||
/// </summary>
|
||||
public event Action<string, string?>? BackupDeleted;
|
||||
|
||||
public FileManagerHubClient(NavigationManager navigationManager)
|
||||
: base(navigationManager.ToAbsoluteUri(HubEndpoints.ScriptFileManagerHubPath))
|
||||
{
|
||||
Connection.On<string?>("EditPermissionRevoked", userId => EditPermissionRevoked?.Invoke(userId));
|
||||
Connection.On<string, string?>("FileSaved", (path, userId) => FileSaved?.Invoke(path, userId));
|
||||
Connection.On<string, string?>("FileCreated", (path, userId) => FileCreated?.Invoke(path, userId));
|
||||
Connection.On<string, string?>("FolderCreated", (path, userId) => FolderCreated?.Invoke(path, userId));
|
||||
Connection.On<string, string?>("FileDeleted", (path, userId) => FileDeleted?.Invoke(path, userId));
|
||||
Connection.On<string, string?>("FolderDeleted", (path, userId) => FolderDeleted?.Invoke(path, userId));
|
||||
Connection.On<string, string?>("BackupCreated", (fileName, userId) => BackupCreated?.Invoke(fileName, userId));
|
||||
Connection.On<string, string?>("BackupRestored", (fileName, userId) => BackupRestored?.Invoke(fileName, userId));
|
||||
Connection.On<string, string?>("BackupDeleted", (fileName, userId) => BackupDeleted?.Invoke(fileName, userId));
|
||||
|
||||
// Request edit permission when reconnected
|
||||
// This will always succeed and force out any previous connection
|
||||
Connection.Reconnected += async _ =>
|
||||
{
|
||||
if (IsConnected)
|
||||
{
|
||||
try
|
||||
{
|
||||
await RequestEditPermissionAsync();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Ignore errors - permission request should always succeed
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public override async Task StartAsync()
|
||||
{
|
||||
await base.StartAsync();
|
||||
|
||||
// Automatically request edit permission when connected
|
||||
// This will always succeed and force out any previous connection
|
||||
if (IsConnected)
|
||||
{
|
||||
try
|
||||
{
|
||||
await RequestEditPermissionAsync();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Ignore errors - permission request should always succeed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the root folder structure with all files and folders.
|
||||
/// </summary>
|
||||
public Task<ScriptFolderDto> GetRootFolderAsync() => Connection.InvokeAsync<ScriptFolderDto>("GetRootFolder");
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current state of the FileManager.
|
||||
/// </summary>
|
||||
public Task<ScriptEngineState> GetStateAsync() => Connection.InvokeAsync<ScriptEngineState>("GetState");
|
||||
|
||||
/// <summary>
|
||||
/// Requests edit permission. If another connection has permission, it will be revoked and notified.
|
||||
/// </summary>
|
||||
public Task<bool> RequestEditPermissionAsync() => Connection.InvokeAsync<bool>("RequestEditPermission");
|
||||
|
||||
/// <summary>
|
||||
/// Revokes edit permission for the current connection.
|
||||
/// </summary>
|
||||
public Task RevokeEditPermissionAsync() => Connection.InvokeAsync("RevokeEditPermission");
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the current connection has edit permission.
|
||||
/// </summary>
|
||||
public Task<bool> HasEditPermissionAsync() => Connection.InvokeAsync<bool>("HasEditPermission");
|
||||
|
||||
/// <summary>
|
||||
/// Saves file content.
|
||||
/// </summary>
|
||||
public Task SaveFileAsync(string relativePath, string content) => Connection.InvokeAsync("SaveFile", relativePath, content);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new file.
|
||||
/// </summary>
|
||||
public Task CreateFileAsync(string relativePath, string content) => Connection.InvokeAsync("CreateFile", relativePath, content);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new folder.
|
||||
/// </summary>
|
||||
public Task CreateFolderAsync(string relativePath) => Connection.InvokeAsync("CreateFolder", relativePath);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a file.
|
||||
/// </summary>
|
||||
public Task DeleteFileAsync(string relativePath) => Connection.InvokeAsync("DeleteFile", relativePath);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a folder.
|
||||
/// </summary>
|
||||
public Task DeleteFolderAsync(string relativePath) => Connection.InvokeAsync("DeleteFolder", relativePath);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a backup of all scripts.
|
||||
/// </summary>
|
||||
public Task<string> CreateBackupAsync(string? backupName = null) => Connection.InvokeAsync<string>("CreateBackup", backupName);
|
||||
|
||||
/// <summary>
|
||||
/// Lists available backup files.
|
||||
/// </summary>
|
||||
public Task<ScriptBackupInfo[]> ListBackupsAsync() => Connection.InvokeAsync<ScriptBackupInfo[]>("ListBackups");
|
||||
|
||||
/// <summary>
|
||||
/// Restores scripts from a backup.
|
||||
/// </summary>
|
||||
public Task RestoreBackupAsync(string backupFileName, bool replaceExisting = true) =>
|
||||
Connection.InvokeAsync("RestoreBackup", backupFileName, replaceExisting);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a backup file.
|
||||
/// </summary>
|
||||
public Task DeleteBackupAsync(string backupFileName) => Connection.InvokeAsync("DeleteBackup", backupFileName);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.SignalR.Client;
|
||||
using RobotNet10.Components.Clients;
|
||||
using RobotNet10.ScriptEngine.Shared;
|
||||
using RobotNet10.Shared;
|
||||
|
||||
namespace RobotNet10.ScriptEditor.Clients;
|
||||
|
||||
/// <summary>
|
||||
/// SignalR HubClient for InstanceMissionHub - handles instance mission operations.
|
||||
/// </summary>
|
||||
public class InstanceMissionHubClient : HubClient
|
||||
{
|
||||
public InstanceMissionHubClient(NavigationManager navigationManager)
|
||||
: base(navigationManager.ToAbsoluteUri(HubEndpoints.InstanceMissionHubPath))
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Searches instance missions with pagination and text search.
|
||||
/// </summary>
|
||||
public Task<SearchResult<InstanceMissionDto>> SearchInstanceMissionsAsync(SearchRequest request)
|
||||
{
|
||||
return Connection.InvokeAsync<SearchResult<InstanceMissionDto>>("SearchInstanceMissions", request);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the log for a specific instance mission.
|
||||
/// </summary>
|
||||
public Task<string?> GetInstanceMissionLogAsync(Guid missionId)
|
||||
{
|
||||
return Connection.InvokeAsync<string?>("GetInstanceMissionLog", missionId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cancels a running or paused mission.
|
||||
/// </summary>
|
||||
public Task<MessageResult> CancelMissionAsync(Guid missionId, string reason)
|
||||
{
|
||||
return Connection.InvokeAsync<MessageResult>("CancelMission", missionId, reason);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pauses a running mission.
|
||||
/// </summary>
|
||||
public Task<MessageResult> PauseMissionAsync(Guid missionId)
|
||||
{
|
||||
return Connection.InvokeAsync<MessageResult>("PauseMission", missionId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resumes a paused mission.
|
||||
/// </summary>
|
||||
public Task<MessageResult> ResumeMissionAsync(Guid missionId)
|
||||
{
|
||||
return Connection.InvokeAsync<MessageResult>("ResumeMission", missionId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,187 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.SignalR.Client;
|
||||
using RobotNet10.Components.Clients;
|
||||
using RobotNet10.ScriptEngine.Shared;
|
||||
using RobotNet10.Shared;
|
||||
|
||||
namespace RobotNet10.ScriptEditor.Clients;
|
||||
|
||||
/// <summary>
|
||||
/// SignalR HubClient for ScriptManagerHub - handles ScriptEngine management operations.
|
||||
/// </summary>
|
||||
public class ScriptManagerHubClient : HubClient
|
||||
{
|
||||
public event Action<ScriptEngineState>? StateChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current ScriptEngine state. Updated when connected.
|
||||
/// </summary>
|
||||
public ScriptEngineState State { get; private set; }
|
||||
|
||||
public ScriptManagerHubClient(NavigationManager navigationManager)
|
||||
: base(navigationManager.ToAbsoluteUri(HubEndpoints.ScriptManagerHubPath))
|
||||
{
|
||||
Connection.On<ScriptEngineState>("StateChanged", state =>
|
||||
{
|
||||
State = state;
|
||||
StateChanged?.Invoke(state);
|
||||
});
|
||||
|
||||
// Reload state when reconnected
|
||||
Connection.Reconnected += async _ =>
|
||||
{
|
||||
if (IsConnected)
|
||||
{
|
||||
try
|
||||
{
|
||||
var newState = await GetStateAsync();
|
||||
if (State != newState)
|
||||
{
|
||||
State = newState;
|
||||
StateChanged?.Invoke(newState);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Even if state hasn't changed, trigger event to update UI
|
||||
StateChanged?.Invoke(newState);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Ignore errors when reloading state on reconnect
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public override async Task StartAsync()
|
||||
{
|
||||
await base.StartAsync();
|
||||
|
||||
// Lưu state khi connected và trigger StateChanged event
|
||||
if (IsConnected)
|
||||
{
|
||||
var newState = await GetStateAsync();
|
||||
if (State != newState)
|
||||
{
|
||||
State = newState;
|
||||
StateChanged?.Invoke(newState);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Even if state hasn't changed, trigger event to update UI
|
||||
StateChanged?.Invoke(newState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current state of the ScriptEngine.
|
||||
/// </summary>
|
||||
public Task<ScriptEngineState> GetStateAsync() => Connection.InvokeAsync<ScriptEngineState>("GetState");
|
||||
|
||||
/// <summary>
|
||||
/// Builds scripts from all files. Only allowed when state is Idle or BuildError.
|
||||
/// </summary>
|
||||
public Task<MessageResult> BuildAsync() => Connection.InvokeAsync<MessageResult>("Build");
|
||||
|
||||
/// <summary>
|
||||
/// Starts the ScriptEngine. Only allowed when state is Ready.
|
||||
/// </summary>
|
||||
public Task<MessageResult> StartEingineAsync() => Connection.InvokeAsync<MessageResult>("Start");
|
||||
|
||||
/// <summary>
|
||||
/// Stops the ScriptEngine. Only allowed when state is Running.
|
||||
/// </summary>
|
||||
public Task<MessageResult> StopEingineAsync() => Connection.InvokeAsync<MessageResult>("Stop");
|
||||
|
||||
/// <summary>
|
||||
/// Resets the ScriptEngine. Allowed from Idle, Ready, BuildError, Running, or Fault.
|
||||
/// </summary>
|
||||
public Task<MessageResult> ResetAsync() => Connection.InvokeAsync<MessageResult>("Reset");
|
||||
|
||||
#region VariableManager Methods
|
||||
|
||||
/// <summary>
|
||||
/// Gets all script variables.
|
||||
/// </summary>
|
||||
public Task<ScriptVariableDto[]> GetScriptVariablesAsync() =>
|
||||
Connection.InvokeAsync<ScriptVariableDto[]>("GetScriptVariables");
|
||||
|
||||
/// <summary>
|
||||
/// Finds specific script variables by names.
|
||||
/// </summary>
|
||||
public Task<ScriptVariableDto[]> FindScriptVariablesAsync(string[] names) =>
|
||||
Connection.InvokeAsync<ScriptVariableDto[]>("FindScriptVariables", names);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the value of a script variable by name.
|
||||
/// </summary>
|
||||
public Task<MessageResult> SetValueAsync(string name, string value) =>
|
||||
Connection.InvokeAsync<MessageResult>("SetValue", name, value);
|
||||
|
||||
#endregion
|
||||
|
||||
#region TaskManager Methods
|
||||
|
||||
/// <summary>
|
||||
/// Gets all script tasks.
|
||||
/// </summary>
|
||||
public Task<ScriptTaskDto[]> GetScriptTasksAsync() =>
|
||||
Connection.InvokeAsync<ScriptTaskDto[]>("GetScriptTasks");
|
||||
|
||||
/// <summary>
|
||||
/// Finds specific script tasks by names.
|
||||
/// </summary>
|
||||
public Task<ScriptTaskDto[]> FindScriptTasksAsync(string[] names) =>
|
||||
Connection.InvokeAsync<ScriptTaskDto[]>("FindScriptTasks", names);
|
||||
|
||||
/// <summary>
|
||||
/// Enables a task (resumes if paused, starts if stopped).
|
||||
/// </summary>
|
||||
public Task<MessageResult> EnableTaskAsync(string name) =>
|
||||
Connection.InvokeAsync<MessageResult>("EnableTask", name);
|
||||
|
||||
/// <summary>
|
||||
/// Disables a task (pauses if running).
|
||||
/// </summary>
|
||||
public Task<MessageResult> DisableTaskAsync(string name) =>
|
||||
Connection.InvokeAsync<MessageResult>("DisableTask", name);
|
||||
|
||||
#endregion
|
||||
|
||||
#region MissionManager Methods
|
||||
|
||||
/// <summary>
|
||||
/// Gets all script missions.
|
||||
/// </summary>
|
||||
public Task<ScriptMissionDto[]> GetScriptMissionsAsync() =>
|
||||
Connection.InvokeAsync<ScriptMissionDto[]>("GetScriptMissions");
|
||||
|
||||
/// <summary>
|
||||
/// Finds specific script missions by names.
|
||||
/// </summary>
|
||||
public Task<ScriptMissionDto[]> FindScriptMissionsAsync(string[] names) =>
|
||||
Connection.InvokeAsync<ScriptMissionDto[]>("FindScriptMissions", names);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a mission instance with parameters provided as a dictionary.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the mission model.</param>
|
||||
/// <param name="args">Dictionary of parameter values keyed by parameter name (as strings).</param>
|
||||
/// <returns>MessageResult containing the mission ID if successful.</returns>
|
||||
public Task<MessageResult<Guid>> CreateMissionAsync(string name, IDictionary<string, string> args) =>
|
||||
Connection.InvokeAsync<MessageResult<Guid>>("CreateMission", name, args);
|
||||
|
||||
/// <summary>
|
||||
/// Cancels a running or paused mission.
|
||||
/// </summary>
|
||||
/// <param name="id">The ID of the mission instance to cancel.</param>
|
||||
/// <param name="reason">The reason for cancellation.</param>
|
||||
/// <returns>True if the mission was canceled successfully, false otherwise.</returns>
|
||||
public Task<bool> CancelMissionAsync(Guid id, string reason) =>
|
||||
Connection.InvokeAsync<bool>("CancelMission", id, reason);
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user