@bytebrand/fe-ui-core 4.2.178 → 4.2.180

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15,6 +15,8 @@ interface IWithRouter {
15
15
  children?: JSX.Element;
16
16
  link?: string;
17
17
  }
18
+ const getCheckoutCarListMock = jest.fn();
19
+
18
20
  const checkoutCars = [
19
21
  {
20
22
  parkedFor: 'N/A',
@@ -541,7 +543,7 @@ const checkoutCars = [
541
543
  seoText: ''
542
544
  }
543
545
  ];
544
- const getCarList = () => {
546
+ const getCheckoutCarList = () => {
545
547
  return new Promise((resolve) => {
546
548
  resolve(checkoutCars);
547
549
  });
@@ -580,34 +582,35 @@ const mockProps = {
580
582
  appStore: { language:'en' },
581
583
  carsStore: { aggStatsData },
582
584
  imagesStore: { getSupportedImageFormat: jest.fn() },
583
- UserActionsAPI:{ getCheckoutCarList:getCarList }
585
+ checkoutStore:{ checkoutCars, getCheckoutCarList:getCheckoutCarListMock }
584
586
  };
585
587
 
586
588
  describe('CheckoutSection', () => {
587
589
  it('renders correctly', () => {
588
590
  const { container } = render(<CheckoutSection {...mockProps as any} />);
591
+ expect(mockProps.checkoutStore.getCheckoutCarList).toHaveBeenCalledTimes(1);
589
592
  expect(container).toBeInTheDocument();
590
593
  });
591
594
  it('should display correct car data', () => {
592
595
  const { container } = render(<CheckoutSection {...mockProps as any} />);
593
- let checkoutCarList:[] = [];
594
- mockProps.UserActionsAPI.getCheckoutCarList()
595
- .then((savedCheckoutDataList: any) => {
596
- checkoutCarList = savedCheckoutDataList;
597
- checkoutCarList.forEach((element:any) => {
598
- expect(container).toHaveTextContent(element.title.make);
599
- });
596
+ // let checkoutCarList:[] = [];
597
+ // mockProps.checkoutStore.getCheckoutCarList()
598
+ // .then((savedCheckoutDataList: any) => {
599
+ // checkoutCarList = mockProps.checkoutStore.checkoutCars;
600
+ mockProps.checkoutStore.checkoutCars.forEach((element:any) => {
601
+ expect(container).toHaveTextContent(element.title.make);
600
602
  });
603
+ // });
601
604
  });
602
605
  it('should open checkout page with correct URL on car select', () => {
603
606
  const { getAllByRole } = render(<CheckoutSection {...mockProps as any} />);
604
- mockProps.UserActionsAPI.getCheckoutCarList()
605
- .then((savedCheckoutDataList: any) => {
606
- const checkoutButton = getAllByRole('link')[0];
607
- fireEvent.click(checkoutButton);
608
- const expectedUrl = `/checkout/contact-information?carId=${savedCheckoutDataList[0].id}&isSavedCheckout=true&mainImageId=${savedCheckoutDataList[0].mainImageId}&model=${savedCheckoutDataList[0].title.model}&subModel=${savedCheckoutDataList[0].title.subModel}&make=${savedCheckoutDataList[0].title.make}`;
609
- waitFor(() => expect(window.open).toHaveBeenCalledWith(expectedUrl, '_blank'));
610
- });
607
+ // mockProps.checkoutStore.getCheckoutCarList()
608
+ // .then((savedCheckoutDataList: any) => {
609
+ const checkoutButton = getAllByRole('link')[0];
610
+ fireEvent.click(checkoutButton);
611
+ const expectedUrl = `/checkout/contact-information?carId=${mockProps.checkoutStore.checkoutCars[0].id}&isSavedCheckout=true&mainImageId=${mockProps.checkoutStore.checkoutCars[0].mainImageId}&model=${mockProps.checkoutStore.checkoutCars[0].title.model}&subModel=${mockProps.checkoutStore.checkoutCars[0].title.subModel}&make=${mockProps.checkoutStore.checkoutCars[0].title.make}`;
612
+ waitFor(() => expect(window.open).toHaveBeenCalledWith(expectedUrl, '_blank'));
613
+ // });
611
614
  });
612
615
 
613
616
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bytebrand/fe-ui-core",
3
- "version": "4.2.178",
3
+ "version": "4.2.180",
4
4
  "description": "UI components for the auto.de project",
5
5
  "main": "index.ts",
6
6
  "module": "dist/common.js",
@@ -4,17 +4,16 @@ import { useStyles } from './CheckoutStepperClasses';
4
4
  import styles from './CheckoutStepper.styl';
5
5
  import { Hidden } from 'react-grid-system';
6
6
  import { Stepper, Step, StepButton, IconSVG } from '../../../../common';
7
+ import { toJS } from 'mobx';
7
8
 
8
9
  interface ICheckoutStepper {
9
- steps: [];
10
- activeStep?: number;
11
- handleStep?: (index: number) => () => void;
12
- completed?: any;
10
+ checkoutStore: any;
13
11
  t?: (phrase: string) => {};
14
12
  }
15
13
 
16
- const CheckoutStepper: FunctionComponent<ICheckoutStepper> = ({ steps, activeStep, completed, handleStep, t }) => {
14
+ const CheckoutStepper: FunctionComponent<ICheckoutStepper> = ({ checkoutStore, t }) => {
17
15
  const classes = useStyles();
16
+ const steps = toJS(checkoutStore.steps);
18
17
  return (
19
18
  <div className={`${classes.root} ${styles.stepperWrapper}`}>
20
19
  <Stepper
@@ -22,34 +21,34 @@ const CheckoutStepper: FunctionComponent<ICheckoutStepper> = ({ steps, activeSte
22
21
  nonLinear
23
22
  orientation={isMobileOnly ? 'horizontal' : 'vertical'}
24
23
  alternativeLabel={isMobileOnly}
25
- activeStep={activeStep}>
24
+ activeStep={checkoutStore.activeStep}>
26
25
  {steps.map(({ title, pathname }, index) => {
27
26
  const labelRep = !!title && !isMobileOnly ? title.replace('-', '') : title;
28
27
  return (
29
28
  <Step key={pathname}
30
- className={`${completed.has(steps[index].pathname) ? classes.isCompleted : ''}
31
- ${completed.has(steps[index].pathname) ? classes.completeLine : ''}
32
- ${activeStep === index && classes.activeLine}
29
+ className={`${checkoutStore.completed.has(steps[index].pathname) ? classes.isCompleted : ''}
30
+ ${checkoutStore.completed.has(steps[index].pathname) ? classes.completeLine : ''}
31
+ ${checkoutStore.activeStep === index && classes.activeLine}
33
32
  `}
34
- >
33
+ >
35
34
  <StepButton
36
- onClick={handleStep(index)}
35
+ onClick={checkoutStore.handleStep(index)}
37
36
  classes={{
38
37
  root: classes.buttonItem,
39
38
  horizontal: classes.labelWrap,
40
39
  vertical: classes.verticalWrap
41
40
  }}
42
41
  className={`
43
- ${activeStep === index ? classes.active : classes.default}
44
- ${completed.has(steps[index].pathname) && activeStep !== index && classes.completeStep}`}>
42
+ ${checkoutStore.activeStep === index ? classes.active : classes.default}
43
+ ${checkoutStore.completed.has(steps[index].pathname) && checkoutStore.activeStep !== index && classes.completeStep}`}>
45
44
  <span>{labelRep}</span>
46
45
  <Hidden xs sm md>
47
- {activeStep !== index && <IconSVG name='menuArrow' className={styles.menuArrow} customDimensions={false}/>}
48
- {!completed.has(steps[index].pathname) &&
46
+ {checkoutStore.activeStep !== index && <IconSVG name='menuArrow' className={styles.menuArrow} customDimensions={false} />}
47
+ {!checkoutStore.completed.has(steps[index].pathname) &&
49
48
  <span
50
49
  className={`
51
50
  ${classes.minutes}
52
- ${completed.has(steps[index].pathname) && activeStep !== index && classes.completeStep}`}
51
+ ${checkoutStore.completed.has(steps[index].pathname) && checkoutStore.activeStep !== index && classes.completeStep}`}
53
52
  >
54
53
  {steps[index].minutes}
55
54
  &nbsp;
@@ -5,7 +5,7 @@ import styles from './CheckoutSection.styl';
5
5
  import { isMobileOnly } from 'react-device-detect';
6
6
  import Slider from 'react-slick';
7
7
  import { VehicleSmallCard } from '../../../../../common';
8
-
8
+ import { toJS } from 'mobx';
9
9
 
10
10
  interface ITFunction {
11
11
  <T = string>(key: string, options?: object): T;
@@ -20,83 +20,70 @@ interface ICheckoutSectionProps {
20
20
  LinkRouter: any;
21
21
  PLACEHOLDER_IMAGE_SMALL_URL:string;
22
22
  UserActionsAPI:any;
23
+ checkoutStore:any;
23
24
  }
24
25
 
25
26
  class CheckoutSection extends React.Component<ICheckoutSectionProps, {}> {
26
- state: {
27
- checkoutCars: any[];
28
- };
29
-
30
- constructor(props: ICheckoutSectionProps) {
31
- super(props);
32
- this.state = {
33
- checkoutCars: []
34
- };
35
- }
36
27
  componentDidMount() {
37
- try {
38
- const { UserActionsAPI } = this.props;
39
- UserActionsAPI.getCheckoutCarList()
40
- .then((savedCheckoutDataList: any) => {
41
- this.setState({ checkoutCars: Object.values(savedCheckoutDataList) });
42
- });
43
- } catch (err) {
44
- console.log('[CheckoutSection] err = ', err);
45
- }
28
+ const { checkoutStore } = this.props;
29
+ checkoutStore.getCheckoutCarList();
46
30
  }
47
31
 
48
32
  onCarSelectCheckout = (carId?: string) => {
49
- const car = this.state.checkoutCars.find((item: any) => item.id === carId);
33
+
34
+ const checkoutCars = toJS(this.props.checkoutStore.checkoutCars);
35
+ const car = checkoutCars.find((item: any) => item.id === carId);
50
36
  const { mainImageId, title: { model, subModel, make } } = car;
51
37
  window.open(`/checkout/contact-information?carId=${carId}&isSavedCheckout=true&mainImageId=${mainImageId}&model=${model}&subModel=${subModel}&make=${make}`, '_blank');
52
38
  };
53
39
 
54
40
  private renderCheckouts = () => {
55
- const { checkoutCars } = this.state;
56
- const { t, appStore: { language }, carsStore, imagesStore , PLACEHOLDER_IMAGE_SMALL_URL } = this.props;
57
- return checkoutCars.map((car: any) => {
58
- const carId = _get(car, 'id');
59
- const { mainImageId, title: { model, subModel, make } } = car;
60
- const src = !!mainImageId && !!car.imagesCount
61
- ? imagesStore.getSupportedImageFormat(carId, mainImageId, 'small')
62
- : PLACEHOLDER_IMAGE_SMALL_URL;
63
- const vehicleProps = {
64
- ...car,
65
- t,
66
- language,
67
- url: `/checkout/contact-information?carId=${carId}&isSavedCheckout=true&mainImageId=${mainImageId}&model=${model}&subModel=${subModel}&make=${make}`,
68
- id: carId,
69
- target: '_blank',
70
- rel: 'noopener noreferrer',
71
- showSlider: false,
72
- showOfferBtn: true,
73
- showFavoriteStar: false,
74
- mainImageId,
75
- priceSubMtl: !isMobileOnly ? t('vehicleProps:value.priceSub') : null,
76
- src,
77
- stats: {
78
- imagesCount: _get(car, 'imagesCount'),
79
- statsData: carsStore.aggStatsData.get(car.id)
80
- },
81
- dashboardButtonText: t('vehicleProps:title.toCheckoutCar'),
82
- i18nPrefixForPriceRating: 'common:',
83
- className: styles.wrapFavorites,
84
- classButton: styles.favoriteBtn,
85
- onDetailsClick: this.onCarSelectCheckout,
86
- vehicleComponentName: 'favorite'
87
- };
41
+ const { t, appStore: { language }, carsStore, imagesStore , PLACEHOLDER_IMAGE_SMALL_URL, checkoutStore } = this.props;
42
+ const checkoutCars = toJS(checkoutStore.checkoutCars);
43
+ if (!checkoutStore.isFetching) {
44
+ return checkoutCars.map((car: any) => {
45
+ const carId = _get(car, 'id');
46
+ const { mainImageId, title: { model, subModel, make } } = car;
47
+ const src = !!mainImageId && !!car.imagesCount
48
+ ? imagesStore.getSupportedImageFormat(carId, mainImageId, 'small')
49
+ : PLACEHOLDER_IMAGE_SMALL_URL;
50
+ const vehicleProps = {
51
+ ...car,
52
+ t,
53
+ language,
54
+ url: `/checkout/contact-information?carId=${carId}&isSavedCheckout=true&mainImageId=${mainImageId}&model=${model}&subModel=${subModel}&make=${make}`,
55
+ id: carId,
56
+ target: '_blank',
57
+ rel: 'noopener noreferrer',
58
+ showSlider: false,
59
+ showOfferBtn: true,
60
+ showFavoriteStar: false,
61
+ mainImageId,
62
+ priceSubMtl: !isMobileOnly ? t('vehicleProps:value.priceSub') : null,
63
+ src,
64
+ stats: {
65
+ imagesCount: _get(car, 'imagesCount'),
66
+ statsData: carsStore.aggStatsData.get(car.id)
67
+ },
68
+ dashboardButtonText: t('vehicleProps:title.toCheckoutCar'),
69
+ i18nPrefixForPriceRating: 'common:',
70
+ className: styles.wrapFavorites,
71
+ classButton: styles.favoriteBtn,
72
+ onDetailsClick: this.onCarSelectCheckout,
73
+ vehicleComponentName: 'favorite'
74
+ };
88
75
 
89
- return (
90
- <div key={`checkoutCar${carId}`} className={styles.checkoutWrapItem}>
91
- <VehicleSmallCard {...vehicleProps} />
92
- </div>
93
- );
94
- });
76
+ return (
77
+ <div key={`checkoutCar${carId}`} className={styles.checkoutWrapItem}>
78
+ <VehicleSmallCard {...vehicleProps} />
79
+ </div>
80
+ );
81
+ });
82
+ }
95
83
  };
96
84
 
97
85
  render(): JSX.Element {
98
- const { t } = this.props;
99
- const { checkoutCars } = this.state;
86
+ const { t, checkoutStore:{ checkoutCars, isFetching } } = this.props;
100
87
  const sliderProps = {
101
88
  slidesToShow: 3,
102
89
  slidesToScroll: 1,
@@ -122,7 +109,7 @@ class CheckoutSection extends React.Component<ICheckoutSectionProps, {}> {
122
109
 
123
110
  return (
124
111
  <>
125
- {Array.isArray(checkoutCars) && checkoutCars.length ?
112
+ {!isFetching ?
126
113
  <DashboardSection className={styles.checkoutSection} title={t('DashboardPage:checkoutTitle')}>
127
114
  {!isMobileOnly ?
128
115
  this.renderCheckouts()
@@ -55,6 +55,11 @@ const OrderStatusCar = ({
55
55
  { icon: 'handingOverDashboard', selector: 'selector_status_handing_over' }
56
56
  ];
57
57
 
58
+ const steps = cardItems.map((step) => {
59
+ const { selector } = step;
60
+ return selector;
61
+ })
62
+
58
63
  useEffect(
59
64
  () => {
60
65
  cardItems.map((step, index) => {
@@ -63,13 +68,12 @@ const OrderStatusCar = ({
63
68
  setActiveStep(index + 1);
64
69
  }
65
70
  });
66
- // if (!!ref && !!ref.current) { TODO: fix scroll for active element for mobile
67
- // ref.current.scrollBy({
68
- // top: 0,
69
- // left: 156 * activeStep,
70
- // behavior: 'smooth'
71
- // });
72
- // }
71
+ if (!!ref && !!ref.current) {
72
+ ref.current.scrollBy({
73
+ behavior: 'smooth',
74
+ left: 156 * steps.indexOf(status)
75
+ })
76
+ }
73
77
  },
74
78
  []
75
79
  );
@@ -100,7 +104,7 @@ const OrderStatusCar = ({
100
104
  </div>
101
105
  </div>
102
106
  </div>
103
- <div className={styles.cardsSection}>
107
+ <div className={styles.cardsSection} ref={ref}>
104
108
  {cardItems.map((card, index) => {
105
109
  const { icon, selector } = card;
106
110
 
@@ -110,7 +114,6 @@ const OrderStatusCar = ({
110
114
 
111
115
  return (
112
116
  <OrderStatusCard
113
- cardRef={selector === status ? ref : null}
114
117
  title={t(`orderStatus.${selector}`)}
115
118
  description={statusDescription}
116
119
  icon={icon}
@@ -8,12 +8,11 @@ interface IOrderStatusCard {
8
8
  title?: string;
9
9
  description?: string;
10
10
  isDisabled?: boolean;
11
- cardRef?: any;
12
11
  isActive?: boolean;
13
12
  isDone?: boolean;
14
13
  }
15
14
 
16
- const OrderStatusCard = ({ icon, title, description, isDisabled, cardRef, isActive, isDone }: IOrderStatusCard) => {
15
+ const OrderStatusCard = ({ icon, title, description, isDisabled, isActive, isDone }: IOrderStatusCard) => {
17
16
  const orderReceivedCardClasses = classnames(
18
17
  styles.orderReceivedCard,
19
18
  { [styles.cardInProgress]: isActive }
@@ -27,7 +26,7 @@ const OrderStatusCard = ({ icon, title, description, isDisabled, cardRef, isActi
27
26
 
28
27
  return (
29
28
  <div className={styles.orderReceivedCardContainer}>
30
- <div data-testid='orderStatusCard' className={orderReceivedCardClasses} ref={cardRef}>
29
+ <div data-testid='orderStatusCard' className={orderReceivedCardClasses}>
31
30
  <div className={styles.cardIcon}>
32
31
  <IconSVG disabled={isDisabled} customDimensions name={icon} width={87}/>
33
32
  </div>