From 3b413474f67f917b3539d1a380e2768c4a28c69d Mon Sep 17 00:00:00 2001 From: totregex Date: Sun, 24 Nov 2024 10:28:40 +0530 Subject: [PATCH 1/7] fix api call issue #9198 --- src/components/Facility/AssetCreate.tsx | 147 +++++++++++++++++++++--- 1 file changed, 129 insertions(+), 18 deletions(-) diff --git a/src/components/Facility/AssetCreate.tsx b/src/components/Facility/AssetCreate.tsx index 5c507bb0a18..4e2f2372ec2 100644 --- a/src/components/Facility/AssetCreate.tsx +++ b/src/components/Facility/AssetCreate.tsx @@ -1,5 +1,6 @@ import { IDetectedBarcode, Scanner } from "@yudiel/react-qr-scanner"; import { navigate } from "raviger"; +import { useRef } from "react"; import { LegacyRef, MutableRefObject, @@ -109,6 +110,45 @@ const AssetCreate = (props: AssetProps) => { let assetClassInitial: AssetClass; + const [initialValues, setInitialValues] = useState<{ + name: string; + description: string; + location: string; + asset_class: AssetClass | undefined; + is_working: string | undefined; + not_working_reason: string; + serial_number: string; + vendor_name: string; + support_name: string; + support_email: string; + support_phone: string; + qr_code_id: string; + manufacturer: string; + warranty_amc_end_of_validity: any; + last_serviced_on: any; + notes: string; + }>({ + name: "", + description: "", + location: "", + asset_class: undefined, + is_working: undefined, + not_working_reason: "", + serial_number: "", + vendor_name: "", + support_name: "", + support_email: "", + support_phone: "", + qr_code_id: "", + manufacturer: "", + warranty_amc_end_of_validity: null, + last_serviced_on: null, + notes: "", + }); + + const [isButtonEnabled, setIsButtonEnabled] = useState(false); + const isInitialLoad = useRef(true); + const [state, dispatch] = useReducer(asset_create_reducer, initialState); const [name, setName] = useState(""); const [asset_class, setAssetClass] = useState(); @@ -182,27 +222,96 @@ const AssetCreate = (props: AssetProps) => { onResponse: ({ data: asset }) => { if (!asset) return; - setName(asset.name); - setDescription(asset.description); - setLocation(asset.location_object.id!); - setAssetClass(asset.asset_class); - setIsWorking(String(asset.is_working)); - setNotWorkingReason(asset.not_working_reason); - setSerialNumber(asset.serial_number); - setVendorName(asset.vendor_name); - setSupportName(asset.support_name); - setSupportEmail(asset.support_email); - setSupportPhone(asset.support_phone); - setQrCodeId(asset.qr_code_id); - setManufacturer(asset.manufacturer); - asset.warranty_amc_end_of_validity && - setWarrantyAmcEndOfValidity(asset.warranty_amc_end_of_validity); - asset.last_service?.serviced_on && - setLastServicedOn(asset.last_service?.serviced_on); - asset.last_service?.note && setNotes(asset.last_service?.note); + const fetchedValues = { + name: asset.name || "", + description: asset.description || "", + location: asset.location_object.id! || "", + asset_class: asset.asset_class, + is_working: String(asset.is_working), + not_working_reason: asset.not_working_reason || "", + serial_number: asset.serial_number || "", + vendor_name: asset.vendor_name || "", + support_name: asset.support_name || "", + support_email: asset.support_email || "", + support_phone: asset.support_phone || "", + qr_code_id: asset.qr_code_id || "", + manufacturer: asset.manufacturer || "", + warranty_amc_end_of_validity: asset.warranty_amc_end_of_validity, + last_serviced_on: asset.last_service?.serviced_on || null, + notes: asset.last_service?.note || "", + }; + + setInitialValues(fetchedValues); + + setName(fetchedValues.name); + setDescription(fetchedValues.description); + setLocation(fetchedValues.location); + setAssetClass(fetchedValues.asset_class); + setIsWorking(fetchedValues.is_working); + setNotWorkingReason(fetchedValues.not_working_reason); + setSerialNumber(fetchedValues.serial_number); + setVendorName(fetchedValues.vendor_name); + setSupportName(fetchedValues.support_name); + setSupportEmail(fetchedValues.support_email); + setSupportPhone(fetchedValues.support_phone); + setQrCodeId(fetchedValues.qr_code_id); + setManufacturer(fetchedValues.manufacturer); + setWarrantyAmcEndOfValidity(fetchedValues.warranty_amc_end_of_validity); + setLastServicedOn(fetchedValues.last_serviced_on); + setNotes(fetchedValues.notes); + + isInitialLoad.current = false; }, }); + useEffect(() => { + if (isInitialLoad.current) return; + + const currentValues = { + name, + description, + location, + asset_class, + is_working, + not_working_reason, + serial_number, + vendor_name, + support_name, + support_email, + support_phone, + qr_code_id: qrCodeId, + manufacturer, + warranty_amc_end_of_validity, + last_serviced_on, + notes, + }; + console.log("Initial Values " + currentValues); + + const isChanged = ( + Object.keys(currentValues) as Array + ).some((key) => currentValues[key] !== initialValues[key]); + + setIsButtonEnabled(isChanged); + }, [ + name, + description, + location, + asset_class, + is_working, + not_working_reason, + serial_number, + vendor_name, + support_name, + support_email, + support_phone, + qrCodeId, + manufacturer, + warranty_amc_end_of_validity, + last_serviced_on, + notes, + initialValues, + ]); + const validateForm = () => { const errors = { ...initError }; let invalidForm = false; @@ -893,12 +1002,14 @@ const AssetCreate = (props: AssetProps) => { handleSubmit(e, false)} label={assetId ? t("update") : t("create_asset")} + disabled={!isButtonEnabled} /> {!assetId && ( handleSubmit(e, true)} label={t("create_add_more")} + disabled={!isButtonEnabled} /> )} From 20634fb6c6796b9267d65a7dfef669d7b706193b Mon Sep 17 00:00:00 2001 From: totregex Date: Mon, 25 Nov 2024 16:28:22 +0530 Subject: [PATCH 2/7] make assetCreate page to use Form component --- src/components/Facility/AssetCreate.tsx | 1413 ++++++++++++----------- 1 file changed, 742 insertions(+), 671 deletions(-) diff --git a/src/components/Facility/AssetCreate.tsx b/src/components/Facility/AssetCreate.tsx index 4e2f2372ec2..3747be6e2b2 100644 --- a/src/components/Facility/AssetCreate.tsx +++ b/src/components/Facility/AssetCreate.tsx @@ -1,13 +1,11 @@ import { IDetectedBarcode, Scanner } from "@yudiel/react-qr-scanner"; import { navigate } from "raviger"; -import { useRef } from "react"; import { LegacyRef, MutableRefObject, RefObject, createRef, useEffect, - useReducer, useState, } from "react"; import { useTranslation } from "react-i18next"; @@ -15,7 +13,6 @@ import { useTranslation } from "react-i18next"; import CareIcon, { IconName } from "@/CAREUI/icons/CareIcon"; import { AssetClass, AssetType } from "@/components/Assets/AssetTypes"; -import { Cancel, Submit } from "@/components/Common/ButtonV2"; import Loading from "@/components/Common/Loading"; import { LocationSelect } from "@/components/Common/LocationSelect"; import Page from "@/components/Common/Page"; @@ -43,6 +40,10 @@ import request from "@/Utils/request/request"; import useQuery from "@/Utils/request/useQuery"; import { dateQueryString, parsePhoneNumber } from "@/Utils/utils"; +import { FieldError, RequiredFieldValidator } from "../Form/FieldValidators"; +import Form from "../Form/Form"; +import { FormErrors } from "../Form/Utils"; + const formErrorKeys = [ "name", "asset_class", @@ -56,17 +57,35 @@ const formErrorKeys = [ "support_email", "manufacturer", "warranty_amc_end_of_validity", - "last_serviced_on", + "last_serviced", "notes", ]; -const initError = formErrorKeys.reduce( - (acc: { [key: string]: string }, key) => { - acc[key] = ""; - return acc; - }, - {}, -); +interface AssetT { + id?: string; + name?: string; + location?: string; + description?: string; + is_working?: boolean; + not_working_reason?: string; + created_date?: string; + modified_date?: string; + serial_number?: string; + asset_type?: AssetType; + asset_class?: AssetClass; + status?: "ACTIVE" | "TRANSFER_IN_PROGRESS"; + vendor_name?: string; + support_name?: string; + support_email?: string; + support_phone?: string; + qr_code_id?: string; + manufacturer?: string; + warranty_amc_end_of_validity?: string; + serviced_on?: string; + latest_status?: string; + last_service?: any; + notes: string; +} const fieldRef = formErrorKeys.reduce( (acc: { [key: string]: RefObject }, key) => { @@ -76,27 +95,27 @@ const fieldRef = formErrorKeys.reduce( {}, ); -const initialState = { - errors: { ...initError }, -}; +// const initialState = { +// errors: { ...initError }, +// }; interface AssetProps { facilityId: string; assetId?: string; } -const asset_create_reducer = (state = initialState, action: any) => { - switch (action.type) { - case "set_error": { - return { - ...state, - errors: action.errors, - }; - } - default: - return state; - } -}; +// const asset_create_reducer = (state = initialState, action: any) => { +// switch (action.type) { +// case "set_error": { +// return { +// ...state, +// errors: action.errors, +// }; +// } +// default: +// return state; +// } +// }; type AssetFormSection = | "General Details" @@ -108,66 +127,55 @@ const AssetCreate = (props: AssetProps) => { const { t } = useTranslation(); const { facilityId, assetId } = props; - let assetClassInitial: AssetClass; - - const [initialValues, setInitialValues] = useState<{ - name: string; - description: string; - location: string; - asset_class: AssetClass | undefined; - is_working: string | undefined; - not_working_reason: string; - serial_number: string; - vendor_name: string; - support_name: string; - support_email: string; - support_phone: string; - qr_code_id: string; - manufacturer: string; - warranty_amc_end_of_validity: any; - last_serviced_on: any; - notes: string; - }>({ + const initialAssetData: AssetT = { + id: "", name: "", - description: "", location: "", - asset_class: undefined, - is_working: undefined, + description: "", + is_working: false, not_working_reason: "", + created_date: "", + modified_date: "", serial_number: "", + asset_type: undefined, + asset_class: undefined, + status: "ACTIVE", vendor_name: "", support_name: "", support_email: "", support_phone: "", qr_code_id: "", manufacturer: "", - warranty_amc_end_of_validity: null, - last_serviced_on: null, + warranty_amc_end_of_validity: "", + latest_status: "", + last_service: null, + serviced_on: "", notes: "", - }); + }; + + // State to store asset data + const [initAssetData, setinitialAssetData] = + useState(initialAssetData); - const [isButtonEnabled, setIsButtonEnabled] = useState(false); - const isInitialLoad = useRef(true); - - const [state, dispatch] = useReducer(asset_create_reducer, initialState); - const [name, setName] = useState(""); - const [asset_class, setAssetClass] = useState(); - const [not_working_reason, setNotWorkingReason] = useState(""); - const [description, setDescription] = useState(""); - const [is_working, setIsWorking] = useState(undefined); - const [serial_number, setSerialNumber] = useState(""); - const [vendor_name, setVendorName] = useState(""); - const [support_name, setSupportName] = useState(""); - const [support_phone, setSupportPhone] = useState(""); - const [support_email, setSupportEmail] = useState(""); - const [location, setLocation] = useState(""); + // const [state, dispatch] = useReducer(asset_create_reducer, initialState); + // const [name, setName] = useState(""); + // const [asset_class, setAssetClass] = useState(); + // const [not_working_reason, setNotWorkingReason] = useState(""); + // const [description, setDescription] = useState(""); + // const [is_working, setIsWorking] = useState(undefined); + // const [serial_number, setSerialNumber] = useState(""); + // const [vendor_name, setVendorName] = useState(""); + // const [support_name, setSupportName] = useState(""); + // const [support_phone, setSupportPhone] = useState(""); + // const [support_email, setSupportEmail] = useState(""); + // const [location, setLocation] = useState(""); const [isLoading, setIsLoading] = useState(false); - const [qrCodeId, setQrCodeId] = useState(""); - const [manufacturer, setManufacturer] = useState(""); - const [warranty_amc_end_of_validity, setWarrantyAmcEndOfValidity] = - useState(null); - const [last_serviced_on, setLastServicedOn] = useState(null); - const [notes, setNotes] = useState(""); + // const [qrCodeId, setQrCodeId] = useState(""); + // const [manufacturer, setManufacturer] = useState(""); + // const [warranty_amc_end_of_validity, setWarrantyAmcEndOfValidity] = + // useState(null); + // const [last_serviced_on, setLastServicedOn] = useState(null); + // const [notes, setNotes] = useState(""); const [isScannerActive, setIsScannerActive] = useState(false); const [currentSection, setCurrentSection] = @@ -216,255 +224,327 @@ const AssetCreate = (props: AssetProps) => { query: { limit: 1 }, }); + // const assetQuery = useQuery(routes.getAsset, { + // pathParams: { external_id: assetId! }, + // prefetch: !!assetId, + // onResponse: ({ data: asset }) => { + // if (!asset) return; + + // setName(asset.name); + // setDescription(asset.description); + // setLocation(asset.location_object.id!); + // setAssetClass(asset.asset_class); + // setIsWorking(String(asset.is_working)); + // setNotWorkingReason(asset.not_working_reason); + // setSerialNumber(asset.serial_number); + // setVendorName(asset.vendor_name); + // setSupportName(asset.support_name); + // setSupportEmail(asset.support_email); + // setSupportPhone(asset.support_phone); + // setQrCodeId(asset.qr_code_id); + // setManufacturer(asset.manufacturer); + // asset.warranty_amc_end_of_validity && + // setWarrantyAmcEndOfValidity(asset.warranty_amc_end_of_validity); + // asset.last_service?.serviced_on && + // setLastServicedOn(asset.last_service?.serviced_on); + // asset.last_service?.note && setNotes(asset.last_service?.note); + // }, + // }); + const assetQuery = useQuery(routes.getAsset, { pathParams: { external_id: assetId! }, prefetch: !!assetId, onResponse: ({ data: asset }) => { if (!asset) return; - const fetchedValues = { - name: asset.name || "", - description: asset.description || "", - location: asset.location_object.id! || "", + // Update the state with the fetched data + setinitialAssetData({ + id: asset.id, + name: asset.name, + location: asset.location_object?.id, + description: asset.description, + is_working: asset.is_working, + not_working_reason: asset.not_working_reason, + created_date: asset.created_date, + modified_date: asset.modified_date, + serial_number: asset.serial_number, + asset_type: asset.asset_type, asset_class: asset.asset_class, - is_working: String(asset.is_working), - not_working_reason: asset.not_working_reason || "", - serial_number: asset.serial_number || "", - vendor_name: asset.vendor_name || "", - support_name: asset.support_name || "", - support_email: asset.support_email || "", - support_phone: asset.support_phone || "", - qr_code_id: asset.qr_code_id || "", - manufacturer: asset.manufacturer || "", + status: asset.status, + vendor_name: asset.vendor_name, + support_name: asset.support_name, + support_email: asset.support_email, + support_phone: asset.support_phone, + qr_code_id: asset.qr_code_id, + manufacturer: asset.manufacturer, warranty_amc_end_of_validity: asset.warranty_amc_end_of_validity, - last_serviced_on: asset.last_service?.serviced_on || null, - notes: asset.last_service?.note || "", - }; - - setInitialValues(fetchedValues); - - setName(fetchedValues.name); - setDescription(fetchedValues.description); - setLocation(fetchedValues.location); - setAssetClass(fetchedValues.asset_class); - setIsWorking(fetchedValues.is_working); - setNotWorkingReason(fetchedValues.not_working_reason); - setSerialNumber(fetchedValues.serial_number); - setVendorName(fetchedValues.vendor_name); - setSupportName(fetchedValues.support_name); - setSupportEmail(fetchedValues.support_email); - setSupportPhone(fetchedValues.support_phone); - setQrCodeId(fetchedValues.qr_code_id); - setManufacturer(fetchedValues.manufacturer); - setWarrantyAmcEndOfValidity(fetchedValues.warranty_amc_end_of_validity); - setLastServicedOn(fetchedValues.last_serviced_on); - setNotes(fetchedValues.notes); - - isInitialLoad.current = false; + latest_status: asset.latest_status, + last_service: asset.last_service, + serviced_on: asset.last_service?.serviced_on, + notes: asset.last_service?.note, + }); }, }); - useEffect(() => { - if (isInitialLoad.current) return; - - const currentValues = { - name, - description, - location, - asset_class, - is_working, - not_working_reason, - serial_number, - vendor_name, - support_name, - support_email, - support_phone, - qr_code_id: qrCodeId, - manufacturer, - warranty_amc_end_of_validity, - last_serviced_on, - notes, - }; - console.log("Initial Values " + currentValues); - - const isChanged = ( - Object.keys(currentValues) as Array - ).some((key) => currentValues[key] !== initialValues[key]); - - setIsButtonEnabled(isChanged); - }, [ - name, - description, - location, - asset_class, - is_working, - not_working_reason, - serial_number, - vendor_name, - support_name, - support_email, - support_phone, - qrCodeId, - manufacturer, - warranty_amc_end_of_validity, - last_serviced_on, - notes, - initialValues, - ]); - - const validateForm = () => { - const errors = { ...initError }; - let invalidForm = false; - Object.keys(state.errors).forEach((field) => { - switch (field) { - case "name": - if (!name) { - errors[field] = "Asset name can't be empty"; - invalidForm = true; - } - return; - case "is_working": - if (is_working === undefined) { - errors[field] = t("field_required"); - invalidForm = true; - } - return; - case "location": - if (!location || location === "0" || location === "") { - errors[field] = "Select a location"; - invalidForm = true; - } - return; - case "support_phone": { - if (!support_phone) { - errors[field] = t("field_required"); - invalidForm = true; - } - // eslint-disable-next-line no-case-declarations - const checkTollFree = support_phone.startsWith("1800"); - const supportPhoneSimple = support_phone - .replace(/[^0-9]/g, "") - .slice(2); - if (supportPhoneSimple.length != 10 && !checkTollFree) { - errors[field] = "Please enter valid phone number"; - invalidForm = true; - } else if ( - (support_phone.length < 10 || support_phone.length > 11) && - checkTollFree - ) { - errors[field] = "Please enter valid phone number"; - invalidForm = true; - } - return; - } - case "support_email": - if (support_email && !validateEmailAddress(support_email)) { - errors[field] = "Please enter valid email id"; - invalidForm = true; - } - return; - case "last_serviced_on": - if (notes && !last_serviced_on) { - errors[field] = "Last serviced on date is require with notes"; - invalidForm = true; - } - return; - default: - return; - } - }); - if (invalidForm) { - dispatch({ type: "set_error", errors }); - const firstError = Object.keys(errors).find((key) => errors[key]); - if (firstError) { - fieldRef[firstError].current?.scrollIntoView({ - behavior: "smooth", - block: "center", - }); + const AssetFormValidator = (form: AssetT): FormErrors => { + const errors: Partial> = {}; // Initialize error object + + errors.name = RequiredFieldValidator()(form.name); + + if (form.is_working === undefined) { + errors.is_working = t("field_required"); + } + + if (!form.location || form.location === "0" || form.location === "") { + errors.location = "Select a location"; + } + + if (!form.support_phone) { + errors.support_phone = t("field_required"); + } else { + const checkTollFree = form.support_phone.startsWith("1800"); + const supportPhoneSimple = form.support_phone + .replace(/[^0-9]/g, "") + .slice(2); + if (supportPhoneSimple.length !== 10 && !checkTollFree) { + errors.support_phone = "Please enter valid phone number"; + } else if ( + (form.support_phone.length < 10 || form.support_phone.length > 11) && + checkTollFree + ) { + errors.support_phone = "Please enter valid phone number"; } - return false; } - dispatch({ type: "set_error", errors }); - return true; - }; - const resetFilters = () => { - setName(""); - setDescription(""); - setLocation(""); - setAssetClass(assetClassInitial); - setIsWorking(undefined); - setNotWorkingReason(""); - setSerialNumber(""); - setVendorName(""); - setSupportName(""); - setSupportEmail(""); - setSupportPhone(""); - setQrCodeId(""); - setManufacturer(""); - setWarrantyAmcEndOfValidity(""); - setLastServicedOn(""); - setNotes(""); - setWarrantyAmcEndOfValidity(null); - setLastServicedOn(null); + if (form.support_email && !validateEmailAddress(form.support_email)) { + errors.support_email = "Please enter valid email id"; + } + + if (form.notes && !form.last_service) { + errors.serviced_on = "Last serviced on date is required with notes"; + } + + return errors; }; - const handleSubmit = async (e: React.SyntheticEvent, addMore: boolean) => { - e.preventDefault(); - const validated = validateForm(); - if (validated) { - setIsLoading(true); - const data: any = { - name: name, - asset_type: AssetType.INTERNAL, - asset_class: asset_class || "", - description: description, - is_working: is_working, - not_working_reason: is_working === "true" ? "" : not_working_reason, - serial_number: serial_number, - location: location, - vendor_name: vendor_name, - support_name: support_name, - support_email: support_email, - support_phone: support_phone.startsWith("1800") - ? support_phone - : parsePhoneNumber(support_phone), - qr_code_id: qrCodeId !== "" ? qrCodeId : null, - manufacturer: manufacturer, - warranty_amc_end_of_validity: warranty_amc_end_of_validity - ? dateQueryString(warranty_amc_end_of_validity) - : null, - }; - - if (last_serviced_on) { - data["last_serviced_on"] = dateQueryString(last_serviced_on); - data["note"] = notes ?? ""; - } + // const validateForm = () => { + // const errors = { ...initError }; + // let invalidForm = false; + // Object.keys(state.errors).forEach((field) => { + // switch (field) { + // case "name": + // if (!name) { + // errors[field] = "Asset name can't be empty"; + // invalidForm = true; + // } + // return; + // case "is_working": + // if (is_working === undefined) { + // errors[field] = t("field_required"); + // invalidForm = true; + // } + // return; + // case "location": + // if (!location || location === "0" || location === "") { + // errors[field] = "Select a location"; + // invalidForm = true; + // } + // return; + // case "support_phone": { + // if (!support_phone) { + // errors[field] = t("field_required"); + // invalidForm = true; + // } + // // eslint-disable-next-line no-case-declarations + // const checkTollFree = support_phone.startsWith("1800"); + // const supportPhoneSimple = support_phone + // .replace(/[^0-9]/g, "") + // .slice(2); + // if (supportPhoneSimple.length != 10 && !checkTollFree) { + // errors[field] = "Please enter valid phone number"; + // invalidForm = true; + // } else if ( + // (support_phone.length < 10 || support_phone.length > 11) && + // checkTollFree + // ) { + // errors[field] = "Please enter valid phone number"; + // invalidForm = true; + // } + // return; + // } + // case "support_email": + // if (support_email && !validateEmailAddress(support_email)) { + // errors[field] = "Please enter valid email id"; + // invalidForm = true; + // } + // return; + // case "last_serviced_on": + // if (notes && !last_serviced_on) { + // errors[field] = "Last serviced on date is require with notes"; + // invalidForm = true; + // } + // return; + // default: + // return; + // } + // }); + // if (invalidForm) { + // dispatch({ type: "set_error", errors }); + // const firstError = Object.keys(errors).find((key) => errors[key]); + // if (firstError) { + // fieldRef[firstError].current?.scrollIntoView({ + // behavior: "smooth", + // block: "center", + // }); + // } + // return false; + // } + // dispatch({ type: "set_error", errors }); + // return true; + // }; - if (!assetId) { + // const resetFilters = () => { + // setName(""); + // setDescription(""); + // setLocation(""); + // setAssetClass(assetClassInitial); + // setIsWorking(undefined); + // setNotWorkingReason(""); + // setSerialNumber(""); + // setVendorName(""); + // setSupportName(""); + // setSupportEmail(""); + // setSupportPhone(""); + // setQrCodeId(""); + // setManufacturer(""); + // setWarrantyAmcEndOfValidity(""); + // setLastServicedOn(""); + // setNotes(""); + // setWarrantyAmcEndOfValidity(null); + // setLastServicedOn(null); + // }; + + // const handleSubmit = async (e: React.SyntheticEvent, addMore: boolean) => { + // e.preventDefault(); + // const validated = validateForm(); + // if (validated) { + // setIsLoading(true); + // const data: any = { + // name: name, + // asset_type: AssetType.INTERNAL, + // asset_class: asset_class || "", + // description: description, + // is_working: is_working, + // not_working_reason: is_working === "true" ? "" : not_working_reason, + // serial_number: serial_number, + // location: location, + // vendor_name: vendor_name, + // support_name: support_name, + // support_email: support_email, + // support_phone: support_phone.startsWith("1800") + // ? support_phone + // : parsePhoneNumber(support_phone), + // qr_code_id: qrCodeId !== "" ? qrCodeId : null, + // manufacturer: manufacturer, + // warranty_amc_end_of_validity: warranty_amc_end_of_validity + // ? dateQueryString(warranty_amc_end_of_validity) + // : null, + // }; + + // if (last_serviced_on) { + // data["last_serviced_on"] = dateQueryString(last_serviced_on); + // data["note"] = notes ?? ""; + // } + + // if (!assetId) { + // const { res } = await request(routes.createAsset, { body: data }); + // if (res?.ok) { + // Notification.Success({ msg: "Asset created successfully" }); + // if (addMore) { + // resetFilters(); + // const pageContainer = window.document.getElementById("pages"); + // pageContainer?.scroll(0, 0); + // } else { + // goBack(); + // } + // } + // setIsLoading(false); + // } else { + // const { res } = await request(routes.updateAsset, { + // pathParams: { external_id: assetId }, + // body: data, + // }); + // if (res?.ok) { + // Notification.Success({ msg: "Asset updated successfully" }); + // goBack(); + // } + // setIsLoading(false); + // } + // } + // }; + + const handleSubmitAsync = async (form: AssetT, addMore: boolean) => { + setIsLoading(true); + + const data: any = { + name: form.name, + asset_type: AssetType.INTERNAL, + asset_class: form.asset_class || "", + description: form.description, + is_working: form.is_working, + not_working_reason: + form.is_working === true ? "" : form.not_working_reason, + serial_number: form.serial_number, + location: form.location, + vendor_name: form.vendor_name, + support_name: form.support_name, + support_email: form.support_email, + support_phone: form.support_phone?.startsWith("1800") + ? form.support_phone + : parsePhoneNumber(String(form.support_phone)), + qr_code_id: form.qr_code_id !== "" ? form.qr_code_id : null, + manufacturer: form.manufacturer, + warranty_amc_end_of_validity: form.warranty_amc_end_of_validity + ? dateQueryString(form.warranty_amc_end_of_validity) + : null, + }; + + if (form.serviced_on) { + data["last_serviced_on"] = dateQueryString(form.serviced_on); + data["note"] = form.notes ?? ""; + } + + try { + if (!form.id) { const { res } = await request(routes.createAsset, { body: data }); if (res?.ok) { Notification.Success({ msg: "Asset created successfully" }); + // Handle "Add More" logic if necessary if (addMore) { - resetFilters(); + // resetFilters(); const pageContainer = window.document.getElementById("pages"); pageContainer?.scroll(0, 0); } else { goBack(); } } - setIsLoading(false); } else { const { res } = await request(routes.updateAsset, { - pathParams: { external_id: assetId }, + pathParams: { external_id: form.id }, body: data, }); if (res?.ok) { Notification.Success({ msg: "Asset updated successfully" }); goBack(); } - setIsLoading(false); } + } catch (error) { + // Handle error (optional) + Notification.Error({ + msg: "An error occurred while processing the asset", + }); + } finally { + setIsLoading(false); } }; @@ -474,7 +554,7 @@ const AssetCreate = (props: AssetProps) => { // QR Maybe searchParams "asset" or "assetQR" const assetId = params.asset || params.assetQR; if (assetId) { - setQrCodeId(assetId); + // setQrCodeId(assetId); setIsScannerActive(false); return; } @@ -490,6 +570,9 @@ const AssetCreate = (props: AssetProps) => { return ; } + const name: string | undefined = + locationsQuery.data?.results[0].facility?.name || undefined; + if (locationsQuery.data?.count === 0) { return ( { ); } + const handleOnCancel: () => void = () => { + navigate(`/facility/${facilityId}/location/add`); + }; + if (isScannerActive) return (
@@ -582,10 +669,10 @@ const AssetCreate = (props: AssetProps) => { className="grow-0 pl-6" crumbsReplacements={{ [facilityId]: { - name: locationsQuery.data?.results[0].facility?.name, + name, }, assets: { style: "text-secondary-200 pointer-events-none" }, - [assetId || "????"]: { name }, + [assetId || "????"]: { name: name || undefined }, }} backUrl={ assetId @@ -619,402 +706,386 @@ const AssetCreate = (props: AssetProps) => {
-
handleSubmit(e, false)} + + disabled={isLoading} + defaults={initAssetData} + onCancel={handleOnCancel} + onSubmit={async (obj) => { + await handleSubmitAsync(obj, Boolean(assetId)); + }} className="rounded bg-white p-6 transition-all sm:rounded-xl sm:p-12" + noPadding + validate={AssetFormValidator} + submitLabel={assetId ? t("update") : t("create_asset")} > -
-
- {/* General Details Section */} - {sectionTitle("General Details")} - {/* Asset Name */} -
- setName(value)} - error={state.errors.name} - /> -
+ {(field) => ( + <> +
+
+ {/* General Details Section */} + {sectionTitle("General Details")} + {/* Asset Name */} +
+ +
- {/* Location */} - - {t("asset_location")} - -
- - setLocation((selectedId as string) || "") - } - selected={location} - showAll={false} - multiple={false} - facilityId={facilityId} - errors={state.errors.location} - /> -
+ {/* Location */} + + {t("asset_location")} + +
+ { + field("location").onChange({ + name: "location", + value: selected, + }); + }} + errors={field("location").error} + facilityId={facilityId} + multiple={false} + showAll={false} + /> +
- {/* Asset Class */} -
- title} - optionValue={({ value }) => value} - onChange={({ value }) => setAssetClass(value)} - error={state.errors.asset_class} - /> -
- {/* Description */} -
- setDescription(value)} - error={state.errors.description} - /> -
- {/* Divider */} -
-
-
- {/* Working Status */} -
- { - return ( - { - true: "Working", - false: "Not Working", - }[option] || "undefined" - ); - }} - optionClassName={(option) => - option === "false" && - "bg-danger-500 text-white border-danger-500 focus:ring-danger-500" - } - value={is_working} - onChange={setIsWorking} - error={state.errors.is_working} - /> -
- {/* Not Working Reason */} -
- setNotWorkingReason(e.value)} - error={state.errors.not_working_reason} - /> -
- {/* Divider */} -
-
-
- {/* Asset QR ID */} -
-
- setQrCodeId(e.value)} - error={state.errors.qr_code_id} - /> -
-
setIsScannerActive(true)} - > - + {/* Asset Class */} +
+ title} + optionValue={({ value }) => value} + /> +
+ {/* Description */} +
+ +
+ {/* Divider */} +
+
+
+ {/* Working Status */} +
+ + field("is_working").onChange({ + name: "is_working", + value: option === "true", // Convert back to boolean + }) + } + optionLabel={(option: "true" | "false") => { + return ( + { + true: "Working", + false: "Not Working", + }[option] || "undefined" + ); + }} + optionClassName={(option) => + option === "false" && + "bg-danger-500 text-white border-danger-500 focus:ring-danger-500" + } + /> +
+ {/* Not Working Reason */} +
+ +
+ {/* Divider */} +
+
+
+ {/* Asset QR ID */} +
+
+ +
+
setIsScannerActive(true)} + > + +
+
-
-
-
- {sectionTitle("Warranty Details")} - - {/* Manufacturer */} -
- setManufacturer(e.value)} - error={state.errors.manufacturer} - /> -
+
+ {sectionTitle("Warranty Details")} - {/* Warranty / AMC Expiry */} -
- { - const value = dayjs(event.value); - const date = new Date(value.toDate().toDateString()); - const today = new Date(new Date().toDateString()); - if (date < today) { - Notification.Error({ - msg: "Warranty / AMC Expiry date can't be in past", - }); - } else { - setWarrantyAmcEndOfValidity(dateQueryString(value)); - } - }} - type="date" - min={dayjs().format("YYYY-MM-DD")} - /> -
+ {/* Manufacturer */} +
+ +
- {/* Customer Support Name */} -
- setSupportName(e.value)} - error={state.errors.support_name} - /> -
+ {/* Warranty / AMC Expiry */} +
+ { + const { value } = event; + const selectedDate = dayjs(value); + const formattedDate = + selectedDate.format("YYYY-MM-DD"); + const today = dayjs().format("YYYY-MM-DD"); - {/* Customer Support Number */} -
- setSupportPhone(e.value)} - error={state.errors.support_phone} - types={["mobile", "landline", "support"]} - /> -
+ if (selectedDate.isBefore(today)) { + Notification.Error({ + msg: "Warranty / AMC Expiry date can't be in the past", + }); + } else { + // Update the provider's state with the valid date + field("warranty_amc_end_of_validity").onChange({ + name: "warranty_amc_end_of_validity", + value: formattedDate, + }); + } + }} + type="date" + min={dayjs().format("YYYY-MM-DD")} + /> +
- {/* Customer Support Email */} -
- setSupportEmail(e.value)} - error={state.errors.support_email} - /> -
+ {/* Customer Support Name */} +
+ +
-
- - {/* Vendor Name */} -
- setVendorName(e.value)} - error={state.errors.vendor_name} - /> -
+ {/* Customer Support Number */} +
+ +
- {/* Serial Number */} -
- setSerialNumber(e.value)} - error={state.errors.serial_number} - /> -
+ {/* Customer Support Email */} +
+ +
-
- {sectionTitle("Service Details")} - - {/* Last serviced on */} -
- { - if ( - dayjs(date.value).format("YYYY-MM-DD") > - new Date().toLocaleDateString("en-ca") - ) { - Notification.Error({ - msg: "Last Serviced date can't be in future", - }); - } else { - setLastServicedOn( - dayjs(date.value).format("YYYY-MM-DD"), - ); - } - }} - /> - -
+
+ + {/* Vendor Name */} +
+ +
+ + {/* Serial Number */} +
+ +
+ +
+ {sectionTitle("Service Details")} + + {/* Last serviced on */} +
+ { + const selectedDate = dayjs(date.value).format( + "YYYY-MM-DD", + ); + const today = new Date().toLocaleDateString( + "en-ca", + ); + + if (selectedDate > today) { + Notification.Error({ + msg: "Last Serviced date can't be in the future", + }); + } else { + field("serviced_on").onChange({ + name: "last_serviced_on", + value: selectedDate, + }); + } + }} + /> + + +
+ + {/* Notes */} +
+ +
+
- {/* Notes */} -
- setNotes(e.value)} - error={state.errors.notes} - /> +
-
- -
- - navigate( - assetId - ? `/facility/${facilityId}/assets/${assetId}` - : `/facility/${facilityId}`, - ) - } - /> - handleSubmit(e, false)} - label={assetId ? t("update") : t("create_asset")} - disabled={!isButtonEnabled} - /> - {!assetId && ( - handleSubmit(e, true)} - label={t("create_add_more")} - disabled={!isButtonEnabled} - /> - )} -
-
- + + )} +
From ea14bd0d495d6de4b7dd46cffc3bdd34c2aa8a7f Mon Sep 17 00:00:00 2001 From: totregex Date: Mon, 25 Nov 2024 21:56:21 +0530 Subject: [PATCH 3/7] wrap form in AssetCreate page using Form component --- src/components/Facility/AssetCreate.tsx | 237 +----------------------- 1 file changed, 9 insertions(+), 228 deletions(-) diff --git a/src/components/Facility/AssetCreate.tsx b/src/components/Facility/AssetCreate.tsx index 3747be6e2b2..4bac8055a27 100644 --- a/src/components/Facility/AssetCreate.tsx +++ b/src/components/Facility/AssetCreate.tsx @@ -66,7 +66,7 @@ interface AssetT { name?: string; location?: string; description?: string; - is_working?: boolean; + is_working?: boolean | null; not_working_reason?: string; created_date?: string; modified_date?: string; @@ -95,28 +95,11 @@ const fieldRef = formErrorKeys.reduce( {}, ); -// const initialState = { -// errors: { ...initError }, -// }; - interface AssetProps { facilityId: string; assetId?: string; } -// const asset_create_reducer = (state = initialState, action: any) => { -// switch (action.type) { -// case "set_error": { -// return { -// ...state, -// errors: action.errors, -// }; -// } -// default: -// return state; -// } -// }; - type AssetFormSection = | "General Details" | "Warranty Details" @@ -132,7 +115,7 @@ const AssetCreate = (props: AssetProps) => { name: "", location: "", description: "", - is_working: false, + is_working: null, not_working_reason: "", created_date: "", modified_date: "", @@ -153,29 +136,10 @@ const AssetCreate = (props: AssetProps) => { notes: "", }; - // State to store asset data const [initAssetData, setinitialAssetData] = useState(initialAssetData); - // const [state, dispatch] = useReducer(asset_create_reducer, initialState); - // const [name, setName] = useState(""); - // const [asset_class, setAssetClass] = useState(); - // const [not_working_reason, setNotWorkingReason] = useState(""); - // const [description, setDescription] = useState(""); - // const [is_working, setIsWorking] = useState(undefined); - // const [serial_number, setSerialNumber] = useState(""); - // const [vendor_name, setVendorName] = useState(""); - // const [support_name, setSupportName] = useState(""); - // const [support_phone, setSupportPhone] = useState(""); - // const [support_email, setSupportEmail] = useState(""); - // const [location, setLocation] = useState(""); const [isLoading, setIsLoading] = useState(false); - // const [qrCodeId, setQrCodeId] = useState(""); - // const [manufacturer, setManufacturer] = useState(""); - // const [warranty_amc_end_of_validity, setWarrantyAmcEndOfValidity] = - // useState(null); - // const [last_serviced_on, setLastServicedOn] = useState(null); - // const [notes, setNotes] = useState(""); const [isScannerActive, setIsScannerActive] = useState(false); const [currentSection, setCurrentSection] = @@ -224,40 +188,12 @@ const AssetCreate = (props: AssetProps) => { query: { limit: 1 }, }); - // const assetQuery = useQuery(routes.getAsset, { - // pathParams: { external_id: assetId! }, - // prefetch: !!assetId, - // onResponse: ({ data: asset }) => { - // if (!asset) return; - - // setName(asset.name); - // setDescription(asset.description); - // setLocation(asset.location_object.id!); - // setAssetClass(asset.asset_class); - // setIsWorking(String(asset.is_working)); - // setNotWorkingReason(asset.not_working_reason); - // setSerialNumber(asset.serial_number); - // setVendorName(asset.vendor_name); - // setSupportName(asset.support_name); - // setSupportEmail(asset.support_email); - // setSupportPhone(asset.support_phone); - // setQrCodeId(asset.qr_code_id); - // setManufacturer(asset.manufacturer); - // asset.warranty_amc_end_of_validity && - // setWarrantyAmcEndOfValidity(asset.warranty_amc_end_of_validity); - // asset.last_service?.serviced_on && - // setLastServicedOn(asset.last_service?.serviced_on); - // asset.last_service?.note && setNotes(asset.last_service?.note); - // }, - // }); - const assetQuery = useQuery(routes.getAsset, { pathParams: { external_id: assetId! }, prefetch: !!assetId, onResponse: ({ data: asset }) => { if (!asset) return; - // Update the state with the fetched data setinitialAssetData({ id: asset.id, name: asset.name, @@ -320,169 +256,13 @@ const AssetCreate = (props: AssetProps) => { errors.support_email = "Please enter valid email id"; } - if (form.notes && !form.last_service) { + if (form.notes && !form.serviced_on) { errors.serviced_on = "Last serviced on date is required with notes"; } return errors; }; - // const validateForm = () => { - // const errors = { ...initError }; - // let invalidForm = false; - // Object.keys(state.errors).forEach((field) => { - // switch (field) { - // case "name": - // if (!name) { - // errors[field] = "Asset name can't be empty"; - // invalidForm = true; - // } - // return; - // case "is_working": - // if (is_working === undefined) { - // errors[field] = t("field_required"); - // invalidForm = true; - // } - // return; - // case "location": - // if (!location || location === "0" || location === "") { - // errors[field] = "Select a location"; - // invalidForm = true; - // } - // return; - // case "support_phone": { - // if (!support_phone) { - // errors[field] = t("field_required"); - // invalidForm = true; - // } - // // eslint-disable-next-line no-case-declarations - // const checkTollFree = support_phone.startsWith("1800"); - // const supportPhoneSimple = support_phone - // .replace(/[^0-9]/g, "") - // .slice(2); - // if (supportPhoneSimple.length != 10 && !checkTollFree) { - // errors[field] = "Please enter valid phone number"; - // invalidForm = true; - // } else if ( - // (support_phone.length < 10 || support_phone.length > 11) && - // checkTollFree - // ) { - // errors[field] = "Please enter valid phone number"; - // invalidForm = true; - // } - // return; - // } - // case "support_email": - // if (support_email && !validateEmailAddress(support_email)) { - // errors[field] = "Please enter valid email id"; - // invalidForm = true; - // } - // return; - // case "last_serviced_on": - // if (notes && !last_serviced_on) { - // errors[field] = "Last serviced on date is require with notes"; - // invalidForm = true; - // } - // return; - // default: - // return; - // } - // }); - // if (invalidForm) { - // dispatch({ type: "set_error", errors }); - // const firstError = Object.keys(errors).find((key) => errors[key]); - // if (firstError) { - // fieldRef[firstError].current?.scrollIntoView({ - // behavior: "smooth", - // block: "center", - // }); - // } - // return false; - // } - // dispatch({ type: "set_error", errors }); - // return true; - // }; - - // const resetFilters = () => { - // setName(""); - // setDescription(""); - // setLocation(""); - // setAssetClass(assetClassInitial); - // setIsWorking(undefined); - // setNotWorkingReason(""); - // setSerialNumber(""); - // setVendorName(""); - // setSupportName(""); - // setSupportEmail(""); - // setSupportPhone(""); - // setQrCodeId(""); - // setManufacturer(""); - // setWarrantyAmcEndOfValidity(""); - // setLastServicedOn(""); - // setNotes(""); - // setWarrantyAmcEndOfValidity(null); - // setLastServicedOn(null); - // }; - - // const handleSubmit = async (e: React.SyntheticEvent, addMore: boolean) => { - // e.preventDefault(); - // const validated = validateForm(); - // if (validated) { - // setIsLoading(true); - // const data: any = { - // name: name, - // asset_type: AssetType.INTERNAL, - // asset_class: asset_class || "", - // description: description, - // is_working: is_working, - // not_working_reason: is_working === "true" ? "" : not_working_reason, - // serial_number: serial_number, - // location: location, - // vendor_name: vendor_name, - // support_name: support_name, - // support_email: support_email, - // support_phone: support_phone.startsWith("1800") - // ? support_phone - // : parsePhoneNumber(support_phone), - // qr_code_id: qrCodeId !== "" ? qrCodeId : null, - // manufacturer: manufacturer, - // warranty_amc_end_of_validity: warranty_amc_end_of_validity - // ? dateQueryString(warranty_amc_end_of_validity) - // : null, - // }; - - // if (last_serviced_on) { - // data["last_serviced_on"] = dateQueryString(last_serviced_on); - // data["note"] = notes ?? ""; - // } - - // if (!assetId) { - // const { res } = await request(routes.createAsset, { body: data }); - // if (res?.ok) { - // Notification.Success({ msg: "Asset created successfully" }); - // if (addMore) { - // resetFilters(); - // const pageContainer = window.document.getElementById("pages"); - // pageContainer?.scroll(0, 0); - // } else { - // goBack(); - // } - // } - // setIsLoading(false); - // } else { - // const { res } = await request(routes.updateAsset, { - // pathParams: { external_id: assetId }, - // body: data, - // }); - // if (res?.ok) { - // Notification.Success({ msg: "Asset updated successfully" }); - // goBack(); - // } - // setIsLoading(false); - // } - // } - // }; - const handleSubmitAsync = async (form: AssetT, addMore: boolean) => { setIsLoading(true); @@ -833,11 +613,11 @@ const AssetCreate = (props: AssetProps) => { String(field("is_working").value) as | "true" | "false" - } // Convert to string + } onChange={(option: "true" | "false") => field("is_working").onChange({ name: "is_working", - value: option === "true", // Convert back to boolean + value: option === "true", }) } optionLabel={(option: "true" | "false") => { @@ -1036,8 +816,9 @@ const AssetCreate = (props: AssetProps) => { className="mt-2" disableFuture value={ - field("serviced_on").value && - new Date(field("serviced_on").value) + field("serviced_on").value + ? new Date(field("serviced_on").value) + : undefined } onChange={(date) => { const selectedDate = dayjs(date.value).format( @@ -1053,7 +834,7 @@ const AssetCreate = (props: AssetProps) => { }); } else { field("serviced_on").onChange({ - name: "last_serviced_on", + name: "serviced_on", value: selectedDate, }); } From 3c1a2acfd69bbed7dfbf372fa266c22a7b217f81 Mon Sep 17 00:00:00 2001 From: totregex Date: Tue, 26 Nov 2024 17:56:17 +0530 Subject: [PATCH 4/7] pass additionalButtons prop --- src/components/Facility/AssetCreate.tsx | 57 ++++++++++++++++++++----- 1 file changed, 46 insertions(+), 11 deletions(-) diff --git a/src/components/Facility/AssetCreate.tsx b/src/components/Facility/AssetCreate.tsx index 4bac8055a27..cde94960079 100644 --- a/src/components/Facility/AssetCreate.tsx +++ b/src/components/Facility/AssetCreate.tsx @@ -61,7 +61,7 @@ const formErrorKeys = [ "notes", ]; -interface AssetT { +interface AssetData { id?: string; name?: string; location?: string; @@ -110,7 +110,7 @@ const AssetCreate = (props: AssetProps) => { const { t } = useTranslation(); const { facilityId, assetId } = props; - const initialAssetData: AssetT = { + const initialAssetData: AssetData = { id: "", name: "", location: "", @@ -137,7 +137,7 @@ const AssetCreate = (props: AssetProps) => { }; const [initAssetData, setinitialAssetData] = - useState(initialAssetData); + useState(initialAssetData); const [isLoading, setIsLoading] = useState(false); const [isScannerActive, setIsScannerActive] = useState(false); @@ -222,8 +222,8 @@ const AssetCreate = (props: AssetProps) => { }, }); - const AssetFormValidator = (form: AssetT): FormErrors => { - const errors: Partial> = {}; // Initialize error object + const AssetFormValidator = (form: AssetData): FormErrors => { + const errors: Partial> = {}; // Initialize error object errors.name = RequiredFieldValidator()(form.name); @@ -232,7 +232,7 @@ const AssetCreate = (props: AssetProps) => { } if (!form.location || form.location === "0" || form.location === "") { - errors.location = "Select a location"; + errors.location = t("select_local_body"); } if (!form.support_phone) { @@ -263,7 +263,35 @@ const AssetCreate = (props: AssetProps) => { return errors; }; - const handleSubmitAsync = async (form: AssetT, addMore: boolean) => { + const resetFilters = () => { + setinitialAssetData({ + id: "", + name: "", + location: "", + description: "", + is_working: null, + not_working_reason: "", + created_date: "", + modified_date: "", + serial_number: "", + asset_type: undefined, + asset_class: undefined, + status: "ACTIVE", + vendor_name: "", + support_name: "", + support_email: "", + support_phone: "", + qr_code_id: "", + manufacturer: "", + warranty_amc_end_of_validity: "", + latest_status: "", + last_service: null, + serviced_on: "", + notes: "", + }); + }; + + const handleSubmitAsync = async (form: AssetData, addMore: boolean) => { setIsLoading(true); const data: any = { @@ -301,7 +329,7 @@ const AssetCreate = (props: AssetProps) => { Notification.Success({ msg: "Asset created successfully" }); // Handle "Add More" logic if necessary if (addMore) { - // resetFilters(); + resetFilters(); const pageContainer = window.document.getElementById("pages"); pageContainer?.scroll(0, 0); } else { @@ -334,7 +362,7 @@ const AssetCreate = (props: AssetProps) => { // QR Maybe searchParams "asset" or "assetQR" const assetId = params.asset || params.assetQR; if (assetId) { - // setQrCodeId(assetId); + setinitialAssetData({ ...initAssetData, qr_code_id: assetId }); setIsScannerActive(false); return; } @@ -452,7 +480,7 @@ const AssetCreate = (props: AssetProps) => { name, }, assets: { style: "text-secondary-200 pointer-events-none" }, - [assetId || "????"]: { name: name || undefined }, + [assetId || "????"]: { name: name || "Asset" }, }} backUrl={ assetId @@ -486,7 +514,7 @@ const AssetCreate = (props: AssetProps) => {
- + disabled={isLoading} defaults={initAssetData} onCancel={handleOnCancel} @@ -497,6 +525,13 @@ const AssetCreate = (props: AssetProps) => { noPadding validate={AssetFormValidator} submitLabel={assetId ? t("update") : t("create_asset")} + additionalButtons={[ + { + type: "submit", + label: t("create_add_more"), + id: "create-asset-add-more-button", + }, + ]} > {(field) => ( <> From 29aa6296dc8faf97735189a2418e51ee64df8ea8 Mon Sep 17 00:00:00 2001 From: totregex Date: Tue, 26 Nov 2024 21:59:20 +0530 Subject: [PATCH 5/7] edit handleOnCancel --- src/components/Facility/AssetCreate.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Facility/AssetCreate.tsx b/src/components/Facility/AssetCreate.tsx index cde94960079..c108d014994 100644 --- a/src/components/Facility/AssetCreate.tsx +++ b/src/components/Facility/AssetCreate.tsx @@ -413,7 +413,7 @@ const AssetCreate = (props: AssetProps) => { } const handleOnCancel: () => void = () => { - navigate(`/facility/${facilityId}/location/add`); + goBack(); }; if (isScannerActive) From c5312fb7f8f6701d77c39a5077af1e900073b9cc Mon Sep 17 00:00:00 2001 From: totregex Date: Thu, 28 Nov 2024 17:29:41 +0530 Subject: [PATCH 6/7] add create asset and add more button --- src/components/Facility/AssetCreate.tsx | 27 +++++++++++++++---------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/components/Facility/AssetCreate.tsx b/src/components/Facility/AssetCreate.tsx index c108d014994..dd8c02efe1a 100644 --- a/src/components/Facility/AssetCreate.tsx +++ b/src/components/Facility/AssetCreate.tsx @@ -291,10 +291,11 @@ const AssetCreate = (props: AssetProps) => { }); }; - const handleSubmitAsync = async (form: AssetData, addMore: boolean) => { + const handleSubmitAsync = async (form: AssetData, buttonId: string) => { setIsLoading(true); const data: any = { + id: form.id, name: form.name, asset_type: AssetType.INTERNAL, asset_class: form.asset_class || "", @@ -328,7 +329,7 @@ const AssetCreate = (props: AssetProps) => { if (res?.ok) { Notification.Success({ msg: "Asset created successfully" }); // Handle "Add More" logic if necessary - if (addMore) { + if (buttonId == "create-asset-add-more-button") { resetFilters(); const pageContainer = window.document.getElementById("pages"); pageContainer?.scroll(0, 0); @@ -518,20 +519,24 @@ const AssetCreate = (props: AssetProps) => { disabled={isLoading} defaults={initAssetData} onCancel={handleOnCancel} - onSubmit={async (obj) => { - await handleSubmitAsync(obj, Boolean(assetId)); + onSubmit={async (obj, buttonId) => { + await handleSubmitAsync(obj, buttonId); }} className="rounded bg-white p-6 transition-all sm:rounded-xl sm:p-12" noPadding validate={AssetFormValidator} submitLabel={assetId ? t("update") : t("create_asset")} - additionalButtons={[ - { - type: "submit", - label: t("create_add_more"), - id: "create-asset-add-more-button", - }, - ]} + additionalButtons={ + !assetId + ? [ + { + type: "submit", + label: t("create_add_more"), + id: "create-asset-add-more-button", + }, + ] + : [] + } > {(field) => ( <> From e602030015177d4400115c542e8ba2c38f71c5c4 Mon Sep 17 00:00:00 2001 From: totregex Date: Sat, 30 Nov 2024 07:13:50 +0530 Subject: [PATCH 7/7] add translation and use PhoneNumberValidator --- public/locale/en.json | 1 + src/components/Facility/AssetCreate.tsx | 38 ++++++++++++------------- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/public/locale/en.json b/public/locale/en.json index 5faa645b133..321e803e77d 100644 --- a/public/locale/en.json +++ b/public/locale/en.json @@ -811,6 +811,7 @@ "last_name": "Last Name", "last_online": "Last Online", "last_serviced_on": "Last Serviced On", + "last_serviced_required": "Last Serviced On Date is required with notes", "latitude_invalid": "Latitude must be between -90 and 90", "left": "Left", "length": "Length ({{unit}})", diff --git a/src/components/Facility/AssetCreate.tsx b/src/components/Facility/AssetCreate.tsx index dd8c02efe1a..860b0e30fe4 100644 --- a/src/components/Facility/AssetCreate.tsx +++ b/src/components/Facility/AssetCreate.tsx @@ -17,6 +17,12 @@ import Loading from "@/components/Common/Loading"; import { LocationSelect } from "@/components/Common/LocationSelect"; import Page from "@/components/Common/Page"; import SwitchV2 from "@/components/Common/Switch"; +import { + FieldError, + PhoneNumberValidator, + RequiredFieldValidator, +} from "@/components/Form/FieldValidators"; +import Form from "@/components/Form/Form"; import DateFormField from "@/components/Form/FormFields/DateFormField"; import { FieldErrorText, @@ -26,6 +32,7 @@ import PhoneNumberFormField from "@/components/Form/FormFields/PhoneNumberFormFi import { SelectFormField } from "@/components/Form/FormFields/SelectFormField"; import TextAreaFormField from "@/components/Form/FormFields/TextAreaFormField"; import TextFormField from "@/components/Form/FormFields/TextFormField"; +import { FormErrors } from "@/components/Form/Utils"; import useAppHistory from "@/hooks/useAppHistory"; import useVisibility from "@/hooks/useVisibility"; @@ -40,10 +47,6 @@ import request from "@/Utils/request/request"; import useQuery from "@/Utils/request/useQuery"; import { dateQueryString, parsePhoneNumber } from "@/Utils/utils"; -import { FieldError, RequiredFieldValidator } from "../Form/FieldValidators"; -import Form from "../Form/Form"; -import { FormErrors } from "../Form/Utils"; - const formErrorKeys = [ "name", "asset_class", @@ -238,26 +241,23 @@ const AssetCreate = (props: AssetProps) => { if (!form.support_phone) { errors.support_phone = t("field_required"); } else { - const checkTollFree = form.support_phone.startsWith("1800"); - const supportPhoneSimple = form.support_phone - .replace(/[^0-9]/g, "") - .slice(2); - if (supportPhoneSimple.length !== 10 && !checkTollFree) { - errors.support_phone = "Please enter valid phone number"; - } else if ( - (form.support_phone.length < 10 || form.support_phone.length > 11) && - checkTollFree - ) { - errors.support_phone = "Please enter valid phone number"; + const validatePhoneNumber = PhoneNumberValidator( + ["mobile", "landline", "support"], + t("invalid_phone_number"), + ); + const isValid = validatePhoneNumber(form.support_phone); + // console.log("Is Valid" ,isValid) + if (isValid == "Invalid Phone Number") { + errors.support_phone = t("invalid_phone_number"); } } if (form.support_email && !validateEmailAddress(form.support_email)) { - errors.support_email = "Please enter valid email id"; + errors.support_email = t("invalid_email"); } if (form.notes && !form.serviced_on) { - errors.serviced_on = "Last serviced on date is required with notes"; + errors.serviced_on = t("last_serviced_on_required"); } return errors; @@ -291,7 +291,7 @@ const AssetCreate = (props: AssetProps) => { }); }; - const handleSubmitAsync = async (form: AssetData, buttonId: string) => { + const handleSubmit = async (form: AssetData, buttonId: string) => { setIsLoading(true); const data: any = { @@ -520,7 +520,7 @@ const AssetCreate = (props: AssetProps) => { defaults={initAssetData} onCancel={handleOnCancel} onSubmit={async (obj, buttonId) => { - await handleSubmitAsync(obj, buttonId); + await handleSubmit(obj, buttonId); }} className="rounded bg-white p-6 transition-all sm:rounded-xl sm:p-12" noPadding