feat(bi): add scrollable modal with fixed header/footer for cost config

Enhanced modal UX with proper scroll handling:

1. Modal Structure:
   - Fixed header (title + description)
   - Scrollable content area (form fields)
   - Fixed footer (Cancel + Save buttons)

2. Flexbox Layout:
   - Container: flex flex-col max-height 90vh
   - Header/Footer: flex-shrink-0 (stays visible)
   - Content: flex-1 overflow-y-auto (scrolls)

3. Custom Purple Scrollbar:
   - WebKit (Chrome/Safari/Edge): 8px width, purple thumb
   - Firefox: thin scrollbar, purple color scheme
   - Matches Tractatus theme (#9333ea purple)

4. Responsive Height:
   - Modal max 90vh ensures it fits any screen
   - Content area scrolls when form is tall
   - Header/footer always visible for context

Users can now scroll through all 4 severity configurations while
always seeing the modal title and action buttons.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
TheFlow 2025-10-27 11:27:15 +13:00
parent 0931a2125b
commit 39ec39f175

View file

@ -969,15 +969,15 @@ async function showCostConfigModal() {
};
const modal = document.createElement('div');
modal.className = 'fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50';
modal.className = 'fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4';
modal.innerHTML = `
<div class="bg-white rounded-lg shadow-xl max-w-2xl w-full mx-4 max-h-screen overflow-y-auto">
<div class="p-6 border-b border-gray-200">
<div class="bg-white rounded-lg shadow-xl max-w-2xl w-full flex flex-col modal-container">
<div class="p-6 border-b border-gray-200 flex-shrink-0">
<h3 class="text-xl font-bold text-gray-900">Configure Cost Factors</h3>
<p class="text-sm text-gray-600 mt-1">Set organizational cost values for different violation severities</p>
</div>
<div class="p-6 space-y-4">
<div class="p-6 space-y-4 overflow-y-auto flex-1 modal-content">
${['CRITICAL', 'HIGH', 'MEDIUM', 'LOW'].map(severity => {
const config = sliderConfig[severity];
const amount = Math.min(Math.max(costFactors[severity].amount, config.min), config.max);
@ -1030,7 +1030,7 @@ async function showCostConfigModal() {
</div>
</div>
<div class="p-6 border-t border-gray-200 flex justify-end space-x-3">
<div class="p-6 border-t border-gray-200 flex justify-end space-x-3 flex-shrink-0">
<button id="cancel-config-btn" class="px-4 py-2 border border-gray-300 rounded-lg text-gray-700 hover:bg-gray-50">
Cancel
</button>
@ -1041,6 +1041,35 @@ async function showCostConfigModal() {
</div>
<style>
/* Modal container styling */
.modal-container {
max-height: 90vh;
}
/* Modal content scrollbar styling */
.modal-content {
scrollbar-width: thin;
scrollbar-color: #9333ea #e9d5ff;
}
.modal-content::-webkit-scrollbar {
width: 8px;
}
.modal-content::-webkit-scrollbar-track {
background: #e9d5ff;
border-radius: 4px;
}
.modal-content::-webkit-scrollbar-thumb {
background: #9333ea;
border-radius: 4px;
}
.modal-content::-webkit-scrollbar-thumb:hover {
background: #7e22ce;
}
/* Custom slider styling */
.slider {
-webkit-appearance: none;