diff --git a/src/ZB.MOM.WW.ScadaBridge.Commons/Messages/Management/TemplateFolderCommands.cs b/src/ZB.MOM.WW.ScadaBridge.Commons/Messages/Management/TemplateFolderCommands.cs
index a60c2f73..9ed9ebbf 100644
--- a/src/ZB.MOM.WW.ScadaBridge.Commons/Messages/Management/TemplateFolderCommands.cs
+++ b/src/ZB.MOM.WW.ScadaBridge.Commons/Messages/Management/TemplateFolderCommands.cs
@@ -1,8 +1,11 @@
+using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
+
namespace ZB.MOM.WW.ScadaBridge.Commons.Messages.Management;
public record ListTemplateFoldersCommand;
public record CreateTemplateFolderCommand(string Name, int? ParentFolderId);
public record RenameTemplateFolderCommand(int FolderId, string NewName);
public record MoveTemplateFolderCommand(int FolderId, int? NewParentFolderId);
+public record ReorderTemplateFolderCommand(int FolderId, ReorderDirection Direction);
public record DeleteTemplateFolderCommand(int FolderId);
public record MoveTemplateToFolderCommand(int TemplateId, int? NewFolderId);
diff --git a/src/ZB.MOM.WW.ScadaBridge.Commons/Types/Enums/ReorderDirection.cs b/src/ZB.MOM.WW.ScadaBridge.Commons/Types/Enums/ReorderDirection.cs
new file mode 100644
index 00000000..f4ef9ea5
--- /dev/null
+++ b/src/ZB.MOM.WW.ScadaBridge.Commons/Types/Enums/ReorderDirection.cs
@@ -0,0 +1,16 @@
+namespace ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
+
+///
+/// Direction for a sibling reorder operation. Ordering is ascending by
+/// SortOrder, so moves an item toward a lower sort
+/// order (earlier in the list) and toward a higher sort
+/// order (later in the list).
+///
+public enum ReorderDirection
+{
+ /// Move toward a lower sort order (swap with the previous sibling).
+ Up,
+
+ /// Move toward a higher sort order (swap with the next sibling).
+ Down
+}
diff --git a/src/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase/Repositories/TemplateEngineRepository.cs b/src/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase/Repositories/TemplateEngineRepository.cs
index ac5e8647..a6657368 100644
--- a/src/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase/Repositories/TemplateEngineRepository.cs
+++ b/src/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase/Repositories/TemplateEngineRepository.cs
@@ -632,7 +632,10 @@ public class TemplateEngineRepository : ITemplateEngineRepository
///
public async Task> GetAllFoldersAsync(CancellationToken cancellationToken = default)
- => await _context.TemplateFolders.ToListAsync(cancellationToken);
+ => await _context.TemplateFolders
+ .OrderBy(f => f.SortOrder)
+ .ThenBy(f => f.Name)
+ .ToListAsync(cancellationToken);
///
public async Task AddFolderAsync(TemplateFolder folder, CancellationToken cancellationToken = default)
diff --git a/src/ZB.MOM.WW.ScadaBridge.ManagementService/ManagementActor.cs b/src/ZB.MOM.WW.ScadaBridge.ManagementService/ManagementActor.cs
index f7c5924c..3f4a60f2 100644
--- a/src/ZB.MOM.WW.ScadaBridge.ManagementService/ManagementActor.cs
+++ b/src/ZB.MOM.WW.ScadaBridge.ManagementService/ManagementActor.cs
@@ -198,7 +198,7 @@ public class ManagementActor : ReceiveActor
or CreateApiMethodCommand or UpdateApiMethodCommand or DeleteApiMethodCommand
or UpdateAreaCommand
or CreateTemplateFolderCommand or RenameTemplateFolderCommand
- or MoveTemplateFolderCommand or DeleteTemplateFolderCommand
+ or MoveTemplateFolderCommand or ReorderTemplateFolderCommand or DeleteTemplateFolderCommand
or MoveTemplateToFolderCommand
or ExportBundleCommand => Roles.Designer,
@@ -267,6 +267,7 @@ public class ManagementActor : ReceiveActor
CreateTemplateFolderCommand cmd => await HandleCreateTemplateFolder(sp, cmd, user.Username),
RenameTemplateFolderCommand cmd => await HandleRenameTemplateFolder(sp, cmd, user.Username),
MoveTemplateFolderCommand cmd => await HandleMoveTemplateFolder(sp, cmd, user.Username),
+ ReorderTemplateFolderCommand cmd => await HandleReorderTemplateFolder(sp, cmd, user.Username),
DeleteTemplateFolderCommand cmd => await HandleDeleteTemplateFolder(sp, cmd, user.Username),
MoveTemplateToFolderCommand cmd => await HandleMoveTemplateToFolder(sp, cmd, user.Username),
@@ -619,6 +620,13 @@ public class ManagementActor : ReceiveActor
return result.IsSuccess ? result.Value : throw new ManagementCommandException(result.Error);
}
+ private static async Task