Compare commits
2 Commits
d8a1878ab1
...
d19f555c7c
| Author | SHA1 | Date | |
|---|---|---|---|
| d19f555c7c | |||
| 1d7253f9a1 |
@@ -640,22 +640,53 @@ const AddBrandDevice = () => {
|
|||||||
}}>
|
}}>
|
||||||
<Card
|
<Card
|
||||||
title={
|
title={
|
||||||
<span style={{
|
<div style={{
|
||||||
fontSize: '16px',
|
|
||||||
fontWeight: '600',
|
|
||||||
color: '#262626',
|
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
gap: '8px'
|
justifyContent: 'space-between',
|
||||||
|
width: '100%'
|
||||||
}}>
|
}}>
|
||||||
<span style={{
|
<span style={{
|
||||||
width: '4px',
|
fontSize: '16px',
|
||||||
height: '20px',
|
fontWeight: '600',
|
||||||
backgroundColor: '#23A55A',
|
color: '#262626',
|
||||||
borderRadius: '2px'
|
display: 'flex',
|
||||||
}}></span>
|
alignItems: 'center',
|
||||||
Error Code Form
|
gap: '8px'
|
||||||
</span>
|
}}>
|
||||||
|
<span style={{
|
||||||
|
width: '4px',
|
||||||
|
height: '20px',
|
||||||
|
backgroundColor: '#23A55A',
|
||||||
|
borderRadius: '2px'
|
||||||
|
}}></span>
|
||||||
|
Error Code Form
|
||||||
|
</span>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
size="large"
|
||||||
|
onClick={handleSaveErrorCode}
|
||||||
|
loading={confirmLoading}
|
||||||
|
style={{
|
||||||
|
backgroundColor: '#23A55A',
|
||||||
|
borderColor: '#23A55A',
|
||||||
|
borderRadius: '8px',
|
||||||
|
height: '40px',
|
||||||
|
padding: '0 24px',
|
||||||
|
fontWeight: '500',
|
||||||
|
boxShadow: '0 2px 4px rgba(35, 165, 90, 0.2)',
|
||||||
|
transition: 'all 0.3s ease'
|
||||||
|
}}
|
||||||
|
onMouseEnter={(e) => {
|
||||||
|
e.target.style.boxShadow = '0 4px 8px rgba(35, 165, 90, 0.3)';
|
||||||
|
}}
|
||||||
|
onMouseLeave={(e) => {
|
||||||
|
e.target.style.boxShadow = '0 2px 4px rgba(35, 165, 90, 0.2)';
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{editingErrorCodeKey ? 'Update Error Code' : 'Save Error Code'}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
style={{
|
style={{
|
||||||
width: '100%',
|
width: '100%',
|
||||||
@@ -681,24 +712,6 @@ const AddBrandDevice = () => {
|
|||||||
transition: 'all 0.3s ease',
|
transition: 'all 0.3s ease',
|
||||||
boxShadow: '0 1px 3px rgba(0,0,0,0.04)'
|
boxShadow: '0 1px 3px rgba(0,0,0,0.04)'
|
||||||
}}>
|
}}>
|
||||||
<div style={{
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
gap: '8px',
|
|
||||||
marginBottom: '12px',
|
|
||||||
paddingBottom: '8px',
|
|
||||||
borderBottom: '1px solid #f5f5f5'
|
|
||||||
}}>
|
|
||||||
<div style={{
|
|
||||||
width: '3px',
|
|
||||||
height: '16px',
|
|
||||||
backgroundColor: '#23A55A',
|
|
||||||
borderRadius: '2px'
|
|
||||||
}}></div>
|
|
||||||
<h4 style={{ margin: 0, color: '#262626', fontSize: '14px', fontWeight: '600' }}>
|
|
||||||
Error Code Details
|
|
||||||
</h4>
|
|
||||||
</div>
|
|
||||||
<ErrorCodeForm
|
<ErrorCodeForm
|
||||||
errorCodeForm={errorCodeForm}
|
errorCodeForm={errorCodeForm}
|
||||||
isErrorCodeFormReadOnly={isErrorCodeFormReadOnly}
|
isErrorCodeFormReadOnly={isErrorCodeFormReadOnly}
|
||||||
@@ -838,34 +851,6 @@ const AddBrandDevice = () => {
|
|||||||
Cancel
|
Cancel
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
||||||
<div style={{ marginLeft: editingErrorCodeKey ? '0' : 'auto' }}>
|
|
||||||
<Button
|
|
||||||
type="primary"
|
|
||||||
size="large"
|
|
||||||
onClick={handleSaveErrorCode}
|
|
||||||
loading={confirmLoading}
|
|
||||||
style={{
|
|
||||||
backgroundColor: '#23A55A',
|
|
||||||
borderColor: '#23A55A',
|
|
||||||
borderRadius: '8px',
|
|
||||||
height: '40px',
|
|
||||||
padding: '0 24px',
|
|
||||||
fontWeight: '500',
|
|
||||||
boxShadow: '0 2px 4px rgba(35, 165, 90, 0.2)',
|
|
||||||
transition: 'all 0.3s ease'
|
|
||||||
}}
|
|
||||||
onMouseEnter={(e) => {
|
|
||||||
e.target.style.boxShadow = '0 4px 8px rgba(35, 165, 90, 0.3)';
|
|
||||||
}}
|
|
||||||
onMouseLeave={(e) => {
|
|
||||||
e.target.style.boxShadow = '0 2px 4px rgba(35, 165, 90, 0.2)';
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{editingErrorCodeKey ? 'Update Error Code' : 'Simpan Error Code'}
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
@@ -1026,7 +1011,7 @@ const AddBrandDevice = () => {
|
|||||||
borderColor: '#23A55A',
|
borderColor: '#23A55A',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Lanjut
|
Error Code
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
{currentStep === 1 && (
|
{currentStep === 1 && (
|
||||||
@@ -1039,7 +1024,7 @@ const AddBrandDevice = () => {
|
|||||||
borderColor: '#23A55A',
|
borderColor: '#23A55A',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Selesai
|
Done
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -724,22 +724,53 @@ const EditBrandDevice = () => {
|
|||||||
}}>
|
}}>
|
||||||
<Card
|
<Card
|
||||||
title={
|
title={
|
||||||
<span style={{
|
<div style={{
|
||||||
fontSize: '16px',
|
|
||||||
fontWeight: '600',
|
|
||||||
color: '#262626',
|
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
gap: '8px'
|
justifyContent: 'space-between',
|
||||||
|
width: '100%'
|
||||||
}}>
|
}}>
|
||||||
<span style={{
|
<span style={{
|
||||||
width: '4px',
|
fontSize: '16px',
|
||||||
height: '20px',
|
fontWeight: '600',
|
||||||
backgroundColor: '#23A55A',
|
color: '#262626',
|
||||||
borderRadius: '2px'
|
display: 'flex',
|
||||||
}}></span>
|
alignItems: 'center',
|
||||||
Error Code Form
|
gap: '8px'
|
||||||
</span>
|
}}>
|
||||||
|
<span style={{
|
||||||
|
width: '4px',
|
||||||
|
height: '20px',
|
||||||
|
backgroundColor: '#23A55A',
|
||||||
|
borderRadius: '2px'
|
||||||
|
}}></span>
|
||||||
|
Error Code Form
|
||||||
|
</span>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
size="large"
|
||||||
|
onClick={handleSaveErrorCode}
|
||||||
|
loading={confirmLoading}
|
||||||
|
style={{
|
||||||
|
backgroundColor: '#23A55A',
|
||||||
|
borderColor: '#23A55A',
|
||||||
|
borderRadius: '8px',
|
||||||
|
height: '40px',
|
||||||
|
padding: '0 24px',
|
||||||
|
fontWeight: '500',
|
||||||
|
boxShadow: '0 2px 4px rgba(35, 165, 90, 0.2)',
|
||||||
|
transition: 'all 0.3s ease'
|
||||||
|
}}
|
||||||
|
onMouseEnter={(e) => {
|
||||||
|
e.target.style.boxShadow = '0 4px 8px rgba(35, 165, 90, 0.3)';
|
||||||
|
}}
|
||||||
|
onMouseLeave={(e) => {
|
||||||
|
e.target.style.boxShadow = '0 2px 4px rgba(35, 165, 90, 0.2)';
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{editingErrorCodeKey ? 'Update Error Code' : 'Save Error Code'}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
style={{
|
style={{
|
||||||
width: '100%',
|
width: '100%',
|
||||||
@@ -765,24 +796,6 @@ const EditBrandDevice = () => {
|
|||||||
transition: 'all 0.3s ease',
|
transition: 'all 0.3s ease',
|
||||||
boxShadow: '0 1px 3px rgba(0,0,0,0.04)'
|
boxShadow: '0 1px 3px rgba(0,0,0,0.04)'
|
||||||
}}>
|
}}>
|
||||||
<div style={{
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
gap: '8px',
|
|
||||||
marginBottom: '12px',
|
|
||||||
paddingBottom: '8px',
|
|
||||||
borderBottom: '1px solid #f5f5f5'
|
|
||||||
}}>
|
|
||||||
<div style={{
|
|
||||||
width: '3px',
|
|
||||||
height: '16px',
|
|
||||||
backgroundColor: '#23A55A',
|
|
||||||
borderRadius: '2px'
|
|
||||||
}}></div>
|
|
||||||
<h4 style={{ margin: 0, color: '#262626', fontSize: '14px', fontWeight: '600' }}>
|
|
||||||
Error Code Details
|
|
||||||
</h4>
|
|
||||||
</div>
|
|
||||||
<ErrorCodeForm
|
<ErrorCodeForm
|
||||||
errorCodeForm={errorCodeForm}
|
errorCodeForm={errorCodeForm}
|
||||||
isErrorCodeFormReadOnly={isErrorCodeFormReadOnly}
|
isErrorCodeFormReadOnly={isErrorCodeFormReadOnly}
|
||||||
@@ -925,34 +938,6 @@ const EditBrandDevice = () => {
|
|||||||
Cancel
|
Cancel
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
||||||
<div style={{ marginLeft: editingErrorCodeKey ? '0' : 'auto' }}>
|
|
||||||
<Button
|
|
||||||
type="primary"
|
|
||||||
size="large"
|
|
||||||
onClick={handleSaveErrorCode}
|
|
||||||
loading={confirmLoading}
|
|
||||||
style={{
|
|
||||||
backgroundColor: '#23A55A',
|
|
||||||
borderColor: '#23A55A',
|
|
||||||
borderRadius: '8px',
|
|
||||||
height: '40px',
|
|
||||||
padding: '0 24px',
|
|
||||||
fontWeight: '500',
|
|
||||||
boxShadow: '0 2px 4px rgba(35, 165, 90, 0.2)',
|
|
||||||
transition: 'all 0.3s ease'
|
|
||||||
}}
|
|
||||||
onMouseEnter={(e) => {
|
|
||||||
e.target.style.boxShadow = '0 4px 8px rgba(35, 165, 90, 0.3)';
|
|
||||||
}}
|
|
||||||
onMouseLeave={(e) => {
|
|
||||||
e.target.style.boxShadow = '0 2px 4px rgba(35, 165, 90, 0.2)';
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{editingErrorCodeKey ? 'Update Error Code' : 'Simpan Error Code'}
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
@@ -1016,7 +1001,7 @@ const EditBrandDevice = () => {
|
|||||||
borderColor: '#23A55A',
|
borderColor: '#23A55A',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Selesai
|
Done
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -46,6 +46,11 @@ const CustomSparepartCard = ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const truncateText = (text, maxLength = 15) => {
|
||||||
|
if (!text) return 'Unnamed';
|
||||||
|
return text.length > maxLength ? `${text.substring(0, maxLength)}...` : text;
|
||||||
|
};
|
||||||
|
|
||||||
const handleCardClick = () => {
|
const handleCardClick = () => {
|
||||||
if (!isReadOnly && onCardClick) {
|
if (!isReadOnly && onCardClick) {
|
||||||
onCardClick(sparepart);
|
onCardClick(sparepart);
|
||||||
@@ -125,210 +130,88 @@ const CustomSparepartCard = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Card
|
<div
|
||||||
hoverable={!!onCardClick && !isReadOnly}
|
style={{
|
||||||
style={getCardStyle()}
|
border: '1px solid #f0f0f0',
|
||||||
styles={{
|
borderRadius: '6px',
|
||||||
body: {
|
padding: '12px 16px',
|
||||||
padding: 0,
|
marginBottom: '8px',
|
||||||
height: 'calc(100% - 48px)',
|
backgroundColor: 'white',
|
||||||
display: 'flex',
|
cursor: onCardClick && !isReadOnly ? 'pointer' : 'default',
|
||||||
flexDirection: 'column'
|
transition: 'all 0.2s ease',
|
||||||
}
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'space-between'
|
||||||
}}
|
}}
|
||||||
actions={getCardActions()}
|
|
||||||
onClick={handleCardClick}
|
onClick={handleCardClick}
|
||||||
>
|
>
|
||||||
<div style={{ display: 'flex', height: '100%' }}>
|
<div style={{ flex: 1, minWidth: 0 }}>
|
||||||
|
<div style={{ display: 'flex', alignItems: 'center', marginBottom: '4px' }}>
|
||||||
<div style={{
|
<Text
|
||||||
width: size === 'small' ? '90px' : '110px',
|
strong
|
||||||
flexShrink: 0,
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'column',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
padding: size === 'small' ? '12px' : '16px',
|
|
||||||
backgroundColor: '#fafafa',
|
|
||||||
borderRight: '1px solid #f0f0f0',
|
|
||||||
position: 'relative'
|
|
||||||
}}>
|
|
||||||
{sparepart.sparepart_item_type && (
|
|
||||||
<Tag
|
|
||||||
color="blue"
|
|
||||||
style={{
|
|
||||||
marginBottom: '8px',
|
|
||||||
fontSize: '10px',
|
|
||||||
fontWeight: 500
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{sparepart.sparepart_item_type}
|
|
||||||
</Tag>
|
|
||||||
)}
|
|
||||||
<div
|
|
||||||
style={{
|
style={{
|
||||||
width: size === 'small' ? '65px' : '75px',
|
fontSize: '14px',
|
||||||
height: size === 'small' ? '65px' : '75px',
|
color: '#262626',
|
||||||
backgroundColor: '#f0f0f0',
|
marginRight: '12px'
|
||||||
borderRadius: '8px',
|
|
||||||
overflow: 'hidden',
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
border: '1px solid #e8e8e8'
|
|
||||||
}}
|
}}
|
||||||
|
title={sparepart.sparepart_name || sparepart.name || 'Unnamed'}
|
||||||
>
|
>
|
||||||
<img
|
{truncateText(sparepart.sparepart_name || sparepart.name || 'Unnamed')}
|
||||||
src={getImageSrc()}
|
</Text>
|
||||||
alt={sparepart.sparepart_name || 'Sparepart'}
|
<Tag
|
||||||
style={{
|
color={sparepart.sparepart_stok === 'Available' ? 'green' : 'red'}
|
||||||
width: '100%',
|
style={{ fontSize: '11px', margin: 0 }}
|
||||||
height: '100%',
|
>
|
||||||
objectFit: 'cover'
|
{sparepart.sparepart_stok || 'Not Available'}
|
||||||
}}
|
</Tag>
|
||||||
onError={(e) => {
|
|
||||||
e.target.src = 'https://via.placeholder.com/75';
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
{isSelected && (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
position: 'absolute',
|
|
||||||
top: '8px',
|
|
||||||
right: '8px',
|
|
||||||
backgroundColor: '#52c41a',
|
|
||||||
borderRadius: '50%',
|
|
||||||
width: '18px',
|
|
||||||
height: '18px',
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
boxShadow: '0 2px 4px rgba(0,0,0,0.15)',
|
|
||||||
zIndex: 2
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<CheckOutlined style={{ color: 'white', fontSize: '10px' }} />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div style={{ display: 'flex', alignItems: 'center', gap: '16px' }}>
|
||||||
<div style={{
|
<div style={{ display: 'flex', alignItems: 'center' }}>
|
||||||
flex: 1,
|
<Text style={{ fontSize: '12px', color: '#666', marginRight: '4px' }}>
|
||||||
padding: size === 'small' ? '12px' : '16px',
|
qty:
|
||||||
display: 'flex',
|
</Text>
|
||||||
flexDirection: 'column',
|
<Text
|
||||||
justifyContent: 'space-between',
|
|
||||||
overflow: 'hidden'
|
|
||||||
}}>
|
|
||||||
<div style={{ flex: 1, overflow: 'hidden' }}>
|
|
||||||
<Title
|
|
||||||
level={size === 'small' ? 5 : 4}
|
|
||||||
style={{
|
style={{
|
||||||
margin: `0 0 ${size === 'small' ? '6px' : '8px'} 0`,
|
fontSize: '12px',
|
||||||
fontSize: size === 'small' ? '12px' : '14px',
|
|
||||||
fontWeight: 600,
|
fontWeight: 600,
|
||||||
lineHeight: '1.4',
|
color: '#262626'
|
||||||
overflow: 'hidden',
|
|
||||||
textOverflow: 'ellipsis',
|
|
||||||
display: '-webkit-box',
|
|
||||||
WebkitLineClamp: size === 'small' ? 2 : 3,
|
|
||||||
WebkitBoxOrient: 'vertical'
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{sparepart.sparepart_name || sparepart.name || 'Unnamed'}
|
{sparepart.sparepart_qty || 0}
|
||||||
</Title>
|
</Text>
|
||||||
|
|
||||||
|
|
||||||
<div style={{ marginBottom: size === 'small' ? '6px' : '8px' }}>
|
|
||||||
|
|
||||||
<div style={{ marginBottom: '4px' }}>
|
|
||||||
<Tag
|
|
||||||
color={sparepart.sparepart_stok === 'Available' ? 'green' : 'red'}
|
|
||||||
style={{
|
|
||||||
fontSize: size === 'small' ? '9px' : '10px',
|
|
||||||
padding: '0 4px',
|
|
||||||
margin: 0,
|
|
||||||
height: 'auto'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{sparepart.sparepart_stok || 'Not Available'}
|
|
||||||
</Tag>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div style={{ display: 'flex', alignItems: 'center' }}>
|
|
||||||
<Text
|
|
||||||
style={{
|
|
||||||
fontSize: size === 'small' ? '10px' : '11px',
|
|
||||||
fontWeight: 500,
|
|
||||||
color: '#262626',
|
|
||||||
marginRight: '4px'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
qty:
|
|
||||||
</Text>
|
|
||||||
<Text
|
|
||||||
style={{
|
|
||||||
fontSize: size === 'small' ? '10px' : '11px',
|
|
||||||
color: sparepart.sparepart_qty > 0 ? '#52c41a' : '#ff4d4f',
|
|
||||||
fontWeight: 600
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{sparepart.sparepart_qty || 0}
|
|
||||||
{sparepart.sparepart_unit ? ` ${sparepart.sparepart_unit}` : ''}
|
|
||||||
</Text>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div style={{ marginBottom: size === 'small' ? '4px' : '6px' }}>
|
|
||||||
<Text
|
|
||||||
code
|
|
||||||
style={{
|
|
||||||
fontSize: size === 'small' ? '10px' : '11px',
|
|
||||||
backgroundColor: '#f5f5f5',
|
|
||||||
padding: '2px 6px',
|
|
||||||
borderRadius: '3px'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{sparepart.sparepart_code || 'No code'}
|
|
||||||
</Text>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{(sparepart.sparepart_merk || sparepart.sparepart_model) && (
|
|
||||||
<div style={{
|
|
||||||
fontSize: size === 'small' ? '9px' : '10px',
|
|
||||||
color: '#666',
|
|
||||||
lineHeight: '1.4',
|
|
||||||
marginBottom: '4px'
|
|
||||||
}}>
|
|
||||||
{sparepart.sparepart_merk && (
|
|
||||||
<div>Brand: {sparepart.sparepart_merk}</div>
|
|
||||||
)}
|
|
||||||
{sparepart.sparepart_model && (
|
|
||||||
<div>Model: {sparepart.sparepart_model}</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Text
|
|
||||||
type="secondary"
|
|
||||||
style={{
|
|
||||||
fontSize: size === 'small' ? '9px' : '10px',
|
|
||||||
marginTop: 'auto',
|
|
||||||
paddingTop: '4px',
|
|
||||||
borderTop: '1px solid #f0f0f0'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{sparepart.updated_at && dayjs(sparepart.updated_at).format('DD MMM YYYY')}
|
|
||||||
</Text>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
|
||||||
|
<Space size="small">
|
||||||
|
{showPreview && (
|
||||||
|
<Button
|
||||||
|
type="text"
|
||||||
|
icon={<EyeOutlined />}
|
||||||
|
size="small"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
handlePreview();
|
||||||
|
}}
|
||||||
|
title="Preview"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{showDelete && !isReadOnly && (
|
||||||
|
<Button
|
||||||
|
type="text"
|
||||||
|
icon={<DeleteOutlined />}
|
||||||
|
size="small"
|
||||||
|
danger
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
onDelete?.(sparepart);
|
||||||
|
}}
|
||||||
|
title="Remove"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Space>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<Modal
|
<Modal
|
||||||
|
|||||||
@@ -201,56 +201,19 @@ const ErrorCodeForm = ({
|
|||||||
error_code_color: '#000000'
|
error_code_color: '#000000'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Form.Item
|
{/* Header bar with color picker, icon upload, and status toggle */}
|
||||||
label="Status"
|
<div style={{
|
||||||
name="status"
|
display: 'flex',
|
||||||
valuePropName="checked"
|
justifyContent: 'space-between',
|
||||||
>
|
alignItems: 'flex-start',
|
||||||
<div style={{ display: 'flex', alignItems: 'center' }}>
|
marginBottom: '16px',
|
||||||
<Form.Item name="status" valuePropName="checked" noStyle>
|
gap: '16px'
|
||||||
<Switch
|
}}>
|
||||||
disabled={isErrorCodeFormReadOnly}
|
{/* Color picker on left */}
|
||||||
/>
|
<div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
|
||||||
</Form.Item>
|
|
||||||
<Text style={{ marginLeft: 8 }}>
|
|
||||||
{statusWatch ? 'Active' : 'Inactive'}
|
|
||||||
</Text>
|
|
||||||
</div>
|
|
||||||
</Form.Item>
|
|
||||||
|
|
||||||
<Form.Item
|
|
||||||
label="Error Code"
|
|
||||||
name="error_code"
|
|
||||||
rules={[{ required: true, message: 'Error code wajib diisi!' }]}
|
|
||||||
>
|
|
||||||
<Input
|
|
||||||
placeholder="Enter error code"
|
|
||||||
disabled={isErrorCodeFormReadOnly}
|
|
||||||
/>
|
|
||||||
</Form.Item>
|
|
||||||
|
|
||||||
<Form.Item
|
|
||||||
label="Error Name"
|
|
||||||
name="error_code_name"
|
|
||||||
rules={[{ required: !isErrorCodeFormReadOnly, message: 'Error name wajib diisi!' }]}
|
|
||||||
>
|
|
||||||
<Input placeholder="Enter error name" disabled={isErrorCodeFormReadOnly} />
|
|
||||||
</Form.Item>
|
|
||||||
|
|
||||||
<Form.Item label="Description" name="error_code_description">
|
|
||||||
<Input.TextArea
|
|
||||||
placeholder="Enter error description"
|
|
||||||
rows={3}
|
|
||||||
disabled={isErrorCodeFormReadOnly}
|
|
||||||
/>
|
|
||||||
</Form.Item>
|
|
||||||
|
|
||||||
<Form.Item label="Color & Icon">
|
|
||||||
<div style={{ display: 'flex', gap: '12px', alignItems: 'flex-start' }}>
|
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="error_code_color"
|
name="error_code_color"
|
||||||
noStyle
|
noStyle
|
||||||
style={{ flex: '0 0 auto' }}
|
|
||||||
getValueFromEvent={(e) => e.target.value}
|
getValueFromEvent={(e) => e.target.value}
|
||||||
getValueProps={(value) => ({ value: value || '#000000' })}
|
getValueProps={(value) => ({ value: value || '#000000' })}
|
||||||
>
|
>
|
||||||
@@ -267,11 +230,55 @@ const ErrorCodeForm = ({
|
|||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Form.Item noStyle style={{ flex: '1 1 auto' }}>
|
{/* Icon upload beside color picker */}
|
||||||
|
<div style={{ flex: 1, maxWidth: '300px' }}>
|
||||||
{renderIconUpload()}
|
{renderIconUpload()}
|
||||||
</Form.Item>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Status toggle on right */}
|
||||||
|
<div style={{ display: 'flex', alignItems: 'center' }}>
|
||||||
|
<Form.Item name="status" valuePropName="checked" noStyle>
|
||||||
|
<Switch
|
||||||
|
disabled={isErrorCodeFormReadOnly}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
<Text style={{ marginLeft: 8 }}>
|
||||||
|
{statusWatch ? 'Active' : 'Inactive'}
|
||||||
|
</Text>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Error Code and Error Name in one row with 1/3 and 2/3 ratio */}
|
||||||
|
<div style={{ display: 'flex', gap: '12px', marginBottom: '16px' }}>
|
||||||
|
<Form.Item
|
||||||
|
label="Error Code"
|
||||||
|
name="error_code"
|
||||||
|
rules={[{ required: true, message: 'Error code wajib diisi!' }]}
|
||||||
|
style={{ flex: 1, marginBottom: 0, maxWidth: '33.33%' }}
|
||||||
|
>
|
||||||
|
<Input
|
||||||
|
placeholder="Enter error code"
|
||||||
|
disabled={isErrorCodeFormReadOnly}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
<Form.Item
|
||||||
|
label="Error Name"
|
||||||
|
name="error_code_name"
|
||||||
|
rules={[{ required: !isErrorCodeFormReadOnly, message: 'Error name wajib diisi!' }]}
|
||||||
|
style={{ flex: 2, marginBottom: 0, maxWidth: '66.67%' }}
|
||||||
|
>
|
||||||
|
<Input placeholder="Enter error name" disabled={isErrorCodeFormReadOnly} />
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Form.Item label="Description" name="error_code_description">
|
||||||
|
<Input.TextArea
|
||||||
|
placeholder="Enter error description"
|
||||||
|
rows={3}
|
||||||
|
disabled={isErrorCodeFormReadOnly}
|
||||||
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
</ConfigProvider>
|
</ConfigProvider>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import { Select, Typography, Tag, Spin, Empty, Button, Row, Col } from 'antd';
|
import { Select, Typography, Tag, Spin, Empty, Button } from 'antd';
|
||||||
import { PlusOutlined, DeleteOutlined, CheckOutlined, EyeOutlined, InfoCircleOutlined } from '@ant-design/icons';
|
import { PlusOutlined, DeleteOutlined, CheckOutlined, EyeOutlined, InfoCircleOutlined } from '@ant-design/icons';
|
||||||
import { getAllSparepart } from '../../../../api/sparepart';
|
import { getAllSparepart } from '../../../../api/sparepart';
|
||||||
import CustomSparepartCard from './CustomSparepartCard';
|
import CustomSparepartCard from './CustomSparepartCard';
|
||||||
@@ -96,20 +96,16 @@ const SparepartSelect = ({
|
|||||||
const isAlreadySelected = selectedSpareparts.some(sp => sp.sparepart_id === sparepart.sparepart_id);
|
const isAlreadySelected = selectedSpareparts.some(sp => sp.sparepart_id === sparepart.sparepart_id);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Col xs={24} sm={24} md={12} lg={12} key={sparepart.sparepart_id}>
|
<CustomSparepartCard
|
||||||
<CustomSparepartCard
|
key={sparepart.sparepart_id}
|
||||||
sparepart={sparepart}
|
sparepart={sparepart}
|
||||||
isSelected={isSelected}
|
isSelected={isSelected}
|
||||||
isReadOnly={isReadOnly}
|
isReadOnly={isReadOnly}
|
||||||
showPreview={true}
|
showPreview={true}
|
||||||
showDelete={isAlreadySelected && !isReadOnly}
|
showDelete={isAlreadySelected && !isReadOnly}
|
||||||
onCardClick={!isAlreadySelected && !isReadOnly ? () => handleSparepartSelect(sparepart.sparepart_id) : undefined}
|
onCardClick={!isAlreadySelected && !isReadOnly ? () => handleSparepartSelect(sparepart.sparepart_id) : undefined}
|
||||||
onDelete={() => handleRemoveSparepart(sparepart.sparepart_id)}
|
onDelete={() => handleRemoveSparepart(sparepart.sparepart_id)}
|
||||||
style={{
|
/>
|
||||||
border: isAlreadySelected ? '2px solid #52c41a' : undefined,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Col>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -163,9 +159,9 @@ const SparepartSelect = ({
|
|||||||
<Title level={5} style={{ marginBottom: 16 }}>
|
<Title level={5} style={{ marginBottom: 16 }}>
|
||||||
Selected Spareparts ({selectedSpareparts.length})
|
Selected Spareparts ({selectedSpareparts.length})
|
||||||
</Title>
|
</Title>
|
||||||
<Row gutter={[16, 16]}>
|
<div>
|
||||||
{selectedSpareparts.map(sparepart => renderSparepartCard(sparepart, true))}
|
{selectedSpareparts.map(sparepart => renderSparepartCard(sparepart, true))}
|
||||||
</Row>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<Empty
|
<Empty
|
||||||
|
|||||||
Reference in New Issue
Block a user