Skip to main content

4. Add side pane

We need to be able to filter the view. That's why we will create filter inputs inside the side pane.

Side pane header#

Inside the sidepane header we show a title, and in case if the filters are changed, we show a link which you can use to clear all filters. Let's add state to keep track if the filters are changed.

components/purchase-order-shipments/overview/purchase-order-shipments.state.ts
.../** * Keeps track of the filters, if their values changed from their default values. */export const filtersPurchaseOrderShipmentsRequestChangedSelector = selector<boolean>({  key: 'PurchaseOrderShipmentsList:Filters:Changed',  get: ({ get }) => {    const currentFilter = get(purchaseOrderShipmentsFilter);    if (!currentFilter) return false;    const defaultFilters = purchaseOrderShipmentsDefaultRequest?.PageConfig?.Filter;
    if (!isEqual(defaultFilters, currentFilter)) {      return true;    }    return false;  },});

Now let's add the component:

components/purchase-order-shipments/overview/side-pane/PurchaseOrderShipmentsSidePaneHeader.tsx
import { hooks } from '@springtree/eva-sdk-react-recoil';import { Box, Grid, LinkButton, Text } from '@springtree/eva-suite-ui';import { FormattedMessage } from 'react-intl';import { useResetRecoilState } from 'recoil';import {  filtersPurchaseOrderShipmentsRequestChangedSelector,  purchaseOrderShipmentsFilter,} from '../purchase-order-shipments.state';
const PurchaseOrderShipmentsSidePaneHeader = () => {  const filtersChanged = hooks.useGetState(    filtersPurchaseOrderShipmentsRequestChangedSelector  );  const resetFilters = useResetRecoilState(purchaseOrderShipmentsFilter);
  return (    <Box p={0} height='50px'>      <Grid container justify='space-between' alignItems='flex-start'>        <Grid item>          <Text variant='h2' s>            <FormattedMessage id='generic.label.filters' />          </Text>        </Grid>        <Grid item>          {filtersChanged ? (            <LinkButton onClick={resetFilters} variant='body2'>              <FormattedMessage id='generic.action.clear-filters' />            </LinkButton>          ) : null}        </Grid>      </Grid>    </Box>  );};
export default PurchaseOrderShipmentsSidePaneHeader;

Filter card#

Let's create a wrapper in which we store our filters.

components/purchase-order-shipments/overview/side-pane/PurchaseOrderShipmentsFilters.tsx
import { Box, Card, ErrorBoundary } from '@springtree/eva-suite-ui';
const PurchaseOrderShipmentsFilters = () => (  <Card>    <ErrorBoundary>      <Box>        <Box p={0} mb='8px'>          {/* add filter here */}        </Box>      </Box>    </ErrorBoundary>  </Card>);
export default PurchaseOrderShipmentsFilters;

Create the input filter#

components/purchase-order-shipments/overview/side-pane/filter/PurchaseOrderShipmentTrackingCodeFilter.tsx
import { useRecoilDebouncedValue } from '@springtree/eva-suite-react-hooks';import { Input } from '@springtree/eva-suite-ui';import { useIntl } from 'react-intl';import { purchaseOrderShipmentsFilter } from '../../purchase-order-shipments.state';
const PurchaseOrderShipmentTrackingCodeFilter = () => {  const intl = useIntl();  const [filter, setFilter] = useRecoilDebouncedValue(    purchaseOrderShipmentsFilter,    500  );
  return (    <Input      label={intl.formatMessage({        id: 'purchase-order-shipments.filters.tracking-code.label',        defaultMessage: 'Tracking code',      })}      value={filter?.TrackingCode ?? ''}      onChange={(event) => {        setFilter((current) => ({          ...current,          TrackingCode: event.target?.value,        }));      }}    />  );};
export default PurchaseOrderShipmentTrackingCodeFilter;

Add the newly created filter, to the filter card#

components/purchase-order-shipments/overview/side-pane/PurchaseOrderShipmentsFilters.tsx
import { Box, Card, ErrorBoundary } from '@springtree/eva-suite-ui';import PurchaseOrderShipmentTrackingCodeFilter from './filters/PurchaseOrderShipmentTrackingCodeFilter';
const PurchaseOrderShipmentsFilters = () => (  <Card>    <ErrorBoundary>      <Box>        <Box p={0} mb='8px'>          <PurchaseOrderShipmentTrackingCodeFilter />        </Box>      </Box>    </ErrorBoundary>  </Card>);
export default PurchaseOrderShipmentsFilters;

Create side pane component#

components/purchase-order-shipments/overview/PurchaseOrderShipmentsSidePane.tsx
import PurchaseOrderShipmentsFilters from './side-pane/PurchaseOrderShipmentsFilters';import PurchaseOrderShipmentsSidePaneHeader from './side-pane/PurchaseOrderShipmentsSidePaneHeader';
const PurchaseOrderShipmentsSidePane = () => (  <>    <PurchaseOrderShipmentsSidePaneHeader />    <PurchaseOrderShipmentsFilters />  </>);
export default PurchaseOrderShipmentsSidePane;