diff --git a/components/config_form.templ b/components/config_form.templ index 397053f..2f07b01 100644 --- a/components/config_form.templ +++ b/components/config_form.templ @@ -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) { Command Configuration - - @common.RcloneFlags() + +
+ if !data.IsNew && data.InitialCommand != nil { + // Pre-render flags if editing and command data is available + @common.RcloneCommandFlagsContent(data.InitialCommand, data.SelectedFlagsMap, data.SelectedFlagValues) + } +
+ + + @common.RcloneFlags(data.Config.CommandID) // Pass current command ID + diff --git a/components/providers/common/common.templ b/components/providers/common/common.templ index efb91ac..98ecaaf 100644 --- a/components/providers/common/common.templ +++ b/components/providers/common/common.templ @@ -138,21 +138,20 @@ templ ArchiveOptions() { } -templ RcloneFlags() { +templ RcloneFlags(currentCommandID uint) {
- @RcloneCommandOptions() + @RcloneCommandOptions(currentCommandID) // Pass it down

Select the rclone command to use for this configuration.

- -
+
@@ -171,12 +170,13 @@ templ RcloneFlags() { } // New placeholder templ for rclone command options -templ RcloneCommandOptions() { -
+ hx-swap="outerHTML" + hx-vals={ fmt.Sprintf(`{"commandId": %d}`, currentCommandID) }>
@@ -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 + value={ value } + if !enabled { + disabled + } /> - @@ -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 + } /> - @@ -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 + } /> - diff --git a/components/providers/destination/minio.templ b/components/providers/destination/minio.templ index c125f26..7f3dfc4 100644 --- a/components/providers/destination/minio.templ +++ b/components/providers/destination/minio.templ @@ -39,6 +39,22 @@ templ MinIODestinationForm() {

+ +
+ +
+
+ +
+ +
+

+ Optional: Specify the region if your MinIO setup requires it. +

+
+
diff --git a/components/providers/source/minio.templ b/components/providers/source/minio.templ index c759260..4c23adb 100644 --- a/components/providers/source/minio.templ +++ b/components/providers/source/minio.templ @@ -39,6 +39,22 @@ templ MinIOSourceForm() {

+ +
+ +
+
+ +
+ +
+

+ Optional: Specify the region if your MinIO setup requires it. +

+
+
diff --git a/internal/db/transfer_config_store.go b/internal/db/transfer_config_store.go index 9bc9ed7..1d43f86 100644 --- a/internal/db/transfer_config_store.go +++ b/internal/db/transfer_config_store.go @@ -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) diff --git a/internal/web/handlers/config_handlers.go b/internal/web/handlers/config_handlers.go index 8350ac1..8cf68c2 100644 --- a/internal/web/handlers/config_handlers.go +++ b/internal/web/handlers/config_handlers.go @@ -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) } diff --git a/internal/web/handlers/rclone_handlers.go b/internal/web/handlers/rclone_handlers.go index 6c55e3f..65305a3 100644 --- a/internal/web/handlers/rclone_handlers.go +++ b/internal/web/handlers/rclone_handlers.go @@ -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