commit changes on Slales Order
This commit is contained in:
parent
1789b83c2d
commit
3c3f9ac6e8
|
@ -14,10 +14,12 @@ import { SearchBox } from '@fluentui/react-search-preview';
|
|||
import { Icon } from '@iconify/react';
|
||||
|
||||
import { appGlobalStateAtom } from '../atoms/appGlobalStateAtom';
|
||||
import { EMessageType } from '../constants/EMessageTypes';
|
||||
import { useGraphAPI } from '../hooks/useGraphAPI';
|
||||
import { ICustomer } from '../models/ICustomer';
|
||||
import { IMenuItem } from '../models/IMenuItem';
|
||||
import { IOrder } from '../models/IOrder';
|
||||
import { ShowMessage } from '../showMessage/ShowMessage';
|
||||
import { CompanyInfo } from './companyInfo/CompanyInfo';
|
||||
import { CustomersGrid } from './customersGrid/CustomersGrid';
|
||||
import { ISalesordersProps } from './ISalesordersProps';
|
||||
|
@ -47,6 +49,7 @@ export const SalesordersControl: React.FunctionComponent<ISalesordersProps> = (
|
|||
const [searchText, setSearchText] = React.useState<string>("");
|
||||
const [isLoading, setIsLoading] = React.useState<boolean>(false);
|
||||
const [customers, setCustomers] = React.useState<ICustomer[]>([]);
|
||||
const [error, setError] = React.useState<Error>((undefined as unknown) as Error);
|
||||
|
||||
React.useEffect(() => {
|
||||
setAppglobalState({ ...appglobalState, ...props });
|
||||
|
@ -59,13 +62,28 @@ export const SalesordersControl: React.FunctionComponent<ISalesordersProps> = (
|
|||
|
||||
React.useEffect(() => {
|
||||
(async () => {
|
||||
const orders = await searchOrders(searchText);
|
||||
const customers = await getCustomers(searchText);
|
||||
try {
|
||||
switch (selectedItem.id) {
|
||||
case 1:
|
||||
setOrders(await searchOrders(searchText));
|
||||
break;
|
||||
case 2:
|
||||
setCustomers(await getCustomers(searchText));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} catch (error) {
|
||||
setError(error);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
/* const customers = await getCustomers(searchText);
|
||||
setCustomers(customers);
|
||||
setOrders(orders );
|
||||
setIsLoading(false);
|
||||
setOrders(orders ); */
|
||||
/* setIsLoading(false); */
|
||||
})();
|
||||
}, [searchText]);
|
||||
}, [searchText, selectedItem]);
|
||||
|
||||
const totalOrders = React.useMemo(() => {
|
||||
return orders.length;
|
||||
|
@ -107,9 +125,8 @@ export const SalesordersControl: React.FunctionComponent<ISalesordersProps> = (
|
|||
pendingOrders={totalPeding}
|
||||
processingOrders={totalProcessing}
|
||||
/>
|
||||
|
||||
<OrdersGrid items={orders} />
|
||||
|
||||
|
||||
<OrdersGrid items={orders} />
|
||||
</>
|
||||
);
|
||||
case 2:
|
||||
|
@ -130,6 +147,24 @@ export const SalesordersControl: React.FunctionComponent<ISalesordersProps> = (
|
|||
}
|
||||
}, [selectedItem]);
|
||||
|
||||
const hasError = React.useMemo(() => {
|
||||
return !error ? false : true;
|
||||
}, [error]);
|
||||
|
||||
const RenderRightContent = React.useCallback(() => {
|
||||
if (hasError) {
|
||||
return <ShowMessage isShow={hasError} messageType={EMessageType.ERROR} message={error.message} />;
|
||||
}
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div style={{ paddingTop: 60 }}>
|
||||
<Spinner />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return <>{!hasOrders ? <NoOrders /> : renderSelectedContent()}</>;
|
||||
}, [ hasError, error, isLoading, hasOrders, renderSelectedContent]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<main className={styles.mainContainer}>
|
||||
|
@ -146,7 +181,7 @@ export const SalesordersControl: React.FunctionComponent<ISalesordersProps> = (
|
|||
style={{ fontSize: tokens.fontSizeBase200, width: 300 }}
|
||||
onChange={(ev: React.ChangeEvent<HTMLInputElement>, data: InputOnChangeData) => {
|
||||
if (data.value.trim().length > 2) {
|
||||
setSearchText(data.value);
|
||||
setSearchText(data.value);
|
||||
}
|
||||
}}
|
||||
dismiss={
|
||||
|
@ -158,13 +193,14 @@ export const SalesordersControl: React.FunctionComponent<ISalesordersProps> = (
|
|||
}
|
||||
/>
|
||||
</div>
|
||||
{isLoading ? (
|
||||
<RenderRightContent />
|
||||
{/* {isLoading ? (
|
||||
<div style={{ paddingTop: 60 }}>
|
||||
<Spinner />
|
||||
</div>
|
||||
) : (
|
||||
<>{!hasOrders ? <NoOrders /> : renderSelectedContent()}</>
|
||||
)}
|
||||
)} */}
|
||||
</Right>
|
||||
</div>
|
||||
</main>
|
||||
|
|
|
@ -19,6 +19,7 @@ import {
|
|||
} from '@fluentui/react-components';
|
||||
|
||||
import { IOrder } from '../../models/IOrder';
|
||||
import { useOrdersGridStyles } from './useOrdersGridStyles';
|
||||
|
||||
const columns: TableColumnDefinition<IOrder>[] = [
|
||||
createTableColumn<IOrder>({
|
||||
|
@ -197,8 +198,10 @@ export const OrdersGrid: React.FunctionComponent<IOrdersGridProps> = (
|
|||
setSortState(nextSortState);
|
||||
}, []);
|
||||
|
||||
const styles = useOrdersGridStyles();
|
||||
|
||||
return (
|
||||
<div style={{ paddingTop: 30 }}>
|
||||
<div className={styles.gridContainer}>
|
||||
<DataGrid
|
||||
items={items}
|
||||
columns={columns}
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
import {
|
||||
makeStyles,
|
||||
shorthands,
|
||||
tokens,
|
||||
} from '@fluentui/react-components';
|
||||
|
||||
export const useOrdersGridStyles = makeStyles({
|
||||
gridContainer: {
|
||||
paddingTop: "30px",
|
||||
width: "100%",
|
||||
height: 'calc(100vh - 440px)',
|
||||
backgroundColor: tokens.colorNeutralBackground2,
|
||||
overflowY: "auto",
|
||||
overflowX: "hidden",
|
||||
"scrollbar-color": tokens.colorNeutralBackground1,
|
||||
"scrollbar-width": "thin",
|
||||
"::-webkit-scrollbar-thumb": {
|
||||
backgroundColor: tokens?.colorBrandStroke2,
|
||||
...shorthands.borderRadius("10px"),
|
||||
...shorthands.borderWidth("1px"),
|
||||
},
|
||||
"::-webkit-scrollbar": {
|
||||
height: "10px",
|
||||
width: "7px",
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
});
|
|
@ -6,30 +6,17 @@ import {
|
|||
|
||||
export const useSalesordersStyles = makeStyles({
|
||||
mainContainer: {
|
||||
|
||||
width: "100%",
|
||||
height: "100vh",
|
||||
height: 'calc(100vh - 200px)',
|
||||
backgroundColor: tokens.colorNeutralBackground2,
|
||||
overflowY: "auto",
|
||||
overflowX: "hidden",
|
||||
"scrollbar-color": tokens.colorNeutralBackground1,
|
||||
"scrollbar-width": "thin",
|
||||
"::-webkit-scrollbar-thumb": {
|
||||
backgroundColor: tokens?.colorBrandStroke2,
|
||||
...shorthands.borderRadius("10px"),
|
||||
...shorthands.borderWidth("1px"),
|
||||
},
|
||||
"::-webkit-scrollbar": {
|
||||
height: "10px",
|
||||
width: "7px",
|
||||
},
|
||||
|
||||
},
|
||||
|
||||
contentContainer: {
|
||||
display: "grid",
|
||||
gridTemplateColumns: "min(100%, 300px) 1fr 1fr 1fr",
|
||||
gridTemplateRows: "1fr",
|
||||
height: "100vh",
|
||||
height: 'calc(100vh - 200px)',
|
||||
},
|
||||
|
||||
leftContainer : {
|
||||
|
@ -74,6 +61,6 @@ export const useSalesordersStyles = makeStyles({
|
|||
justifyContent: "space-between",
|
||||
rowGap: "20px",
|
||||
...shorthands.padding("20px 0px"),
|
||||
|
||||
|
||||
} ,
|
||||
});
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
export enum EMessageType {
|
||||
INFO = 'info',
|
||||
ERROR = 'error',
|
||||
SUCCESS = 'success',
|
||||
}
|
|
@ -23,6 +23,86 @@ export const useGraphAPI = (context: BaseComponentContext): IuseGraphAPI => {
|
|||
return await context.msGraphClientFactory.getClient("3");
|
||||
}, [context]);
|
||||
|
||||
|
||||
const mappingOrders = React.useCallback((result: SearchHit[]): IOrder[] => {
|
||||
const ordersList: IOrder[] = [];
|
||||
for (const item of result) {
|
||||
const { resource } = item;
|
||||
if (resource) {
|
||||
const { properties } = resource as any;
|
||||
if (properties) {
|
||||
const {
|
||||
id,
|
||||
custcode,
|
||||
custname,
|
||||
email,
|
||||
state,
|
||||
country,
|
||||
orders,
|
||||
orderdates,
|
||||
ordertotals,
|
||||
orderstatus,
|
||||
} = properties as any;
|
||||
|
||||
for (let i = 0; i < orders.length; i++) {
|
||||
const order: IOrder = {
|
||||
customer: custname,
|
||||
city: `${state} ${country}`,
|
||||
order: orders[i],
|
||||
total: ordertotals[i],
|
||||
orderDate: orderdates[i],
|
||||
status: orderstatus[i],
|
||||
customerCode: custcode,
|
||||
custmoerEmail: email,
|
||||
customerState: state,
|
||||
id: id,
|
||||
};
|
||||
ordersList.push(order);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ordersList;
|
||||
}, [ graphClient]);
|
||||
|
||||
const mappingCustomers = React.useCallback((result: SearchHit[]): ICustomer[] => {
|
||||
const customersList: ICustomer[] = [];
|
||||
for (const item of result) {
|
||||
const { resource } = item;
|
||||
if (resource) {
|
||||
const { properties } = resource as any;
|
||||
if (properties) {
|
||||
const {
|
||||
custcode,
|
||||
custname,
|
||||
email,
|
||||
state,
|
||||
country,
|
||||
orders,
|
||||
orderdates,
|
||||
ordertotals,
|
||||
orderstatus,
|
||||
} = properties as any;
|
||||
|
||||
const customer: ICustomer = {
|
||||
customerName: custname,
|
||||
customerCode: custcode,
|
||||
customerEmail: email,
|
||||
customerState: state,
|
||||
customerCountry: country,
|
||||
lastOrder: orders[orders.length - 1],
|
||||
totalOrders: orders.length,
|
||||
lastOrderDate: orderdates[orderdates.length - 1],
|
||||
lastOrderTotal: ordertotals[ordertotals.length - 1],
|
||||
lastOrderStatus: orderstatus[orderstatus.length - 1],
|
||||
};
|
||||
customersList.push(customer);
|
||||
}
|
||||
}
|
||||
}
|
||||
return customersList;
|
||||
}, [ graphClient]);
|
||||
|
||||
const searchOrders = React.useCallback(
|
||||
async (searchText: string): Promise<any> => {
|
||||
if (!graphClient) return undefined;
|
||||
|
@ -45,55 +125,9 @@ export const useGraphAPI = (context: BaseComponentContext): IuseGraphAPI => {
|
|||
const response = await (await graphClient)?.api(`search/query`).post(request);
|
||||
|
||||
const result: SearchHit[] = response?.value[0]?.hitsContainers[0]?.hits;
|
||||
if (!result) return [];
|
||||
const ordersList: IOrder[] = [];
|
||||
for (const item of result) {
|
||||
const { resource } = item;
|
||||
if (resource) {
|
||||
const { properties } = resource as any;
|
||||
if (properties) {
|
||||
const {
|
||||
id,
|
||||
custcode,
|
||||
custname,
|
||||
email,
|
||||
state,
|
||||
country,
|
||||
orders,
|
||||
orderdates,
|
||||
ordertotals,
|
||||
orderstatus,
|
||||
} = properties as any;
|
||||
if (!result) return [];
|
||||
|
||||
if (!custname || !state || !country || !orders || !orderdates || !ordertotals || !orderstatus) continue;
|
||||
for (let i = 0; i < orders.length; i++) {
|
||||
const order: IOrder = {
|
||||
customer: custname,
|
||||
|
||||
city: `${state} ${country}`,
|
||||
|
||||
order: orders[i],
|
||||
|
||||
total: ordertotals[i],
|
||||
|
||||
orderDate: orderdates[i],
|
||||
|
||||
status: orderstatus[i],
|
||||
|
||||
customerCode: custcode,
|
||||
|
||||
custmoerEmail: email,
|
||||
|
||||
customerState: state,
|
||||
|
||||
id: id,
|
||||
};
|
||||
ordersList.push(order);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* setCacheValue(searchText, ordersList); */
|
||||
const ordersList = mappingOrders(result);
|
||||
console.log(ordersList);
|
||||
return ordersList;
|
||||
} catch (error) {
|
||||
|
@ -104,69 +138,36 @@ export const useGraphAPI = (context: BaseComponentContext): IuseGraphAPI => {
|
|||
[graphClient]
|
||||
);
|
||||
|
||||
const getCustomers = React.useCallback(async (searchText:string): Promise<ICustomer[] | []> => {
|
||||
if (!graphClient) return [];
|
||||
|
||||
const request = {
|
||||
requests: [
|
||||
{
|
||||
entityTypes: ["externalItem"],
|
||||
contentSources: ["/external/connections/ibmdb2lob"],
|
||||
query: {
|
||||
queryString: `${searchText}*`,
|
||||
const getCustomers = React.useCallback(
|
||||
async (searchText: string): Promise<ICustomer[] | []> => {
|
||||
if (!graphClient) return [];
|
||||
const request = {
|
||||
requests: [
|
||||
{
|
||||
entityTypes: ["externalItem"],
|
||||
contentSources: ["/external/connections/ibmdb2lob"],
|
||||
query: {
|
||||
queryString: `${searchText}*`,
|
||||
},
|
||||
from: 0,
|
||||
size: 100,
|
||||
},
|
||||
from: 0,
|
||||
size: 100,
|
||||
},
|
||||
],
|
||||
};
|
||||
],
|
||||
};
|
||||
try {
|
||||
const response = await (await graphClient)?.api(`search/query`).post(request);
|
||||
|
||||
try {
|
||||
const response = await (await graphClient)?.api(`search/query`).post(request);
|
||||
|
||||
const result: SearchHit[] = response?.value[0]?.hitsContainers[0]?.hits;
|
||||
|
||||
const customersList: ICustomer[] = [];
|
||||
for (const item of result) {
|
||||
const { resource } = item;
|
||||
if (resource) {
|
||||
const { properties } = resource as any;
|
||||
if (properties) {
|
||||
const {
|
||||
custcode,
|
||||
custname,
|
||||
email,
|
||||
state,
|
||||
country,
|
||||
orders,
|
||||
orderdates,
|
||||
ordertotals,
|
||||
orderstatus,
|
||||
} = properties as any;
|
||||
|
||||
const customer: ICustomer = {
|
||||
customerName: custname,
|
||||
customerCode: custcode,
|
||||
customerEmail: email,
|
||||
customerState: state,
|
||||
customerCountry: country,
|
||||
lastOrder: orders[orders.length - 1],
|
||||
totalOrders: orders.length,
|
||||
lastOrderDate: orderdates[orderdates.length - 1],
|
||||
lastOrderTotal: ordertotals[ordertotals.length - 1],
|
||||
lastOrderStatus: orderstatus[orderstatus.length - 1],
|
||||
};
|
||||
customersList.push(customer);
|
||||
}
|
||||
}
|
||||
const result: SearchHit[] = response?.value[0]?.hitsContainers[0]?.hits;
|
||||
const customersList = mappingCustomers(result);
|
||||
const uniqueCustomers = uniqBy(customersList, "customerCode");
|
||||
return sortBy(uniqueCustomers, "customerName");
|
||||
} catch (error) {
|
||||
console.log("[getCustomers] error:", error);
|
||||
throw new Error("Something went wrong when getting customers");
|
||||
}
|
||||
const uniqueCustomers = uniqBy(customersList, "customerCode");
|
||||
return sortBy(uniqueCustomers, "customerName");
|
||||
} catch (error) {
|
||||
console.log("[getCustomers] error:", error);
|
||||
throw new Error("Something went wrong when getting customers");
|
||||
}
|
||||
}, [graphClient]);
|
||||
},
|
||||
[graphClient]
|
||||
);
|
||||
|
||||
return {
|
||||
searchOrders,
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
import * as React from 'react';
|
||||
|
||||
import { EMessageType } from '../constants/EMessageTypes';
|
||||
|
||||
export interface IShowMessageProps {
|
||||
isShow: boolean;
|
||||
messageType: EMessageType;
|
||||
message: string | React.ReactNode;
|
||||
children?: React.ReactNode;
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
import * as React from 'react';
|
||||
|
||||
import {
|
||||
Body1,
|
||||
Body1Strong,
|
||||
tokens,
|
||||
} from '@fluentui/react-components';
|
||||
import {
|
||||
CheckmarkCircle32Regular,
|
||||
Info32Regular,
|
||||
} from '@fluentui/react-icons';
|
||||
import { Icon } from '@iconify/react';
|
||||
|
||||
import { EMessageType } from '../constants/EMessageTypes';
|
||||
import { IShowMessageProps } from './IShowMessageProps';
|
||||
import { useShowMessageStyles } from './useShowMessageStyles';
|
||||
|
||||
export const ShowMessage: React.FunctionComponent<IShowMessageProps> = (
|
||||
props: React.PropsWithChildren<IShowMessageProps>
|
||||
) => {
|
||||
const { messageType, children, message, isShow } = props;
|
||||
const styles = useShowMessageStyles();
|
||||
const [renderMessageIcon, setRenderMessageIcon] = React.useState<JSX.Element | null>(null);
|
||||
|
||||
const RenderError = React.useCallback(() => {
|
||||
return (
|
||||
<>
|
||||
<div className={styles.errorContainer}>
|
||||
<div className={styles.errorIcon}>
|
||||
<Icon
|
||||
icon="fluent:error-circle-24-regular"
|
||||
width="32"
|
||||
height="32"
|
||||
color={tokens.colorStatusDangerForeground1}
|
||||
/>
|
||||
</div>
|
||||
<Body1 style={{ width: "100%" }}>{message}</Body1>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}, [message]);
|
||||
|
||||
React.useEffect(() => {
|
||||
switch (messageType) {
|
||||
case EMessageType.SUCCESS:
|
||||
setRenderMessageIcon(<CheckmarkCircle32Regular primaryFill={tokens.colorStatusSuccessForeground1} />);
|
||||
break;
|
||||
case EMessageType.INFO:
|
||||
setRenderMessageIcon(<Info32Regular primaryFill={tokens.colorStatusWarningForeground1} />);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}, [messageType]);
|
||||
|
||||
if (!isShow) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
if (messageType === EMessageType.ERROR) {
|
||||
return <RenderError />;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={styles.root}>
|
||||
{renderMessageIcon}
|
||||
<Body1Strong>{messageType}</Body1Strong>
|
||||
{children}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,35 @@
|
|||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import {
|
||||
makeStyles,
|
||||
shorthands,
|
||||
tokens,
|
||||
} from '@fluentui/react-components';
|
||||
|
||||
export const useShowMessageStyles = makeStyles({
|
||||
root: {
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
...shorthands.padding("10px"),
|
||||
...shorthands.gap("10px"),
|
||||
width: '100%',
|
||||
} ,
|
||||
iconClass: {
|
||||
width: "32px",
|
||||
height: "32px",
|
||||
} as any,
|
||||
errorContainer: {
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
justifyContent: "start",
|
||||
alignItems: "center",
|
||||
...shorthands.gap("10px"),
|
||||
...shorthands.padding("10px"),
|
||||
backgroundColor: tokens.colorStatusDangerBackground1,
|
||||
} ,
|
||||
errorIcon: {
|
||||
width: "32px",
|
||||
height: "32px",
|
||||
} ,
|
||||
});
|
Loading…
Reference in New Issue