mirror of
https://github.com/StarFleetCPTN/GoMFT.git
synced 2026-09-08 15:41:20 +02:00
feat: Enhance Rclone command configuration with pre-rendered flags and region support
- Added fields for pre-rendering flags in the config form, allowing for better user experience during edits. - Updated Rclone command options to accept current command ID for pre-selection. - Introduced region input fields for MinIO source and destination forms, enhancing configuration flexibility. - Modified backend logic to handle region parameters when generating Rclone configurations. - Improved flag handling by parsing selected flags and values for better state management in the UI.
This commit is contained in:
@@ -12,6 +12,10 @@ import (
|
||||
type ConfigFormData struct {
|
||||
Config *db.TransferConfig
|
||||
IsNew bool
|
||||
// Fields for pre-rendering flags on edit
|
||||
InitialCommand *db.RcloneCommand
|
||||
SelectedFlagsMap map[uint]bool
|
||||
SelectedFlagValues map[uint]string
|
||||
}
|
||||
|
||||
func getConfigFormTitle(isNew bool) string {
|
||||
@@ -455,8 +459,17 @@ templ ConfigForm(ctx context.Context, data ConfigFormData) {
|
||||
<i class="fas fa-terminal mr-2 text-blue-500 dark:text-blue-400"></i>Command Configuration
|
||||
</h3>
|
||||
|
||||
<!-- Use the RcloneFlags component from common package -->
|
||||
@common.RcloneFlags()
|
||||
<!-- Container for flags, pre-rendered on edit, loaded via HTMX on new/change -->
|
||||
<div id="command-flags-container" class="mt-4">
|
||||
if !data.IsNew && data.InitialCommand != nil {
|
||||
// Pre-render flags if editing and command data is available
|
||||
@common.RcloneCommandFlagsContent(data.InitialCommand, data.SelectedFlagsMap, data.SelectedFlagValues)
|
||||
}
|
||||
</div>
|
||||
|
||||
<!-- Additonal Rclone Flags -->
|
||||
@common.RcloneFlags(data.Config.CommandID) // Pass current command ID
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Source Configuration Section -->
|
||||
|
||||
@@ -138,21 +138,20 @@ templ ArchiveOptions() {
|
||||
</div>
|
||||
}
|
||||
|
||||
templ RcloneFlags() {
|
||||
templ RcloneFlags(currentCommandID uint) {
|
||||
<div class="mb-6">
|
||||
<label for="command_id" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Rclone Command</label>
|
||||
<div class="relative">
|
||||
<div class="absolute inset-y-0 start-0 flex items-center ps-3.5 pointer-events-none">
|
||||
<i class="fas fa-terminal text-gray-400 dark:text-gray-500"></i>
|
||||
</div>
|
||||
@RcloneCommandOptions()
|
||||
@RcloneCommandOptions(currentCommandID) // Pass it down
|
||||
</div>
|
||||
<p class="mt-2 text-sm text-gray-500 dark:text-gray-400">
|
||||
Select the rclone command to use for this configuration.
|
||||
</p>
|
||||
|
||||
<!-- Command flags container - will be populated via HTMX -->
|
||||
<div id="command-flags-container" class="mt-4"></div>
|
||||
<!-- Flag container is now rendered directly in ConfigForm -->
|
||||
|
||||
<label for="rclone_flags" class="block mb-2 mt-6 text-sm font-medium text-gray-900 dark:text-white">Additional Rclone Flags</label>
|
||||
<div class="relative">
|
||||
@@ -171,12 +170,13 @@ templ RcloneFlags() {
|
||||
}
|
||||
|
||||
// New placeholder templ for rclone command options
|
||||
templ RcloneCommandOptions() {
|
||||
<div
|
||||
hx-get="/api/rclone/commands"
|
||||
templ RcloneCommandOptions(currentCommandID uint) { // Accept currentCommandID
|
||||
<div
|
||||
hx-get="/api/rclone/commands"
|
||||
hx-trigger="load"
|
||||
hx-target="this"
|
||||
hx-swap="outerHTML">
|
||||
hx-swap="outerHTML"
|
||||
hx-vals={ fmt.Sprintf(`{"commandId": %d}`, currentCommandID) }>
|
||||
<!-- Loading placeholder -->
|
||||
<option value="">Loading commands...</option>
|
||||
</div>
|
||||
@@ -231,12 +231,13 @@ templ DestinationSelection() {
|
||||
}
|
||||
|
||||
// RcloneCommandOptionsContent renders the command options organized by category
|
||||
templ RcloneCommandOptionsContent(categoryMap map[string][]db.RcloneCommand, categories []string) {
|
||||
templ RcloneCommandOptionsContent(categoryMap map[string][]db.RcloneCommand, categories []string, currentCommandID uint, commandFlagsJSON string, commandFlagValuesJSON string) { // Add flag JSON strings
|
||||
<select id="command_id" name="command_id" x-model="commandId"
|
||||
hx-get="/api/rclone/command-flags"
|
||||
hx-target="#command-flags-container"
|
||||
hx-trigger="change"
|
||||
hx-trigger="load, change"
|
||||
hx-include="[name='command_id']"
|
||||
hx-vals={ fmt.Sprintf(`{"commandFlags": %s, "commandFlagValues": %s}`, commandFlagsJSON, commandFlagValuesJSON) }
|
||||
@change="updateCommandRequirements()"
|
||||
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full ps-10 p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500">
|
||||
<option value="">Select command...</option>
|
||||
@@ -244,7 +245,11 @@ templ RcloneCommandOptionsContent(categoryMap map[string][]db.RcloneCommand, cat
|
||||
if commands, ok := categoryMap[category]; ok && len(commands) > 0 {
|
||||
<optgroup label={ category }>
|
||||
for _, cmd := range commands {
|
||||
<option value={ fmt.Sprintf("%d", cmd.ID) }>{ cmd.Name } - { cmd.Description }</option>
|
||||
if cmd.ID == currentCommandID {
|
||||
<option value={ fmt.Sprintf("%d", cmd.ID) } selected>{ cmd.Name } - { cmd.Description }</option>
|
||||
} else {
|
||||
<option value={ fmt.Sprintf("%d", cmd.ID) }>{ cmd.Name } - { cmd.Description }</option>
|
||||
}
|
||||
}
|
||||
</optgroup>
|
||||
}
|
||||
@@ -253,7 +258,7 @@ templ RcloneCommandOptionsContent(categoryMap map[string][]db.RcloneCommand, cat
|
||||
}
|
||||
|
||||
// RcloneCommandFlagsContent renders the command flags for a selected command
|
||||
templ RcloneCommandFlagsContent(command *db.RcloneCommand) {
|
||||
templ RcloneCommandFlagsContent(command *db.RcloneCommand, selectedFlagsMap map[uint]bool, selectedFlagValues map[uint]string) {
|
||||
if command == nil {
|
||||
<div class="p-4 text-red-500">Command not found</div>
|
||||
return
|
||||
@@ -277,7 +282,9 @@ templ RcloneCommandFlagsContent(command *db.RcloneCommand) {
|
||||
name="command_flags"
|
||||
value={ fmt.Sprintf("%d", flag.ID) }
|
||||
class="mt-0.5 rounded border-gray-300 text-blue-600 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700 dark:focus:ring-blue-600"
|
||||
/>
|
||||
if selectedFlagsMap[flag.ID] {
|
||||
checked
|
||||
} />
|
||||
<div class="ml-3">
|
||||
<label for={ fmt.Sprintf("flag_%d", flag.ID) } class="font-medium text-gray-900 dark:text-white">
|
||||
{ flag.Name } - { flag.Description }
|
||||
@@ -299,14 +306,16 @@ templ RcloneCommandFlagsContent(command *db.RcloneCommand) {
|
||||
class="mr-2 rounded border-gray-300 text-blue-600 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700 dark:focus:ring-blue-600"
|
||||
data-input-id={ fmt.Sprintf("flag_value_%d", flag.ID) }
|
||||
onclick="toggleFlagValue(this)"
|
||||
/>
|
||||
if selectedFlagsMap[flag.ID] {
|
||||
checked
|
||||
} />
|
||||
<label for={ fmt.Sprintf("flag_enable_%d", flag.ID) } class="font-medium text-gray-900 dark:text-white">
|
||||
{ flag.Name } - { flag.Description }
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="w-full mt-2">
|
||||
@renderFlagInput(flag)
|
||||
@renderFlagInput(flag, selectedFlagValues[flag.ID], selectedFlagsMap[flag.ID]) // Pass value and enabled status
|
||||
if flag.DefaultValue != "" {
|
||||
<p class="text-xs text-gray-500 dark:text-gray-400 mt-1">Default: { flag.DefaultValue }</p>
|
||||
}
|
||||
@@ -345,23 +354,7 @@ templ RcloneCommandFlagsContent(command *db.RcloneCommand) {
|
||||
}
|
||||
|
||||
// Initialize all flag inputs on page load
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const checkboxes = document.querySelectorAll('input[id^="flag_enable_"]');
|
||||
checkboxes.forEach(function(checkbox) {
|
||||
const inputId = checkbox.getAttribute('data-input-id');
|
||||
const input = document.getElementById(inputId);
|
||||
if (input) {
|
||||
input.disabled = !checkbox.checked;
|
||||
|
||||
// Also initialize the hidden input
|
||||
const hiddenId = inputId.replace('flag_value_', 'flag_hidden_');
|
||||
const hiddenInput = document.getElementById(hiddenId);
|
||||
if (hiddenInput) {
|
||||
hiddenInput.disabled = !checkbox.checked;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
// Initialization is now handled by server-side rendering
|
||||
</script>
|
||||
|
||||
<div class="mt-4 p-3 bg-blue-50 text-blue-800 rounded-lg border border-blue-100 dark:bg-blue-900/20 dark:text-blue-300 dark:border-blue-900 text-sm">
|
||||
@@ -402,7 +395,7 @@ templ RcloneCommandFlagsContent(command *db.RcloneCommand) {
|
||||
}
|
||||
|
||||
// Helper function to render appropriate input based on flag data type
|
||||
templ renderFlagInput(flag db.RcloneCommandFlag) {
|
||||
templ renderFlagInput(flag db.RcloneCommandFlag, value string, enabled bool) {
|
||||
if flag.DataType == "int" {
|
||||
<input
|
||||
type="number"
|
||||
@@ -410,14 +403,18 @@ templ renderFlagInput(flag db.RcloneCommandFlag) {
|
||||
name={ fmt.Sprintf("flag_value_%d", flag.ID) }
|
||||
class="w-full bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 p-2 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
|
||||
placeholder={ flag.DefaultValue }
|
||||
disabled
|
||||
/>
|
||||
value={ value }
|
||||
if !enabled {
|
||||
disabled
|
||||
} />
|
||||
<!-- Hidden input to include this flag ID when checked -->
|
||||
<input
|
||||
type="hidden"
|
||||
name="command_flags"
|
||||
<input
|
||||
type="hidden"
|
||||
name="command_flags"
|
||||
value={ fmt.Sprintf("%d", flag.ID) }
|
||||
disabled
|
||||
if !enabled {
|
||||
disabled
|
||||
}
|
||||
id={ fmt.Sprintf("flag_hidden_%d", flag.ID) }
|
||||
data-enable-with={ fmt.Sprintf("flag_enable_%d", flag.ID) }
|
||||
/>
|
||||
@@ -429,14 +426,18 @@ templ renderFlagInput(flag db.RcloneCommandFlag) {
|
||||
step="0.01"
|
||||
class="w-full bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 p-2 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
|
||||
placeholder={ flag.DefaultValue }
|
||||
disabled
|
||||
/>
|
||||
value={ value }
|
||||
if !enabled {
|
||||
disabled
|
||||
} />
|
||||
<!-- Hidden input to include this flag ID when checked -->
|
||||
<input
|
||||
type="hidden"
|
||||
name="command_flags"
|
||||
<input
|
||||
type="hidden"
|
||||
name="command_flags"
|
||||
value={ fmt.Sprintf("%d", flag.ID) }
|
||||
disabled
|
||||
if !enabled {
|
||||
disabled
|
||||
}
|
||||
id={ fmt.Sprintf("flag_hidden_%d", flag.ID) }
|
||||
data-enable-with={ fmt.Sprintf("flag_enable_%d", flag.ID) }
|
||||
/>
|
||||
@@ -448,14 +449,18 @@ templ renderFlagInput(flag db.RcloneCommandFlag) {
|
||||
name={ fmt.Sprintf("flag_value_%d", flag.ID) }
|
||||
class="w-full bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 p-2 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
|
||||
placeholder={ flag.DefaultValue }
|
||||
disabled
|
||||
/>
|
||||
value={ value }
|
||||
if !enabled {
|
||||
disabled
|
||||
} />
|
||||
<!-- Hidden input to include this flag ID when checked -->
|
||||
<input
|
||||
type="hidden"
|
||||
name="command_flags"
|
||||
<input
|
||||
type="hidden"
|
||||
name="command_flags"
|
||||
value={ fmt.Sprintf("%d", flag.ID) }
|
||||
disabled
|
||||
if !enabled {
|
||||
disabled
|
||||
}
|
||||
id={ fmt.Sprintf("flag_hidden_%d", flag.ID) }
|
||||
data-enable-with={ fmt.Sprintf("flag_enable_%d", flag.ID) }
|
||||
/>
|
||||
|
||||
@@ -39,6 +39,22 @@ templ MinIODestinationForm() {
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="mb-6">
|
||||
<label for="dest_region" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Region (Optional)</label>
|
||||
<div class="relative">
|
||||
<div class="absolute inset-y-0 start-0 flex items-center ps-3.5 pointer-events-none">
|
||||
<i class="fas fa-globe-americas text-gray-400 dark:text-gray-500"></i>
|
||||
</div>
|
||||
<input type="text" id="dest_region" name="dest_region" x-model="destRegion"
|
||||
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full ps-10 p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
|
||||
placeholder="us-east-1" />
|
||||
</div>
|
||||
<p class="mt-2 text-sm text-gray-500 dark:text-gray-400">
|
||||
Optional: Specify the region if your MinIO setup requires it.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="mb-6">
|
||||
<label for="dest_access_key" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Access Key</label>
|
||||
<div class="relative">
|
||||
|
||||
@@ -39,6 +39,22 @@ templ MinIOSourceForm() {
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="mb-6">
|
||||
<label for="source_region" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Region (Optional)</label>
|
||||
<div class="relative">
|
||||
<div class="absolute inset-y-0 start-0 flex items-center ps-3.5 pointer-events-none">
|
||||
<i class="fas fa-globe-americas text-gray-400 dark:text-gray-500"></i>
|
||||
</div>
|
||||
<input type="text" id="source_region" name="source_region" x-model="sourceRegion"
|
||||
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full ps-10 p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
|
||||
placeholder="us-east-1" />
|
||||
</div>
|
||||
<p class="mt-2 text-sm text-gray-500 dark:text-gray-400">
|
||||
Optional: Specify the region if your MinIO setup requires it.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="mb-6">
|
||||
<label for="source_access_key" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Access Key</label>
|
||||
<div class="relative">
|
||||
|
||||
@@ -141,6 +141,10 @@ func (db *DB) GenerateRcloneConfig(config *TransferConfig) error {
|
||||
"--config", configPath,
|
||||
"--log-level", "ERROR",
|
||||
}
|
||||
// Add region if specified
|
||||
if config.SourceRegion != "" {
|
||||
args = append(args, "region", config.SourceRegion)
|
||||
}
|
||||
cmd := exec.Command(rclonePath, args...)
|
||||
if output, err := cmd.CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("failed to create source config (minio): %v\nOutput: %s", err, output)
|
||||
@@ -212,6 +216,10 @@ func (db *DB) GenerateRcloneConfig(config *TransferConfig) error {
|
||||
"--config", configPath,
|
||||
"--log-level", "ERROR",
|
||||
}
|
||||
// Add region if specified
|
||||
if config.DestRegion != "" {
|
||||
args = append(args, "region", config.DestRegion)
|
||||
}
|
||||
cmd := exec.Command(rclonePath, args...)
|
||||
if output, err := cmd.CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("failed to create destination config (minio): %v\nOutput: %s", err, output)
|
||||
|
||||
@@ -65,9 +65,43 @@ func (h *Handlers) HandleEditConfig(c *gin.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch the initial command details for pre-rendering flags
|
||||
initialCommand, err := h.DB.GetRcloneCommandWithFlags(config.CommandID)
|
||||
if err != nil {
|
||||
// Log the error but proceed, the form might still be usable without pre-rendered flags
|
||||
log.Printf("Warning: Failed to get initial command flags for config %d: %v", config.ID, err)
|
||||
initialCommand = nil // Ensure it's nil if fetching failed
|
||||
}
|
||||
|
||||
// Parse the selected flags and values from the config
|
||||
selectedFlagsMap := make(map[uint]bool)
|
||||
if config.CommandFlags != "" {
|
||||
var selectedFlagIDs []uint
|
||||
// Use json.Unmarshal directly as CommandFlags should be a JSON array string
|
||||
if err := json.Unmarshal([]byte(config.CommandFlags), &selectedFlagIDs); err == nil {
|
||||
for _, id := range selectedFlagIDs {
|
||||
selectedFlagsMap[id] = true
|
||||
}
|
||||
} else {
|
||||
log.Printf("Warning: Failed to unmarshal CommandFlags for config %d: %v. JSON: %s", config.ID, err, config.CommandFlags)
|
||||
}
|
||||
}
|
||||
|
||||
selectedFlagValues := make(map[uint]string)
|
||||
if config.CommandFlagValues != "" {
|
||||
// Use json.Unmarshal directly as CommandFlagValues should be a JSON object string
|
||||
if err := json.Unmarshal([]byte(config.CommandFlagValues), &selectedFlagValues); err != nil {
|
||||
log.Printf("Warning: Failed to unmarshal CommandFlagValues for config %d: %v. JSON: %s", config.ID, err, config.CommandFlagValues)
|
||||
selectedFlagValues = make(map[uint]string) // Reset on error
|
||||
}
|
||||
}
|
||||
|
||||
data := components.ConfigFormData{
|
||||
Config: &config,
|
||||
IsNew: false,
|
||||
Config: &config,
|
||||
IsNew: false,
|
||||
InitialCommand: initialCommand,
|
||||
SelectedFlagsMap: selectedFlagsMap,
|
||||
SelectedFlagValues: selectedFlagValues,
|
||||
}
|
||||
components.ConfigForm(c.Request.Context(), data).Render(c, c.Writer)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"html/template"
|
||||
"log"
|
||||
"net/http"
|
||||
@@ -26,6 +27,14 @@ func NewRcloneHandler(db *db.DB) *RcloneHandler {
|
||||
|
||||
// RcloneCommandOptions renders the rclone command options for the config form
|
||||
func (h *RcloneHandler) RcloneCommandOptions(c *gin.Context) {
|
||||
// Get the current command ID if provided (for pre-selection)
|
||||
currentCommandIDStr := c.DefaultQuery("commandId", "1") // Default to 1 (copy)
|
||||
currentCommandID, err := strconv.ParseUint(currentCommandIDStr, 10, 64)
|
||||
if err != nil {
|
||||
log.Printf("Error parsing current command ID: %v, using default 1", err)
|
||||
currentCommandID = 1
|
||||
}
|
||||
|
||||
commands, err := h.DB.GetRcloneCommands()
|
||||
if err != nil {
|
||||
log.Printf("Error getting rclone commands: %v", err)
|
||||
@@ -47,12 +56,20 @@ func (h *RcloneHandler) RcloneCommandOptions(c *gin.Context) {
|
||||
categoryMap[cmd.Category] = append(categoryMap[cmd.Category], cmd)
|
||||
}
|
||||
|
||||
_ = common.RcloneCommandOptionsContent(categoryMap, categories).Render(c.Request.Context(), c.Writer)
|
||||
// Get the initial flag JSON strings passed from the placeholder's hx-vals
|
||||
commandFlagsJSON := c.DefaultQuery("commandFlags", "[]")
|
||||
commandFlagValuesJSON := c.DefaultQuery("commandFlagValues", "{}")
|
||||
|
||||
// Pass the current command ID and flag JSON strings to the template
|
||||
_ = common.RcloneCommandOptionsContent(categoryMap, categories, uint(currentCommandID), commandFlagsJSON, commandFlagValuesJSON).Render(c.Request.Context(), c.Writer)
|
||||
}
|
||||
|
||||
// RcloneCommandFlags renders the rclone command flags for the selected command
|
||||
func (h *RcloneHandler) RcloneCommandFlags(c *gin.Context) {
|
||||
commandIDStr := c.DefaultQuery("command_id", "")
|
||||
commandFlagsJSON := c.DefaultQuery("commandFlags", "[]") // Get selected flag IDs JSON
|
||||
commandFlagValuesJSON := c.DefaultQuery("commandFlagValues", "{}") // Get selected flag values JSON
|
||||
|
||||
if commandIDStr == "" {
|
||||
c.String(http.StatusBadRequest, "Command ID is required")
|
||||
return
|
||||
@@ -72,6 +89,25 @@ func (h *RcloneHandler) RcloneCommandFlags(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// Parse the selected flags and values
|
||||
var selectedFlagIDs []uint
|
||||
if err := json.Unmarshal([]byte(commandFlagsJSON), &selectedFlagIDs); err != nil {
|
||||
log.Printf("Error unmarshaling commandFlags JSON: %v, JSON: %s", err, commandFlagsJSON)
|
||||
// Don't fail, just proceed with no flags selected
|
||||
selectedFlagIDs = []uint{}
|
||||
}
|
||||
selectedFlagsMap := make(map[uint]bool)
|
||||
for _, id := range selectedFlagIDs {
|
||||
selectedFlagsMap[id] = true
|
||||
}
|
||||
|
||||
var selectedFlagValues map[uint]string
|
||||
if err := json.Unmarshal([]byte(commandFlagValuesJSON), &selectedFlagValues); err != nil {
|
||||
log.Printf("Error unmarshaling commandFlagValues JSON: %v, JSON: %s", err, commandFlagValuesJSON)
|
||||
// Don't fail, just proceed with no values
|
||||
selectedFlagValues = make(map[uint]string)
|
||||
}
|
||||
|
||||
if command == nil {
|
||||
c.String(http.StatusNotFound, "Command not found")
|
||||
return
|
||||
@@ -82,7 +118,8 @@ func (h *RcloneHandler) RcloneCommandFlags(c *gin.Context) {
|
||||
return command.Flags[i].Name < command.Flags[j].Name
|
||||
})
|
||||
|
||||
_ = common.RcloneCommandFlagsContent(command).Render(c.Request.Context(), c.Writer)
|
||||
// Pass the parsed selected flags and values to the template
|
||||
_ = common.RcloneCommandFlagsContent(command, selectedFlagsMap, selectedFlagValues).Render(c.Request.Context(), c.Writer)
|
||||
}
|
||||
|
||||
// RcloneCommandUsage renders the usage information for a command
|
||||
|
||||
Reference in New Issue
Block a user