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