Bladeren bron

fix(ui): locale-aware date inputs on audit log filter

Switch the From/To filter inputs from raw text+ISO placeholders to
datetime-local so the picker UI follows the browser locale, matching
how the rest of the UI renders dates. A small inline script converts
ISO query-string values into the input's local-time format on load and
back to ISO 8601 UTC on submit, so the API still receives ISO.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
chiappa 1 week geleden
bovenliggende
commit
de1f2ea203
1 gewijzigde bestanden met toevoegingen van 38 en 7 verwijderingen
  1. 38 7
      ui/resources/views/pages/audit/index.twig

+ 38 - 7
ui/resources/views/pages/audit/index.twig

@@ -32,7 +32,7 @@
         <div class="mt-4 rounded-md border border-red-300 bg-red-50 px-4 py-2 text-sm text-red-800 dark:border-red-800 dark:bg-red-950 dark:text-red-300">{{ error }}</div>
     {% endif %}
 
-    <form method="get" action="/app/audit" class="mt-4 grid grid-cols-2 gap-3 rounded-2xl border border-slate-200 bg-white p-4 text-sm shadow-sm dark:border-slate-800 dark:bg-slate-900 md:grid-cols-7">
+    <form id="audit-filter-form" method="get" action="/app/audit" class="mt-4 grid grid-cols-2 gap-3 rounded-2xl border border-slate-200 bg-white p-4 text-sm shadow-sm dark:border-slate-800 dark:bg-slate-900 md:grid-cols-7">
         <div>
             <label for="f-actor-kind" class="block text-xs font-medium text-slate-600 dark:text-slate-400">Actor kind</label>
             <select id="f-actor-kind" name="actor_kind" class="mt-1 w-full rounded-md border border-slate-300 bg-white px-2 py-1.5 text-sm dark:border-slate-700 dark:bg-slate-950">
@@ -68,14 +68,14 @@
         </div>
         <div class="col-span-2 md:col-span-7 grid grid-cols-1 gap-3 md:grid-cols-3 md:items-end">
             <div>
-                <label for="f-from" class="block text-xs font-medium text-slate-600 dark:text-slate-400">From (ISO)</label>
-                <input type="text" id="f-from" name="from" placeholder="2026-04-01T00:00:00Z" value="{{ filters.from|default('') }}"
-                       class="mt-1 w-full rounded-md border border-slate-300 bg-white px-2 py-1.5 font-mono text-sm dark:border-slate-700 dark:bg-slate-950">
+                <label for="f-from" class="block text-xs font-medium text-slate-600 dark:text-slate-400">From</label>
+                <input type="datetime-local" id="f-from" name="from" step="1" data-irdb-iso-filter="{{ filters.from|default('') }}"
+                       class="mt-1 w-full rounded-md border border-slate-300 bg-white px-2 py-1.5 text-sm dark:border-slate-700 dark:bg-slate-950">
             </div>
             <div>
-                <label for="f-to" class="block text-xs font-medium text-slate-600 dark:text-slate-400">To (ISO)</label>
-                <input type="text" id="f-to" name="to" placeholder="2026-04-30T23:59:59Z" value="{{ filters.to|default('') }}"
-                       class="mt-1 w-full rounded-md border border-slate-300 bg-white px-2 py-1.5 font-mono text-sm dark:border-slate-700 dark:bg-slate-950">
+                <label for="f-to" class="block text-xs font-medium text-slate-600 dark:text-slate-400">To</label>
+                <input type="datetime-local" id="f-to" name="to" step="1" data-irdb-iso-filter="{{ filters.to|default('') }}"
+                       class="mt-1 w-full rounded-md border border-slate-300 bg-white px-2 py-1.5 text-sm dark:border-slate-700 dark:bg-slate-950">
             </div>
             <div class="flex justify-end gap-2">
                 <a href="/app/audit" class="rounded-md border border-slate-300 px-3 py-1.5 text-sm hover:bg-slate-50 dark:border-slate-700 dark:hover:bg-slate-800">Reset</a>
@@ -84,6 +84,37 @@
         </div>
     </form>
 
+    <script>
+    (function () {
+        function pad(n) { return String(n).padStart(2, '0'); }
+        function isoToLocalInput(iso) {
+            if (!iso) return '';
+            const d = new Date(iso);
+            if (isNaN(d.getTime())) return '';
+            return d.getFullYear() + '-' + pad(d.getMonth() + 1) + '-' + pad(d.getDate())
+                + 'T' + pad(d.getHours()) + ':' + pad(d.getMinutes()) + ':' + pad(d.getSeconds());
+        }
+        function localInputToIso(value) {
+            if (!value) return '';
+            const d = new Date(value);
+            if (isNaN(d.getTime())) return '';
+            return d.toISOString();
+        }
+        document.querySelectorAll('#audit-filter-form input[data-irdb-iso-filter]').forEach((el) => {
+            const iso = el.getAttribute('data-irdb-iso-filter');
+            if (iso) el.value = isoToLocalInput(iso);
+        });
+        const form = document.getElementById('audit-filter-form');
+        if (form) {
+            form.addEventListener('submit', () => {
+                form.querySelectorAll('input[type="datetime-local"]').forEach((el) => {
+                    if (el.value) el.value = localInputToIso(el.value);
+                });
+            });
+        }
+    })();
+    </script>
+
     {% if list %}
         <div class="mt-6 overflow-hidden rounded-2xl border border-slate-200 bg-white shadow-sm dark:border-slate-800 dark:bg-slate-900" x-data="{ open: null }">
             <table class="w-full text-sm" data-sortable-table="audit-index">