Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* eslint-disable react/prop-types */
- /* eslint-disable max-len */
- import React, { useCallback, useMemo } from 'react';
- import { useTranslation } from 'react-i18next';
- import {
- Box, FormControlLabelProps, Grid, RadioProps, Stack, Typography,
- } from '@mui/material';
- import { Field, Form, Formik } from 'formik';
- import { useDispatch, useSelector } from 'react-redux';
- import useInsightsDashboard from 'scenes/Insights/hooks/useInsightsDashboard';
- import Button from 'components/Controls/Button/Button';
- import { disableDrawer } from 'ducks/Drawer/actions';
- import { selectors as globalSelectors } from 'ducks/global';
- import { getDateRangeInMilSecs, renderRangeDate } from 'utils/dateUtils';
- import useApig from 'shared/hooks/useApig';
- import { trackEvent } from '@sbd-ctg/user-behavior-tracking';
- import { InsightsAssignment, InsightsDashboardFilter } from '../../domain/insightsDashboard';
- import FilterDrawer from './FilterDrawer';
- import FilterDrawerToggleButton from './FilterDrawerToggleButton';
- import {
- ContentWrapper,
- StyledLabelWeeks,
- StyledRadioGroup,
- StyledRadioWeeks,
- } from './InsightsFilterDrawer.style';
- import AssignmentIdDropdown from '../Fields/AssignmentIdDropdown';
- import ToolClassDropdown from '../Fields/ToolClassDropdown';
- import ModelNumberDropdown from '../Fields/ModelNumberDropdown';
- import { GET_JOBSITE_POWERSHIFT_LIST_SUCCESS } from '../../../../ducks/Insights/types';
- import { InsightsFilterDrawerSchema } from 'schemas/validation';
- type RadioButtonProps = Omit<FormControlLabelProps, 'control'> & RadioProps & { testid: string };
- const WeeksRadioButton: React.FC<RadioButtonProps> = ({
- label, testid = '', ...props
- }) => (
- <StyledLabelWeeks
- control={(
- <StyledRadioWeeks
- {...props}
- icon={<span>{label}</span>}
- checkedIcon={<span>{label}</span>}
- data-testid={testid}
- />
- )}
- label=""
- />
- );
- const InsightsFilterDrawer = () => {
- const { t } = useTranslation();
- const dispatch = useDispatch();
- const companyId = useSelector((state: any) => globalSelectors.getSelectedCompanyId(state));
- const status = useApig(GET_JOBSITE_POWERSHIFT_LIST_SUCCESS);
- const {
- filters,
- fetchData,
- fetchCompareData,
- setDashboardFilter,
- isComparingAssets,
- assetClassesState,
- getInsightsUrl,
- insightsUnavailable,
- } = useInsightsDashboard();
- const initialValues: InsightsDashboardFilter = { ...filters };
- const dateRanges = [
- { value: 1, label: t('Insights.FilterDrawer.DateRangeLastWeek'), testid: 'insights-filters-weeks-1' },
- { value: 2, label: t('Insights.FilterDrawer.DateRangeLast2Weeks'), testid: 'insights-filters-weeks-2' },
- { value: 4, label: t('Insights.FilterDrawer.DateRangeLast4Weeks'), testid: 'insights-filters-weeks-4' },
- { value: 12, label: t('Insights.FilterDrawer.DateRangeLast12Weeks'), testid: 'insights-filters-weeks-12' },
- ];
- const renderDateRangeSelected = useCallback((weeks) => {
- const { start, end } = getDateRangeInMilSecs(weeks);
- return (
- weeks
- ? (
- <Typography variant="caption" color="text.secondary" marginTop="10px" component="div">
- {renderRangeDate(start, end)}
- </Typography>
- )
- : null
- );
- }, []);
- const handleAssetClassChange = useCallback((assetClass: string, { setFieldValue }: any) => {
- setFieldValue('assetClass', assetClass);
- setFieldValue('modelNumber', null);
- setFieldValue('assignmentId', null);
- setFieldValue('assignmentId2', null);
- }, []);
- const handleModelNumberChange = useCallback((modelNumber: string, { setFieldValue }: any) => {
- setFieldValue('modelNumber', modelNumber);
- setFieldValue('assignmentId', null);
- setFieldValue('assignmentId2', null);
- }, []);
- const handleDateRangeChange = (weeks: string, setFieldValue: (...params: any) => void) => {
- const intWeek = +weeks;
- const { start, end } = getDateRangeInMilSecs(intWeek);
- const defineWindow = intWeek === 4 || intWeek === 12 ? 'Weeks' : 'Days';
- setFieldValue('start', start);
- setFieldValue('end', end);
- setFieldValue('window', defineWindow);
- setFieldValue('weeks', intWeek);
- };
- const getAssignments = useCallback((values: InsightsDashboardFilter): InsightsAssignment[] => {
- const { assetClass, modelNumber } = values;
- if (assetClass && modelNumber) {
- const assetClassData = assetClassesState.data[assetClass]; // Safe indexing since `data` is always an object
- return assetClassData?.assignmentsByModelNumber?.[modelNumber] || [];
- }
- return [];
- }, [assetClassesState]);
- const handleSubmit = useCallback((values: InsightsDashboardFilter) => {
- const checkDirty: Array<keyof InsightsDashboardFilter> = ['assetClass', 'modelNumber', 'weeks', 'assignmentId', 'assignmentId2'];
- const changes = checkDirty.reduce((acc: Record<string, boolean>, field) => {
- acc[field] = values[field] !== filters[field];
- // if (valueChanged) {
- // console.debug(`${field} changed from ${filters[field]} to ${values[field]}`);
- // }
- return acc;
- }, {});
- const fetchLeft = changes.assetClass || changes.modelNumber || changes.assignmentId || changes.weeks;
- const fetchRight = isComparingAssets && (changes.assetClass || changes.modelNumber || changes.assignmentId2 || changes.weeks);
- const trackingValues = {
- assetClass: values.assetClass,
- modelNumber: values.modelNumber,
- window: values.window,
- dateRange: renderRangeDate(values.start, values.end),
- assignment1: values.assignmentId,
- ...(isComparingAssets && { assignment2: values.assignmentId2 }),
- };
- trackEvent('apply_filter', { category: 'Insights', filters: trackingValues });
- if (fetchLeft || fetchRight) {
- const newValues = isComparingAssets ? { ...values } : {
- ...values, assignmentId2: '',
- };
- setDashboardFilter(newValues);
- if (fetchLeft) {
- fetchData(newValues);
- }
- if (fetchRight) {
- fetchCompareData(newValues);
- }
- }
- dispatch(disableDrawer());
- }, [filters, isComparingAssets, getAssignments]);
- const handleCopyFilters = (event: React.MouseEvent<HTMLButtonElement>, values: InsightsDashboardFilter) => {
- if (event.ctrlKey || event.metaKey) {
- event.preventDefault(); // Prevent the form from submitting
- const url = getInsightsUrl(values);
- navigator.clipboard.writeText(url)
- .then(() => {
- alert('Text copied to clipboard!');
- })
- .catch((err) => {
- console.error('Failed to copy text: ', err);
- });
- }
- };
- return (
- <FilterDrawer
- key={`UtilizationFilter-${companyId}`}
- drawerName="DASHBOARD"
- title={t('Common.Filters')}
- content={(
- <Formik initialValues={initialValues} onSubmit={handleSubmit} validationSchema={InsightsFilterDrawerSchema(isComparingAssets)}>
- {({ values, setFieldValue, isValid }) => {
- const memoizedAssignments = useMemo(() => getAssignments(values), [getAssignments, values]);
- return (
- <Form style={{ height: '100%' }}>
- <ContentWrapper direction="column">
- <Stack direction="column" spacing={2} className="fields-controllers">
- <Stack direction="column" spacing={2}>
- <Typography variant="body1">
- {t('Insights.FilterDrawer.AssetHeading')}
- </Typography>
- <Field name="assetClass">
- {({ form } : any) => (
- <ToolClassDropdown
- defaultValue={filters.assetClass}
- disabled={isComparingAssets || insightsUnavailable}
- onChange={e => handleAssetClassChange(e.target.value as string, form)}
- />
- )}
- </Field>
- <Field name="modelNumber" disabled={isComparingAssets}>
- {({ form }: any) => (
- <ModelNumberDropdown
- key={`ModelNumber-${values.assetClass}`}
- value={values.modelNumber}
- assetClass={values.assetClass}
- disabled={isComparingAssets}
- onChange={e => handleModelNumberChange(e.target.value as string, form)}
- />
- )}
- </Field>
- <Field name="assignmentId">
- {() => (
- <AssignmentIdDropdown
- key={`AssignmentId-${values.assetClass}-${values.modelNumber}`}
- label={isComparingAssets ? t('Insights.FilterDrawer.Assignment1') : t('Insights.FilterDrawer.Assignment')}
- value={values.assignmentId}
- assignments={memoizedAssignments}
- loading={status === 'loading'}
- onChange={e => setFieldValue('assignmentId', e.target.value)}
- disabled={!values.modelNumber}
- />
- )}
- </Field>
- {isComparingAssets && (
- <Field name="assignmentId2">
- {() => (
- <AssignmentIdDropdown
- key={`AssignmentId2-${values.assetClass}-${values.modelNumber}`}
- label={t('Insights.FilterDrawer.Assignment2')}
- value={values.assignmentId2}
- assignments={memoizedAssignments}
- loading={status === 'loading'}
- onChange={e => setFieldValue('assignmentId2', e.target.value)}
- disabled={!values.modelNumber}
- />
- )}
- </Field>
- )}
- </Stack>
- <Box marginTop={2}>
- <Typography variant="body1" margin="20px 0 10px 0">
- {t('Insights.FilterDrawer.DateHeading')}
- </Typography>
- <StyledRadioGroup
- name="weeks"
- value={values.weeks}
- onChange={({ target }: any) => {
- handleDateRangeChange(target.value, setFieldValue);
- }}
- >
- {dateRanges.map(({ label, value, testid }) => (
- <WeeksRadioButton
- name="weeks"
- value={value}
- defaultValue={value}
- label={label}
- key={label}
- testid={testid}
- disabled={insightsUnavailable}
- required
- />
- ))}
- </StyledRadioGroup>
- {renderDateRangeSelected(values.weeks)}
- </Box>
- </Stack>
- <Grid spacing={2} paddingTop={2} textTransform="capitalize" container>
- <Grid item xs={6}>
- <FilterDrawerToggleButton
- size="medium"
- variant="outlined"
- color="secondary"
- drawerName="DASHBOARD"
- disabled={insightsUnavailable}
- fullWidth
- sx={{ height: '42px' }}
- testid="insights-filters-cancel"
- >
- {t('Common.Cancel')}
- </FilterDrawerToggleButton>
- </Grid>
- <Grid item xs={6}>
- <Button
- size="medium"
- variant="contained"
- color="primary"
- type="submit"
- fullWidth
- disabled={!isValid}
- sx={{ height: '42px' }}
- data-testid="insights-filters-apply"
- onClick={e => handleCopyFilters(e, values)}
- >
- {t('RateTableSettingsModal.Buttons.Apply')}
- </Button>
- </Grid>
- </Grid>
- </ContentWrapper>
- </Form>
- );
- }}
- </Formik>
- )}
- />
- );
- };
- export default InsightsFilterDrawer;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement