From caf15840aaa481821c24bebbc8fc4bafc38f2938 Mon Sep 17 00:00:00 2001 From: suryac Date: Tue, 18 Aug 2026 13:19:58 +0530 Subject: [PATCH] feat/search api is added --- src/api/config.ts | 2 +- src/components/forms/DynamicForm.tsx | 37 -------------- src/components/forms/LogVisitForm.tsx | 51 +++++-------------- src/components/forms/fields/SelectField.tsx | 6 +++ src/components/forms/fields/WfLookupField.tsx | 6 ++- src/components/reusable/Select.tsx | 28 ++++++++-- 6 files changed, 47 insertions(+), 83 deletions(-) diff --git a/src/api/config.ts b/src/api/config.ts index 7aaebf2..375ab93 100644 --- a/src/api/config.ts +++ b/src/api/config.ts @@ -271,5 +271,5 @@ export const HIDDEN_FORM_FIELDS = [ 'store_code_3' ]; -export const LOOKUP_RECORD_LIMIT = 500; +export const LOOKUP_RECORD_LIMIT = 200; export const MAX_SKUS_PER_CHUNK = 20; diff --git a/src/components/forms/DynamicForm.tsx b/src/components/forms/DynamicForm.tsx index 5fe7d65..364aaa5 100644 --- a/src/components/forms/DynamicForm.tsx +++ b/src/components/forms/DynamicForm.tsx @@ -173,43 +173,6 @@ export function DynamicForm({ client, activityId: initialActivityId, instanceId: } } } - - if (currentActivityId === ORDER_BOOKING.activities.LOG_VISIT.uid) { - const user = client.currentUser(); - const userMobile = user?.mobile || localStorage.getItem('krishna_sales_user_mobile') || user?.email; - if (userMobile) { - try { - const headers: Record = { - 'templateid': '192', - 'x-pipeline-version': 'latest', - 'orgid': '57', - 'groupid': '25' - }; - - const summaryRes = await client.request( - 'POST', - PIPELINE.endpoints.productiveCallSummary, - { mobile: userMobile }, - headers - ); - let summaryData = summaryRes.data || summaryRes; - if (Array.isArray(summaryData)) { - summaryData = summaryData[0] || {}; - } - - if (summaryData.productive_call !== undefined) { - summaryData.total_productive_calls = summaryData.productive_call; - } - if (summaryData.non_productive_call !== undefined) { - summaryData.total_non_productive_calls = summaryData.non_productive_call; - } - - mapPrefillData(summaryData); - } catch (e) { - console.warn('Failed to load productive call summary for Log Visit', e); - } - } - } setValues(defaultValues); setLoading(false); diff --git a/src/components/forms/LogVisitForm.tsx b/src/components/forms/LogVisitForm.tsx index 022c64e..0960f1c 100644 --- a/src/components/forms/LogVisitForm.tsx +++ b/src/components/forms/LogVisitForm.tsx @@ -61,9 +61,9 @@ export function LogVisitForm({ client, onSuccess, onCancel, onActivityChange }: }, [values]); const [storeOptions, setStoreOptions] = useState<{ value: string; label: string; _raw?: any }[]>([]); + const [storeSearchQuery, setStoreSearchQuery] = useState(''); const [fetchingDailyLog, setFetchingDailyLog] = useState(false); const [fetchingStores, setFetchingStores] = useState(false); - const fetchingStoresRef = useRef(false); const [chainedActivity, setChainedActivity] = useState<{ activityId: string; @@ -119,40 +119,6 @@ export function LogVisitForm({ client, onSuccess, onCancel, onActivityChange }: Object.assign(initialValues, res.data); } - // Execute mobile pipeline prefill - const user = client.currentUser(); - const userMobile = user?.mobile || localStorage.getItem('krishna_sales_user_mobile') || user?.email; - if (userMobile) { - try { - const headers: Record = { - 'templateid': '192', - 'x-pipeline-version': 'latest', - 'orgid': '57', - 'groupid': '25' - }; - - const summaryRes = await client.request( - 'POST', - PIPELINE.endpoints.productiveCallSummary, - { mobile: userMobile }, - headers - ); - let summaryData = summaryRes.data || summaryRes; - if (Array.isArray(summaryData)) { - summaryData = summaryData[0] || {}; - } - if (summaryData.productive_call !== undefined) { - summaryData.total_productive_calls = summaryData.productive_call; - } - if (summaryData.non_productive_call !== undefined) { - summaryData.total_non_productive_calls = summaryData.non_productive_call; - } - Object.assign(initialValues, summaryData); - } catch (e) { - console.warn('Failed to load productive call summary for Log Visit', e); - } - } - setValues(prev => { const next = { ...initialValues, ...prev }; valuesRef.current = next; @@ -170,9 +136,7 @@ export function LogVisitForm({ client, onSuccess, onCancel, onActivityChange }: }, [client, activityId, todayStr, nowTimeStr]); // 2. Helper to fetch select_store options ONLY using updated prefilled formData - const fetchStoreOptions = useCallback(async (formDataOverride?: Record) => { - if (fetchingStoresRef.current) return; - fetchingStoresRef.current = true; + const fetchStoreOptions = useCallback(async (formDataOverride?: Record, search: string = '') => { setFetchingStores(true); setStoreError(null); @@ -184,6 +148,7 @@ export function LogVisitForm({ client, onSuccess, onCancel, onActivityChange }: activityId, fieldId: 'select_store', formData: formDataToSend, + search, limit: LOOKUP_RECORD_LIMIT, }); @@ -234,10 +199,16 @@ export function LogVisitForm({ client, onSuccess, onCancel, onActivityChange }: } } finally { setFetchingStores(false); - fetchingStoresRef.current = false; } }, [client, activityId]); + useEffect(() => { + const timer = setTimeout(() => { + fetchStoreOptions(undefined, storeSearchQuery); + }, 300); + return () => clearTimeout(timer); + }, [storeSearchQuery, fetchStoreOptions]); + // 3. Fetch Daily Log lookup data initially & prefill form state const loadDailyLogData = useCallback(async (dateVal: string, timeVal: string) => { setFetchingDailyLog(true); @@ -464,6 +435,8 @@ export function LogVisitForm({ client, onSuccess, onCancel, onActivityChange }: options={[{ value: '', label: `Select ${f.name}...` }, ...storeOptions]} onDropdownOpen={handleStoreDropdownOpen} onChange={e => handleStoreSelect(fieldId, e.target.value)} + onSearchChange={setStoreSearchQuery} + disableLocalSearch={true} disabled={isDisabled} /> {fetchingStores && ( diff --git a/src/components/forms/fields/SelectField.tsx b/src/components/forms/fields/SelectField.tsx index a3926f5..bc13858 100644 --- a/src/components/forms/fields/SelectField.tsx +++ b/src/components/forms/fields/SelectField.tsx @@ -6,12 +6,16 @@ export function SelectField({ value, options, onChange, + onSearchChange, + disableLocalSearch, }: { label: string; required?: boolean; value: string; options: any[]; onChange: (val: string, fullRow?: any) => void; + onSearchChange?: (query: string) => void; + disableLocalSearch?: boolean; }) { return ( setSearchQuery(e.target.value)} + onChange={(e) => { + const val = e.target.value; + setSearchQuery(val); + onSearchChange?.(val); + }} placeholder="Search options..." className="w-full text-xs bg-transparent border-none outline-none text-strong placeholder:text-muted" autoFocus @@ -192,6 +202,7 @@ export function Select({ e.preventDefault(); e.stopPropagation(); setSearchQuery(''); + onSearchChange?.(''); }} className="text-muted hover:text-strong p-0.5 rounded cursor-pointer" > @@ -270,6 +281,7 @@ export interface MultiSelectProps { className?: string; /** Disable search header filter if set to false */ searchable?: boolean; + onSearchChange?: (query: string) => void; } /** Custom searchable multiselect component using React Portal. */ @@ -285,6 +297,7 @@ export function MultiSelect({ disabled, placeholder, searchable = true, + onSearchChange, }: MultiSelectProps) { const [isOpen, setIsOpen] = useState(false); const [searchQuery, setSearchQuery] = useState(''); @@ -453,7 +466,11 @@ export function MultiSelect({ setSearchQuery(e.target.value)} + onChange={(e) => { + const val = e.target.value; + setSearchQuery(val); + onSearchChange?.(val); + }} placeholder="Search options..." className="w-full text-xs bg-transparent border-none outline-none text-strong placeholder:text-muted" autoFocus @@ -465,6 +482,7 @@ export function MultiSelect({ e.preventDefault(); e.stopPropagation(); setSearchQuery(''); + onSearchChange?.(''); }} className="text-muted hover:text-strong p-0.5 rounded cursor-pointer" >