feat: Implement command flag management for rclone configurations

- Added functionality to manage command flags and their values in the configuration form.
- Updated the database schema to include a new field for storing command flag values.
- Enhanced backend logic to process and store flag values for non-boolean flags during configuration creation and updates.
- Improved the user interface to dynamically require destination fields based on selected commands.
- Refactored related templates and handlers to support the new command flag management features.
This commit is contained in:
StarFleetCPTN committed 2025-03-23 20:30:02 -07:00
1 parent 0cebfcf1f5
commit 233f1779d8
20 files changed
+457 -239

No files matched your search

+179 -22
View File
@@ -160,6 +160,7 @@ templ RcloneFlags() {
<i class="fas fa-flag text-gray-400 dark:text-gray-500"></i>
</div>
<input type="text" name="rclone_flags" id="rclone_flags" x-model="rcloneFlags"
@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"
placeholder="--transfers 4 --checkers 8" />
</div>
@@ -198,8 +199,8 @@ templ SourceSelection() {
<option value="smb">SMB</option>
<option value="nextcloud">NextCloud</option>
<option value="webdav">WebDAV</option>
<option value="gdrive">Google Drive</option>
<option value="gphotos">Google Photos</option>
<option value="gdrive">Google Drive (BETA)</option>
<option value="gphotos">Google Photos (BETA)</option>
</select>
</div>
</div>
@@ -222,8 +223,8 @@ templ DestinationSelection() {
<option value="smb">SMB</option>
<option value="nextcloud">NextCloud</option>
<option value="webdav">WebDAV</option>
<option value="gdrive">Google Drive</option>
<option value="gphotos">Google Photos</option>
<option value="gdrive">Google Drive (BETA)</option>
<option value="gphotos">Google Photos (BETA)</option>
</select>
</div>
</div>
@@ -236,6 +237,7 @@ templ RcloneCommandOptionsContent(categoryMap map[string][]db.RcloneCommand, cat
hx-target="#command-flags-container"
hx-trigger="change"
hx-include="[name='command_id']"
@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>
for _, category := range categories {
@@ -266,33 +268,127 @@ templ RcloneCommandFlagsContent(command *db.RcloneCommand) {
<h5 class="font-medium text-gray-900 dark:text-white mb-2">Command Flags:</h5>
<div class="space-y-3">
for _, flag := range command.Flags {
<div class="flex items-start">
<input
type="checkbox"
id={ fmt.Sprintf("flag_%d", flag.ID) }
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"
/>
<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 }
</label>
if flag.DefaultValue != "" {
<p class="text-xs text-gray-500 dark:text-gray-400">Default: { flag.DefaultValue }</p>
}
if flag.DataType == "bool" {
<!-- Boolean flag (simple checkbox) -->
<div class="flex items-start mb-4">
<input
type="checkbox"
id={ fmt.Sprintf("flag_%d", flag.ID) }
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"
/>
<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 }
</label>
if flag.DefaultValue != "" {
<p class="text-xs text-gray-500 dark:text-gray-400">Default: { flag.DefaultValue }</p>
}
</div>
</div>
</div>
} else {
<!-- Non-boolean flag (requires value) -->
<div class="flex items-start mb-4 w-full">
<div class="w-full">
<div class="flex items-center mb-2">
<input
type="checkbox"
id={ fmt.Sprintf("flag_enable_%d", flag.ID) }
name={ fmt.Sprintf("flag_enable_%d", flag.ID) }
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)"
/>
<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)
if flag.DefaultValue != "" {
<p class="text-xs text-gray-500 dark:text-gray-400 mt-1">Default: { flag.DefaultValue }</p>
}
</div>
</div>
</div>
}
}
</div>
</div>
<!-- JavaScript to handle enabling/disabling flag value inputs -->
<script>
function toggleFlagValue(checkbox) {
const inputId = checkbox.getAttribute('data-input-id');
const input = document.getElementById(inputId);
if (input) {
input.disabled = !checkbox.checked;
if (checkbox.checked) {
// Focus on the input when enabled
input.focus();
}
// Also enable/disable the hidden input for flag ID
const hiddenId = inputId.replace('flag_value_', 'flag_hidden_');
const hiddenInput = document.getElementById(hiddenId);
if (hiddenInput) {
hiddenInput.disabled = !checkbox.checked;
console.log('Toggle hidden input:', hiddenId, checkbox.checked);
}
// For debugging
console.log('Toggle flag value:', inputId, checkbox.checked);
}
}
// 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;
}
}
});
});
</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">
<div class="flex items-center mb-1">
<i class="fas fa-info-circle mr-2"></i>
<span class="font-medium">Usage Example</span>
<span class="font-medium">Usage Examples</span>
</div>
<code class="block mt-1 font-mono text-xs overflow-x-auto">rclone { command.Name } [flags] source:path dest:path</code>
if command.Name == "ls" ||
command.Name == "lsd" ||
command.Name == "lsl" ||
command.Name == "lsjson" ||
command.Name == "lsf" ||
command.Name == "delete" ||
command.Name == "purge" ||
command.Name == "rmdirs" ||
command.Name == "mkdir" ||
command.Name == "touch" ||
command.Name == "md5sum" ||
command.Name == "sha1sum" ||
command.Name == "sha256sum" ||
command.Name == "size" ||
command.Name == "stat" ||
command.Name == "version" {
<code class="block mt-1 font-mono text-xs overflow-x-auto">rclone { command.Name } [flags] source:path</code>
} else {
<code class="block mt-1 font-mono text-xs overflow-x-auto">rclone { command.Name } [flags] source:path dest:path</code>
}
</div>
} else {
<div class="p-3 bg-gray-50 text-gray-600 rounded-lg border border-gray-200 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-700 text-sm">
@@ -303,4 +399,65 @@ templ RcloneCommandFlagsContent(command *db.RcloneCommand) {
</div>
}
</div>
}
// Helper function to render appropriate input based on flag data type
templ renderFlagInput(flag db.RcloneCommandFlag) {
if flag.DataType == "int" {
<input
type="number"
id={ fmt.Sprintf("flag_value_%d", flag.ID) }
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
/>
<!-- Hidden input to include this flag ID when checked -->
<input
type="hidden"
name="command_flags"
value={ fmt.Sprintf("%d", flag.ID) }
disabled
id={ fmt.Sprintf("flag_hidden_%d", flag.ID) }
data-enable-with={ fmt.Sprintf("flag_enable_%d", flag.ID) }
/>
} else if flag.DataType == "float" {
<input
type="number"
id={ fmt.Sprintf("flag_value_%d", flag.ID) }
name={ fmt.Sprintf("flag_value_%d", flag.ID) }
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
/>
<!-- Hidden input to include this flag ID when checked -->
<input
type="hidden"
name="command_flags"
value={ fmt.Sprintf("%d", flag.ID) }
disabled
id={ fmt.Sprintf("flag_hidden_%d", flag.ID) }
data-enable-with={ fmt.Sprintf("flag_enable_%d", flag.ID) }
/>
} else {
<!-- Default to text input for string and other types -->
<input
type="text"
id={ fmt.Sprintf("flag_value_%d", flag.ID) }
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
/>
<!-- Hidden input to include this flag ID when checked -->
<input
type="hidden"
name="command_flags"
value={ fmt.Sprintf("%d", flag.ID) }
disabled
id={ fmt.Sprintf("flag_hidden_%d", flag.ID) }
data-enable-with={ fmt.Sprintf("flag_enable_%d", flag.ID) }
/>
}
}
+4 -4
View File
@@ -8,7 +8,7 @@ templ FTPDestinationForm() {
<div class="absolute inset-y-0 start-0 flex items-center ps-3.5 pointer-events-none">
<i class="fas fa-server text-gray-400 dark:text-gray-500"></i>
</div>
<input type="text" id="dest_host" name="dest_host" x-model="destinationHost" required
<input type="text" id="dest_host" name="dest_host" x-model="destinationHost" x-bind:required="requiresDestination"
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="ftp.example.com" />
</div>
@@ -34,7 +34,7 @@ templ FTPDestinationForm() {
<div class="absolute inset-y-0 start-0 flex items-center ps-3.5 pointer-events-none">
<i class="fas fa-user text-gray-400 dark:text-gray-500"></i>
</div>
<input type="text" id="dest_user" name="dest_user" x-model="destinationUser" required
<input type="text" id="dest_user" name="dest_user" x-model="destinationUser" x-bind:required="requiresDestination"
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="username" />
</div>
@@ -47,7 +47,7 @@ templ FTPDestinationForm() {
<div class="absolute inset-y-0 start-0 flex items-center ps-3.5 pointer-events-none">
<i class="fas fa-lock text-gray-400 dark:text-gray-500"></i>
</div>
<input type="password" id="dest_password" name="dest_password" x-model="destinationPassword" required
<input type="password" id="dest_password" name="dest_password" x-model="destinationPassword" x-bind:required="requiresDestination"
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="Enter password" />
</div>
@@ -69,7 +69,7 @@ templ FTPDestinationForm() {
<div class="absolute inset-y-0 start-0 flex items-center ps-3.5 pointer-events-none">
<i class="fas fa-folder-open text-gray-400 dark:text-gray-500"></i>
</div>
<input type="text" id="destination_path" name="destination_path" x-model="destinationPath" required
<input type="text" id="destination_path" name="destination_path" x-model="destinationPath" x-bind:required="requiresDestination"
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="/remote/path/to/files" />
</div>
+7 -7
View File
@@ -8,29 +8,29 @@ templ LocalDestinationForm() {
<div class="absolute inset-y-0 start-0 flex items-center ps-3.5 pointer-events-none">
<i class="fas fa-folder-open text-gray-400 dark:text-gray-500"></i>
</div>
<input type="text" id="destination_path" name="destination_path" x-model="destinationPath" required
:class="{ 'border-red-500 dark:border-red-700': destinationPathValid === false, 'border-green-500 dark:border-green-700': destinationPathValid === true }"
<input type="text" id="destination_path" name="destination_path" x-model="destinationPath" x-bind:required="requiresDestination"
:class="{ 'border-red-500 dark:border-red-700': destPathValid === false, 'border-green-500 dark:border-green-700': destPathValid === true }"
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="/path/to/files" />
</div>
<p class="mt-2 text-sm text-gray-500 dark:text-gray-400">Full path to the local directory containing your files</p>
<div x-show="destinationPathValid === false" class="mt-2 text-sm text-red-600 dark:text-red-400">
<div x-show="destPathValid === false" class="mt-2 text-sm text-red-600 dark:text-red-400">
<div class="flex items-center">
<i class="fas fa-exclamation-circle mr-2"></i>
<span x-text="destinationPathError"></span>
<span x-text="destPathError"></span>
</div>
</div>
<div x-show="destinationPathValid === true" class="mt-2 text-sm text-green-600 dark:text-green-400">
<div x-show="destPathValid === true" class="mt-2 text-sm text-green-600 dark:text-green-400">
<div class="flex items-center">
<i class="fas fa-check-circle mr-2"></i>
<span x-text="destinationPathError || 'Path is valid'"></span>
<span x-text="destPathError || 'Path is valid'"></span>
</div>
</div>
</div>
<button
type="button"
class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800"
@click="checkPath(destinationPath, 'destination')"
@click="checkPath(destinationPath, 'dest')"
>
<svg class="w-4 h-4 mr-2 inline" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 10a3 3 0 1 0 0-6 3 3 0 0 0 0 6Zm-6.5 4.5A5.5 5.5 0 0 1 9 9h2a5.5 5.5 0 0 1 5.5 5.5V17a1 1 0 0 1-1 1h-11a1 1 0 0 1-1-1v-2.5Z"/>
+4 -4
View File
@@ -15,7 +15,7 @@ templ MinIODestinationForm() {
<div class="absolute inset-y-0 start-0 flex items-center ps-3.5 pointer-events-none">
<i class="fas fa-server text-gray-400 dark:text-gray-500"></i>
</div>
<input type="text" id="dest_endpoint" name="dest_endpoint" x-model="destinationEndpoint" required
<input type="text" id="dest_endpoint" name="dest_endpoint" x-model="destinationEndpoint" x-bind:required="requiresDestination"
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="https://minio.example.com" />
</div>
@@ -30,7 +30,7 @@ templ MinIODestinationForm() {
<div class="absolute inset-y-0 start-0 flex items-center ps-3.5 pointer-events-none">
<i class="fas fa-archive text-gray-400 dark:text-gray-500"></i>
</div>
<input type="text" id="dest_bucket" name="dest_bucket" x-model="destinationBucket" required
<input type="text" id="dest_bucket" name="dest_bucket" x-model="destinationBucket" x-bind:required="requiresDestination"
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="my-bucket" />
</div>
@@ -45,7 +45,7 @@ templ MinIODestinationForm() {
<div class="absolute inset-y-0 start-0 flex items-center ps-3.5 pointer-events-none">
<i class="fas fa-key text-gray-400 dark:text-gray-500"></i>
</div>
<input type="text" id="dest_access_key" name="dest_access_key" x-model="destinationAccessKey" required
<input type="text" id="dest_access_key" name="dest_access_key" x-model="destinationAccessKey" x-bind:required="requiresDestination"
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="minioadmin" />
</div>
@@ -60,7 +60,7 @@ templ MinIODestinationForm() {
<div class="absolute inset-y-0 start-0 flex items-center ps-3.5 pointer-events-none">
<i class="fas fa-lock text-gray-400 dark:text-gray-500"></i>
</div>
<input type="password" id="dest_secret_key" name="dest_secret_key" x-model="destinationSecretKey" required
<input type="password" id="dest_secret_key" name="dest_secret_key" x-model="destinationSecretKey" x-bind:required="requiresDestination"
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="minioadmin" />
</div>
@@ -15,7 +15,7 @@ templ NextCloudDestinationForm() {
<div class="absolute inset-y-0 start-0 flex items-center ps-3.5 pointer-events-none">
<i class="fas fa-cloud text-gray-400 dark:text-gray-500"></i>
</div>
<input type="text" id="dest_endpoint" name="dest_endpoint" x-model="destinationEndpoint" required
<input type="text" id="dest_endpoint" name="dest_endpoint" x-model="destinationEndpoint" x-bind:required="requiresDestination"
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="https://nextcloud.example.com" />
</div>
@@ -30,7 +30,7 @@ templ NextCloudDestinationForm() {
<div class="absolute inset-y-0 start-0 flex items-center ps-3.5 pointer-events-none">
<i class="fas fa-user text-gray-400 dark:text-gray-500"></i>
</div>
<input type="text" id="dest_user" name="dest_user" x-model="destinationUser" required
<input type="text" id="dest_user" name="dest_user" x-model="destinationUser" x-bind:required="requiresDestination"
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="nextcloud_username" />
</div>
@@ -45,7 +45,7 @@ templ NextCloudDestinationForm() {
<div class="absolute inset-y-0 start-0 flex items-center ps-3.5 pointer-events-none">
<i class="fas fa-lock text-gray-400 dark:text-gray-500"></i>
</div>
<input type="password" id="dest_password" name="dest_password" x-model="destinationPassword" required
<input type="password" id="dest_password" name="dest_password" x-model="destinationPassword" x-bind:required="requiresDestination"
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="NextCloud password" />
</div>
@@ -60,7 +60,7 @@ templ NextCloudDestinationForm() {
<div class="absolute inset-y-0 start-0 flex items-center ps-3.5 pointer-events-none">
<i class="fas fa-folder-open text-gray-400 dark:text-gray-500"></i>
</div>
<input type="text" id="destination_path" name="destination_path" x-model="destinationPath" required
<input type="text" id="destination_path" name="destination_path" x-model="destinationPath" x-bind:required="requiresDestination"
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="remote.php/dav/files/username/path/to/files" />
</div>
+4 -4
View File
@@ -15,7 +15,7 @@ templ S3DestinationForm() {
<div class="absolute inset-y-0 start-0 flex items-center ps-3.5 pointer-events-none">
<i class="fas fa-globe text-gray-400 dark:text-gray-500"></i>
</div>
<input type="text" id="dest_region" name="dest_region" x-model="destinationRegion" required
<input type="text" id="dest_region" name="dest_region" x-model="destinationRegion" x-bind:required="requiresDestination"
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>
@@ -30,7 +30,7 @@ templ S3DestinationForm() {
<div class="absolute inset-y-0 start-0 flex items-center ps-3.5 pointer-events-none">
<i class="fas fa-archive text-gray-400 dark:text-gray-500"></i>
</div>
<input type="text" id="dest_bucket" name="dest_bucket" x-model="destinationBucket" required
<input type="text" id="dest_bucket" name="dest_bucket" x-model="destinationBucket" x-bind:required="requiresDestination"
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="my-bucket" />
</div>
@@ -45,7 +45,7 @@ templ S3DestinationForm() {
<div class="absolute inset-y-0 start-0 flex items-center ps-3.5 pointer-events-none">
<i class="fas fa-key text-gray-400 dark:text-gray-500"></i>
</div>
<input type="text" id="dest_access_key" name="dest_access_key" x-model="destinationAccessKey" required
<input type="text" id="dest_access_key" name="dest_access_key" x-model="destinationAccessKey" x-bind:required="requiresDestination"
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="AKIAIOSFODNN7EXAMPLE" />
</div>
@@ -60,7 +60,7 @@ templ S3DestinationForm() {
<div class="absolute inset-y-0 start-0 flex items-center ps-3.5 pointer-events-none">
<i class="fas fa-lock text-gray-400 dark:text-gray-500"></i>
</div>
<input type="password" id="dest_secret_key" name="dest_secret_key" x-model="destinationSecretKey" required
<input type="password" id="dest_secret_key" name="dest_secret_key" x-model="destinationSecretKey" x-bind:required="requiresDestination"
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="wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" />
</div>
+3 -3
View File
@@ -8,7 +8,7 @@ templ SFTPDestinationForm() {
<div class="absolute inset-y-0 start-0 flex items-center ps-3.5 pointer-events-none">
<i class="fas fa-server text-gray-400 dark:text-gray-500"></i>
</div>
<input type="text" id="dest_host" name="dest_host" x-model="destinationHost" required
<input type="text" id="dest_host" name="dest_host" x-model="destinationHost" x-bind:required="requiresDestination"
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="sftp.example.com" />
</div>
@@ -34,7 +34,7 @@ templ SFTPDestinationForm() {
<div class="absolute inset-y-0 start-0 flex items-center ps-3.5 pointer-events-none">
<i class="fas fa-user text-gray-400 dark:text-gray-500"></i>
</div>
<input type="text" id="dest_user" name="dest_user" x-model="destinationUser" required
<input type="text" id="dest_user" name="dest_user" x-model="destinationUser" x-bind:required="requiresDestination"
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="username" />
</div>
@@ -87,7 +87,7 @@ templ SFTPDestinationForm() {
<div class="absolute inset-y-0 start-0 flex items-center ps-3.5 pointer-events-none">
<i class="fas fa-folder-open text-gray-400 dark:text-gray-500"></i>
</div>
<input type="text" id="destination_path" name="destination_path" x-model="destinationPath" required
<input type="text" id="destination_path" name="destination_path" x-model="destinationPath" x-bind:required="requiresDestination"
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="/remote/path/to/files" />
</div>
+4 -4
View File
@@ -15,7 +15,7 @@ templ SMBDestinationForm() {
<div class="absolute inset-y-0 start-0 flex items-center ps-3.5 pointer-events-none">
<i class="fas fa-server text-gray-400 dark:text-gray-500"></i>
</div>
<input type="text" id="dest_host" name="dest_host" x-model="destinationHost" required
<input type="text" id="dest_host" name="dest_host" x-model="destinationHost" x-bind:required="requiresDestination"
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="192.168.1.100 or server.example.com" />
</div>
@@ -30,7 +30,7 @@ templ SMBDestinationForm() {
<div class="absolute inset-y-0 start-0 flex items-center ps-3.5 pointer-events-none">
<i class="fas fa-share-alt text-gray-400 dark:text-gray-500"></i>
</div>
<input type="text" id="dest_share" name="dest_share" x-model="destinationShare" required
<input type="text" id="dest_share" name="dest_share" x-model="destinationShare" x-bind:required="requiresDestination"
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="Documents" />
</div>
@@ -60,7 +60,7 @@ templ SMBDestinationForm() {
<div class="absolute inset-y-0 start-0 flex items-center ps-3.5 pointer-events-none">
<i class="fas fa-user text-gray-400 dark:text-gray-500"></i>
</div>
<input type="text" id="dest_user" name="dest_user" x-model="destinationUser" required
<input type="text" id="dest_user" name="dest_user" x-model="destinationUser" x-bind:required="requiresDestination"
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="smb_username" />
</div>
@@ -75,7 +75,7 @@ templ SMBDestinationForm() {
<div class="absolute inset-y-0 start-0 flex items-center ps-3.5 pointer-events-none">
<i class="fas fa-lock text-gray-400 dark:text-gray-500"></i>
</div>
<input type="password" id="dest_password" name="dest_password" x-model="destinationPassword" required
<input type="password" id="dest_password" name="dest_password" x-model="destinationPassword" x-bind:required="requiresDestination"
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="SMB password" />
</div>
@@ -15,7 +15,7 @@ templ WebDAVDestinationForm() {
<div class="absolute inset-y-0 start-0 flex items-center ps-3.5 pointer-events-none">
<i class="fas fa-globe text-gray-400 dark:text-gray-500"></i>
</div>
<input type="text" id="dest_endpoint" name="dest_endpoint" x-model="destinationEndpoint" required
<input type="text" id="dest_endpoint" name="dest_endpoint" x-model="destinationEndpoint" x-bind:required="requiresDestination"
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="https://webdav.example.com" />
</div>
@@ -30,7 +30,7 @@ templ WebDAVDestinationForm() {
<div class="absolute inset-y-0 start-0 flex items-center ps-3.5 pointer-events-none">
<i class="fas fa-user text-gray-400 dark:text-gray-500"></i>
</div>
<input type="text" id="dest_user" name="dest_user" x-model="destinationUser" required
<input type="text" id="dest_user" name="dest_user" x-model="destinationUser" x-bind:required="requiresDestination"
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="webdav_username" />
</div>
@@ -45,7 +45,7 @@ templ WebDAVDestinationForm() {
<div class="absolute inset-y-0 start-0 flex items-center ps-3.5 pointer-events-none">
<i class="fas fa-lock text-gray-400 dark:text-gray-500"></i>
</div>
<input type="password" id="dest_password" name="dest_password" x-model="destinationPassword" required
<input type="password" id="dest_password" name="dest_password" x-model="destinationPassword" x-bind:required="requiresDestination"
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="WebDAV password" />
</div>