lavoce #2
@@ -188,6 +188,7 @@ const DetailTag = (props) => {
|
|||||||
const params = new URLSearchParams({ limit: 1000 });
|
const params = new URLSearchParams({ limit: 1000 });
|
||||||
const response = await getAllDevice(params);
|
const response = await getAllDevice(params);
|
||||||
if (response && response.data && response.data.data) {
|
if (response && response.data && response.data.data) {
|
||||||
|
console.log('Loaded devices:', response.data.data); // Debug
|
||||||
setDeviceList(response.data.data);
|
setDeviceList(response.data.data);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -305,82 +306,7 @@ const DetailTag = (props) => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div style={{ marginBottom: 12 }}>
|
{/* Status dipindah ke atas Tag Name */}
|
||||||
<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 || ''} />
|
|
||||||
<div style={{ marginBottom: 12 }}>
|
<div style={{ marginBottom: 12 }}>
|
||||||
<div>
|
<div>
|
||||||
<Text strong>Status</Text>
|
<Text strong>Status</Text>
|
||||||
@@ -408,6 +334,91 @@ const DetailTag = (props) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</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>
|
</div>
|
||||||
)}
|
)}
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|||||||
@@ -115,7 +115,15 @@ const columns = (showPreviewModal, showEditModal, showDeleteDialog) => [
|
|||||||
const ListTag = memo(function ListTag(props) {
|
const ListTag = memo(function ListTag(props) {
|
||||||
const [trigerFilter, setTrigerFilter] = useState(false);
|
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 [formDataFilter, setFormDataFilter] = useState(defaultFilter);
|
||||||
const [searchValue, setSearchValue] = useState('');
|
const [searchValue, setSearchValue] = useState('');
|
||||||
|
|
||||||
@@ -132,18 +140,19 @@ const ListTag = memo(function ListTag(props) {
|
|||||||
}
|
}
|
||||||
}, [props.actionMode]);
|
}, [props.actionMode]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
// Memicu filter setiap kali formDataFilter berubah
|
|
||||||
doFilter();
|
|
||||||
}, [formDataFilter]);
|
|
||||||
|
|
||||||
const doFilter = () => {
|
const doFilter = () => {
|
||||||
setTrigerFilter((prev) => !prev);
|
setTrigerFilter((prev) => !prev);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSearch = (value) => {
|
const handleSearch = () => {
|
||||||
setSearchValue(value);
|
setFormDataFilter((prev) => ({ ...prev, criteria: searchValue }));
|
||||||
setFormDataFilter({ search: value });
|
doFilter();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSearchClear = () => {
|
||||||
|
setSearchValue('');
|
||||||
|
setFormDataFilter((prev) => ({ ...prev, criteria: '' }));
|
||||||
|
doFilter();
|
||||||
};
|
};
|
||||||
const showPreviewModal = (param) => {
|
const showPreviewModal = (param) => {
|
||||||
props.setSelectedData(param);
|
props.setSelectedData(param);
|
||||||
@@ -210,11 +219,16 @@ const ListTag = memo(function ListTag(props) {
|
|||||||
placeholder="Search tag by code, name, or type..."
|
placeholder="Search tag by code, name, or type..."
|
||||||
value={searchValue}
|
value={searchValue}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
const { value } = e.target;
|
const value = e.target.value;
|
||||||
setSearchValue(value);
|
setSearchValue(value);
|
||||||
|
// Auto search when clearing by backspace/delete
|
||||||
|
if (value === '') {
|
||||||
|
handleSearchClear();
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
onSearch={handleSearch}
|
onSearch={handleSearch}
|
||||||
allowClear
|
allowClear
|
||||||
|
onClear={handleSearchClear}
|
||||||
enterButton={
|
enterButton={
|
||||||
<Button
|
<Button
|
||||||
type="primary"
|
type="primary"
|
||||||
|
|||||||
Reference in New Issue
Block a user