diff --git a/src/components/OrgComboAutocomplete.js b/src/components/OrgComboAutocomplete.js new file mode 100644 index 0000000..0677e54 --- /dev/null +++ b/src/components/OrgComboAutocomplete.js @@ -0,0 +1,166 @@ +import { Autocomplete, CircularProgress, Grid, TextField, Typography } from '@mui/material'; +import debounce from 'lodash/debounce'; +import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import { fetchOrgCombo, getOrgOptionLabel } from 'utils/OrgComboUtils'; +import { renderOrgOption } from 'components/OrgOptionLabel'; + +const SEARCH_DEBOUNCE_MS = 300; + +export default function OrgComboAutocomplete({ + value, + onChange, + register, + initialOrgId, + initialOrgName, + label = 'Organisation', + size = 'small', + sx, + clearText, + closeText, + openText, + noOptionsText, +}) { + const [options, setOptions] = useState([]); + const [inputValue, setInputValue] = useState(''); + const [loading, setLoading] = useState(false); + const requestIdRef = useRef(0); + const restoredRef = useRef(false); + + const runFetch = useCallback((query, id, onComplete) => { + const requestId = ++requestIdRef.current; + setLoading(true); + + fetchOrgCombo({ + query, + id, + onSuccess: (data) => { + if (requestId !== requestIdRef.current) return; + setOptions(data); + onComplete?.(data); + }, + onFinally: () => { + if (requestId === requestIdRef.current) { + setLoading(false); + } + }, + }); + }, []); + + const debouncedSearch = useMemo( + () => debounce((query) => runFetch(query), SEARCH_DEBOUNCE_MS), + [runFetch] + ); + + useEffect(() => () => debouncedSearch.cancel(), [debouncedSearch]); + + useEffect(() => { + setInputValue(value ? getOrgOptionLabel(value) : ''); + }, [value]); + + const onChangeRef = useRef(onChange); + onChangeRef.current = onChange; + + useEffect(() => { + if (restoredRef.current) return; + if (!initialOrgId && !initialOrgName) return; + + restoredRef.current = true; + + if (initialOrgId) { + runFetch(null, initialOrgId, (data) => { + const org = data?.[0]; + if (org) { + onChangeRef.current(org); + } + }); + } else if (initialOrgName) { + runFetch(initialOrgName, null, (data) => { + const org = data?.find((item) => item.name === initialOrgName) ?? data?.[0]; + if (org) { + onChangeRef.current(org); + } + }); + } + }, [initialOrgId, initialOrgName, runFetch]); + + const handleInputChange = (event, newInputValue, reason) => { + setInputValue(newInputValue); + + if (reason === 'reset') { + return; + } + + debouncedSearch.cancel(); + + if (!newInputValue.trim()) { + requestIdRef.current += 1; + setOptions([]); + setLoading(false); + return; + } + + debouncedSearch(newInputValue); + }; + + return ( + option.groupType} + size={size} + value={value ?? null} + getOptionLabel={getOrgOptionLabel} + filterOptions={(opts) => opts} + renderOption={renderOrgOption} + loading={loading} + inputValue={inputValue} + onInputChange={handleInputChange} + onOpen={() => { + if (inputValue.trim() && options.length === 0) { + runFetch(inputValue); + } + }} + onChange={(event, newValue) => { + onChange(newValue); + }} + sx={{ + '& .MuiInputBase-root': { alignItems: 'center' }, + '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' }, + '& .MuiOutlinedInput-root': { height: 40 }, + ...sx, + }} + renderInput={(params) => ( + + {loading ? : null} + {params.InputProps.endAdornment} + + ), + }} + /> + )} + renderGroup={(params) => ( + + + {params.group} + + {params.children} + + )} + clearText={clearText} + closeText={closeText} + openText={openText} + noOptionsText={noOptionsText} + /> + ); +} diff --git a/src/components/OrgOptionLabel.js b/src/components/OrgOptionLabel.js new file mode 100644 index 0000000..bb25b5c --- /dev/null +++ b/src/components/OrgOptionLabel.js @@ -0,0 +1,32 @@ +import { Box, Typography } from '@mui/material'; +import { getOrgDisplayNames } from 'utils/OrgComboUtils'; + +export default function OrgOptionLabel({ option }) { + const { primary, secondary } = getOrgDisplayNames(option); + + if (!primary) return null; + + return ( + + + {primary} + + {secondary ? ( + + {secondary} + + ) : null} + + ); +} + +export const renderOrgOption = (props, option) => ( +
  • + +
  • +); diff --git a/src/pages/DemandNote/Search/SearchForm.js b/src/pages/DemandNote/Search/SearchForm.js index 0cb0589..3a1756a 100644 --- a/src/pages/DemandNote/Search/SearchForm.js +++ b/src/pages/DemandNote/Search/SearchForm.js @@ -6,6 +6,7 @@ import { Typography } from '@mui/material'; import MainCard from "components/MainCard"; +import OrgComboAutocomplete from "components/OrgComboAutocomplete"; import { useForm } from "react-hook-form"; import * as React from "react"; import * as ComboData from "utils/ComboData"; @@ -21,12 +22,11 @@ import {DemoItem} from "@mui/x-date-pickers/internals/demo"; import {LocalizationProvider} from "@mui/x-date-pickers/LocalizationProvider"; import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs"; // ==============================|| DASHBOARD - DEFAULT ||============================== // -const SearchDemandNoteForm = ({ applySearch, orgComboData, searchCriteria, issueComboData, onGridReady +const SearchDemandNoteForm = ({ applySearch, searchCriteria, issueComboData, onGridReady }) => { const [type, setType] = React.useState([]); const [orgSelected, setOrgSelected] = React.useState({}); - const [orgCombo, setOrgCombo] = React.useState(); const [issueSelected, setIssueSelected] = React.useState({}); const [issueCombo, setIssueCombo] = React.useState([]); const [selectedStatus, setSelectedStatus] = React.useState(ComboData.denmandNoteStatus[0]); @@ -122,15 +122,6 @@ const SearchDemandNoteForm = ({ applySearch, orgComboData, searchCriteria, issue }; - React.useEffect(() => { - if (orgComboData && orgComboData.length > 0) { - setOrgCombo(orgComboData); - if(searchCriteria.orgId!=undefined){ - setOrgSelected(orgComboData.find(item => item.key === searchCriteria.orgId)) - } - } - }, [orgComboData]); - React.useEffect(() => { if (issueComboData && issueComboData.length > 0) { setIssueCombo(issueComboData); @@ -244,56 +235,20 @@ const SearchDemandNoteForm = ({ applySearch, orgComboData, searchCriteria, issue /> - { - orgCombo ? - - option.groupType} - size="small" - value={orgSelected} - getOptionLabel={(option) => option.name? option.name : ""} - inputValue={orgSelected ? orgSelected.name!=undefined?orgSelected.name:"" : ""} - - onChange={(event, newValue) => { - if (newValue !== null) { - setOrgSelected(newValue); - }else{ - setOrgSelected({}); - } - }} - sx={{ - '& .MuiInputBase-root': { alignItems: 'center' }, - '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' }, - '& .MuiOutlinedInput-root': { height: 40 } - }} - renderInput={(params) => ( - - )} - renderGroup={(params) => ( - - - {params.group} - - {params.children} - - )} - clearText={intl.formatMessage({ id: "muiClear" })} - closeText={intl.formatMessage({ id: "muiClose" })} - openText={intl.formatMessage({ id: "muiOpen" })} - noOptionsText={intl.formatMessage({ id: "muiNoOptions" })} - /> - - : <> - } + + { + setOrgSelected(newValue ?? {}); + }} + clearText={intl.formatMessage({ id: "muiClear" })} + closeText={intl.formatMessage({ id: "muiClose" })} + openText={intl.formatMessage({ id: "muiOpen" })} + noOptionsText={intl.formatMessage({ id: "muiNoOptions" })} + /> + { - const [orgCombo, setOrgCombo] = React.useState([]); const [issueCombo, setIssueCombo] = React.useState([]); const [searchCriteria, setSearchCriteria] = React.useState({ // dateTo: DateUtils.dateValue(new Date()), @@ -45,7 +44,6 @@ const UserSearchPage_Individual = () => { const [onGridReady, setGridOnReady] = React.useState(false); React.useEffect(() => { - getOrgCombo(); getIssueCombo(); if (Object.keys(getSearchCriteria(window.location.pathname)).length>0){ setSearchCriteria(getSearchCriteria(window.location.pathname)) @@ -63,16 +61,6 @@ const UserSearchPage_Individual = () => { }, [searchCriteria]); - function getOrgCombo() { - HttpUtils.get({ - url: UrlUtils.GET_ORG_COMBO, - onSuccess: function (responseData) { - let combo = responseData; - setOrgCombo(combo); - } - }); - } - function getIssueCombo() { HttpUtils.get({ url: UrlUtils.GET_ISSUE_COMBO, @@ -115,7 +103,6 @@ const UserSearchPage_Individual = () => { { usePageTitle("paymentInfoRecord"); - const [orgCombo, setOrgCombo] = React.useState([]); const [issueCombo, setIssueCombo] = React.useState([]); const [searchCriteria, setSearchCriteria] = React.useState({}); const [onReady, setOnReady] = React.useState(false); const [onGridReady, setGridOnReady] = React.useState(false); React.useEffect(() => { - getOrgCombo(); getIssueCombo(); if (Object.keys(getSearchCriteria(window.location.pathname)).length>0){ setSearchCriteria(getSearchCriteria(window.location.pathname)) @@ -59,16 +57,6 @@ const SearchPage_DemandNote_Pub = () => { }, [searchCriteria]); - function getOrgCombo() { - HttpUtils.get({ - url: GET_ORG_COMBO, - onSuccess: function (responseData) { - let combo = responseData; - setOrgCombo(combo); - } - }); - } - function getIssueCombo() { HttpUtils.get({ url: GET_ISSUE_COMBO, @@ -112,7 +100,6 @@ const SearchPage_DemandNote_Pub = () => { { const [type, setType] = React.useState([]); const [status, setStatus] = React.useState(searchCriteria.statusKey!=undefined?ComboData.proofStatus_GLD[searchCriteria.statusKey]:ComboData.proofStatus_GLD[0]); const [orgSelected, setOrgSelected] = React.useState(null); - const [orgCombo, setOrgCombo] = React.useState(); const [issueSelected, setIssueSelected] = React.useState(null); const [issueCombo, setIssueCombo] = React.useState([]); const [groupSelected, setGroupSelected] = React.useState( @@ -119,15 +119,6 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss applySearch(temp); }; - React.useEffect(() => { - if (orgComboData && orgComboData.length > 0) { - setOrgCombo(orgComboData); - if(searchCriteria.orgId!=undefined){ - setOrgSelected(orgComboData.find(item => item.key === searchCriteria.orgId)) - } - } - }, [orgComboData]); - React.useEffect(() => { if (issueComboData && issueComboData.length > 0) { setIssueCombo(issueComboData); @@ -384,48 +375,16 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss /> - { - orgCombo ? - - option.groupType} - size="small" - value={orgSelected} - getOptionLabel={(option) => option.name? option.name : ""} - inputValue={orgSelected ? orgSelected.name!=undefined?orgSelected.name:"" : ""} - - onChange={(event, newValue) => { - setOrgSelected(newValue ?? null); - }} - sx={{ - '& .MuiInputBase-root': { alignItems: 'center' }, - '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' }, - '& .MuiOutlinedInput-root': { height: 40 } - }} - renderInput={(params) => ( - - )} - renderGroup={(params) => ( - - - {params.group} - - {params.children} - - )} - /> - - : <> - } + + { + setOrgSelected(newValue ?? null); + }} + /> + diff --git a/src/pages/Proof/Search_GLD/index.js b/src/pages/Proof/Search_GLD/index.js index fb015c9..49fbdba 100644 --- a/src/pages/Proof/Search_GLD/index.js +++ b/src/pages/Proof/Search_GLD/index.js @@ -9,7 +9,7 @@ import MainCard from "components/MainCard"; import * as React from "react"; import * as HttpUtils from "utils/HttpUtils"; import * as DateUtils from "utils/DateUtils"; -import {GET_ORG_COMBO, GET_ISSUE_COMBO} from "utils/ApiPathConst"; +import {GET_ISSUE_COMBO} from "utils/ApiPathConst"; import { getSearchCriteria } from "auth/utils"; import Loadable from 'components/Loadable'; @@ -31,14 +31,12 @@ const BackgroundHead = { // ==============================|| DASHBOARD - DEFAULT ||============================== // const UserSearchPage_Individual = () => { - const [orgCombo, setOrgCombo] = React.useState([]); const [issueCombo, setIssueCombo] = React.useState([]); const [searchCriteria, setSearchCriteria] = React.useState({}); const [onReady, setOnReady] = React.useState(false); const [onGridReady, setGridOnReady] = React.useState(false); React.useEffect(() => { - getOrgCombo(); getIssueCombo(); if (Object.keys(getSearchCriteria(window.location.pathname)).length>0){ setSearchCriteria(getSearchCriteria(window.location.pathname)) @@ -56,16 +54,6 @@ const UserSearchPage_Individual = () => { }, [searchCriteria]); - function getOrgCombo() { - HttpUtils.get({ - url: GET_ORG_COMBO, - onSuccess: function (responseData) { - let combo = responseData; - setOrgCombo(combo); - } - }); - } - function getIssueCombo() { HttpUtils.get({ url: GET_ISSUE_COMBO, @@ -106,7 +94,6 @@ const UserSearchPage_Individual = () => { { const [type, setType] = React.useState([]); - // const [status, setStatus] = React.useState({ key: 0, label: 'All', type: 'all' }); const [orgSelected, setOrgSelected] = React.useState(null); - const [inputValue, setInputValue] = React.useState(""); - const [orgCombo, setOrgCombo] = React.useState(); const [issueSelected, setIssueSelected] = React.useState({}); const [issueCombo, setIssueCombo] = React.useState([]); const [selectedStatus, setSelectedStatus] = React.useState({key: 0, label: 'All', type: 'all'}); @@ -102,15 +100,6 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss // setSearchReady(true) }; - React.useEffect(() => { - if (orgComboData && orgComboData.length > 0) { - setOrgCombo(orgComboData); - if(searchCriteria.orgId!=undefined){ - setOrgSelected(orgComboData.find(item => item.key === searchCriteria.orgId)) - } - } - }, [orgComboData]); - React.useEffect(() => { if (issueComboData && issueComboData.length > 0) { setIssueCombo(issueComboData); @@ -124,7 +113,6 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss setType([]); // setStatus({ key: 0, label: 'All', type: 'all' }); setOrgSelected(null); - setInputValue(""); setIssueSelected({}); setGroupSelected({}); setSelectedStatus({key: 0, label: 'All', type: 'all'}); @@ -330,56 +318,16 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss /> */} - { - orgCombo ? - - option.groupType} - size="small" - value={orgSelected} - getOptionLabel={(option) => option?.name ?? ""} - inputValue={inputValue} - onInputChange={(event, newInputValue) => { - setInputValue(newInputValue); - }} - onChange={(event, newValue) => { - if (newValue) { - setOrgSelected(newValue); - } else { - setOrgSelected({}); - } - }} - sx={{ - '& .MuiInputBase-root': { alignItems: 'center' }, - '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' }, - '& .MuiOutlinedInput-root': { height: 40 } - }} - renderInput={(params) => ( - - )} - renderGroup={(params) => ( - - - {params.group} - - {params.children} - - )} - /> - - - : <> - } + + { + setOrgSelected(newValue ?? null); + }} + /> + { - const [orgCombo, setOrgCombo] = React.useState([]); const [issueCombo, setIssueCombo] = React.useState([]); const [searchCriteria, setSearchCriteria] = React.useState({}); const [onReady, setOnReady] = React.useState(false); const [onGridReady, setGridOnReady] = React.useState(false); React.useEffect(() => { - getOrgCombo(); getIssueCombo(); if (Object.keys(getSearchCriteria(window.location.pathname)).length>0){ setSearchCriteria(getSearchCriteria(window.location.pathname)) @@ -54,16 +52,6 @@ const UserSearchPage_Individual = () => { setOnReady(true); }, [searchCriteria]); - function getOrgCombo() { - HttpUtils.get({ - url: UrlUtils.GET_ORG_COMBO, - onSuccess: function (responseData) { - let combo = responseData; - setOrgCombo(combo); - } - }); - } - function getIssueCombo() { HttpUtils.get({ url: UrlUtils.GET_ISSUE_COMBO, @@ -104,7 +92,6 @@ const UserSearchPage_Individual = () => { { const [type, setType] = React.useState([]); - // const [status, setStatus] = React.useState({ key: 0, label: 'All', type: 'all' }); const [orgSelected, setOrgSelected] = React.useState({}); - const [orgCombo, setOrgCombo] = React.useState(); const [issueSelected, setIssueSelected] = React.useState({}); const [issueCombo, setIssueCombo] = React.useState([]); const [selectedStatus, setSelectedStatus] = React.useState({key: 0, label: 'All', type: 'all'}); @@ -92,15 +91,6 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss applySearch(temp); }; - React.useEffect(() => { - if (orgComboData && orgComboData.length > 0) { - setOrgCombo(orgComboData); - if(searchCriteria.orgId!=undefined){ - setOrgSelected(orgComboData.find(item => item.key === searchCriteria.orgId)) - } - } - }, [orgComboData]); - React.useEffect(() => { if (issueComboData && issueComboData.length > 0) { setIssueCombo(issueComboData); @@ -317,51 +307,16 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss />*/} - { - orgCombo ? - - option.groupType} - size="small" - value={orgSelected} - getOptionLabel={(option) => option.name? option.name : ""} - inputValue={orgSelected ? orgSelected.name!=undefined?orgSelected.name:"" : ""} - onChange={(event, newValue) => { - if (newValue !== null) { - setOrgSelected(newValue); - }else{ - setOrgSelected({}); - } - }} - sx={{ - '& .MuiInputBase-root': { alignItems: 'center' }, - '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' }, - '& .MuiOutlinedInput-root': { height: 40 } - }} - renderInput={(params) => ( - - )} - renderGroup={(params) => ( - - - {params.group} - - {params.children} - - )} - /> - - : <> - } + + { + setOrgSelected(newValue ?? {}); + }} + /> + { - const [orgCombo, setOrgCombo] = React.useState([]); const [issueCombo, setIssueCombo] = React.useState([]); const [searchCriteria, setSearchCriteria] = React.useState({}); const [onReady, setOnReady] = React.useState(false); const [onGridReady, setGridOnReady] = React.useState(false); React.useEffect(() => { - getOrgCombo(); getIssueCombo(); if (Object.keys(getSearchCriteria(window.location.pathname)).length>0){ setSearchCriteria(getSearchCriteria(window.location.pathname)) @@ -54,16 +52,6 @@ const UserSearchPage_Individual = () => { setOnReady(true); }, [searchCriteria]); - function getOrgCombo() { - HttpUtils.get({ - url: UrlUtils.GET_ORG_COMBO, - onSuccess: function (responseData) { - let combo = responseData; - setOrgCombo(combo); - } - }); - } - function getIssueCombo() { HttpUtils.get({ url: UrlUtils.GET_ISSUE_COMBO, @@ -104,7 +92,6 @@ const UserSearchPage_Individual = () => { {FieldUtils.getComboField({ label: "Organisation:", valueName: "orgId", - getOptionLabel: (option) => option.enCompanyName ? option.enCompanyName : option.chCompanyName ? option.chCompanyName : "", + getOptionLabel: getOrgOptionLabel, + renderOption: renderOrgOption, + filterOptions: filterOrgComboOptions, dataList: orgData, disabled: (!editMode), form: formik diff --git a/src/pages/User/SearchPage_Organization/UserSearchForm_Organization.js b/src/pages/User/SearchPage_Organization/UserSearchForm_Organization.js index 8137a9e..e3ae73f 100644 --- a/src/pages/User/SearchPage_Organization/UserSearchForm_Organization.js +++ b/src/pages/User/SearchPage_Organization/UserSearchForm_Organization.js @@ -6,6 +6,7 @@ import { Typography } from '@mui/material'; import MainCard from "../../../components/MainCard"; +import OrgComboAutocomplete from "../../../components/OrgComboAutocomplete"; import {useForm} from "react-hook-form"; import { useState, useEffect} from "react"; @@ -14,11 +15,10 @@ import {ThemeProvider} from "@emotion/react"; // ==============================|| DASHBOARD - DEFAULT ||============================== // -const UserSearchForm_Organization = ({applySearch, orgComboData, onGridReady, searchCriteria}) => { +const UserSearchForm_Organization = ({applySearch, onGridReady, searchCriteria}) => { const [type, setType] = useState([]); const [accountFilter, setAccountFilter] = useState("All"); - const [orgCombo, setOrgCombo] = useState(); const [orgSelected, setOrgSelected] = useState({}); const { reset, register, handleSubmit } = useForm() @@ -58,15 +58,6 @@ const UserSearchForm_Organization = ({applySearch, orgComboData, onGridReady, se applySearch(temp); }; - useEffect(() => { - if (orgComboData && orgComboData.length > 0) { - setOrgCombo(orgComboData); - if(searchCriteria.orgName!=undefined){ - setOrgSelected(orgComboData.find(item => item.name === searchCriteria.orgName)) - } - } - }, [orgComboData]); - function resetForm(){ setType([]); setAccountFilter("All"); @@ -98,52 +89,16 @@ const UserSearchForm_Organization = ({applySearch, orgComboData, onGridReady, se {/*row 2*/} - { - orgCombo ? - - option.groupType} - size="small" - value={orgSelected} - getOptionLabel={(option) => option.name? option.name : ""} - inputValue={orgSelected ? orgSelected.name!=undefined?orgSelected.name:"" : ""} - - onChange={(event, newValue) => { - if (newValue !== null) { - setOrgSelected(newValue); - }else{ - setOrgSelected({}); - } - }} - sx={{ - '& .MuiInputBase-root': { alignItems: 'center' }, - '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' }, - '& .MuiOutlinedInput-root': { height: 40 } - }} - renderInput={(params) => ( - - )} - renderGroup={(params) => ( - - - {params.group} - - {params.children} - - )} - /> - - : <> - } + + { + setOrgSelected(newValue ?? {}); + }} + /> + { // Localized document title/meta for organization user search usePageTitle("organizationProfile"); - const [orgCombo, setOrgCombo] = useState([]); const [searchCriteria, setSearchCriteria] = useState({}); const [onReady, setOnReady] = useState(false); const [onGridReady, setGridOnReady] = useState(false); useEffect(() => { - getOrgCombo(); - // getIssueCombo(); if (Object.keys(getSearchCriteria(window.location.pathname)).length>0){ setSearchCriteria(getSearchCriteria(window.location.pathname)) }else{ @@ -47,16 +42,6 @@ const UserSearchPage_Organization = () => { } }, []); - function getOrgCombo() { - HttpUtils.get({ - url: GET_ORG_COMBO, - onSuccess: function (responseData) { - let combo = responseData; - setOrgCombo(combo); - } - }); - } - useEffect(() => { setOnReady(true); }, [searchCriteria]); @@ -91,7 +76,6 @@ const UserSearchPage_Organization = () => { diff --git a/src/utils/OrgComboUtils.js b/src/utils/OrgComboUtils.js new file mode 100644 index 0000000..c7eb7c2 --- /dev/null +++ b/src/utils/OrgComboUtils.js @@ -0,0 +1,64 @@ +import { GET_ORG_COMBO } from 'utils/ApiPathConst'; +import * as HttpUtils from 'utils/HttpUtils'; + +export const getOrgDisplayNames = (option) => { + if (!option) return { primary: "", secondary: "" }; + + const en = option.enCompanyName?.trim() || ""; + const ch = option.chCompanyName?.trim() || ""; + + if (en && ch) return { primary: en, secondary: ch }; + if (en) return { primary: en, secondary: "" }; + if (ch) return { primary: ch, secondary: "" }; + return { primary: option.name ?? "", secondary: "" }; +}; + +export const getOrgOptionLabel = (option) => getOrgDisplayNames(option).primary; + +const orgSearchFields = (option) => [ + option.name, + option.label, + option.brNo, + option.enCompanyName, + option.chCompanyName, +]; + +export const filterOrgComboOptions = (options, state) => { + const inputValue = state?.inputValue?.trim(); + if (!inputValue) return options; + + const searchStr = inputValue.toLowerCase(); + return options.filter((option) => + orgSearchFields(option).some( + (field) => field != null && String(field).toLowerCase().includes(searchStr) + ) + ); +}; + +export const fetchOrgCombo = ({ query, id, onSuccess, onFinally }) => { + const params = {}; + if (id) { + params.id = id; + } else if (query?.trim()) { + params.query = query.trim(); + } else { + onSuccess?.([]); + onFinally?.(); + return; + } + + HttpUtils.get({ + url: GET_ORG_COMBO, + params, + onSuccess: (responseData) => { + onSuccess?.(Array.isArray(responseData) ? responseData : []); + }, + onFail: () => { + onSuccess?.([]); + }, + onError: () => { + onSuccess?.([]); + }, + onFinally, + }); +};