Advertisement
frolkin28

Untitled

Oct 3rd, 2023
788
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /* eslint-disable max-classes-per-file */
  2. import React from 'react';
  3. import PropTypes from 'prop-types';
  4.  
  5.  
  6. function ColbertMountNode(props) {
  7.     return <div>{props.children}</div>;
  8. }
  9.  
  10.  
  11. function ColbertPreloader(props) {
  12.     return <div>{props.children}</div>;
  13. }
  14.  
  15.  
  16. class ColbertQuestionnaireError extends Error {}
  17.  
  18.  
  19. class ColbertQuestionnaire extends React.Component {
  20.     static propTypes = {
  21.         questionId: PropTypes.string.isRequired,
  22.     };
  23.  
  24.     constructor(props) {
  25.         super(props);
  26.         this.references = {};
  27.     }
  28.  
  29.     state = {
  30.         loading: true,
  31.         mounted: false,
  32.     };
  33.  
  34.     componentDidMount() {
  35.         if (!window.colbert) {
  36.             this.hide();
  37.             return;
  38.         }
  39.         if (!this.references.mountNode) {
  40.             throw new ColbertQuestionnaireError('"ColbertMountNode" is not found in child components');
  41.         }
  42.         const options = {
  43.             id: this.props.questionId,
  44.             onSuccess: this.onSuccess,
  45.             onFailure: this.onFailure,
  46.         };
  47.         window.colbert('mountQuestionnaire', this.references.mountNode, options);
  48.     }
  49.  
  50.     onSuccess = () => {
  51.         if (this.isStillMounted()) {
  52.             this.setState({ loading: false, mounted: true });
  53.         }
  54.     };
  55.  
  56.     onFailure = () => {
  57.         if (this.isStillMounted()) {
  58.             this.hide();
  59.         }
  60.     };
  61.  
  62.     getOptsForComponent = (component) => {
  63.         switch (component.type) {
  64.             case ColbertPreloader:
  65.                 return { hidden: !this.state.loading };
  66.             case ColbertMountNode:
  67.                 return {
  68.                     ref: (ref) => { this.references.mountNode = ref; },
  69.                     hidden: !this.state.mounted,
  70.                 };
  71.             default:
  72.                 return null;
  73.         }
  74.     };
  75.  
  76.     isStillMounted = () => {
  77.         // This component has methods that's used as callbacks in external library
  78.         // so we should check that's this component is still mounted
  79.         return this.references.mountNode;
  80.     };
  81.  
  82.     hide = () => {
  83.         this.setState({ loading: false, mounted: false });
  84.     };
  85.  
  86.     childrenWithRefs = () => {
  87.         return React.Children.map(this.props.children, (child) => {
  88.             const opts = this.getOptsForComponent(child);
  89.             if (!opts) {
  90.                 return child;
  91.             }
  92.             return (
  93.                 <div className={child.props.className} {...opts}>
  94.                     {child}
  95.                 </div>
  96.             );
  97.         });
  98.     };
  99.  
  100.     render() {
  101.         const hidden = !(this.state.loading || this.state.mounted);
  102.         return (
  103.             <div className={this.props.className} hidden={hidden}>
  104.                 {this.childrenWithRefs()}
  105.             </div>
  106.         );
  107.     }
  108. }
  109.  
  110. export {
  111.     ColbertQuestionnaire,
  112.     ColbertMountNode,
  113.     ColbertPreloader,
  114. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement