diff --git a/assets/pasted-20260201-034855-b2075578.png b/assets/pasted-20260201-034855-b2075578.png new file mode 100644 index 0000000..a6282bc Binary files /dev/null and b/assets/pasted-20260201-034855-b2075578.png differ diff --git a/assets/vm-shot-2026-02-01T03-47-53-669Z.jpg b/assets/vm-shot-2026-02-01T03-47-53-669Z.jpg new file mode 100644 index 0000000..2984fa1 Binary files /dev/null and b/assets/vm-shot-2026-02-01T03-47-53-669Z.jpg differ diff --git a/assets/vm-shot-2026-02-01T03-48-00-010Z.jpg b/assets/vm-shot-2026-02-01T03-48-00-010Z.jpg new file mode 100644 index 0000000..2984fa1 Binary files /dev/null and b/assets/vm-shot-2026-02-01T03-48-00-010Z.jpg differ diff --git a/config/__pycache__/settings.cpython-311.pyc b/config/__pycache__/settings.cpython-311.pyc index 93d1415..a6dee05 100644 Binary files a/config/__pycache__/settings.cpython-311.pyc and b/config/__pycache__/settings.cpython-311.pyc differ diff --git a/core/__pycache__/admin.cpython-311.pyc b/core/__pycache__/admin.cpython-311.pyc index 2701d72..a2adaf4 100644 Binary files a/core/__pycache__/admin.cpython-311.pyc and b/core/__pycache__/admin.cpython-311.pyc differ diff --git a/core/__pycache__/models.cpython-311.pyc b/core/__pycache__/models.cpython-311.pyc index b11287a..6cd1cb2 100644 Binary files a/core/__pycache__/models.cpython-311.pyc and b/core/__pycache__/models.cpython-311.pyc differ diff --git a/core/__pycache__/serializers.cpython-311.pyc b/core/__pycache__/serializers.cpython-311.pyc index c2e22d3..c4acfad 100644 Binary files a/core/__pycache__/serializers.cpython-311.pyc and b/core/__pycache__/serializers.cpython-311.pyc differ diff --git a/staticfiles/css/custom.css b/staticfiles/css/custom.css index 0749166..b3c7f4b 100644 --- a/staticfiles/css/custom.css +++ b/staticfiles/css/custom.css @@ -177,4 +177,39 @@ body.model-platformprofile label[for="id_admin_panel_logo"] { .form-row { padding: 15px 10px; border-bottom: 1px solid #f0f0f0; +} + +/* --- Fix Admin Search Box Layout --- */ + +/* Target the search form container in Jazzmin/AdminLTE */ +#changelist-search, +#changelist-search .form-group, +#changelist-search .input-group { + display: flex !important; + align-items: center !important; + flex-wrap: nowrap !important; /* Prevent wrapping */ + max-width: 400px !important; /* Reduce the overall width */ +} + +/* Make the input field take available space but respect the container width */ +#changelist-search input[type="text"] { + width: auto !important; + flex-grow: 1 !important; + margin-right: 8px !important; /* Space between input and button */ +} + +/* Fix for RTL */ +[dir="rtl"] #changelist-search input[type="text"] { + margin-right: 0 !important; + margin-left: 8px !important; +} + +/* Ensure the button stays inline and overrides any block behavior */ +#changelist-search button[type="submit"], +#changelist-search .btn { + margin-top: 0 !important; + margin-bottom: 0 !important; + white-space: nowrap !important; + width: auto !important; + height: auto !important; } \ No newline at end of file diff --git a/staticfiles/js/admin_date_range_dropdown.js b/staticfiles/js/admin_date_range_dropdown.js new file mode 100644 index 0000000..80b92ae --- /dev/null +++ b/staticfiles/js/admin_date_range_dropdown.js @@ -0,0 +1,135 @@ +(function($) { + $(document).ready(function() { + // Helper to format date as YYYY-MM-DD + function formatDate(d) { + var year = d.getFullYear(); + var month = ('0' + (d.getMonth() + 1)).slice(-2); + var day = ('0' + d.getDate()).slice(-2); + return year + '-' + month + '-' + day; + } + + function initDateRangeDropdown() { + // Find start date inputs for 'created_at' (or generic generic approach for any range filter) + // rangefilter inputs typically have names ending in __gte and __lte + var $gteInputs = $('input[name$="__gte"]'); + + $gteInputs.each(function() { + var $gte = $(this); + var name = $gte.attr('name'); + var prefix = name.substring(0, name.lastIndexOf('__gte')); + var $lte = $('input[name="' + prefix + '__lte"]'); + + if ($lte.length === 0) return; // Not a pair + + // Find a container to inject the dropdown. + // In Jazzmin/Standard, this might be inside a .admindatefilter div, + // or just a li, or a div.controls. + // We'll look for the closest container that seems to wrap the filter. + + // Try to find .admindatefilter first + var $container = $gte.closest('.admindatefilter'); + if ($container.length === 0) { + // Fallback for Jazzmin or other themes: closest .card-body or similar? + // Or just the parent form/div + $container = $gte.closest('div[data-filter-name], li, .form-row, .card-body'); + } + + if ($container.length === 0) $container = $gte.parent(); + + if ($container.data('dropdown-init')) return; + $container.data('dropdown-init', true); + + // Hide the original inputs/controls container + // We need to be careful not to hide the form itself if it's the main filter form + // Usually rangefilter puts inputs in a 'controls' div or paragraphs. + var $controls = $gte.closest('.controls'); + if ($controls.length === 0) { + // Try to find the immediate parent if it contains both inputs + $controls = $gte.parent(); + } + + // Create Select + var $select = $(''); + + // Inject before the controls (inputs) + if ($controls.length) { + $controls.before($select); + } else { + $gte.before($select); + } + + // Initial State + var gteVal = $gte.val(); + var lteVal = $lte.val(); + + if (gteVal || lteVal) { + $select.val('custom'); + $controls.show(); + } else { + $select.val('any'); + $controls.hide(); + } + + $select.on('change', function() { + var val = $(this).val(); + var today = new Date(); + + if (val === 'custom') { + $controls.slideDown(); + } else { + if (val === 'any') { + $gte.val(''); + $lte.val(''); + } else { + var startStr = ''; + var endStr = formatDate(today); + + if (val === 'today') { + startStr = formatDate(today); + } else if (val === '7days') { + var past = new Date(); + past.setDate(today.getDate() - 7); + startStr = formatDate(past); + } else if (val === 'month') { + var firstDay = new Date(today.getFullYear(), today.getMonth(), 1); + startStr = formatDate(firstDay); + } else if (val === 'year') { + var firstDay = new Date(today.getFullYear(), 0, 1); + startStr = formatDate(firstDay); + } + + $gte.val(startStr); + $lte.val(endStr); + } + + // Submit form + // In Jazzmin, the filter form might be #changelist-search or similiar + var $form = $gte.closest('form'); + if ($form.length) { + $form.submit(); + } else { + // Try to find a global apply button or trigger change? + // Some admin themes auto-submit on change. + // rangefilter usually has a submit button. + var $btn = $container.find('input[type="submit"], button[type="submit"]'); + if ($btn.length) $btn.click(); + } + } + }); + }); + } + + // Run init + initDateRangeDropdown(); + + // Safety: Run again after a slight delay in case of dynamic loading (unlikely in admin but possible) + setTimeout(initDateRangeDropdown, 500); + }); +})(django.jQuery); \ No newline at end of file diff --git a/staticfiles/pasted-20260201-034855-b2075578.png b/staticfiles/pasted-20260201-034855-b2075578.png new file mode 100644 index 0000000..a6282bc Binary files /dev/null and b/staticfiles/pasted-20260201-034855-b2075578.png differ diff --git a/staticfiles/vm-shot-2026-02-01T03-47-53-669Z.jpg b/staticfiles/vm-shot-2026-02-01T03-47-53-669Z.jpg new file mode 100644 index 0000000..2984fa1 Binary files /dev/null and b/staticfiles/vm-shot-2026-02-01T03-47-53-669Z.jpg differ diff --git a/staticfiles/vm-shot-2026-02-01T03-48-00-010Z.jpg b/staticfiles/vm-shot-2026-02-01T03-48-00-010Z.jpg new file mode 100644 index 0000000..2984fa1 Binary files /dev/null and b/staticfiles/vm-shot-2026-02-01T03-48-00-010Z.jpg differ