...
Developing new API which is completely driven by address hierarchy and uses AddressNode
psql table to get required nodes data
Expand |
---|
title | api/CustomerPortal/fetchGeneralAddressCode |
---|
|
Code Block |
---|
const fetchGeneralAddressCode = async (organisationId, extendedModels, params, options = {}) => {
const { searchType, queryString } = params;
if (!searchType) {
throw helper.wrongInputError('Location Key should be present');
}
const metaData = await addressHierarchy.getAddressMetadata(extendedModels, organisationId);
if (!metaData) {
throw helper.wrongInputError('Metadata not found');
}
const hierarchy = metaData.hierarchy || [];
const nodeHierarchyMetaData = hierarchy.find(obj => helper.sanitizeStringCode(obj.location_key) === helper.sanitizeStringCode(searchType));
if (!nodeHierarchyMetaData) {
throw helper.wrongInputError('Invalid Location Key');
}
const parentMetaDataArr = [];
let searchTypeNodeFound = false;
if (Array.isArray(hierarchy) && hierarchy.length > 0) {
for (let i = 0; i < (hierarchy.length - 1); i++) {
if (searchTypeNodeFound || helper.sanitizeStringCode(hierarchy[i].location_key) === helper.sanitizeStringCode(searchType)) {
searchTypeNodeFound = true;
parentMetaDataArr.push(hierarchy[i + 1]);
}
}
}
const queryParameters = [];
let heirarchyId = nodeHierarchyMetaData.id;
let nodeCode = helper.sanitizeStringCode(queryString);
const toRet = {};
toRet.data = {};
queryParameters.push(organisationId);
queryParameters.push(heirarchyId);
queryParameters.push(nodeCode);
const selectPart = 'SELECT addressNode.id as node_id,addressNode.code as node_code,addressNode.name as node_name,addressNode.hierarchy_id as hierarchy_id';
const fromPart = ' FROM addressNode';
let extendedSelectPart = '';
let joinPart = '';
const wherePart = ' WHERE addressNode.organisation_id = $1 and addressNode.hierarchy_id = $2 and addressNode.code = $3';
if (parentMetaDataArr.length) {
extendedSelectPart = ',addressNode.parent_node_id as parent_node_id,parentAddressNode.code as parent_code,parentAddressNode.name as parent_name';
joinPart = ' JOIN addressNode AS parentAddressNode on addressNode.parent_node_id = parentAddressNode.id';
}
const queryToExecute = selectPart + extendedSelectPart + fromPart + joinPart + wherePart;
const result = await helper.executeQueryAsync(extendedModels.AddressNode, queryToExecute, queryParameters, options);
if (result[0] && result[0].node_name) {
toRet.data[searchType] = result[0].node_name;
} else {
throw helper.wrongInputError('Data not found for this location key');
}
let nextNodesResult = result;
for (let i = 0; i < parentMetaDataArr.length; i++) {
try {
heirarchyId = parentMetaDataArr[i].id;
nodeCode = nextNodesResult[0].parent_code;
const locationKey = parentMetaDataArr[i].location_key;
queryParameters[1] = heirarchyId;
queryParameters[2] = nodeCode;
if (i === (parentMetaDataArr.length - 1)) {
const lastNodeQueryResult = selectPart + fromPart + wherePart;
nextNodesResult = await helper.executeQueryAsync(extendedModels.AddressNode, lastNodeQueryResult, queryParameters, options);
} else {
nextNodesResult = await helper.executeQueryAsync(extendedModels.AddressNode, queryToExecute, queryParameters, options);
}
if (nextNodesResult[0] && nextNodesResult[0].node_name) {
toRet.data[locationKey] = nextNodesResult[0].node_name;
}
} catch (err) {
//do nothing
}
}
return toRet;
}; |
|
Code Block |
---|
//success response type will be like |
...
Code Block |
---|
{
"data": {
"pincode": "DAM",
"city": "Z1",
"state": "DAMMAM"
}
} |
...
To make filter also applicable on name and code both while fetching node list at frontend, updating filter logic.
Current filter logic:
Expand |
---|
title | Current filter logic: |
---|
|
Code Block |
---|
const conditions = {
hierarchy_id: hierarchyId,
organisation_id: organisationId
};
if (isDataSearchApplied) {
searchQuery = helper.sanitizeStringCode(searchQuery);
let queryString = `${searchQuery}%`;
if (sortResult) {
queryString = `%${queryString}`;
}
conditions.code = {ilike: queryString};
if (shouldSearchByName) {
conditions.name = {ilike: queryString};
delete conditions.code;
}
}
const heirarchyData = await extendedModels.AddressNode.find({
where: conditions,
fields: { code: true, name: true, id: true },
order: sortResult && 'name ASC',
});
|
|
Updated filter logic:
Expand |
---|
title | Updated filter logic: |
---|
|
Code Block |
---|
const conditions = {
and: [
{hierarchy_id: hierarchyId},
{organisation_id: organisationId},
],
};
if (isDataSearchApplied) {
searchQuery = helper.sanitizeStringCode(searchQuery);
let queryString = `${searchQuery}%`;
if (sortResult) {
queryString = `%${queryString}`;
}
const orConditions = shouldIncludeNameInSearchFilter
? [
{ name: { ilike: queryString } },
{ code: { ilike: queryString } }
]
:
[{ code: { ilike: queryString } }];
conditions.and.push({ or: orConditions });
}
const heirarchyData = await extendedModels.AddressNode.find({
where: conditions,
fields: { code: true, name: true, id: true }
});
|
|
Frontend changes:
At frontend side changes are to be done at 3 places
Add Consignment modal (src/components/pages/details/AddDetails.tsx
)
Counter Booking → Add Address ( src/components/pages/OpsDashboard/Manage/counterBooking/AddAddress2.tsx
)
Customer-Portal → src/components/address/create-address.tsx
List to be populated in dropdown will be fetched after entering atleast 3 characters in the input field for corresponding node( pincode, city, state, country).
Debouncing will be implemented at all places whereever we are fetching list to be populated in the dropdown.
In case allowOverrideHierarchy
is false , we will let user only enter values from dropdown only.
In case allowOverrideHierarchy
is true: user can either select from dropdown or enter other values too.
Only those fields will be disabled for which data is fetched, only when allow override hierarchy is false
...
Instead of showing only Name of options in dropdown it will now be shown as Name (Code)
. This will require another update in find query in common/models/customer-portal-parts/address-node-api-helper.js
→ getAddressNodeData
(mentioned above in backend changes).
Customer Portal changes
Changes in src/components/address/create-address.tsx
General Function to be called whenever any option from rendered dropdown is selected, it make call to api api/CustomerPortal/fetchGeneralAddressCode
Code Block |
---|
// this logic will be used to get whether isAddressHierarchyPresent is true or false
if (Array.isArray(response.data.hierarchy) && response.data.hierarchy.length) {
})(setIsAddressHierarchyPresent(true);
<Select
showSearch
} |
In case isAddressHierarchyPresent
is false then we will render only Simple Input text field.
If isAddressHierarchyPresent
is true:
It fetches data from AddressNode table on basis of address hierarchy setup, and returns data for current and higher nodes to populate.
It also handle the logic to either disbale the higher level nodes based on whether their value is fetched and allow_override_hierarchy is false.
It also update (auto populate) the value of higher nodes
Expand |
---|
title | saveAddressUsingAddressHierarchy code snippet called on onChange |
---|
|
Code Block |
---|
const saveAddressUsingAddressHierarchy = async (nodeValue: string, nodeType: string) => {
if (!isKeyOfNewAddress(nodeType) || !nodeValue) return;
| optionFilterProp="children" setLoading(true);
const fetchLocality = await fetchAddressUsingAddressHierarchy({ queryString: nodeValue, searchType: nodeType | onChange={(value => this.saveAddressUsingAddressHierarchy(value, 'country', 'sender')};
if (!fetchLocality.isSuccess) {
setNewAddress({
| placeholder={t("Country")}disabled={this.state.senderDisableCountry}onSearch={this.loadCountries}allowClear });
setDisableLocality(false);
| >{this.state?.countriesList?.map(opt => <Option key={opt.id} value={opt.code}>{t(opt.name)} ({opt.code})</Option>)}let nodeFound = false;
const parentLevelNodes = [];
| </Select>, for (let i = 0; i < hierarchyData?.length; i += 1) {
| )} {this.state.allowOverrideHierarchy && getFieldDecorator('sender_country', {= hierarchyData[i].location_key.toLowerCase();
if ((nodeFound || curNode === nodeType.toLocaleLowerCase()) && | rules: [curNode in fetchLocality?.data) {
| required:false,message:t('cannot_be_empty')}],})(<AutoComplete parentLevelNodes.push({ key: hierarchyData[i].location_key, value: fetchLocality?.data[curNode] });
| options={this.state?.countriesList?.map(item=>({label:`${item.name} (${item.code})`, value: item.code }))}}
}
const fetchedAddressFieldsObj | onSearch{this.loadCountries}
parentLevelNodes?.reduce((acc, curr) => {
if | onSelect={(value(isKeyOfNewAddress(curr.key)) | => this.saveAddressUsingAddressHierarchy(value, 'country', 'sender')} onChange={(value) => this.handleAddressFields('country', value, !this.state.allowOverrideHierarchy, 'sender')}acc[curr.key] = curr.value || null;
if | disabled={this.state.senderDisableCountry}
(curr.key !== nodeType && (!isAddressMappingAllowed && curr.value)) {
| allowClear setDisableLocality(true, curr.key);
| ><Input setDisableLocality(false, curr.key);
| allowClearplaceholder={t("Country")}/> </AutoComplete>, |
Instead of showing only Name of options in dropdown it will now be shown as Name (Code)
. This will require another update in find query in common/models/customer-portal-parts/address-node-api-helper.js
→ getAddressNodeData
(mentioned above in backend changes).
Customer Portal changes
Changes in src/components/address/create-address.tsx
General Function to be called whenever any option from rendered dropdown is selected, it make call to api api/CustomerPortal/fetchGeneralAddressCode
It fetches data from AddressNode table on basis of address hierarchy setup, and returns data for current and higher nodes to populate.
It also handle the logic to either disbale the higher level nodes based on whether their value is fetched and allow_override_hierarchy is false.
It also update (auto populate) the value of higher nodes.
Code Block |
---|
const saveAddressUsingAddressHierarchy = async (nodeValue: string, nodeType: string) => {
if (!isKeyOfNewAddress(nodeType) || !nodeValue) return;
setLoading(true);{} as { [key: string]: string | null });
setNewAddress({
...newAddress,
...fetchedAddressFieldsObj,
});
}
setLoading(false);
}; |
|
Function to be called on typing text to be searched in address fields( pincode, city, state country)
Expand |
---|
title | Searching function logic called on onSearch |
---|
|
Code Block |
---|
const loadPincodes = async (value: any) => {
if (value?.length < 3) return;
if (!hierarchyData?.some((node: any) => node.location_key === 'pincode')) return;
setLoading(true);
const response = await fetchPincodeList(value);
if (response && response.isSuccess && Array.isArray(response?.data)) {
setLocalityPincodesList(response.data || []);
}
setLoading(false);
};
const loadCitiesList = async (value: any) => {
if (value?.length < 3) return;
if (!hierarchyData?.some((node: any) => node.location_key === 'city')) return;
setLoading(true);
const response = await fetchCitiesList(value);
if (response && response.isSuccess && Array.isArray(response?.data)) {
setLocalityCitiesList(response.data || []);
}
setLoading(false);
};
const loadStatesList = async (value: any) => {
if (value?.length < 3) return;
if (!hierarchyData?.some((node: any) => node.location_key === 'state')) return;
setLoading(true);
const response = await fetchStatesList(value);
if (response && response.isSuccess && Array.isArray(response?.data)) {
setLocalityStatesList(response.data || []);
}
setLoading(false);
};
const loadCountriesList = async (value: any) => {
if (value?.length < 3) return;
if (!hierarchyData?.some((node: any) => node.location_key === 'country')) return;
setLoading(true);
const response = await fetchCountriesList(value);
if (response && response.isSuccess && Array.isArray(response?.data)) {
setCountriesList(response.data || []);
}
setLoading(false);
}; |
|
Debouncing logic is also applied :
Expand |
---|
|
Code Block |
---|
useEffect(() => {
loadPincodes(newAddress.pincode);
}, [debouncePincode]);
useEffect(() => {
loadCitiesList(newAddress.city);
}, [debounceCity]);
useEffect(() => {
loadStatesList(newAddress.state);
}, [debounceState]);
useEffect(() => {
loadCountriesList(newAddress.country);
}, [debounceCountry]);
//import { useDebounce } from 'hooks/use-debounce'; using already imported (was being used for w3wCode) useDebounce HoC
//SEARCH_TIMEOUT = 500 -> debounce time is used by default
const debouncePincode = useDebounce(newAddress.pincode);
const debounceCity = useDebounce(newAddress.city);
const debounceState = useDebounce(newAddress.state);
const debounceCountry = useDebounce(newAddress.country);
|
|
Following rendering logic is used for all nodes (pincode, state, city, country)
It renders only dropdown for case when allow_override_hierarchy
is false (user can only select options from dropdown only).
When allow_override_hierarchy
is true: user can type and search will be done in db, if data found user can select any option from dropdown and on basis of it higher level nodes is auto-populated, and can also enter anything out of option in dropdown for current node and higher nodes too.
On clearing a node’s value, all higher node's value will also be cleared.
Expand |
---|
title | Rendering snippet for address fields |
---|
|
Code Block |
---|
const renderPincodeBox = () => {
if (isAddressHierarchyPresent && isAddressMappingAllowed) {
return (
<AutoComplete
value={newAddress.pincode}
className={classes.pincodeInput}
dropdownClassName={classes.pincodeInputDropdown}
options={
localityPincodesList.map((pincode: any) => {
return {
label: `${pincode.name} (${pincode.code})`,
value: pincode.code,
};
})
}
onSearch={loadPincodes}
onSelect={(e) => saveAddressUsingAddressHierarchy(e, 'pincode')}
onChange={(value) => updateAddressFieldWithValidations('pincode', value)}
style={{ textAlign: 'left' }}
allowClear
>
<Input
className={classes.autoCompleteInputBox}
allowClear
placeholder={t('address_pincode')}
/>
</AutoComplete>
);
} else if (isAddressHierarchyPresent && !isAddressMappingAllowed) {
return (
| constfetchLocality=awaitfetchAddressUsingAddressHierarchy({queryString: nodeValue, searchType: nodeType });if(!fetchLocality.isSuccess){ className={classes.pincodeWithExtra}
| setNewAddress({...newAddress,city: '',
extra={samplePincode ? `Ex. ${samplePincode}` : undefined}
| state:'',country:'',});setDisableLocality(false); value={newAddress.pincode}
| }else{letnodeFound=false; dropdownClassName={classes.pincodeInputDropdown}
| constparentLevelNodes=[];for (let i = 0; i < hierarchyData?.length; i += 1) {placeholder={t('address_pincode')}
onChange={(e) => {
| constcurNode=hierarchyData[i].location_key.toLowerCase();if((nodeFound||curNode===nodeType.toLocaleLowerCase())&&curNode in fetchLocality?.data) { updateAddressFieldWithValidations('pincode', e);
| nodeFound=true; const isValid = isValidPincode(e);
| parentLevelNodes.push({key:hierarchyData[i].location_key,value:fetchLocality?.data[curNode]}); if (isValid !== validPincode) {
| }}constfetchedAddressFieldsObj=parentLevelNodes?.reduce((acc, curr) => {setValidPincode(isValid);
| if (isKeyOfNewAddress(curr.key)) {acc[curr.key]=curr.value||null;if(curr.key!==nodeType&&(!isAddressMappingAllowed&&curr.value)){setDisableLocality(true,curr.key); localityPincodesList.map((pincode: any) => {
| }else{setDisableLocality(false,curr.key);} label: `${pincode.name} (${pincode.code})`,
| }returnacc;}, {} as { [key: string]: string | null });setNewAddress({...newAddress,...fetchedAddressFieldsObj, ;
}setLoading(false);}; |
Function to be called on typing text to be searched in address fields( pincode, city, state country)
Code Block |
---|
const loadPincodes = async (value: any) => {if(value?.length<3)return;if(!hierarchyData?.some((node: anynode.location_key ===saveAddressUsingAddressHierarchy(e, 'pincode') | )return;setLoading(true);constresponse=awaitfetchPincodeList(value);
defaultActiveFirstOption={false}
| if (response && response.isSuccess && Array.isArray(response?.data)){setLocalityPincodesList(response.data||[]);
}setLoading(false);};constloadCitiesList=async(value:any)=>{if(value?.length<3)return;if(!hierarchyData?.some((node:any)=>node.location_key==='city'))return;setLoading(true);constresponse=awaitfetchCitiesList(value);if(response&&response.isSuccess && Array.isArray(response?.data)) { style={validPincode ? {} : { borderColor: 'red' }}
| setLocalityCitiesList(response.data||[]);}setLoading(false);};constloadStatesList=async(value:any)=>{if(value?.length<3)return;if(!hierarchyData?.some((node:any)=>node.location_key==='state'))return;setLoading(true);constresponse=awaitfetchStatesList(value);if(response&&response.isSuccess&&Array.isArray(response?.data)){ value={newAddress.pincode}
| setLocalityStatesList(response.data||[]); className={classes.pincodeInput} |
setLoading(false);};constloadCountriesList async (value: any) => {if(value?.length<3)return; if (!hierarchyData?.some((node: any) => node.location_key === 'country')) return;updateAddressFieldWithValidations('pincodeInput', e.target.value)}
| setLoading(true);constresponse=awaitfetchCountriesList(valueif(response&&response.isSuccess && Array.isArray(response?.data)) {
setCountriesList(response.data || []);
}
setLoading(false);
}; |
Debouncing logic is also applied :
Code Block |
---|
useEffect(() => {
loadPincodes(newAddress.pincode);
}, [debouncePincode]);
useEffect(() => {
loadCitiesList(newAddress.city);
}, [debounceCity]);
useEffect(() => { |
Changes in src/network/pickup.api.ts
Expand |
---|
title | Changes in src/network/pickup.api.ts |
---|
|
Code Block |
---|
//api to fetch states list
export const FETCH_STATES_LIST = '/api/CustomerPortal/addressManagement/getAddressNodeData?type=State';
//api to fetch nodes value based on address hierarchy (new dev api)
export const FETCH_ADDRESS_FROM_ADDRESS_HIERARCHY = '/api/CustomerPortal/fetchGeneralAddressCode';
export const fetchAddressUsingAddressHierarchy = (params: any) => {
return POST(`${API_BASE_URL}${FETCH_ADDRESS_FROM_ADDRESS_HIERARCHY}`, params);
};
//exporting functions to fetch nodes' list to be called from create-address.tsx file on entering sompething in inpit fileds (> 3chars)
export const fetchCountriesList = (params: any) => {
return GET(`${API_BASE_URL}${FETCH_COUNTRIES_NODE_DATA}`,
{ | loadStatesList(newAddress.state);
}, [debounceState]);
useEffect((isDataSearchApplied: true, searchQuery: params, sortResult: true });
};
export const fetchCitiesList = (params: any) => {
return GET(`${API_BASE_URL}${FETCH_CITIES_LIST}`,
| loadCountriesList(newAddress.country);}[debounceCountry]);
//import { useDebounce } from 'hooks/use-debounce'; using already imported (was being used for w3wCode) useDebounce HoC
//SEARCH_TIMEOUT = 500 -> debounce time is used by default
const debouncePincode = useDebounce(newAddress.pincode);
const debounceCity = useDebounce(newAddress.city);
const debounceState = useDebounce(newAddress.state);
const debounceCountry = useDebounce(newAddress.country);
|
Following rendering logic is used for all nodes (pincode, state, city, country)
It renders only dropdown for case when allow_override_hierarchy
is false (user can only select options from dropdown only).
When allow_override_hierarchy
is true: user can type and search will be done in db, if data found user can select any option from dropdown and on basis of it higher level nodes is auto-populated, and can also enter anything out of option in dropdown for current node and higher nodes too.
On clearing a node’s value, all higher node's value will also be cleared.
Code Block |
---|
const renderStateBox = () => {
if (isAddressMappingAllowed) {
return (
<AutoComplete
value={newAddress.state}
className={classes.stateInput}
searchQuery: params, sortResult: true });
};
export const fetchStatesList = (params: any) => {
return GET(`${API_BASE_URL}${FETCH_STATES_LIST}`,
{ isDataSearchApplied: true, searchQuery: params, sortResult: true });
}; |
|
Changes in src/network/api.constants.ts
Expand |
---|
title | changes in src/network/api.constants.ts |
---|
|
Code Block |
---|
export const FETCH_STATES_LIST = '/api/CustomerPortal/addressManagement/getAddressNodeData?type=State';
export const FETCH_COUNTRIES_NODE_DATA = '/api/CustomerPortal/addressManagement/getAddressNodeData?type=Country';
export const FETCH_ADDRESS_FROM_ADDRESS_HIERARCHY = '/api/CustomerPortal/fetchGeneralAddressCode'; |
|
CRMDashboard changes:
General Function to be called whenever any option from rendered dropdown is selected, it make call to api api/CustomerPortal/fetchGeneralAddressCode
In case isAddressHierarchyPresent
is false then we will render only Simple Input text field.
If isAddressHierarchyPresent
is true:
It fetches data from AddressNode table on basis of address hierarchy setup, and returns data for current and higher nodes to populate.
It also handle the logic to either disbale the higher level nodes based on whether their value is fetched and allow_override_hierarchy is false.
It also update (auto populate) the value of higher nodes
Expand |
---|
title | saveAddressUsingAddressHierarchy code snippet called on onChange |
---|
|
Code Block |
---|
const saveAddressUsingAddressHierarchy = async (nodeValue, nodeType) => {
if (!nodeType) return;
if (!nodeValue) {
handleAddressFields(nodeType, null, false);
return;
}
const fetchLocality = await fetchAddressUsingAddressHierarchy({ queryString: nodeValue, searchType: nodeType });
if (!fetchLocality.isSuccess) {
form.setFieldsValue({
cityName: '',
stateName: '',
| dropdownClassName={classes.pincodeInputDropdown} countryName: '',
});
setDisableLocality(false, null);
| options={ } else {
handleAddressFields(nodeType, fetchLocality, false);
}
}; |
|
Expand |
---|
title | Searching function logic called on onSearch for pincode |
---|
|
Code Block |
---|
const debouncePincode = | localityStatesListmap(state: anyasync (value) => {
const pincodesListResp = await searchAddressNodeData({ type: 'pincode', isDataSearchApplied: true, searchQuery: value, sortResult: true });
if (pincodesListResp?.isSuccess | return && Array.isArray(pincodesListResp?.data)) {
| setPincodesList(pincodesListResp.data || []);
}
}, 500);
const loadPincodes = async | label: state.name,
(value) => {
if (value?.length < 3) return;
if (!hierarchyData?.some((node: any) => node.location_key === 'pincode')) return;
debouncePincode(value);
| value: state.code, |
Expand |
---|
title | Rendering logic for address fields (pincode) similar for others: |
---|
|
Code Block |
---|
<FormItem
{...formItemLayoutNew}
className={classes.formCounterBooking} | ; })label={<div>{t("pincode")}</div>}
>
| } {!allowOverrideHierarchy && isAddressHierarchyPresent && getFieldDecorator('pincode', {
| onSearch={loadStatesList} initialValue: address['pincode'],
| onSelect={(e)=>saveAddressUsingAddressHierarchy(e, 'state')}
onChange={(value) => updateAddressFieldWithValidations('state', value)}{ required: false, message: 'Cannot be empty!' },
],
| style={{textAlign:'left'}}disabled={disableState}allowClear style={{ textAlign: 'left' }}
| ><Input optionFilterProp="children"
onChange={(value) | className={classes.autoCompleteInputBox=> saveAddressUsingAddressHierarchy(value, 'pincode')}
placeholder={t("pincode_placeholder")}
| allowClearplaceholder={t('address_state')}/></AutoComplete> {pincodesList?.map(opt => <Option style={{ textAlign: 'left' }} key={opt.id} | );
value={opt.code}>{opt.name} ({opt.code})</Option>)}
| return(<Selectvalue={newAddress.state} {allowOverrideHierarchy && isAddressHierarchyPresent && getFieldDecorator('pincode', {
| className={classes.stateInput} dropdownClassName={classes.pincodeInputDropdown}initialValue: address['pincode'],
| onChange={(eany)=>updateAddressFieldWithValidations('state',e)} placeholder={t('address_state')}
{ required: false, message: 'Cannot be empty!' },
| options={localityStatesList.map((state: any) => {return{ options={pincodesList?.map(item => ({ label: `${item.name} (${item.code})`, value: item.code }))}
| label:state.name, value: state.name,
onSelect={(value) => saveAddressUsingAddressHierarchy(value, 'pincode')}
onChange={(value) => handleAddressFields('pincode', value, !allowOverrideHierarchy)}
| }; style={{ textAlign: 'left' } | )}onSelect={(e)=saveAddressUsingAddressHierarchy(e,'state')}onSearch={loadStatesList}disabled={disableState}showSearch placeholder={t("pincode_placeholder")}
| allowClear);};
|
Changes in src/network/pickup.api.ts
Code Block |
---|
//api to fetch states list
export const FETCH_STATES_LIST = '/api/CustomerPortal/addressManagement/getAddressNodeData?type=State';
//api to fetch nodes value based on address hierarchy (new dev api)
export const FETCH_ADDRESS_FROM_ADDRESS_HIERARCHY = '/api/CustomerPortal/fetchGeneralAddressCode';
export const fetchAddressUsingAddressHierarchy = (params: any) => { </AutoComplete>,
)}
{!isAddressHierarchyPresent && getFieldDecorator('pincode', {
| returnPOST(`${API_BASE_URL}${FETCH_ADDRESS_FROM_ADDRESS_HIERARCHY}`,params);};//exportingfunctionstofetch nodes' list to be called from create-address.tsx file on entering sompething in inpit fileds (> 3chars)
export const fetchCountriesList = (params: any) => {initialValue: address['pincode'],
rules: [
| returnGET(`${API_BASE_URL}${FETCH_COUNTRIES_NODE_DATA}`,isDataSearchAppliedtruesearchQueryparams, sortResult: true });
};
export const fetchCitiesList = (params: any) => {return GET(`${API_BASE_URL}${FETCH_CITIES_LIST}`{isDataSearchApplied: true,searchQuery:params,sortResult:true;};exportconstfetchStatesList=(params:any)=>{return GET(`${API_BASE_URL}${FETCH_STATES_LIST}`<Input placeholder={t("pincode_placeholder")} />,
| {isDataSearchApplied:true,searchQuery:params,sortResult:true};
; |
changes in src/network/api.constants.ts
Code Block |
---|
exportconst FETCH_STATES_LIST='/api/CustomerPortal/addressManagement/getAddressNodeData?type=State';exportconstFETCH_COUNTRIES_NODE_DATA='/api/CustomerPortal/addressManagement/getAddressNodeData?type=Country';exportconstFETCH_ADDRESS_FROM_ADDRESS_HIERARCHY= '/api/CustomerPortal/fetchGeneralAddressCode'; |
...
Above logic is updated in
src/components/pages/OpsDashboard/Manage/counterBooking/AddAddress2.tsx
src/components/pages/details/AddDetails.tsx