fix: горизонтальная раскладка GeoField/ContactField и убран max-width у обёрток в TaskDetail

This commit is contained in:
2026-07-20 11:32:26 +03:00
parent 219c7a6203
commit 9fff937209
3 changed files with 101 additions and 86 deletions

View File

@@ -93,107 +93,121 @@ export default function ContactField({ value, onChange, disabled = false }: Cont
};
return (
<div className="space-y-3">
<div className="space-y-1">
<label className="text-xs text-muted-foreground">ФИО</label>
<div>
<div className="flex flex-wrap gap-2 items-start">
{/* ФИО */}
<Input
value={name}
onChange={(e) => handleNameChange(e.target.value)}
disabled={disabled}
placeholder="Иванов И.И."
className="h-8"
placeholder="ФИО (Иванов И.И.)"
className="h-8 flex-1 min-w-[140px]"
/>
</div>
<div className="space-y-1">
<label className="text-xs text-muted-foreground">Должность</label>
{/* Должность */}
<Input
value={position}
onChange={(e) => handlePositionChange(e.target.value)}
disabled={disabled}
placeholder="Директор"
className="h-8"
placeholder="Должность (Директор)"
className="h-8 flex-1 min-w-[140px]"
/>
</div>
<div className="space-y-1">
<label className="text-xs text-muted-foreground">Телефоны</label>
<div className="space-y-1">
{phones.map((phone, idx) => (
<div key={`phone-${idx}`} className="flex items-center gap-1">
<Input
value={phone}
onChange={(e) => changePhone(idx, e.target.value)}
disabled={disabled}
placeholder="+7 (999) 123-45-67"
className="h-8 flex-1"
/>
{phones.length > 1 && (
<Button
type="button"
variant="ghost"
size="icon"
className="h-8 w-8 shrink-0"
onClick={() => removePhone(idx)}
disabled={disabled}
>
<X className="h-3.5 w-3.5" />
</Button>
)}
</div>
))}
{/* Телефон — первый + кнопка добавить */}
<div className="flex gap-1 flex-1 min-w-[180px]">
<Input
value={phones[0] || ""}
onChange={(e) => changePhone(0, e.target.value)}
disabled={disabled}
placeholder="Телефон +7 (999) 123-45-67"
className="h-8 flex-1 min-w-0"
/>
<Button
type="button"
variant="outline"
size="sm"
className="h-7 text-xs"
size="icon"
className="h-8 w-8 shrink-0"
onClick={addPhone}
disabled={disabled}
title="Добавить телефон"
>
<Plus className="h-3 w-3 mr-1" />
Добавить телефон
<Plus className="h-3 w-3" />
</Button>
</div>
{/* Email — первый + кнопка добавить */}
<div className="flex gap-1 flex-1 min-w-[180px]">
<Input
value={emails[0] || ""}
onChange={(e) => changeEmail(0, e.target.value)}
disabled={disabled}
placeholder="Email ivan@example.com"
className="h-8 flex-1 min-w-0"
/>
<Button
type="button"
variant="outline"
size="icon"
className="h-8 w-8 shrink-0"
onClick={addEmail}
disabled={disabled}
title="Добавить email"
>
<Plus className="h-3 w-3" />
</Button>
</div>
</div>
<div className="space-y-1">
<label className="text-xs text-muted-foreground">Email</label>
<div className="space-y-1">
{emails.map((email, idx) => (
<div key={`email-${idx}`} className="flex items-center gap-1">
{/* Дополнительные телефоны (если есть) */}
{phones.length > 1 && (
<div className="flex flex-wrap gap-1 mt-1">
{phones.slice(1).map((phone, idx) => (
<div key={`phone-${idx + 1}`} className="flex items-center gap-1 flex-1 min-w-[180px]">
<Input
value={email}
onChange={(e) => changeEmail(idx, e.target.value)}
value={phone}
onChange={(e) => changePhone(idx + 1, e.target.value)}
disabled={disabled}
placeholder="ivan@example.com"
className="h-8 flex-1"
placeholder="+7 (999) 123-45-67"
className="h-8 flex-1 min-w-0"
/>
{emails.length > 1 && (
<Button
type="button"
variant="ghost"
size="icon"
className="h-8 w-8 shrink-0"
onClick={() => removeEmail(idx)}
disabled={disabled}
>
<X className="h-3.5 w-3.5" />
</Button>
)}
<Button
type="button"
variant="ghost"
size="icon"
className="h-8 w-8 shrink-0"
onClick={() => removePhone(idx + 1)}
disabled={disabled}
>
<X className="h-3.5 w-3.5" />
</Button>
</div>
))}
<Button
type="button"
variant="outline"
size="sm"
className="h-7 text-xs"
onClick={addEmail}
disabled={disabled}
>
<Plus className="h-3 w-3 mr-1" />
Добавить email
</Button>
</div>
</div>
)}
{/* Дополнительные email (если есть) */}
{emails.length > 1 && (
<div className="flex flex-wrap gap-1 mt-1">
{emails.slice(1).map((email, idx) => (
<div key={`email-${idx + 1}`} className="flex items-center gap-1 flex-1 min-w-[180px]">
<Input
value={email}
onChange={(e) => changeEmail(idx + 1, e.target.value)}
disabled={disabled}
placeholder="ivan@example.com"
className="h-8 flex-1 min-w-0"
/>
<Button
type="button"
variant="ghost"
size="icon"
className="h-8 w-8 shrink-0"
onClick={() => removeEmail(idx + 1)}
disabled={disabled}
>
<X className="h-3.5 w-3.5" />
</Button>
</div>
))}
</div>
)}
</div>
);
}

View File

@@ -156,18 +156,18 @@ export default function GeoField({ value, onChange, disabled = false }: GeoField
};
return (
<div className="space-y-2">
<div className="flex flex-wrap gap-2 items-start">
{/* Адрес с подсказками */}
<Popover open={isOpen} onOpenChange={setIsOpen} modal={false}>
<PopoverAnchor asChild>
<div className="relative">
<div className="relative flex-1 min-w-[200px]">
<MapPin className="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground" />
<Input
placeholder="Начните вводить адрес..."
value={inputValue}
onChange={(e) => handleAddressChange(e.target.value)}
disabled={disabled}
className="pl-9"
className="pl-9 w-full"
/>
{isLoading && (
<Loader2 className="absolute right-2.5 top-2.5 h-4 w-4 animate-spin text-muted-foreground" />
@@ -195,18 +195,19 @@ export default function GeoField({ value, onChange, disabled = false }: GeoField
</Popover>
{/* Координаты — совмещённое поле */}
<div className="flex gap-2">
<div className="flex gap-2 flex-1 min-w-[180px]">
<Input
placeholder="55.707339, 52.315169"
value={coordInput}
onChange={(e) => handleCoordChange(e.target.value)}
disabled={disabled}
className="flex-1 font-mono text-sm"
className="flex-1 font-mono text-sm min-w-0"
/>
<Button
type="button"
variant="outline"
size="icon"
className="shrink-0"
onClick={handleGeolocate}
disabled={disabled || isGeoLoading || !geo.lat || !geo.lng}
title="Определить адрес по координатам"

View File

@@ -1059,7 +1059,7 @@ function FieldValueRow({
? new Set([String(editorValue)])
: new Set<string>();
return (
<div className="w-full max-w-[320px]" onClick={e => e.stopPropagation()}>
<div className="flex-1 min-w-0" onClick={e => e.stopPropagation()}>
<SearchableMultiSelect
options={opts.map((o) => ({ value: o.value, label: o.label }))}
selected={selected}
@@ -1112,7 +1112,7 @@ function FieldValueRow({
}
if (field.type === 'geo') {
return (
<div className="w-full max-w-[320px]" onClick={e => e.stopPropagation()}>
<div className="flex-1 min-w-0" onClick={e => e.stopPropagation()}>
<GeoField
value={editorValue as unknown as GeoValue | string | null}
onChange={val => onDraftChange?.(val as unknown as string | number | boolean | null | undefined)}
@@ -1122,7 +1122,7 @@ function FieldValueRow({
}
if (field.type === 'company') {
return (
<div className="w-full max-w-[280px]" onClick={e => e.stopPropagation()}>
<div className="flex-1 min-w-0" onClick={e => e.stopPropagation()}>
<CompanyFieldInput
value={editorValue === null || editorValue === undefined ? '' : String(editorValue)}
onChange={val => onDraftChange?.(val)}
@@ -1171,7 +1171,7 @@ function FieldValueRow({
const opts = field.options && !Array.isArray(field.options) ? (field.options as Record<string, any>) : {};
const showSubdirectory = !!opts.showSubdirectory;
return (
<div className="w-full max-w-[280px]" onClick={e => e.stopPropagation()}>
<div className="flex-1 min-w-0" onClick={e => e.stopPropagation()}>
{showSubdirectory ? (
<TableFieldWithSubdirectory
fieldId={field.id}
@@ -1206,7 +1206,7 @@ function FieldValueRow({
}
if (field.type === 'contact') {
return (
<div className="w-full max-w-[320px]" onClick={e => e.stopPropagation()}>
<div className="flex-1 min-w-0" onClick={e => e.stopPropagation()}>
<ContactField
value={editorValue as any}
onChange={(val) => onDraftChange?.(JSON.stringify(val))}
@@ -1216,7 +1216,7 @@ function FieldValueRow({
}
if (field.type === 'task' && field.linkedFormId) {
return (
<div className="w-full max-w-[320px]" onClick={e => e.stopPropagation()}>
<div className="flex-1 min-w-0" onClick={e => e.stopPropagation()}>
<TaskFieldSelect
formField={field as any}
value={editorValue}