фикс багов
This commit is contained in:
@@ -111,11 +111,13 @@ export const selectDefinition: ElementDefinition<SelectConfig, string> = {
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
{config.options.map((option, index) => (
|
||||
<SelectItem key={index} value={option.value}>
|
||||
{option.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
{config.options
|
||||
.filter(option => option.value.trim() !== '')
|
||||
.map((option, index) => (
|
||||
<SelectItem key={index} value={option.value}>
|
||||
{option.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
@@ -127,11 +129,13 @@ export const selectDefinition: ElementDefinition<SelectConfig, string> = {
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
{config.options.map((option, index) => (
|
||||
<SelectItem key={index} value={option.value}>
|
||||
{option.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
{config.options
|
||||
.filter(option => option.value.trim() !== '')
|
||||
.map((option, index) => (
|
||||
<SelectItem key={index} value={option.value}>
|
||||
{option.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Button } from '@/component/ui/button'
|
||||
import { Calendar } from '@/component/ui/calendar'
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/component/ui/card'
|
||||
import {
|
||||
Dialog,
|
||||
@@ -10,7 +9,6 @@ import {
|
||||
} from '@/component/ui/dialog'
|
||||
import { Input } from '@/component/ui/input'
|
||||
import { Label } from '@/component/ui/label'
|
||||
import { Popover, PopoverContent, PopoverTrigger } from '@/component/ui/popover'
|
||||
import {
|
||||
AlertCircle,
|
||||
Building2,
|
||||
@@ -47,7 +45,6 @@ export function VerificationConditionsRender({
|
||||
config.selectedDate || new Date().toISOString().split('T')[0]
|
||||
)
|
||||
const [editDialogOpen, setEditDialogOpen] = useState(false)
|
||||
const [calendarOpen, setCalendarOpen] = useState(false)
|
||||
const [editingConditions, setEditingConditions] = useState<
|
||||
Record<string, string>
|
||||
>({})
|
||||
@@ -67,26 +64,23 @@ export function VerificationConditionsRender({
|
||||
const hasConditions =
|
||||
dailyCondition && Object.keys(dailyCondition.conditions).length > 0
|
||||
|
||||
// Автоматическая инициализация onChange при загрузке данных
|
||||
// Инициализация данных при загрузке из БД, только если данные еще не заполнены
|
||||
useEffect(() => {
|
||||
if (dailyCondition && onChange && hasConditions) {
|
||||
if (
|
||||
dailyCondition &&
|
||||
hasConditions &&
|
||||
onChange &&
|
||||
(!value?.conditions || Object.keys(value.conditions).length === 0)
|
||||
) {
|
||||
onChange({
|
||||
date: selectedDate,
|
||||
conditions: dailyCondition.conditions,
|
||||
})
|
||||
}
|
||||
}, [dailyCondition, onChange, selectedDate, hasConditions])
|
||||
}, [dailyCondition, hasConditions, onChange, selectedDate, value?.conditions])
|
||||
|
||||
const handleDateChange = (date: string) => {
|
||||
setSelectedDate(date)
|
||||
}
|
||||
|
||||
const handleCalendarSelect = (date: Date | undefined) => {
|
||||
if (date) {
|
||||
const dateString = date.toISOString().split('T')[0]
|
||||
setSelectedDate(dateString)
|
||||
setCalendarOpen(false)
|
||||
}
|
||||
const handleDateChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setSelectedDate(event.target.value)
|
||||
}
|
||||
|
||||
const handleOpenEditDialog = (isCreating = false) => {
|
||||
@@ -167,25 +161,13 @@ export function VerificationConditionsRender({
|
||||
{/* Выбор даты */}
|
||||
<div className="flex items-center gap-2">
|
||||
<CalendarIcon className="h-3.5 w-3.5 text-muted-foreground" />
|
||||
<Popover open={calendarOpen} onOpenChange={setCalendarOpen}>
|
||||
<PopoverTrigger asChild>
|
||||
<Button
|
||||
variant="outline"
|
||||
className="h-6 justify-start border-none bg-muted/50 px-2 text-xs font-normal hover:bg-muted/70"
|
||||
>
|
||||
{new Date(selectedDate).toLocaleDateString('ru-RU')}
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-auto p-0" align="start">
|
||||
<Calendar
|
||||
mode="single"
|
||||
selected={new Date(selectedDate)}
|
||||
onSelect={handleCalendarSelect}
|
||||
className="rounded-md border shadow-sm"
|
||||
captionLayout="dropdown"
|
||||
/>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
<Input
|
||||
type="date"
|
||||
value={selectedDate}
|
||||
onChange={handleDateChange}
|
||||
lang="ru"
|
||||
className="h-6 border-none bg-muted/50 px-2 text-xs font-normal hover:bg-muted/70 focus:bg-background"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Статус и данные */}
|
||||
|
||||
@@ -31,6 +31,14 @@ export const verificationConditionsElementDefinition: ElementDefinition<
|
||||
Preview: VerificationConditionsPreview,
|
||||
Render: VerificationConditionsRender,
|
||||
|
||||
// Получение начальных значений из конфигурации
|
||||
getInitialValue: config => {
|
||||
return {
|
||||
date: config.selectedDate || new Date().toISOString().split('T')[0],
|
||||
conditions: {},
|
||||
}
|
||||
},
|
||||
|
||||
// Получение ячеек для записи данных на основе маппинга условий
|
||||
mapToCells: (config): CellTarget[] => {
|
||||
// Возвращаем только те targetCells, которые замаплены к условиям
|
||||
|
||||
@@ -39,6 +39,15 @@ export const standardsDefinition: ElementDefinition<
|
||||
},
|
||||
Editor: StandardsEditor,
|
||||
Preview: StandardsPreview,
|
||||
|
||||
// Получение начальных значений из конфигурации
|
||||
getInitialValue: config => {
|
||||
return {
|
||||
standardIds: config.selectedStandards || [],
|
||||
standardNames: [], // Будет заполнено при рендере компонента
|
||||
}
|
||||
},
|
||||
|
||||
Render: ({ config, value, onChange }) => {
|
||||
const [isStandardsDialogOpen, setIsStandardsDialogOpen] = useState(false)
|
||||
const [selectedStandardIds, setSelectedStandardIds] = useState<string[]>(
|
||||
@@ -60,9 +69,14 @@ export const standardsDefinition: ElementDefinition<
|
||||
.map(id => standards.find(s => s.id === id))
|
||||
.filter(Boolean)
|
||||
|
||||
// Автоматическая инициализация onChange при загрузке данных эталонов
|
||||
// Обновляем standardNames при получении данных из API, если они еще не заполнены
|
||||
useEffect(() => {
|
||||
if (standards.length > 0 && selectedStandardIds.length > 0) {
|
||||
if (
|
||||
standards.length > 0 &&
|
||||
selectedStandardIds.length > 0 &&
|
||||
(!value?.standardNames || value.standardNames.length === 0) &&
|
||||
onChange
|
||||
) {
|
||||
const standardNames = selectedStandardIds
|
||||
.map((id, index) => {
|
||||
const standard = standards.find(s => s.id === id)
|
||||
@@ -72,12 +86,14 @@ export const standardsDefinition: ElementDefinition<
|
||||
})
|
||||
.filter(Boolean)
|
||||
|
||||
onChange?.({
|
||||
standardIds: selectedStandardIds,
|
||||
standardNames,
|
||||
})
|
||||
if (standardNames.length > 0) {
|
||||
onChange({
|
||||
standardIds: selectedStandardIds,
|
||||
standardNames,
|
||||
})
|
||||
}
|
||||
}
|
||||
}, [selectedStandardIds, standards, onChange])
|
||||
}, [standards, selectedStandardIds, value?.standardNames, onChange])
|
||||
|
||||
return (
|
||||
<div className="space-y-2">
|
||||
|
||||
@@ -20,6 +20,7 @@ export interface ElementDefinition<Config = any, Value = any> {
|
||||
|
||||
/* бизнес-логика */
|
||||
defaultConfig: Config
|
||||
getInitialValue?(config: Config): Value // получение начальных значений из конфигурации
|
||||
mapToCells(config: Config): CellTarget[] // куда пишем данные (для отображения)
|
||||
mapToCellValues(
|
||||
config: Config,
|
||||
|
||||
@@ -74,10 +74,36 @@ const FormElement: FC<FormElementProps> = ({ element, value, onChange }) => {
|
||||
const ProtocolForm: FC<ProtocolFormProps> = ({ template, onSave, onBack }) => {
|
||||
const [formData, setFormData] = useState<Record<string, any>>({})
|
||||
const [showSpreadsheet, setShowSpreadsheet] = useState(false)
|
||||
const [isInitialized, setIsInitialized] = useState(false)
|
||||
const engineRef = useRef<any>(null)
|
||||
const toast = useToast()
|
||||
const navigate = useNavigate()
|
||||
|
||||
// Инициализация значений для специальных элементов
|
||||
useEffect(() => {
|
||||
if (!isInitialized && template.elements.length > 0) {
|
||||
const initialData: Record<string, any> = {}
|
||||
|
||||
template.elements.forEach(element => {
|
||||
// Получаем определение элемента
|
||||
const elementDefinition = getElementDefinition(element.type)
|
||||
if (elementDefinition?.getInitialValue) {
|
||||
// Используем метод getInitialValue для получения начального значения
|
||||
const initialValue = elementDefinition.getInitialValue(element as any)
|
||||
if (initialValue !== undefined) {
|
||||
initialData[element.id] = initialValue
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
if (Object.keys(initialData).length > 0) {
|
||||
setFormData(initialData)
|
||||
}
|
||||
|
||||
setIsInitialized(true)
|
||||
}
|
||||
}, [template.elements, isInitialized])
|
||||
|
||||
const handleFieldChange = (elementId: string, value: any) => {
|
||||
setFormData(prev => ({
|
||||
...prev,
|
||||
|
||||
Reference in New Issue
Block a user