Merge branch 'fix/day-picker-ordinis-styles' into 'main'
fix(admin-ui): /audit — стили DayPicker + UserPicker fallback на TextInput See merge request 2-6/2-6-4/terravault/ordinis!264
This commit is contained in:
@@ -269,7 +269,7 @@ export function PeriodFilter({ value, onChange, label, disabled }: PeriodFilterP
|
||||
mode="range"
|
||||
selected={dpRange}
|
||||
onSelect={handleSelect}
|
||||
numberOfMonths={2}
|
||||
numberOfMonths={1}
|
||||
showOutsideDays
|
||||
weekStartsOn={1}
|
||||
className="ord-day-picker"
|
||||
|
||||
@@ -2,7 +2,7 @@ import * as React from 'react'
|
||||
import { useMemo, useState } from 'react'
|
||||
import { CaretDownIcon, MagnifyingGlassIcon, UserIcon, XIcon } from '@phosphor-icons/react'
|
||||
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from 'cmdk'
|
||||
import { Popover, PopoverTrigger, PopoverContent, FieldLabel } from '@/ui'
|
||||
import { Popover, PopoverTrigger, PopoverContent, FieldLabel, TextInput } from '@/ui'
|
||||
import { useAllUsers, type UserListItem } from '@/api/queries'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
@@ -38,11 +38,32 @@ export function UserPicker({ value, onChange, label, placeholder, disabled }: Us
|
||||
const [open, setOpen] = useState(false)
|
||||
const usersQ = useAllUsers()
|
||||
|
||||
// Fallback на TextInput если cache пустой или endpoint вернул 403/404 (юзер
|
||||
// без INTERNAL scope, либо writer был только-что рестартован и cache не
|
||||
// прогрелся). Без этого user-фильтр становится недоступен — раньше тут был
|
||||
// TextInput, не лишаем юзера возможности вписать UUID руками.
|
||||
const usersList = usersQ.data ?? []
|
||||
const fallbackToTextInput =
|
||||
!usersQ.isLoading && !usersQ.isError && usersList.length === 0
|
||||
|
||||
const usersBySub = useMemo(() => {
|
||||
const m = new Map<string, UserListItem>()
|
||||
for (const u of usersQ.data ?? []) m.set(u.sub, u)
|
||||
for (const u of usersList) m.set(u.sub, u)
|
||||
return m
|
||||
}, [usersQ.data])
|
||||
}, [usersList])
|
||||
|
||||
if (fallbackToTextInput) {
|
||||
return (
|
||||
<TextInput
|
||||
label={label}
|
||||
value={value ?? ''}
|
||||
onChange={(e) => onChange(e.target.value || undefined)}
|
||||
placeholder="UUID или username"
|
||||
hint="Список юзеров пуст — введите вручную"
|
||||
disabled={disabled}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
const selected = value ? usersBySub.get(value) : undefined
|
||||
const triggerLabel = useMemo(() => {
|
||||
|
||||
@@ -443,3 +443,112 @@ body {
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* === react-day-picker — кастомизация под ordinis design system.
|
||||
* Без этих overrides DayPicker рендерится дефолтными rdp-* стилями
|
||||
* (большие квадратные ячейки, нет hover/selected состояний под наш
|
||||
* accent). Класс `.ord-day-picker` ставится на корень DayPicker'а
|
||||
* в DateRangePicker и PeriodFilter. === */
|
||||
.ord-day-picker {
|
||||
--rdp-day-width: 2rem;
|
||||
--rdp-day-height: 2rem;
|
||||
--rdp-day_button-width: 2rem;
|
||||
--rdp-day_button-height: 2rem;
|
||||
--rdp-day_button-border-radius: 6px;
|
||||
--rdp-months-gap: 1rem;
|
||||
--rdp-nav_button-height: 1.75rem;
|
||||
--rdp-nav_button-width: 1.75rem;
|
||||
--rdp-weekday-text-transform: lowercase;
|
||||
--rdp-weekday-padding: 0.25rem 0;
|
||||
--rdp-month_caption-font: 600 0.875rem/1.25 'Inter', sans-serif;
|
||||
--rdp-day-font: 400 0.8125rem/1 'JetBrains Mono', monospace;
|
||||
--rdp-weekday-font: 500 0.7rem/1 'Inter', sans-serif;
|
||||
--rdp-accent-color: var(--color-accent);
|
||||
--rdp-accent-background-color: var(--color-accent-bg);
|
||||
font-family: 'Inter', sans-serif;
|
||||
color: var(--color-ink);
|
||||
}
|
||||
|
||||
/* Multi-month layout (если когда-то нужно): 2 столбца side-by-side
|
||||
* вместо wrap'а вниз. */
|
||||
.ord-day-picker .rdp-months {
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
.ord-day-picker .rdp-month_caption {
|
||||
padding: 0 0 0.5rem;
|
||||
color: var(--color-ink);
|
||||
}
|
||||
|
||||
.ord-day-picker .rdp-weekday {
|
||||
color: var(--color-mute);
|
||||
text-transform: lowercase;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.ord-day-picker .rdp-day_button {
|
||||
border-radius: 6px;
|
||||
transition: background-color 120ms, color 120ms;
|
||||
}
|
||||
|
||||
.ord-day-picker .rdp-day_button:hover:not(:disabled):not([aria-disabled='true']) {
|
||||
background-color: var(--color-surface-2);
|
||||
color: var(--color-ink);
|
||||
}
|
||||
|
||||
.ord-day-picker .rdp-day.rdp-outside .rdp-day_button {
|
||||
color: var(--color-mute);
|
||||
opacity: 0.55;
|
||||
}
|
||||
|
||||
.ord-day-picker .rdp-day.rdp-today .rdp-day_button {
|
||||
font-weight: 600;
|
||||
outline: 1px solid var(--color-line-2, var(--color-line));
|
||||
outline-offset: -2px;
|
||||
}
|
||||
|
||||
/* Selected range */
|
||||
.ord-day-picker .rdp-day.rdp-selected .rdp-day_button {
|
||||
background-color: var(--color-accent);
|
||||
color: var(--color-on-accent, white);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.ord-day-picker .rdp-day.rdp-range_middle .rdp-day_button {
|
||||
background-color: var(--color-accent-bg);
|
||||
color: var(--color-accent);
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.ord-day-picker .rdp-day.rdp-range_start .rdp-day_button {
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
|
||||
.ord-day-picker .rdp-day.rdp-range_end .rdp-day_button {
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
|
||||
.ord-day-picker .rdp-day.rdp-range_start.rdp-range_end .rdp-day_button {
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
/* Nav buttons */
|
||||
.ord-day-picker .rdp-button_previous,
|
||||
.ord-day-picker .rdp-button_next {
|
||||
border-radius: 6px;
|
||||
color: var(--color-accent);
|
||||
transition: background-color 120ms;
|
||||
}
|
||||
|
||||
.ord-day-picker .rdp-button_previous:hover,
|
||||
.ord-day-picker .rdp-button_next:hover {
|
||||
background-color: var(--color-surface-2);
|
||||
}
|
||||
|
||||
.ord-day-picker .rdp-button_previous:disabled,
|
||||
.ord-day-picker .rdp-button_next:disabled {
|
||||
opacity: 0.35;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user