mirror of
https://github.com/StarFleetCPTN/GoMFT.git
synced 2026-09-08 23:50:48 +02:00
- Update .gitignore to include new provider files and ensure proper tracking. - Refactor job and config forms to support multiple configuration selections, improving user experience. - Implement logic to handle the initialization of skipProcessedFiles with a default value. - Add new provider form templates for better organization and management of source and destination configurations. - Enhance tests for provider forms and job configurations to ensure robust functionality. - Introduce nullable handling for skipProcessedFiles in the database schema and update related migrations. - Improve error handling and validation in job creation and editing processes.
357 lines
9.4 KiB
Templ
357 lines
9.4 KiB
Templ
package components
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/starfleetcptn/gomft/internal/db"
|
|
"context"
|
|
"github.com/starfleetcptn/gomft/components/providers/source"
|
|
"github.com/starfleetcptn/gomft/components/providers/destination"
|
|
"github.com/starfleetcptn/gomft/components/providers/common"
|
|
)
|
|
|
|
type ConfigFormData struct {
|
|
Config *db.TransferConfig
|
|
IsNew bool
|
|
}
|
|
|
|
func getConfigFormTitle(isNew bool) string {
|
|
if isNew {
|
|
return "New Configuration"
|
|
}
|
|
return "Edit Configuration"
|
|
}
|
|
|
|
func getInitialData(config *db.TransferConfig) string {
|
|
// Default values for a new configuration
|
|
name := ""
|
|
sourceType := "local"
|
|
sourcePath := ""
|
|
sourceHost := ""
|
|
sourcePort := 22
|
|
sourceUser := ""
|
|
sourcePassword := ""
|
|
sourceKeyFile := ""
|
|
sourceAuthType := "password"
|
|
sourceBucket := ""
|
|
sourceRegion := ""
|
|
sourceAccessKey := ""
|
|
sourceSecretKey := ""
|
|
sourceEndpoint := ""
|
|
sourceShare := ""
|
|
sourceDomain := ""
|
|
sourcePassiveMode := false
|
|
sourceClientId := ""
|
|
sourceClientSecret := ""
|
|
sourceDriveId := ""
|
|
sourceTeamDrive := ""
|
|
|
|
filePattern := ""
|
|
outputPattern := "${filename}"
|
|
|
|
destinationType := "local"
|
|
destinationPath := ""
|
|
destHost := ""
|
|
destPort := 22
|
|
destUser := ""
|
|
destPassword := ""
|
|
destKeyFile := ""
|
|
destAuthType := "password"
|
|
destBucket := ""
|
|
destRegion := ""
|
|
destAccessKey := ""
|
|
destSecretKey := ""
|
|
destEndpoint := ""
|
|
destShare := ""
|
|
destDomain := ""
|
|
destPassiveMode := false
|
|
destClientId := ""
|
|
destClientSecret := ""
|
|
destDriveId := ""
|
|
destTeamDrive := ""
|
|
|
|
archivePath := ""
|
|
archiveEnabled := false
|
|
deleteAfterTransfer := false
|
|
skipProcessedFiles := true
|
|
maxConcurrentTransfers := 4
|
|
rcloneFlags := ""
|
|
|
|
// If editing an existing config, populate with those values
|
|
if config != nil {
|
|
name = config.Name
|
|
sourceType = config.SourceType
|
|
sourcePath = config.SourcePath
|
|
sourceHost = config.SourceHost
|
|
sourcePort = config.SourcePort
|
|
sourceUser = config.SourceUser
|
|
sourcePassword = config.SourcePassword
|
|
sourceKeyFile = config.SourceKeyFile
|
|
if sourceKeyFile != "" && sourcePassword == "" {
|
|
sourceAuthType = "key"
|
|
}
|
|
sourceBucket = config.SourceBucket
|
|
sourceRegion = config.SourceRegion
|
|
sourceAccessKey = config.SourceAccessKey
|
|
sourceSecretKey = config.SourceSecretKey
|
|
sourceEndpoint = config.SourceEndpoint
|
|
sourceShare = config.SourceShare
|
|
sourceDomain = config.SourceDomain
|
|
sourcePassiveMode = config.SourcePassiveMode
|
|
sourceClientId = config.SourceClientID
|
|
sourceClientSecret = config.SourceClientSecret
|
|
sourceDriveId = config.SourceDriveID
|
|
sourceTeamDrive = config.SourceTeamDrive
|
|
|
|
filePattern = config.FilePattern
|
|
outputPattern = config.OutputPattern
|
|
|
|
destinationType = config.DestinationType
|
|
destinationPath = config.DestinationPath
|
|
destHost = config.DestHost
|
|
destPort = config.DestPort
|
|
destUser = config.DestUser
|
|
destPassword = config.DestPassword
|
|
destKeyFile = config.DestKeyFile
|
|
if destKeyFile != "" && destPassword == "" {
|
|
destAuthType = "key"
|
|
}
|
|
destBucket = config.DestBucket
|
|
destRegion = config.DestRegion
|
|
destAccessKey = config.DestAccessKey
|
|
destSecretKey = config.DestSecretKey
|
|
destEndpoint = config.DestEndpoint
|
|
destShare = config.DestShare
|
|
destDomain = config.DestDomain
|
|
destPassiveMode = config.DestPassiveMode
|
|
destClientId = config.DestClientID
|
|
destClientSecret = config.DestClientSecret
|
|
destDriveId = config.DestDriveID
|
|
destTeamDrive = config.DestTeamDrive
|
|
|
|
archivePath = config.ArchivePath
|
|
archiveEnabled = config.ArchiveEnabled
|
|
deleteAfterTransfer = config.DeleteAfterTransfer
|
|
skipProcessedFiles = config.GetSkipProcessedFiles()
|
|
maxConcurrentTransfers = config.MaxConcurrentTransfers
|
|
rcloneFlags = config.RcloneFlags
|
|
}
|
|
|
|
// Return the JSON-formatted string with all the data
|
|
return fmt.Sprintf(`{
|
|
name: '%s',
|
|
sourceType: '%s',
|
|
sourcePath: '%s',
|
|
sourceHost: '%s',
|
|
sourcePort: %d,
|
|
sourceUser: '%s',
|
|
sourcePassword: '%s',
|
|
sourceKeyFile: '%s',
|
|
sourceAuthType: '%s',
|
|
sourceBucket: '%s',
|
|
sourceRegion: '%s',
|
|
sourceAccessKey: '%s',
|
|
sourceSecretKey: '%s',
|
|
sourceEndpoint: '%s',
|
|
sourceShare: '%s',
|
|
sourceDomain: '%s',
|
|
sourcePassiveMode: %v,
|
|
sourceClientId: '%s',
|
|
sourceClientSecret: '%s',
|
|
sourceDriveId: '%s',
|
|
sourceTeamDrive: '%s',
|
|
|
|
filePattern: '%s',
|
|
outputPattern: '%s',
|
|
|
|
destinationType: '%s',
|
|
destinationPath: '%s',
|
|
destHost: '%s',
|
|
destPort: %d,
|
|
destUser: '%s',
|
|
destPassword: '%s',
|
|
destKeyFile: '%s',
|
|
destAuthType: '%s',
|
|
destBucket: '%s',
|
|
destRegion: '%s',
|
|
destAccessKey: '%s',
|
|
destSecretKey: '%s',
|
|
destEndpoint: '%s',
|
|
destShare: '%s',
|
|
destDomain: '%s',
|
|
destPassiveMode: %v,
|
|
destClientId: '%s',
|
|
destClientSecret: '%s',
|
|
destDriveId: '%s',
|
|
destTeamDrive: '%s',
|
|
|
|
archivePath: '%s',
|
|
archiveEnabled: %v,
|
|
deleteAfterTransfer: %v,
|
|
skipProcessedFiles: %v,
|
|
maxConcurrentTransfers: %d,
|
|
rcloneFlags: '%s',
|
|
}`,
|
|
name, sourceType, sourcePath, sourceHost, sourcePort, sourceUser, sourcePassword, sourceKeyFile, sourceAuthType,
|
|
sourceBucket, sourceRegion, sourceAccessKey, sourceSecretKey, sourceEndpoint, sourceShare, sourceDomain, sourcePassiveMode,
|
|
sourceClientId, sourceClientSecret, sourceDriveId, sourceTeamDrive,
|
|
filePattern, outputPattern,
|
|
destinationType, destinationPath, destHost, destPort, destUser, destPassword, destKeyFile, destAuthType,
|
|
destBucket, destRegion, destAccessKey, destSecretKey, destEndpoint, destShare, destDomain, destPassiveMode,
|
|
destClientId, destClientSecret, destDriveId, destTeamDrive,
|
|
archivePath, archiveEnabled, deleteAfterTransfer, skipProcessedFiles, maxConcurrentTransfers, rcloneFlags)
|
|
}
|
|
|
|
templ ConfigForm(ctx context.Context, data ConfigFormData) {
|
|
@LayoutWithContext(getConfigFormTitle(data.IsNew), ctx) {
|
|
<div class="flex flex-col items-center justify-center min-h-screen bg-gray-50 py-12 px-4 sm:px-6 lg:px-8">
|
|
<div class="max-w-3xl w-full bg-white rounded-lg shadow-md p-8">
|
|
<div class="flex justify-center mb-6">
|
|
<div class="p-4 bg-blue-100 rounded-full">
|
|
<i class="fas fa-cog text-blue-500 text-2xl"></i>
|
|
</div>
|
|
</div>
|
|
|
|
<h1 class="mt-2 text-center text-3xl font-extrabold text-gray-900">
|
|
{ getConfigFormTitle(data.IsNew) }
|
|
</h1>
|
|
<p class="mt-2 text-center text-sm text-gray-600">
|
|
Set up your file transfer configuration
|
|
</p>
|
|
|
|
<form
|
|
class="space-y-8"
|
|
if data.IsNew {
|
|
hx-post="/configs"
|
|
} else {
|
|
hx-post={ fmt.Sprintf("/configs/%d", data.Config.ID) }
|
|
}
|
|
hx-target="body"
|
|
hx-redirect="/configs"
|
|
hx-boost="true"
|
|
x-data={ getInitialData(data.Config) }
|
|
x-init="$nextTick(() => {
|
|
// Ensure initial form state displays correctly on load
|
|
sourceType = sourceType || 'local';
|
|
destinationType = destinationType || 'local';
|
|
sourcePort = sourcePort || 22;
|
|
destPort = destPort || 22;
|
|
})"
|
|
>
|
|
|
|
<!-- Name field -->
|
|
@common.NameField()
|
|
|
|
<!-- Source section -->
|
|
@common.SourceSelection()
|
|
|
|
<!-- Source type specific forms -->
|
|
<template x-if="sourceType === 'local'">
|
|
@source.LocalSourceForm()
|
|
</template>
|
|
|
|
<template x-if="sourceType === 'sftp'">
|
|
@source.SFTPSourceForm()
|
|
</template>
|
|
|
|
<template x-if="sourceType === 'ftp'">
|
|
@source.FTPSourceForm()
|
|
</template>
|
|
|
|
<template x-if="sourceType === 's3'">
|
|
@source.S3SourceForm()
|
|
</template>
|
|
|
|
<template x-if="sourceType === 'minio'">
|
|
@source.MinIOSourceForm()
|
|
</template>
|
|
|
|
<template x-if="sourceType === 'smb'">
|
|
@source.SMBSourceForm()
|
|
</template>
|
|
|
|
<template x-if="sourceType === 'webdav'">
|
|
@source.WebDAVSourceForm()
|
|
</template>
|
|
|
|
<template x-if="sourceType === 'nextcloud'">
|
|
@source.NextCloudSourceForm()
|
|
</template>
|
|
|
|
|
|
<!-- File pattern fields -->
|
|
@common.FilePatternFields()
|
|
|
|
<!-- Destination section -->
|
|
@common.DestinationSelection()
|
|
|
|
<!-- Destination type specific forms -->
|
|
<template x-if="destinationType === 'local'">
|
|
@destination.LocalDestinationForm()
|
|
</template>
|
|
|
|
<template x-if="destinationType === 'sftp'">
|
|
@destination.SFTPDestinationForm()
|
|
</template>
|
|
|
|
<template x-if="destinationType === 'ftp'">
|
|
@destination.FTPDestinationForm()
|
|
</template>
|
|
|
|
<template x-if="destinationType === 's3'">
|
|
@destination.S3DestinationForm()
|
|
</template>
|
|
|
|
<template x-if="destinationType === 'minio'">
|
|
@destination.MinIODestinationForm()
|
|
</template>
|
|
|
|
<template x-if="destinationType === 'smb'">
|
|
@destination.SMBDestinationForm()
|
|
</template>
|
|
|
|
<template x-if="destinationType === 'nextcloud'">
|
|
@destination.NextCloudDestinationForm()
|
|
</template>
|
|
|
|
<template x-if="destinationType === 'webdav'">
|
|
@destination.WebDAVDestinationForm()
|
|
</template>
|
|
|
|
|
|
<!-- Archive options -->
|
|
@common.ArchiveOptions()
|
|
|
|
<!-- Rclone flags -->
|
|
@common.RcloneFlags()
|
|
|
|
<!-- Form actions -->
|
|
<div class="flex justify-end mt-8">
|
|
<a href="/configs"
|
|
class="btn-secondary mr-4 px-6 py-3 rounded-lg flex items-center0">
|
|
Cancel
|
|
</a>
|
|
<button
|
|
type="submit"
|
|
class="btn-primary px-6 py-3 rounded-lg flex items-center"
|
|
>
|
|
<span class="flex items-center">
|
|
<template>
|
|
<i class="fas fa-save mr-2"></i>
|
|
</template>
|
|
if data.IsNew {
|
|
Create Configuration
|
|
} else {
|
|
Save Changes
|
|
}
|
|
</span>
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<div class="mt-6 text-center text-xs text-gray-500">
|
|
<p>Configure your file transfer settings carefully for optimal performance</p>
|
|
</div>
|
|
</div>
|
|
}
|
|
} |