file manager popup rework

This commit is contained in:
2026-07-27 09:30:09 +02:00
parent a9d6cedd1e
commit 1e9132f240
3 changed files with 68 additions and 9 deletions
+7 -2
View File
@@ -13,11 +13,16 @@ ActiveAdmin.register_page "Files" do
entries = []
end
# Picker mode: hide admin header/menu/footer
if picker_mode
text_node '<style>#header,#tabs,.footer,#title_bar,#utility_nav{display:none!important}#active_admin_content{margin:0;padding:0}#wrapper{margin:0}body{min-height:auto}</style>'.html_safe
end
div class: "file-manager" do
h2 do
text_node "File Manager"
if picker_mode
span " (Select a file)", style: "font-size:14px; color:#888; font-weight:normal;"
span " — select a file or folder", style: "font-size:14px; color:#888; font-weight:normal;"
end
end
@@ -117,7 +122,7 @@ ActiveAdmin.register_page "Files" do
text_node " "
abs_path = "/softwares/#{entry[:path]}"
a "Select", href: "#", class: "fm-btn fm-btn-select",
onclick: "window.opener.postMessage({type:'file-picked',field:'#{j picker_field}',path:'#{j abs_path}'},'*');window.close();return false;"
onclick: "window.parent.postMessage({type:'file-picked',field:'#{j picker_field}',path:'#{j abs_path}'},'*');return false;"
end
# Hidden rename form
@@ -14,17 +14,54 @@
btn.className = 'fm-browse-btn';
btn.addEventListener('click', function(e) {
e.preventDefault();
window.open(
'/admin/files?picker=1&field=' + encodeURIComponent(input.id),
'file_picker',
'width=960,height=640,scrollbars=yes,resizable=yes'
);
openFilePicker(input.id);
});
input.parentNode.insertBefore(btn, input.nextSibling);
});
});
}
function openFilePicker(fieldId) {
// Backdrop
var overlay = document.createElement('div');
overlay.className = 'fm-modal-overlay';
overlay.addEventListener('click', function(e) {
if (e.target === overlay) closeFilePicker();
});
// Modal container
var modal = document.createElement('div');
modal.className = 'fm-modal';
// Close button
var closeBtn = document.createElement('button');
closeBtn.className = 'fm-modal-close';
closeBtn.innerHTML = '&times;';
closeBtn.addEventListener('click', closeFilePicker);
modal.appendChild(closeBtn);
// Iframe
var iframe = document.createElement('iframe');
iframe.src = '/admin/files?picker=1&field=' + encodeURIComponent(fieldId);
iframe.className = 'fm-modal-iframe';
modal.appendChild(iframe);
overlay.appendChild(modal);
document.body.appendChild(overlay);
document.body.style.overflow = 'hidden';
window._fmOverlay = overlay;
}
function closeFilePicker() {
if (window._fmOverlay) {
window._fmOverlay.remove();
window._fmOverlay = null;
document.body.style.overflow = '';
}
}
// Listen for file selection from iframe
window.addEventListener('message', function(event) {
if (event.data && event.data.type === 'file-picked') {
var input = document.getElementById(event.data.field);
@@ -32,6 +69,7 @@
input.value = event.data.path;
input.dispatchEvent(new Event('change', { bubbles: true }));
}
closeFilePicker();
}
});
@@ -29,6 +29,22 @@
// Browse button in release forms
.fm-browse-btn {
display: inline-block; margin-left: 8px; padding: 4px 10px; background: #6c757d; color: #fff; border-radius: 3px; font-size: 11px; text-decoration: none; vertical-align: middle;
&:hover { background: #5a6268; color: #fff; }
display: inline-block; margin-left: 8px; padding: 4px 10px; background: #6c757d; color: #fff !important; border-radius: 3px; font-size: 11px; text-decoration: none !important; vertical-align: middle;
&:hover { background: #5a6268; color: #fff !important; }
&:visited { color: #fff !important; }
}
// Inline file picker modal
.fm-modal-overlay {
position: fixed; inset: 0; z-index: 9999; background: rgba(0,0,0,0.6); display: flex; align-items: center; justify-content: center;
}
.fm-modal {
position: relative; width: 90vw; max-width: 1000px; height: 80vh; background: #fff; border-radius: 8px; box-shadow: 0 20px 60px rgba(0,0,0,0.3); overflow: hidden;
}
.fm-modal-close {
position: absolute; top: 8px; right: 12px; z-index: 10; background: none; border: none; font-size: 28px; color: #666; cursor: pointer; line-height: 1;
&:hover { color: #000; }
}
.fm-modal-iframe {
width: 100%; height: 100%; border: none;
}