Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 2x 3x 5x 5x 5x 2x 3x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 2x 2x 2x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 1x 1x 1x 5x 5x 5x 5x 5x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 5x 5x 5x 5x 5x 5x | /**
* ItemFormDialog - Main dialog container for item creation/editing
*
* @module dialogs/ItemFormDialog/ItemFormDialog
* @description
* Manages dialog lifecycle (title, open/close, actions).
* Delegates all form logic to useItemForm hook.
*
* @enterprise
* - Thin container following separation of concerns
* - Dialog title changes: "Create Item" for new / "Edit Item" for existing
* - Help button links to appropriate documentation section
* - Cancel button dismisses without changes
* - Save/Create button triggers submission with loading state
*/
import {
Dialog,
DialogTitle,
DialogContent,
DialogActions,
Button,
Box,
CircularProgress,
Tooltip,
IconButton,
} from '@mui/material';
import HelpOutlineIcon from '@mui/icons-material/HelpOutline';
import { useTranslation } from 'react-i18next';
import { useRef } from 'react';
import { ItemForm } from './ItemForm';
import { useItemForm } from './useItemForm';
import type { ItemFormDialogProps } from './ItemFormDialog.types';
/**
* ItemFormDialog - Main dialog component
*
* Opens when isOpen is true. Renders ItemForm and manages dialog actions.
* All form state/queries/validation delegated to useItemForm hook.
*
* @param isOpen - Whether dialog is visible
* @param onClose - Called on cancel or successful save
* @param initial - Initial item data (undefined for create mode)
*/
export function ItemFormDialog({
isOpen,
onClose,
initial,
onSaved,
}: ItemFormDialogProps) {
const { t } = useTranslation(['common', 'inventory']);
const dialogRef = useRef<HTMLDivElement>(null);
// All form state and handlers delegated to hook
const state = useItemForm({ isOpen, onClose, initial, onSaved });
// Dialog title reflects create vs edit mode
const dialogTitle = initial?.id
? t('inventory:dialogs.editItem', 'Edit Item')
: t('inventory:dialogs.createItem', 'Create Item');
// Button label also changes based on mode
const submitLabel = initial?.id
? t('common:actions.save', 'Save')
: t('common:actions.create', 'Create');
return (
<Dialog
ref={dialogRef}
open={isOpen}
onClose={() => state.handleClose()}
maxWidth="sm"
fullWidth
>
{/* Title with help icon */}
<DialogTitle
sx={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
}}
>
<span>{dialogTitle}</span>
<Tooltip title={t('common:help', 'Help')}>
<IconButton
size="small"
onClick={() => {
const section = initial?.id ? 'edit_item' : 'create_item';
window.open(`#/help?section=${section}`, '_blank');
}}
aria-label="help"
>
<HelpOutlineIcon fontSize="small" />
</IconButton>
</Tooltip>
</DialogTitle>
{/* Form content */}
<DialogContent>
<ItemForm state={state} initial={initial} />
</DialogContent>
{/* Dialog actions */}
<DialogActions>
<Button onClick={() => state.handleClose()} disabled={state.formState.isSubmitting}>
{t('common:actions.cancel', 'Cancel')}
</Button>
<Box sx={{ position: 'relative', display: 'inline-block' }}>
<Button
variant="contained"
onClick={(e) => {
e.preventDefault();
state.handleSubmit(state.onSubmit)(e);
}}
disabled={state.formState.isSubmitting}
>
{submitLabel}
</Button>
{state.formState.isSubmitting && (
<CircularProgress
size={24}
sx={{
position: 'absolute',
top: '50%',
left: '50%',
marginTop: '-12px',
marginLeft: '-12px',
}}
/>
)}
</Box>
</DialogActions>
</Dialog>
);
}
|