Facing issue with Material UI Popper position

19 views Asked by At

I am using Popper component of Material UI to render data inside popup when clicked on Item.

The issue I am facing is when certain item is clicked the Popper opens at the start of viewPort and then it corrects it's position to the anchor element.

The two possible reasons that might be true here is of Opening of Popper at the start of viewPort and then shifting to correct position with respect to anchor element is that initially it do has anchorElement as null or due to dynamic contnet rendring.

Here is my component code where I am using Popper :

const RightPanel = (props: any) => {
  const { dispatch, state } = useContext(stateContext);
  const { dprState, dprDispatch } = useContext(DPRContext);
  // const [anchorEl, setAnchorEl]: any = useState(null);
  const [anchorEl, setAnchorEl] = useState<PopperProps['anchorEl']>(document.getElementById(`icon-${0}`));
  const [openIndex, setOpenIndex] = useState(-1);
  const [sideMenuOptions, setSideMenuOptions] = useState<MenuOption[]>([]);
  const [isMarkerEnabled, setIsMarkerEnabled] = useState(false);
  const [isDataLoaded,setIsDataLoaded] = useState<boolean>(false)
  const [markerMode, setMarkerMode] = useState<MarkerMode>();
  const {
    viewType,
    setViewType,
    showReport,
    setShowReport,
    setShowDprMedia,
    showDprMedia,
    showActivities,
    setShowActivities,
    modelIds,
    marker,
    viewer,
    setManageScreen,
    manageScreen,
    setShowDrawingMenu,
  } = props;
  const classes = menuStyle();
  const { dprAdmin, dprEditor, dprViewer } = useDprPermission();
  const { track } = useAnalytics();
  const projectId = useProjectId();


console.log("anchorEl",anchorEl)
  useEffect(() => {
    const menuOptions: MenuOption[] = [
      {
        img: info,
        imgActive: infoActive,
        imgDisabled:infoDisabled,
        isMenu: true,
        tooltipsText: 'Activity information',
        show: true,
        isDisabled:false,
        id:"info",
        isOpen:false
      },
      {
        img: threeD,
        imgActive: threeDActive,
        imgDisabled:threeDDisabled,
        isMenu: false,
        tooltipsText: '3D view',
        show: true,
        isDisabled:false,
        id:"3d",
      },
      {
        img: twoD,
        imgActive: twoDActive,
        imgDisabled:twoDDisabled,
        isMenu: false,
        tooltipsText: '2D view',
        show: true,
        isDisabled:false,
        id:"2d"
      },
      {
        img: filter,
        imgActive: filterActive,
        imgDisabled:filterDisabled,
        isMenu: true,
        tooltipsText: 'Filters',
        show: true,
        isDisabled:false,
        id:"filter",
        isOpen:false
      },
      {
        img: linkWhite,
        imgActive: linkCyan,
        isMenu: false,
        tooltipsText: 'Marker setup mode',
        show: dprAdmin || dprEditor,
        isDisabled:false,
        id:"link"
      },
      {
        img: progressWhite,
        imgActive: progressCyan,
        isMenu: false,
        tooltipsText: 'Marker progress mode',
        show: dprAdmin || dprEditor,
        isDisabled:false,
        id:"progress"
      },
      {
        img: analytics,
        imgActive: analyticsActive,
        isMenu: false,
        tooltipsText: 'Progress view',
        show: true,
        isDisabled:false,
        id:"analytics"
      },
      {
        img: list,
        imgActive: listActive,
        isMenu: false,
        tooltipsText: 'Progress List view',
        show: true,
        isDisabled:false,
        id:"list"
      },
      {
        img: photos,
        imgActive: photosActive,
        isMenu: false,
        tooltipsText: 'Progress Media',
        show: true,
        isDisabled:false,
        id:"photos"
      },
      {
        img: files,
        imgActive: filesActive,
        isMenu: true,
        tooltipsText: 'Manage',
        show: true,
        isDisabled:false,
        id:"files"
      },
    ];

    setSideMenuOptions(menuOptions);
  }, [state.selectedProjectToken]);


  useEffect(
    () => setupMarkerWithViewer(),
    [marker?.mode, marker?.isEnabled, showReport]
  );

  useEffect(() => {
    marker?.disable();
    marker?.changeMode('setup');
    setupMarkerWithViewer()
    dprDispatch(setUpdateMarker(dprState.updateMarker + 1));
  }, [state.selectedDprTaskDetails]);

  useEffect(() => {
    updateMarkerChanges();
  }, [dprState.updateMarker]);

  const setupMarkerWithViewer = () => {
    if (!marker) return;
    if (showReport) {
      viewer?.deleteFilters(['selectedTaskElements']);
      return;
    }
    viewer?.deleteFilters(['selectedTaskElements', 'completedFilter']);
    if (marker?.isEnabled) {
      if (
        !state.selectedDprTaskDetails ||
        !state.selectedDprTaskDetails?.projectTaskElementAssociations.length
      ) {
        marker?.updateSelectableIds(null, {}, {});
        marker.changeMode('setup');
      } else {
        if (
          state.selectedDprTaskDetails.status !== 'To-Do' &&
          marker.mode === 'setup'
        ) {
          marker?.changeMode('progress');
          addSelectedFilter(true);
          marker?.enable();
          dprDispatch(setUpdateMarker(dprState.updateMarker + 1));
          return;
        }
        if (marker.mode === 'progress') {
          addSelectedFilter(true);
          marker?.enable();
        } else {
          const {selectableIndex, allIds} = getCompletedSelectedIds(state.selectedDprTaskDetails);
          marker?.updateSelectableIds(null, {}, {});
          marker?.enable(allIds, selectableIndex);
        }
      }
    } else {
      addSelectedFilter(false);
    }
    dprDispatch(setUpdateMarker(dprState.updateMarker + 1));
  };

  const addSelectedFilter = (updateMarker: boolean) => {
    if(!state.selectedDprTaskDetails) return;
    const {selectableIds, completedIds, selectableIndex, completedIndex, allIds} = getCompletedSelectedIds(state.selectedDprTaskDetails);
    if (props.marker.isEnabled) {
      props.viewer?.addOrUpdateFilter([getSelectedFilter(selectableIds, selectableIndex, completedIndex), getCompletedFilter(completedIds, selectableIndex, completedIndex, {}, {})]);
    } else {
      props.viewer?.addOrUpdateFilter([getSelectedFilter(allIds, selectableIndex, {})]);
    }

    updateMarker
      ? props.marker?.updateSelectableIds(selectableIds || [], selectableIndex, completedIndex)
      : props.marker?.updateSelectableIds(null);
  };


  const handleMenu = (index: any, isMenu: any) => (event: any) => {

    if (isMenu) {
      const anchorEle = document.getElementById(`icon-${index}`)
      setAnchorEl(anchorEle)
    }
    if (index === 1) {
      setViewType('3D');
    } else if (index === 2) {
      setViewType('2D');
    } else if (index === 4) {
      if (
        state.selectedDprTaskDetails &&
        state.selectedDprTaskDetails.status === 'To-Do'
      ) {
        (!marker.isEnabled || markerMode === 'progress') &&
        !showReport &&
        !showActivities &&
        !showDprMedia
          ? marker?.enable()
          : marker?.disable();
        marker.changeMode('setup');
        dprDispatch(setUpdateMarker(dprState.updateMarker + 1));
      }
    } else if (index === 5) {
      if (
        state.selectedDprTaskDetails &&
        state.selectedDprTaskDetails?.projectTaskElementAssociations.length
      ) {
        (!marker.isEnabled || markerMode === 'setup') &&
        !showReport &&
        !showActivities &&
        !showDprMedia
          ? marker?.enable()
          : marker?.disable();
        marker.changeMode('progress');
        dprDispatch(setUpdateMarker(dprState.updateMarker + 1));
      }
    } else if (index === 6) {
      track(TrackingEvents["progress-view"])
       setShowReport(!showReport);
    const updatedMenuOptions = sideMenuOptions.map((menuOption) => {
      if (["3d", "2d", "photos", "files", "list", "analytics", "filter"].includes(menuOption.id)) {
          // These options should always be enabled
          menuOption.isDisabled = false;
      } else {
          // For other options, update based on the showReport condition
          menuOption.isDisabled = !showReport;
      }
      return menuOption;
  });
    setSideMenuOptions(updatedMenuOptions)
      marker?.disable();
      updateMarkerChanges();
      setShowActivities(false);
      setShowDprMedia(false);
    } else if (index === 7) {
      track(TrackingEvents["dpr-list-view"])
      const updatedMenuOptions = sideMenuOptions.map((menuOption)=>{
          if(menuOption.id !="photos" &&  menuOption.id !="files" && menuOption.id !="list" && menuOption.id !="analytics"){
          menuOption.isDisabled = showActivities? false: true
        }
        return menuOption

      })
      setSideMenuOptions(updatedMenuOptions)
      marker?.disable();
      setShowReport(false);
      setShowDprMedia(false);
      setShowActivities(!showActivities);
    } else if (index === 8) {
      track(TrackingEvents["dpr-media-asset"])
      const updatedMenuOptions = sideMenuOptions.map((menuOption,index)=>{
        if(menuOption.id !="photos" &&  menuOption.id !="files" && menuOption.id !="list" && menuOption.id !="analytics"){
           menuOption.isDisabled = showDprMedia? false: true
        }
        return menuOption

      })
      setSideMenuOptions(updatedMenuOptions)
      marker?.disable();
      setShowReport(false);
      setShowActivities(false);
      setShowDprMedia(!showDprMedia);
    } else if (index === 9) {
      track(TrackingEvents["manage"])
      setManageScreen(!manageScreen);
      dprDispatch(setCategoryFilters([]));
      dprDispatch(setOtherFiltersList([]));
      dprDispatch(setLevelList([]));


    } else {
      setOpenIndex(openIndex === index ? -1 : index); // set current menu index to open

    }
  };

  useEffect(()=>{
 if(openIndex==3){
  track(TrackingEvents["filtering-geometry"],{projectId})
 }
  },[openIndex])

  const handleMenuClose = (e:any) => {
   // console.log("closing-menu",openIndex, e?.target,e)
    setAnchorEl(null);
    setOpenIndex(-1);
  };

  const updateMarkerChanges = () => {
    setMarkerMode(marker?.mode);
    setIsMarkerEnabled(marker?.isEnabled);
    setShowDrawingMenu(marker?.isEnabled);
  };

 
  return (
    <div className="rightPanelMain">
      {sideMenuOptions?.map((option: any, index: number) => {
        if (index === 1 && viewType === '3D') return <></>;
        if (index === 2 && viewType === '2D') return <></>;
        if (option.show) {
          return (
            <div key={index}>
              <div
                id={`icon-${index}`}
                className="rightPanelMain__icon"
                onClick={ option.isDisabled?()=>{return undefined}: handleMenu(index, option?.isMenu)}
              >
                <Tooltip title={`${option?.tooltipsText}`} placement="left">
                  <img
                    src={
                      (index === 1 && viewType === '3D') ||
                      (index === 2 && viewType === '2D') ||
                      (index === 4 &&
                        marker?.isEnabled &&
                        markerMode === 'setup') ||
                      (index === 5 &&
                        marker?.isEnabled &&
                        markerMode === 'progress') ||
                      (index === 6 && showReport) ||
                      (index === 7 && showActivities) ||
                      (index === 8 && showDprMedia) ||
                      openIndex === index
                        ? option.imgActive
                        : option.img
                    }
                    className={
                      (index === 4 &&
                        (!state.selectedDprTaskDetails ||
                          state.selectedDprTaskDetails.status !== 'To-Do')) ||
                      (index === 5 &&
                        (!state.selectedDprTaskDetails ||
                          !state.selectedDprTaskDetails
                            ?.projectTaskElementAssociations.length)) ||
                      ((index === 4 || index === 5) && (showActivities ||
                      showDprMedia ||
                      showReport)) || option.isDisabled
                        ? 'rightPanelMain__icon__disabled'
                        : ''
                    }
                  />
                </Tooltip>
              </div>
              {index !== sideMenuOptions?.length - 1 && (
                <div className="rightPanelMain__divider"></div>
              )}
              {(openIndex !== -1 && anchorEl !=null) ? (
                <Popper
                id={`custom-popper-${index}`}
                anchorEl={anchorEl}
                open={Boolean(anchorEl) && (index === openIndex)}
                placement={'left-start'}
                sx={{zIndex:3}}
                className={classes.paper}
                keepMounted
                
                >
               
                  <div className="floating-menu--container">
                    {openIndex === 0 ? (
                      <InfoTab marker={marker} modelIds={modelIds}/>
                    ) : openIndex === 3 ? (
                      <Filters
                        modelIds={modelIds}
                        viewer={viewer}
                        marker={marker}
                        setIsDataLoaded={setIsDataLoaded}
                      />
                    ) : null}
                  </div>
                  </Popper>
              ) : null}
            </div>
          );
        }
      })}
    </div>
  );
};

Inside Popper I have two components InfoTab , Filters, that is getting rendered inside Popper and these two components data I am getting from Api.

The issue I am facing is when certain item is clicked the Popper opens at the start of viewPort and then it corrects it's position to the anchor element.

The two possible reasons that might be true here is of Opening of Popper at the start of viewPort and then shifting to correct position with respect to anchor element is that initially it do has anchorElement as null or due to dynamic contnet rendring.

0

There are 0 answers