diff --git a/components/storage_providers_import.templ b/components/storage_providers_import.templ index 5d9cd68..3ca67da 100644 --- a/components/storage_providers_import.templ +++ b/components/storage_providers_import.templ @@ -27,9 +27,93 @@ templ StorageProvidersImport(ctx context.Context, preview RcloneImportPreview) {
+

Import from rclone Config

- Upload your rclone configuration file to import storage providers. You'll be able to preview and select which remotes to import. + Upload your rclone configuration file to import storage providers. You'll be able to preview and select which remotes to import, and add any missing credentials.

+ + + +
@@ -98,12 +182,82 @@ templ RcloneImportPreviewContent(ctx context.Context, preview RcloneImportPrevie
+ for k, v := range remote.Fields {
{k}:
} + + +
+
Add or Update Credentials
+ + + if _, exists := remote.Fields["user"]; !exists && (remote.Type == "sftp" || remote.Type == "ftp" || remote.Type == "smb" || remote.Type == "webdav") { +
+ user: + +
+ } + + + if _, exists := remote.Fields["pass"]; !exists && (remote.Type == "sftp" || remote.Type == "ftp" || remote.Type == "smb" || remote.Type == "webdav") { +
+ pass: + +
+ } + + + if remote.Type == "s3" || remote.Type == "wasabi" || remote.Type == "minio" || remote.Type == "b2" { + + if _, exists := remote.Fields["access_key_id"]; !exists { +
+ access_key_id: + +
+ } + + + if _, exists := remote.Fields["secret_access_key"]; !exists { +
+ secret_access_key: + +
+ } + } + + + if remote.Type == "drive" || remote.Type == "onedrive" || remote.Type == "gphotos" { + + if _, exists := remote.Fields["client_id"]; !exists { +
+ client_id: + +
+ } + + + if _, exists := remote.Fields["client_secret"]; !exists { +
+ client_secret: + +
+ } + } + + +
+ +
+ + +
+
@@ -126,13 +280,150 @@ templ RcloneImportPreviewContent(ctx context.Context, preview RcloneImportPrevie
+ } + + function addCustomField(remoteName) { + console.log('Adding custom field for remote:', remoteName); + const container = document.getElementById('custom-fields-' + remoteName); + if (!container) { + console.error('Container not found for remote:', remoteName); + return; + } + + const fieldCount = container.children.length; + const fieldId = 'custom-field-' + remoteName + '-' + fieldCount; + + const fieldRow = document.createElement('div'); + fieldRow.className = 'flex items-center gap-2 mt-2'; + fieldRow.id = fieldId; + + // Create key input + const keyInput = document.createElement('input'); + keyInput.type = 'text'; + keyInput.className = 'bg-gray-50 border border-gray-300 text-gray-900 text-xs rounded-lg focus:ring-blue-500 focus:border-blue-500 w-1/3 p-1.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'; + keyInput.placeholder = 'Field name'; + keyInput.id = 'custom-key-' + remoteName + '-' + fieldCount; + keyInput.onchange = function() { + const valueInput = document.getElementById('custom-value-' + remoteName + '-' + fieldCount); + if (valueInput && this.value) { + valueInput.name = 'field_' + remoteName + '_' + this.value; + } + }; + + // Create value input + const valueInput = document.createElement('input'); + valueInput.type = 'text'; + valueInput.className = 'bg-gray-50 border border-gray-300 text-gray-900 text-xs rounded-lg focus:ring-blue-500 focus:border-blue-500 w-2/3 p-1.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'; + valueInput.placeholder = 'Value'; + valueInput.id = 'custom-value-' + remoteName + '-' + fieldCount; + // Name will be set when key changes + + // Create remove button + const removeBtn = document.createElement('button'); + removeBtn.type = 'button'; + removeBtn.className = 'text-red-500 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300'; + removeBtn.innerHTML = ''; + removeBtn.onclick = function() { + document.getElementById(fieldId).remove(); + }; + + // Add elements to the row + fieldRow.appendChild(keyInput); + fieldRow.appendChild(valueInput); + fieldRow.appendChild(removeBtn); + + // Add row to container + container.appendChild(fieldRow); + + // Focus on the new key input + keyInput.focus(); + } + + // Initialize the buttons directly instead of using DOMContentLoaded + function initializeCustomFieldButtons() { + console.log('Initializing custom field buttons'); + const addFieldButtons = document.querySelectorAll('[id^="add-field-btn-"]'); + console.log('Found buttons:', addFieldButtons.length); + + // Add click event listeners to each button + addFieldButtons.forEach(function(button) { + const remoteName = button.id.replace('add-field-btn-', ''); + console.log('Adding listener for remote:', remoteName); + button.addEventListener('click', function() { + console.log('Button clicked for remote:', remoteName); + addCustomField(remoteName); + }); + }); + } + + // Try both approaches for maximum compatibility + // 1. Initialize immediately if document is already loaded + if (document.readyState === 'complete' || document.readyState === 'interactive') { + setTimeout(initializeCustomFieldButtons, 1); + } + + // 2. Also listen for DOMContentLoaded + document.addEventListener('DOMContentLoaded', initializeCustomFieldButtons); + + // 3. Also initialize when the form is loaded via HTMX + document.addEventListener('htmx:afterSwap', function(event) { + if (event.detail.target.id === 'import-preview') { + console.log('HTMX content loaded, initializing buttons'); + setTimeout(initializeCustomFieldButtons, 1); + } + }); + + // 4. Toggle common values reference + function initializeReferenceToggle() { + console.log('Initializing reference toggle buttons'); + const showBtn = document.getElementById('show-common-values'); + const hideBtn = document.getElementById('hide-common-values'); + const reference = document.getElementById('common-values-reference'); + + if (showBtn && hideBtn && reference) { + console.log('Found reference toggle elements'); + // Remove any existing listeners to prevent duplicates + showBtn.removeEventListener('click', showReference); + hideBtn.removeEventListener('click', hideReference); + + // Add new listeners + showBtn.addEventListener('click', showReference); + hideBtn.addEventListener('click', hideReference); + + // Define the functions + function showReference() { + console.log('Showing reference'); + reference.classList.remove('hidden'); + } + + function hideReference() { + console.log('Hiding reference'); + reference.classList.add('hidden'); + } + } else { + console.log('Reference toggle elements not found'); + } + } + + // Initialize on DOMContentLoaded + document.addEventListener('DOMContentLoaded', initializeReferenceToggle); + + // Also initialize on page load + if (document.readyState === 'complete' || document.readyState === 'interactive') { + setTimeout(initializeReferenceToggle, 1); + } + + // Also initialize when content is loaded via HTMX + document.addEventListener('htmx:afterSwap', function(event) { + console.log('HTMX content swapped, target:', event.detail.target.id); + setTimeout(initializeReferenceToggle, 1); + }); +
} else {