• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

cfpb / ccdb5-ui / 8089320809

29 Feb 2024 12:55AM UTC coverage: 89.671%. First build
8089320809

Pull #491

github

web-flow
Merge e26b762ba into ce78b7801
Pull Request #491: Ww datap 412 mobile tour

893 of 1067 branches covered (83.69%)

Branch coverage included in aggregate %.

5 of 20 new or added lines in 1 file covered. (25.0%)

2649 of 2883 relevant lines covered (91.88%)

85.87 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

28.57
/src/components/Tour/Tour.js
1
import './Tour.less';
2
import * as d3 from 'd3';
3
import React, { useEffect, useRef } from 'react';
4
import { useDispatch, useSelector } from 'react-redux';
5
import { selectQueryTab } from '../../reducers/query/selectors';
6
import {
7
  selectViewIsPrintMode,
8
  selectViewShowTour,
9
  selectViewWidth,
10
} from '../../reducers/view/selectors';
11
import { Steps } from 'intro.js-react';
12
import { TOUR_STEPS } from './constants/tourStepsConstants';
13
import { TourButton } from './TourButton';
14
import { tourHidden } from '../../actions/view';
15

16
export const Tour = () => {
1✔
17
  const dispatch = useDispatch();
1✔
18
  const showTour = useSelector(selectViewShowTour);
1✔
19
  const tab = useSelector(selectQueryTab);
1✔
20
  const isPrintMode = useSelector(selectViewIsPrintMode);
1✔
21
  const viewWidth = useSelector(selectViewWidth);
1✔
22

23
  useEffect(() => {});
1✔
24

25
  const mobileStepOpen = {
1✔
26
    disableInteraction: false,
27
    element: '.filter-panel-toggle .m-btn-group .a-btn',
28
    intro:
29
      'On mobile devices, click the Filter Panel toggle button to open the Filter Panel. Please click the button to proceed.',
30
  };
31
  const mobileStepClose = {
1✔
32
    disableInteraction: false,
33
    element: '.filter-panel-toggle .m-btn-group .a-btn',
34
    intro:
35
      'Click the Filter Panel toggle button again to close the Filter Panel. Please close the Filter Panel to proceed.',
36
  };
37

38
  const steps =
39
    viewWidth < 750
1!
40
      ? TOUR_STEPS[tab]
41
          .slice(0, 3)
42
          .concat(
43
            mobileStepOpen,
44
            TOUR_STEPS[tab].slice(4, 7),
45
            mobileStepClose,
46
            TOUR_STEPS[tab].slice(7),
47
          )
48
      : TOUR_STEPS[tab];
49
  const stepRef = useRef();
1✔
50

51
  // INTRODUCTION / TUTORIAL OPTIONS:
52
  const options = {
1✔
53
    disableInteraction: true,
54
    scrollToElement: true,
55
    scrollTo: 'tooltip',
56
    showStepNumbers: false,
57
    exitOnOverlayClick: false,
58
    exitOnEsc: true,
59
    nextLabel: 'Next',
60
    prevLabel: 'Previous',
61
    doneLabel: 'End Tour',
62
    steps: steps,
63
  };
64

65
  /**
66
   * Before Change handler
67
   *
68
   * @param {object} ref - React component reference.
69
   */
70
  function handleBeforeChange(ref) {
71
    const currentStep = ref.current.introJs.currentStep();
×
72

73
    // exit out when we're on last step and keyboard nav pressed
74
    if (!steps[currentStep]) {
×
75
      return;
×
76
    }
77

78
    if (steps[currentStep].element === '.row-chart-section') {
×
79
      // when the tour is initiated, we reset the chart so that the
80
      // rows are collapsed. This way we can click the first row to expand it
81
      // to guarantee a consistent tour.
82
      const expandable = d3.select('#row-chart-product .tick.expandable');
×
83
      expandable.dispatch('click');
×
84
    }
85

86
    const callBack = () => {
×
87
      steps.forEach((step, idx) => {
×
88
        if (ref.current !== null) {
×
89
          ref.current.updateStepElement(idx);
×
90
        }
91
      });
92
    };
93
    const waitOn = new MutationObserver(callBack);
×
NEW
94
    waitOn.observe(document.querySelector('#ccdb-ui-root'), {
×
95
      subtree: true,
96
      childList: true,
97
    });
98

99
    // Add listener to filter toggle if it's mobile and at step 4 or 7
NEW
100
    const filterListener = () => {
×
101
      // Make sure next button isn't being hidden from steps 3 or 7
NEW
102
      document
×
103
        .querySelector('.introjs-nextbutton')
104
        ?.setAttribute('style', 'display: inline');
105
      // Wait for date inputs to render, then proceed
NEW
106
      const promise = new Promise((resolve) => {
×
NEW
107
        if (currentStep === 7) return resolve();
×
NEW
108
        const interval = setInterval(() => {
×
NEW
109
          if (document.querySelector('.date-filter') !== null) {
×
NEW
110
            clearInterval(interval);
×
NEW
111
            return resolve();
×
112
          }
113
        }, 10);
114
      });
NEW
115
      promise.then(() => {
×
NEW
116
        ref.current.introJs.nextStep().then(() => {
×
NEW
117
          document
×
118
            .querySelector(mobileStepOpen.element)
119
            .removeEventListener('click', filterListener);
120
        });
121
      });
122
    };
NEW
123
    if (viewWidth < 750 && (currentStep === 3 || currentStep === 7)) {
×
NEW
124
      document
×
125
        .querySelector('.introjs-nextbutton')
126
        .setAttribute('style', 'display: none');
NEW
127
      document
×
128
        .querySelector(mobileStepOpen.element)
129
        .addEventListener('click', filterListener);
130
    }
131
  }
132

133
  /**
134
   * Exit handler
135
   *
136
   * @param {object} ref - React component reference.
137
   * @returns {boolean} Can we exit?
138
   */
139
  function handleBeforeExit(ref) {
140
    if (ref.current === null) {
1!
141
      return true;
1✔
142
    }
143
    if (ref.current.introJs.currentStep() + 1 < steps.length) {
×
144
      // eslint-disable-next-line no-alert
145
      return window.confirm('Are you sure you want to exit the tour?');
×
146
    }
147
    return true;
×
148
  }
149

150
  return isPrintMode ? null : (
1!
151
    // eslint-disable-next-line react/react-in-jsx-scope
152
    <>
153
      <TourButton />
154
      <Steps
155
        enabled={showTour}
156
        initialStep={0}
157
        steps={steps}
158
        onExit={() => dispatch(tourHidden())}
1✔
159
        options={options}
160
        onBeforeChange={() => handleBeforeChange(stepRef)}
×
161
        onBeforeExit={() => handleBeforeExit(stepRef)}
1✔
162
        ref={stepRef}
163
      />
164
    </>
165
  );
166
};
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc