import React, { useEffect, useState } from 'react'; import { useSelector, useDispatch } from 'react-redux'; import { useHistory } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import { Remove, Visibility, Search } from '@material-ui/icons'; import { EnergyFormatter, formatCurrencyComplete, EnergyTypes, getConfiguration, IPaginatedLoaderHooksFetchDataParameters, IPaginatedLoaderFetchDataReturnValues, usePaginatedLoaderFiltered, checkRecordPassesFilters, ICustomFilterDefinition, CustomFilterInputType, FilterRules, TableMaterial, useLinks, TableFallback, fromGeneralSelectors } from '@energyweb/origin-ui-core'; import { useDeviceDataLayer } from '../../deviceDataLayer'; import { Order, ANY_VALUE, ANY_OPERATOR, getDeviceName, deviceTypeChecker } from '../../utils'; import { RemoveOrderConfirmation, OrderDetailsModal } from '../modal'; import moment from 'moment'; const ORDERS_PER_PAGE = 5; interface IOwnProsp { asks: Order[]; } export const AsksTable = ({ asks }: IOwnProsp) => { const { t } = useTranslation(); const [askToView, setToView] = useState(); const [askToRemove, setToRemove] = useState(); const configuration = useSelector(getConfiguration); const deviceTypeService = configuration?.deviceTypeService; const environment = useSelector(fromGeneralSelectors.getEnvironment); const deviceDataLayer = useDeviceDataLayer(); const deviceClient = deviceDataLayer.deviceClient; const deviceSelector = deviceDataLayer.getMyDevices; const deviceFetcher = deviceDataLayer.fetchMyDevices; const devices = useSelector(deviceSelector); const { exchangePageUrl } = useLinks(); const history = useHistory(); const dispatch = useDispatch(); useEffect(() => { if (deviceClient) { dispatch(deviceFetcher()); } }, [deviceClient]); const columns = [ { id: 'volume', label: t('order.properties.volume') }, { id: 'price', label: t('order.properties.price') }, { id: 'facilityName', label: t('device.properties.facilityName') }, { id: 'generationFrom', label: t('order.properties.generation_start') }, { id: 'generationTo', label: t('order.properties.generation_end') }, { id: 'filled', label: t('order.properties.filled') } ]; const getTableFilters = (): ICustomFilterDefinition[] => [ { property: (record: Order) => getDeviceName(record.asset.deviceId, devices, environment), label: t('device.properties.facilityName'), input: { type: CustomFilterInputType.dropdown, availableOptions: devices.map((device) => ({ label: deviceTypeChecker(device) ? device?.facilityName : device?.name, value: deviceTypeChecker(device) ? device?.facilityName : device?.name })) } }, { property: (record: Order) => record.product.deviceType[0].split(';')[0].toLowerCase(), label: t('certificate.properties.deviceType'), input: { type: CustomFilterInputType.dropdown, availableOptions: Object.values(EnergyTypes).map((type) => ({ label: `${type[0].toUpperCase()}${type.slice(1).toLowerCase()}`, value: type })), defaultOptions: [] } }, { property: (record: Order) => new Date(record.product.generationFrom).getTime() / 1000, label: t('certificate.properties.generationDateStart'), input: { type: CustomFilterInputType.yearMonth, filterRule: FilterRules.FROM } }, { property: (record: Order) => new Date(record.product.generationTo).getTime() / 1000, label: t('certificate.properties.generationDateEnd'), input: { type: CustomFilterInputType.yearMonth, filterRule: FilterRules.TO } } ]; async function getPaginatedData({ requestedPageSize, offset, requestedFilters }: IPaginatedLoaderHooksFetchDataParameters): Promise { const filteredBids = asks.filter((bid) => { return checkRecordPassesFilters(bid, requestedFilters, deviceTypeService); }); return { paginatedData: filteredBids.slice(offset, offset + requestedPageSize), total: filteredBids.length }; } const { paginatedData, loadPage, total, pageSize, setPageSize } = usePaginatedLoaderFiltered({ getPaginatedData, initialPageSize: ORDERS_PER_PAGE }); useEffect(() => { setPageSize(ORDERS_PER_PAGE); loadPage(1); }, [asks]); const [currency = 'USD'] = useSelector(fromGeneralSelectors.getCurrencies); const rows = paginatedData.map((order) => { const { currentVolume, price, filled, asset: { deviceId }, product: { deviceType, generationFrom, generationTo } } = order; return { volume: EnergyFormatter.format(Number(currentVolume), true), price: formatCurrencyComplete(price / 100, currency), facilityName: getDeviceName(deviceId, devices, environment), device_type: deviceType[0].split(';')[0], generationFrom: moment(generationFrom) .utcOffset(Number(environment.MARKET_UTC_OFFSET)) .format('MMM, YYYY'), generationTo: moment(generationTo).format('MMM, YYYY'), filled: `${filled * 100}%`, askId: order.id }; }); function prepareRedirectFilters( ask: Order ): { deviceType: string[]; location: string[]; gridOperator: string[] } { const newType = [ask.product.deviceType[0]]; const separatedTypes = ask.product.deviceType[0].split(';'); if (separatedTypes.length === 2) { newType.unshift(separatedTypes[0]); } if (separatedTypes.length === 3) { newType.unshift(separatedTypes.slice(0, -1).join(';')); newType.unshift(separatedTypes[0]); } const deviceType = ask.product.deviceType[0].length > 1 ? newType : [ANY_VALUE]; const isEmptyLocation = ask.product.location[0].split(';')[1].length < 1; const upperLevel = ask.product.location[0].split(';').slice(0, -1).join(';'); const lowerLevel = ask.product.location[0]; const location = isEmptyLocation ? [ANY_VALUE] : [upperLevel, lowerLevel]; const gridOperator = ask.product.gridOperator[0].length > 0 ? ask.product.gridOperator : [ANY_OPERATOR]; return { deviceType, location, gridOperator }; } const viewDetails = (rowIndex: number) => { const { askId } = rows[rowIndex]; const ask = asks.find((o) => o.id === askId); setToView(ask); }; const cancelAsk = (rowIndex: number) => { const { askId } = rows[rowIndex]; const ask = asks.find((o) => o.id === askId); setToRemove(ask); }; const viewMarket = (rowIndex: number) => { const { askId } = rows[rowIndex]; const ask = asks.find((o) => o.id === askId); const prepared = prepareRedirectFilters(ask); history.push(`${exchangePageUrl}/view-market`, { redirectDeviceType: prepared.deviceType, redirectLocation: prepared.location, redirectGridOperator: prepared.gridOperator, redirectGenerationFrom: ask.product.generationFrom, redirectGenerationTo: ask.product.generationTo }); }; const actions = [ { icon: , name: t('order.actions.viewMarket'), onClick: (row: string) => viewMarket(parseInt(row, 10)) }, { icon: , name: t('order.actions.view'), onClick: (row: string) => viewDetails(parseInt(row, 10)) }, { icon: , name: t('order.actions.remove'), onClick: (row: string) => cancelAsk(parseInt(row, 10)) } ]; if (devices === null) { return ; } return ( <> viewDetails(parseInt(row, 10))} columns={columns} rows={rows} filters={getTableFilters()} loadPage={loadPage} total={total} pageSize={pageSize} actions={actions} caption={t('order.captions.open_asks')} /> {askToView && ( setToView(null)} showCancelOrder={(ask: Order) => { setToView(null); setToRemove(ask); }} /> )} {askToRemove && ( setToRemove(null)} /> )} ); };