feat: enhance DetailTag and ListTag components with improved device handling and search functionality

This commit is contained in:
2025-10-14 14:40:01 +07:00
parent 251ad44371
commit eb90d89e0e
2 changed files with 111 additions and 86 deletions

View File

@@ -188,6 +188,7 @@ const DetailTag = (props) => {
const params = new URLSearchParams({ limit: 1000 });
const response = await getAllDevice(params);
if (response && response.data && response.data.data) {
console.log('Loaded devices:', response.data.data); // Debug
setDeviceList(response.data.data);
}
} catch (error) {
@@ -305,82 +306,7 @@ const DetailTag = (props) => {
/>
</div>
)}
<div style={{ marginBottom: 12 }}>
<Text strong>Tag Name</Text>
<Text style={{ color: 'red' }}> *</Text>
<Input
name="tag_name"
value={FormData.tag_name}
onChange={handleInputChange}
placeholder="Enter Tag Name"
readOnly={props.readOnly}
/>
</div>
<div style={{ marginBottom: 12 }}>
<Text strong>Tag Number</Text>
<Text style={{ color: 'red' }}> *</Text>
<Input
name="tag_number"
value={FormData.tag_number}
onChange={handleInputChange}
placeholder="Enter Tag Number"
readOnly={props.readOnly}
/>
</div>
<div style={{ marginBottom: 12 }}>
<Text strong>Data Type</Text>
<Text style={{ color: 'red' }}> *</Text>
<Input
name="data_type"
value={FormData.data_type}
onChange={handleInputChange}
placeholder="Enter Data Type"
readOnly={props.readOnly}
/>
</div>
<div style={{ marginBottom: 12 }}>
<Text strong>Unit</Text>
<Text style={{ color: 'red' }}> *</Text>
<Input
name="unit"
value={FormData.unit}
onChange={handleInputChange}
placeholder="Enter Unit"
readOnly={props.readOnly}
/>
</div>
<div style={{ marginBottom: 12 }}>
<Text strong>Device Code</Text>
<Text style={{ color: 'red' }}> *</Text>
<Select
style={{ width: '100%' }}
placeholder="Select Device Code"
value={FormData.device_id || undefined}
onChange={handleDeviceChange}
disabled={props.readOnly}
loading={loadingDevices}
showSearch
filterOption={(input, option) =>
(option?.label ?? '').toLowerCase().includes(input.toLowerCase())
}
options={deviceList.map((device) => ({
value: device.device_id,
label: device.device_code || '',
}))}
/>
</div>
<div style={{ marginBottom: 12 }}>
<Text strong>Device Name</Text>
<Input
name="device_name"
value={FormData.device_name}
placeholder="Auto-filled from selected device code"
disabled
style={{ backgroundColor: '#f5f5f5' }}
/>
</div>
{/* Device ID hidden - value dari dropdown */}
<input type="hidden" name="device_id" value={FormData.device_id || ''} />
{/* Status dipindah ke atas Tag Name */}
<div style={{ marginBottom: 12 }}>
<div>
<Text strong>Status</Text>
@@ -408,6 +334,91 @@ const DetailTag = (props) => {
</div>
</div>
</div>
<div style={{ marginBottom: 12 }}>
<Text strong>Tag Name</Text>
<Text style={{ color: 'red' }}> *</Text>
<Input
name="tag_name"
value={FormData.tag_name}
onChange={handleInputChange}
placeholder="Enter Tag Name"
readOnly={props.readOnly}
/>
</div>
<div style={{ marginBottom: 12 }}>
<Text strong>Tag Number</Text>
<Text style={{ color: 'red' }}> *</Text>
<Input
name="tag_number"
value={FormData.tag_number}
onChange={handleInputChange}
placeholder="Enter Tag Number"
readOnly={props.readOnly}
/>
</div>
<div style={{ marginBottom: 12 }}>
<Text strong>Data Type</Text>
<Text style={{ color: 'red' }}> *</Text>
<Select
style={{ width: '100%' }}
placeholder="Select Data Type"
value={FormData.data_type || undefined}
onChange={(value) => handleSelectChange('data_type', value)}
disabled={props.readOnly}
>
<Select.Option value="Diskrit">Diskrit</Select.Option>
<Select.Option value="Analog">Analog</Select.Option>
</Select>
</div>
<div style={{ marginBottom: 12 }}>
<Text strong>Unit</Text>
<Text style={{ color: 'red' }}> *</Text>
<Input
name="unit"
value={FormData.unit}
onChange={handleInputChange}
placeholder="Enter Unit"
readOnly={props.readOnly}
/>
</div>
<div style={{ marginBottom: 12 }}>
<Text strong>Device Code</Text>
<Text style={{ color: 'red' }}> *</Text>
<Select
style={{ width: '100%' }}
placeholder="Search device by code, name, or type..."
value={FormData.device_id || undefined}
onChange={handleDeviceChange}
disabled={props.readOnly}
loading={loadingDevices}
showSearch
allowClear
optionFilterProp="children"
filterOption={(input, option) => {
const text = option.children;
if (!text) return false;
return text.toLowerCase().includes(input.toLowerCase());
}}
>
{deviceList.map((device) => (
<Select.Option key={device.device_id} value={device.device_id}>
{device.device_code || ''}
</Select.Option>
))}
</Select>
</div>
<div style={{ marginBottom: 12 }}>
<Text strong>Device Name</Text>
<Input
name="device_name"
value={FormData.device_name}
placeholder="Auto-filled from selected device code"
disabled
style={{ backgroundColor: '#f5f5f5' }}
/>
</div>
{/* Device ID hidden - value dari dropdown */}
<input type="hidden" name="device_id" value={FormData.device_id || ''} />
</div>
)}
</Modal>

View File

@@ -115,7 +115,15 @@ const columns = (showPreviewModal, showEditModal, showDeleteDialog) => [
const ListTag = memo(function ListTag(props) {
const [trigerFilter, setTrigerFilter] = useState(false);
const defaultFilter = { search: '' };
const defaultFilter = {
criteria: '', // Global search (OR condition)
name: '',
code: '',
data: '',
unit: '',
device: '',
subsection: '',
};
const [formDataFilter, setFormDataFilter] = useState(defaultFilter);
const [searchValue, setSearchValue] = useState('');
@@ -132,18 +140,19 @@ const ListTag = memo(function ListTag(props) {
}
}, [props.actionMode]);
useEffect(() => {
// Memicu filter setiap kali formDataFilter berubah
doFilter();
}, [formDataFilter]);
const doFilter = () => {
setTrigerFilter((prev) => !prev);
};
const handleSearch = (value) => {
setSearchValue(value);
setFormDataFilter({ search: value });
const handleSearch = () => {
setFormDataFilter((prev) => ({ ...prev, criteria: searchValue }));
doFilter();
};
const handleSearchClear = () => {
setSearchValue('');
setFormDataFilter((prev) => ({ ...prev, criteria: '' }));
doFilter();
};
const showPreviewModal = (param) => {
props.setSelectedData(param);
@@ -210,11 +219,16 @@ const ListTag = memo(function ListTag(props) {
placeholder="Search tag by code, name, or type..."
value={searchValue}
onChange={(e) => {
const { value } = e.target;
const value = e.target.value;
setSearchValue(value);
// Auto search when clearing by backspace/delete
if (value === '') {
handleSearchClear();
}
}}
onSearch={handleSearch}
allowClear
onClear={handleSearchClear}
enterButton={
<Button
type="primary"