diff --git a/src/api/master-tag.jsx b/src/api/master-tag.jsx index eeec3c8..f6a8eca 100644 --- a/src/api/master-tag.jsx +++ b/src/api/master-tag.jsx @@ -6,8 +6,6 @@ const getAllTag = async (queryParams) => { method: 'get', prefix: `tags?${queryParams.toString()}`, }); - console.log('getAllTag response:', response); - console.log('Query params:', queryParams.toString()); // Check if response has error if (response.error) { @@ -106,8 +104,6 @@ const createTag = async (queryParams) => { prefix: `tags`, params: queryParams, }); - console.log('createTag full response:', response); - console.log('createTag payload sent:', queryParams); // Check if response has error flag if (response.error) { @@ -134,8 +130,6 @@ const updateTag = async (tag_id, queryParams) => { prefix: `tags/${tag_id}`, params: queryParams, }); - console.log('updateTag full response:', response); - console.log('updateTag payload sent:', queryParams); // Check if response has error flag if (response.error) { @@ -161,7 +155,6 @@ const deleteTag = async (queryParams) => { method: 'delete', prefix: `tags/${queryParams}`, }); - console.log('deleteTag full response:', response); // Check if response has error flag if (response.error) { diff --git a/src/pages/master/tag/component/DetailTag.jsx b/src/pages/master/tag/component/DetailTag.jsx index 754d49e..4eae340 100644 --- a/src/pages/master/tag/component/DetailTag.jsx +++ b/src/pages/master/tag/component/DetailTag.jsx @@ -1,20 +1,27 @@ import { useEffect, useState } from 'react'; -import { Modal, Input, Divider, Typography, Button, ConfigProvider, Select } from 'antd'; +import { Modal, Input, Typography, Button, ConfigProvider, Switch, Select } from 'antd'; import { NotifAlert, NotifOk } from '../../../../components/Global/ToastNotif'; +import { createTag, updateTag } from '../../../../api/master-tag'; +import { getAllDevice } from '../../../../api/master-device'; const { Text } = Typography; -const { TextArea } = Input; const DetailTag = (props) => { const [confirmLoading, setConfirmLoading] = useState(false); + const [deviceList, setDeviceList] = useState([]); + const [loadingDevices, setLoadingDevices] = useState(false); const defaultData = { tag_id: '', tag_code: '', tag_name: '', - tag_value: 'Off', - tag_type: 'alarm', - tag_description: '', + tag_number: '', + data_type: '', + unit: '', + device_name: '', // Read-only, auto-display dari device yang dipilih + is_active: true, + device_id: null, // akan set ketika user select device dari dropdown + sub_section_id: null, }; const [FormData, setFormData] = useState(defaultData); @@ -27,18 +34,8 @@ const DetailTag = (props) => { const handleSave = async () => { setConfirmLoading(true); - // Validasi required fields - if (!FormData.tag_code) { - NotifOk({ - icon: 'warning', - title: 'Peringatan', - message: 'Kolom Tag Code Tidak Boleh Kosong', - }); - setConfirmLoading(false); - return; - } - - if (!FormData.tag_name) { + // Validasi required fields untuk CREATE + if (!FormData.tag_name || FormData.tag_name.trim() === '') { NotifOk({ icon: 'warning', title: 'Peringatan', @@ -48,55 +45,114 @@ const DetailTag = (props) => { return; } - if (!FormData.tag_value) { + if (!FormData.tag_number || FormData.tag_number === '') { NotifOk({ icon: 'warning', title: 'Peringatan', - message: 'Kolom Tag Value Tidak Boleh Kosong', + message: 'Kolom Tag Number Tidak Boleh Kosong', }); setConfirmLoading(false); return; } - if (!FormData.tag_type) { + // Validasi format number untuk tag_number + const tagNumberInt = parseInt(FormData.tag_number); + if (isNaN(tagNumberInt)) { NotifOk({ icon: 'warning', title: 'Peringatan', - message: 'Kolom Tag Type Tidak Boleh Kosong', + message: 'Tag Number harus berupa angka yang valid', }); setConfirmLoading(false); return; } - const payload = { - tag_code: FormData.tag_code, - tag_name: FormData.tag_name, - tag_value: FormData.tag_value, - tag_type: FormData.tag_type, - tag_description: FormData.tag_description, - }; + if (!FormData.data_type || FormData.data_type.trim() === '') { + NotifOk({ + icon: 'warning', + title: 'Peringatan', + message: 'Kolom Data Type Tidak Boleh Kosong', + }); + setConfirmLoading(false); + return; + } + + if (!FormData.unit || FormData.unit.trim() === '') { + NotifOk({ + icon: 'warning', + title: 'Peringatan', + message: 'Kolom Unit Tidak Boleh Kosong', + }); + setConfirmLoading(false); + return; + } + + // Device validation + if (!FormData.device_id) { + NotifOk({ + icon: 'warning', + title: 'Peringatan', + message: 'Device harus dipilih', + }); + setConfirmLoading(false); + return; + } + + // Prepare payload berdasarkan backend validation schema + let payload; + + if (FormData.tag_id) { + payload = {}; + + if (FormData.tag_name && FormData.tag_name.trim() !== '') { + payload.tag_name = FormData.tag_name; + } + if (FormData.tag_number && FormData.tag_number !== '') { + payload.tag_number = parseInt(FormData.tag_number); + } + if (FormData.data_type && FormData.data_type.trim() !== '') { + payload.data_type = FormData.data_type; + } + if (FormData.unit && FormData.unit.trim() !== '') { + payload.unit = FormData.unit; + } + if (FormData.device_id) { + payload.device_id = parseInt(FormData.device_id); + } + payload.is_active = FormData.is_active; + } else { + // CREATE: device_id hardcoded + payload = { + tag_name: FormData.tag_name, + tag_number: parseInt(FormData.tag_number), + data_type: FormData.data_type, + unit: FormData.unit, + is_active: FormData.is_active, + device_id: parseInt(FormData.device_id), // Hardcoded dari defaultData (9) + }; + } try { - // Simulate API call - await new Promise((resolve) => setTimeout(resolve, 500)); + let response; - const response = { - statusCode: FormData.tag_id ? 200 : 201, - data: { - tag_name: FormData.tag_name, - }, - }; - - console.log('Save Tag Response:', response); + if (FormData.tag_id) { + // Update existing tag + response = await updateTag(FormData.tag_id, payload); + } else { + // Create new tag + response = await createTag(payload); + } // Check if response is successful if (response && (response.statusCode === 200 || response.statusCode === 201)) { NotifOk({ icon: 'success', title: 'Berhasil', - message: `Data Tag "${response.data?.tag_name || FormData.tag_name}" berhasil ${ - FormData.tag_id ? 'diubah' : 'ditambahkan' - }.`, + message: + response.message || + `Data Tag "${response.data?.tag_name || FormData.tag_name}" berhasil ${ + FormData.tag_id ? 'diubah' : 'ditambahkan' + }.`, }); props.setActionMode('list'); @@ -134,11 +190,60 @@ const DetailTag = (props) => { }); }; + const handleDeviceChange = (deviceId) => { + const selectedDevice = deviceList.find((device) => device.device_id === deviceId); + setFormData({ + ...FormData, + device_id: deviceId, + device_name: selectedDevice ? selectedDevice.device_name : '', + }); + }; + + const handleStatusToggle = (isChecked) => { + setFormData({ + ...FormData, + is_active: isChecked, + }); + }; + + const loadDevices = async () => { + setLoadingDevices(true); + try { + const params = new URLSearchParams({ limit: 1000 }); + const response = await getAllDevice(params); + if (response && response.data && response.data.data) { + setDeviceList(response.data.data); + } + } catch (error) { + console.error('Error loading devices:', error); + } finally { + setLoadingDevices(false); + } + }; + useEffect(() => { const token = localStorage.getItem('token'); if (token) { + if (props.showModal) { + // Load devices when modal opens + loadDevices(); + } + if (props.selectedData != null) { - setFormData(props.selectedData); + // Only set fields that are in defaultData to avoid sending extra fields + const filteredData = { + tag_id: props.selectedData.tag_id || '', + tag_code: props.selectedData.tag_code || '', + tag_name: props.selectedData.tag_name || '', + tag_number: props.selectedData.tag_number || '', + data_type: props.selectedData.data_type || '', + unit: props.selectedData.unit || '', + device_name: props.selectedData.device_name || '', + is_active: props.selectedData.is_active ?? true, + device_id: props.selectedData.device_id || null, + sub_section_id: props.selectedData.sub_section_id || null, + }; + setFormData(filteredData); } else { setFormData(defaultData); } @@ -169,8 +274,6 @@ const DetailTag = (props) => { defaultColor: '#23A55A', defaultBorderColor: '#23A55A', defaultHoverColor: '#23A55A', - defaultHoverBorderColor: '#23A55A', - defaultHoverColor: '#23A55A', }, }, }} @@ -213,17 +316,19 @@ const DetailTag = (props) => { disabled /> -
- Tag Code - * - -
+ {/* Tag Code hanya ditampilkan saat EDIT atau PREVIEW */} + {(props.actionMode === 'edit' || props.actionMode === 'preview') && ( +
+ Tag Code + +
+ )}
Tag Name * @@ -236,47 +341,97 @@ const DetailTag = (props) => { />
- Tag Value + Tag Number * - handleSelectChange('tag_type', value)} - disabled={props.readOnly} - style={{ width: '100%' }} - placeholder="Select Type" - options={[ - { value: 'alarm', label: 'Alarm' }, - { value: 'measurement', label: 'Measurement' }, - ]} - /> -
-
- Tag Description -