react-router#useRouteMatch TypeScript Examples

The following examples show how to use react-router#useRouteMatch. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Preview.tsx    From dnde with GNU General Public License v3.0 6 votes vote down vote up
NewItem = () => {
  const history = useHistory();
  const { path } = useRouteMatch();
  const onClick = () => {
    history.push(`${path}/template/new`);
  };

  return (
    <PreviewContainer>
      <div className="newTemplate">
        <PlusOutlined style={{ fontSize: '40px' }} />
      </div>
      <div className="hoverItem alwaysActive">
        <div className="content">
          <Button onClick={onClick} size="large" type="primary" className="btn-choose">
            New Template
          </Button>
        </div>
      </div>
      <div>
        <img src={newTemplate} alt="img new template" />
      </div>
    </PreviewContainer>
  );
}
Example #2
Source File: Preview.tsx    From dnde with GNU General Public License v3.0 6 votes vote down vote up
Preview = ({ image, id, skeleton }: PreviewProps) => {
  const history = useHistory();
  const { path } = useRouteMatch();
  const onClick = () => {
    history.push(`${path}/template/${id}`);
  };
  return (
    <PreviewContainer>
      {skeleton ? (
        <div style={{ height: '350px', minWidth: '280px', maxWidth: '280px', padding: '24px 24px' }}>{skeleton}</div>
      ) : (
        <img height="350px" src={image} alt="preview" />
      )}
      <div className="hoverItem">
        <div className="content">
          <Button onClick={onClick} size="large" type="primary" className="btn-choose">
            choose
          </Button>
        </div>
      </div>
    </PreviewContainer>
  );
}
Example #3
Source File: AppsPage.tsx    From disco-cube-admin with MIT License 6 votes vote down vote up
AppsPage: React.FC<Props> = ({}) => {
  const match = useRouteMatch();

  return (
    <Page>
      <Switch>
        <Route exact path={match.path}>
          <ConnectedAppsPageContent />
        </Route>
        {Object.entries(apps).map(([key, { path, render }]) => (
          <Route key={key} path={`${match.path}${path}`}>
            {render()}
          </Route>
        ))}
      </Switch>
    </Page>
  );
}
Example #4
Source File: index.tsx    From datart with Apache License 2.0 6 votes vote down vote up
AuthorizationPage = () => {
  const dispatch = useDispatch();
  const history = useHistory();
  const paramsMatch = useRouteMatch<{ token: string }>();
  const token = paramsMatch.params.token;
  const t = useI18NPrefix('authorization');

  useEffect(() => {
    if (token) {
      dispatch(
        getUserInfoByToken({
          token,
          resolve: () => {
            const redirectUrl = persistence.session.get(
              StorageKeys.AuthRedirectUrl,
            );
            if (redirectUrl) {
              persistence.session.remove(StorageKeys.AuthRedirectUrl);
              window.location.href = redirectUrl;
            } else {
              history.replace('/');
            }
          },
        }),
      );
    }
  }, [token, dispatch, history]);
  return (
    <Wrapper>
      <EmptyFiller loading title={t('processing')} />
    </Wrapper>
  );
}
Example #5
Source File: index.tsx    From datart with Apache License 2.0 6 votes vote down vote up
Main = memo(() => {
  const {
    params: { viewpoint, type: viewpointType, id: viewpointId },
  } = useRouteMatch<{
    viewpoint: Viewpoints;
    type: ResourceTypes | SubjectTypes;
    id: string;
  }>();
  const orgId = useSelector(selectOrgId);

  return (
    <Wrapper>
      {viewpoint === Viewpoints.Subject ? (
        <ResourcesPermissionSetting
          viewpoint={viewpoint}
          viewpointId={viewpointId}
          viewpointType={viewpointType}
          orgId={orgId}
        />
      ) : (
        <SubjectPermissionSetting
          viewpoint={viewpoint}
          viewpointId={viewpointId}
          viewpointType={viewpointType}
          orgId={orgId}
        />
      )}
    </Wrapper>
  );
})
Example #6
Source File: index.tsx    From taskcafe with MIT License 5 votes vote down vote up
GlobalTopNavbar: React.FC<GlobalTopNavbarProps> = ({
  currentTab,
  onSetTab,
  menuType,
  teamID,
  onChangeProjectOwner,
  onChangeRole,
  name,
  popupContent,
  projectMembers,
  projectInvitedMembers,
  onInviteUser,
  onSaveProjectName,
  onRemoveInvitedFromBoard,
  onRemoveFromBoard,
}) => {
  const { user } = useCurrentUser();
  const match = useRouteMatch();
  if (user) {
    return (
      <LoggedInNavbar
        currentTab={currentTab}
        projectID={null}
        onSetTab={onSetTab}
        menuType={menuType}
        teamID={teamID}
        onChangeRole={onChangeRole}
        onChangeProjectOwner={onChangeProjectOwner}
        name={name}
        popupContent={popupContent}
        projectMembers={projectMembers}
        projectInvitedMembers={projectInvitedMembers}
        onInviteUser={onInviteUser}
        onSaveProjectName={onSaveProjectName}
        onRemoveInvitedFromBoard={onRemoveInvitedFromBoard}
        onRemoveFromBoard={onRemoveFromBoard}
      />
    );
  }
  return <LoggedOutNavbar match={match.url} name={name} menuType={menuType} />;
}
Example #7
Source File: index.tsx    From taskcafe with MIT License 5 votes vote down vote up
Teams = () => {
  const { teamID } = useParams<TeamsRouteProps>();
  const history = useHistory();
  const { loading, data } = useGetTeamQuery({
    variables: { teamID },
    onCompleted: resp => {
      document.title = `${resp.findTeam.name} | Taskcafé`;
    },
  });
  const { user } = useCurrentUser();
  const [currentTab, setCurrentTab] = useState(0);
  const match = useRouteMatch();
  if (data && user) {
    /*
TODO: re-add permission check
    if (!user.isVisible(PermissionLevel.TEAM, PermissionObjectType.TEAM, teamID)) {
      return <Redirect to="/" />;
    }
     */
    return (
      <>
        <GlobalTopNavbar
          menuType={[
            { name: 'Projects', link: `${match.url}` },
            { name: 'Members', link: `${match.url}/members` },
          ]}
          currentTab={currentTab}
          onSetTab={tab => {
            setCurrentTab(tab);
          }}
          popupContent={<TeamPopup history={history} name={data.findTeam.name} teamID={teamID} />}
          onSaveProjectName={NOOP}
          projectID={null}
          name={data.findTeam.name}
        />
        <OuterWrapper>
          <Wrapper>
            <Switch>
              <Route exact path={match.path}>
                <Projects teamID={teamID} />
              </Route>
              <Route path={`${match.path}/members`}>
                <Members teamID={teamID} />
              </Route>
            </Switch>
          </Wrapper>
        </OuterWrapper>
      </>
    );
  }
  return (
    <GlobalTopNavbar
      menuType={[
        { name: 'Projects', link: `${match.url}` },
        { name: 'Members', link: `${match.url}/members` },
      ]}
      currentTab={currentTab}
      onSetTab={tab => {
        setCurrentTab(tab);
      }}
      onSaveProjectName={NOOP}
      projectID={null}
      name={null}
    />
  );
}
Example #8
Source File: RootPathContext.ts    From frontegg-react with MIT License 5 votes vote down vote up
useRootPath = (props: any, defaultRoute: string = '/'): [string, boolean] => {
  const rootPathFromContext = useContext(RootPathContext);
  const routeMatch = useRouteMatch();
  const rootPath = rootPathFromContext ?? props.rootPath ?? routeMatch?.url ?? defaultRoute;
  const isRootPathContext = rootPathFromContext != null;

  return [rootPath, isRootPathContext];
}
Example #9
Source File: DrawerMenu.tsx    From shadowsocks-electron with GNU General Public License v3.0 5 votes vote down vote up
DrawerMenu: React.FC<DrawerMenuProps> = props => {
  const { t } = useTranslation();
  const styles = useStyles();
  const { onClick, hideIcon } = props;

  const getMatchedClasses = (matched: boolean) => clsx(styles['text'], matched && styles['matchHighlight']);

  const matchHomePath = getMatchedClasses(!!useRouteMatch('/home'));
  const matchSettingsPath = getMatchedClasses(!!useRouteMatch('/settings'));
  const matchAboutPath = getMatchedClasses(!!useRouteMatch('/about'));

  return (
    <>
      { !hideIcon && (
        <>
          <img className={styles.banner} src={banner}></img>
          <Divider />
        </>
        )
      }
      <List>
        <Link to="/home" onClick={onClick}>
          <ListItem button>
            <ListItemIcon className={matchHomePath}>
              <HomeIcon />
            </ListItemIcon>
            <ListItemText primary={t('home')} className={matchHomePath}/>
          </ListItem>
        </Link>
        <Link to="/settings" onClick={props.onClick}>
          <ListItem button>
            <ListItemIcon className={matchSettingsPath}>
              <SettingsIcon />
            </ListItemIcon>
            <ListItemText primary={t('settings')} className={matchSettingsPath}/>
          </ListItem>
        </Link>
        <Link to="/about" onClick={props.onClick} >
          <ListItem button>
            <ListItemIcon className={matchAboutPath}>
              <InfoIcon />
            </ListItemIcon>
            <ListItemText primary={t('about')} className={matchAboutPath} />
          </ListItem>
        </Link>
      </List>
    </>
  );
}
Example #10
Source File: index.tsx    From datart with Apache License 2.0 5 votes vote down vote up
Sidebar = memo(() => {
  const history = useHistory();
  const orgId = useSelector(selectOrgId);
  const list = useSelector(selectSources);
  const archived = useSelector(selectArchived);
  const matchSourceDetail = useRouteMatch<{ sourceId: string }>(
    '/organizations/:orgId/sources/:sourceId',
  );
  const sourceId = matchSourceDetail?.params.sourceId;
  const t = useI18NPrefix('source.sidebar');
  const allowCreate = useAccess(allowCreateSource());

  const { filteredData: sourceList, debouncedSearch: listSearch } =
    useDebouncedSearch(list, (keywords, d) =>
      d.name.toLowerCase().includes(keywords.toLowerCase()),
    );
  const { filteredData: archivedList, debouncedSearch: archivedSearch } =
    useDebouncedSearch(archived, (keywords, d) =>
      d.name.toLowerCase().includes(keywords.toLowerCase()),
    );

  const toAdd = useCallback(() => {
    history.push(`/organizations/${orgId}/sources/add`);
  }, [history, orgId]);

  const moreMenuClick = useCallback((key, _, onNext) => {
    switch (key) {
      case 'recycle':
        onNext();
        break;
    }
  }, []);

  const titles = useMemo(
    () => [
      {
        key: 'list',
        title: t('title'),
        search: true,
        onSearch: listSearch,
        ...allowCreate({
          add: { items: [{ key: 'add', text: t('add') }], callback: toAdd },
        }),
        more: {
          items: [
            {
              key: 'recycle',
              text: t('recycle'),
              prefix: <DeleteOutlined className="icon" />,
            },
          ],
          callback: moreMenuClick,
        },
      },
      {
        key: 'recycle',
        title: t('recycle'),
        back: true,
        search: true,
        onSearch: archivedSearch,
      },
    ],
    [toAdd, moreMenuClick, listSearch, archivedSearch, allowCreate, t],
  );

  return (
    <Wrapper defaultActiveKey="list">
      <ListPane key="list">
        <ListTitle {...titles[0]} />
        <SourceList sourceId={sourceId} list={sourceList} />
      </ListPane>
      <ListPane key="recycle">
        <ListTitle {...titles[1]} />
        <Recycle sourceId={sourceId} list={archivedList} />
      </ListPane>
    </Wrapper>
  );
})
Example #11
Source File: RelatedPage.tsx    From covidex with MIT License 4 votes vote down vote up
RelatedPage = () => {
  const {
    params: { articleId },
  } = useRouteMatch<any>();

  const [loading, setLoading] = useState<boolean>(false);
  const [notFound, setNotFound] = useState<boolean>(false);
  const [hasMore, setHasMore] = useState<boolean>(true);
  const [page, setPage] = useState<number>(1);
  const [queryId, setQueryId] = useState<string>('');

  const [originalArticle, setOriginalArticle] = useState<RelatedArticle | null>(null);
  const [relatedArticles, setRelatedArticles] = useState<RelatedArticle[] | null>(null);

  useEffect(() => {
    const fetchData = async () => {
      if (articleId === undefined || articleId === null || articleId === '') {
        setLoading(false);
        setNotFound(true);
        setPage(1);
        return;
      }

      try {
        setLoading(true);
        setRelatedArticles(null);

        let response = await fetch(
          `${API_BASE}${RELATED_ENDPOINT}/${articleId.toLowerCase()}?page_number=${1}`,
        );
        setLoading(false);

        let data = await response.json();
        const { query_id, response: responseArticles } = data;
        const originalArticle = responseArticles
          ? responseArticles.find((a: RelatedArticle) => a.id === articleId)
          : null;

        setQueryId(query_id);
        setOriginalArticle(originalArticle);
        setRelatedArticles(responseArticles.filter((a: RelatedArticle) => a.id !== articleId));
        setPage(2);
      } catch {
        setLoading(false);
        setNotFound(true);
        setPage(2);
      }
    };

    fetchData();
  }, [articleId]);

  const loadMoreResults = async () => {
    let response = await fetch(
      `${API_BASE}${RELATED_ENDPOINT}/${articleId.toLowerCase()}?page_number=${page}`,
    );
    setPage(page + 1);

    if (response.status > 400) {
      setHasMore(false);
    }

    let data = await response.json();
    const { response: responseArticles } = data;
    const currentArticles = relatedArticles || [];
    setRelatedArticles([...currentArticles, ...responseArticles]);
  };

  const TitleRow = (
    <Row>
      <RelatedTitle>
        Related Articles <FileText size={24} style={{ marginLeft: '8px' }} />
      </RelatedTitle>
      <SearchLink to={HOME_ROUTE}>
        <ArrowLeft size={16} style={{ marginRight: '4px' }} />
        Search All Articles
      </SearchLink>
    </Row>
  );

  return (
    <PageWrapper>
      <PageContent>
        <ErrorBoundary FallbackComponent={NotFoundComponent}>
          <RelatedContent>
            {loading && <Loading />}
            {notFound && (
              <>
                {TitleRow}
                <NotFoundComponent />
              </>
            )}
            {originalArticle && relatedArticles && (
              <>
                {TitleRow}
                <OriginalArticle>
                  <SmallTitle>Showing articles related to:</SmallTitle>
                  <ArticleInfo article={originalArticle} boldTitle />
                  {originalArticle.abstract && (
                    <>
                      <AbstractTitle className="hideCollapsed">Abstract</AbstractTitle>
                      <Paragraph>{parseAbstract(originalArticle.abstract)}</Paragraph>
                    </>
                  )}
                </OriginalArticle>
                <InfiniteScroll
                  pageStart={page}
                  loadMore={loadMoreResults}
                  hasMore={hasMore}
                  loader={
                    <Row>
                      <Loading />
                    </Row>
                  }
                >
                  {relatedArticles.map((article, idx) => (
                    <RelatedResult
                      key={article.id}
                      article={article}
                      position={idx}
                      queryId={queryId}
                    />
                  ))}
                </InfiniteScroll>
                {relatedArticles.length === 0 && <NotFound>No related articles found</NotFound>}
              </>
            )}
          </RelatedContent>
        </ErrorBoundary>
      </PageContent>
    </PageWrapper>
  );
}
Example #12
Source File: index.tsx    From datart with Apache License 2.0 4 votes vote down vote up
export function MainPage() {
  useAppSlice();
  const { actions } = useMainSlice();
  const { actions: vizActions } = useVizSlice();
  const { actions: viewActions } = useViewSlice();
  const dispatch = useDispatch();
  const organizationMatch = useRouteMatch<MainPageRouteParams>(
    '/organizations/:orgId',
  );
  const orgId = useSelector(selectOrgId);
  const history = useHistory();
  // loaded first time
  useEffect(() => {
    ChartManager.instance()
      .load()
      .catch(err => console.error('Fail to load customize charts with ', err));
    dispatch(getUserSettings(organizationMatch?.params.orgId));
    dispatch(getDataProviders());
    return () => {
      dispatch(actions.clear());
    };
  }, []);

  useEffect(() => {
    if (orgId) {
      dispatch(vizActions.clear());
      dispatch(viewActions.clear());
      dispatch(getLoggedInUserPermissions(orgId));
    }
  }, [dispatch, vizActions, viewActions, orgId]);

  const onSaveInDataChart = useCallback(
    (orgId: string, backendChartId: string) => {
      dispatch(
        initChartPreviewData({
          backendChartId,
          orgId,
        }),
      );
      history.push(`/organizations/${orgId}/vizs/${backendChartId}`);
    },
    [dispatch, history],
  );

  return (
    <AppContainer>
      <Background />
      <Navbar />
      {orgId && (
        <Switch>
          <Route path="/" exact>
            <Redirect to={`/organizations/${orgId}`} />
          </Route>
          <Route path="/confirminvite" component={ConfirmInvitePage} />
          <Route path="/organizations/:orgId" exact>
            <Redirect
              to={`/organizations/${organizationMatch?.params.orgId}/vizs`}
            />
          </Route>
          <Route
            path="/organizations/:orgId/vizs/chartEditor"
            render={res => {
              const hisSearch = new URLSearchParams(res.location.search);
              const hisState = {
                dataChartId: hisSearch.get('dataChartId') || '',
                chartType: hisSearch.get('chartType') || 'dataChart',
                container: hisSearch.get('container') || 'dataChart',
                defaultViewId: hisSearch.get('defaultViewId') || '',
              } as ChartEditorBaseProps;
              return (
                <AccessRoute module={ResourceTypes.Viz}>
                  <ChartEditor
                    dataChartId={hisState.dataChartId}
                    orgId={orgId}
                    chartType={hisState.chartType}
                    container={hisState.container}
                    defaultViewId={hisState.defaultViewId}
                    onClose={() => history.go(-1)}
                    onSaveInDataChart={onSaveInDataChart}
                  />
                </AccessRoute>
              );
            }}
          />

          <Route
            path="/organizations/:orgId/vizs/storyPlayer/:storyId"
            render={() => <StoryPlayer />}
          />
          <Route
            path="/organizations/:orgId/vizs/storyEditor/:storyId"
            render={() => <StoryEditor />}
          />
          <Route
            path="/organizations/:orgId/vizs/:vizId?"
            render={() => (
              <AccessRoute module={ResourceTypes.Viz}>
                <VizPage />
              </AccessRoute>
            )}
          />
          <Route
            path="/organizations/:orgId/views/:viewId?"
            render={() => (
              <AccessRoute module={ResourceTypes.View}>
                <ViewPage />
              </AccessRoute>
            )}
          />
          <Route
            path="/organizations/:orgId/sources"
            render={() => (
              <AccessRoute module={ResourceTypes.Source}>
                <SourcePage />
              </AccessRoute>
            )}
          />
          <Route
            path="/organizations/:orgId/schedules"
            render={() => (
              <AccessRoute module={ResourceTypes.Schedule}>
                <SchedulePage />
              </AccessRoute>
            )}
          />
          <Route
            path="/organizations/:orgId/members"
            render={() => (
              <AccessRoute module={ResourceTypes.User}>
                <MemberPage />
              </AccessRoute>
            )}
          />
          <Route
            path="/organizations/:orgId/roles"
            render={() => (
              <AccessRoute module={ResourceTypes.User}>
                <MemberPage />
              </AccessRoute>
            )}
          />
          <Route path="/organizations/:orgId/permissions" exact>
            <Redirect
              to={`/organizations/${organizationMatch?.params.orgId}/permissions/subject`}
            />
          </Route>
          <Route
            path="/organizations/:orgId/permissions/:viewpoint"
            render={() => (
              <AccessRoute module={ResourceTypes.Manager}>
                <PermissionPage />
              </AccessRoute>
            )}
          />
          <Route
            path="/organizations/:orgId/variables"
            render={() => (
              <AccessRoute module={ResourceTypes.Manager}>
                <VariablePage />
              </AccessRoute>
            )}
          />
          <Route
            path="/organizations/:orgId/orgSettings"
            render={() => (
              <AccessRoute module={ResourceTypes.Manager}>
                <OrgSettingPage />
              </AccessRoute>
            )}
          />
          <Route path="*" component={NotFoundPage} />
        </Switch>
      )}
    </AppContainer>
  );
}
Example #13
Source File: index.tsx    From datart with Apache License 2.0 4 votes vote down vote up
Sidebar = memo(() => {
  const matchScheduleDetail = useRouteMatch<{
    scheduleId: string;
  }>('/organizations/:orgId/schedules/:scheduleId');
  const scheduleId = matchScheduleDetail?.params?.scheduleId;
  const orgId = useSelector(selectOrgId);
  const list = useSelector(selectSchedules);
  const archived = useSelector(selectArchived);
  const allowCreate = useAccess(allowCreateSchedule());
  const t = useI18NPrefix('main.pages.schedulePage.sidebar.index');
  const { filteredData: scheduleList, debouncedSearch: listSearch } =
    useDebouncedSearch(list, (keywords, d) =>
      d.name.toLowerCase().includes(keywords.toLowerCase()),
    );
  const { filteredData: archivedList, debouncedSearch: archivedSearch } =
    useDebouncedSearch(archived, (keywords, d) =>
      d.name.toLowerCase().includes(keywords.toLowerCase()),
    );

  const { toDetails } = useToScheduleDetails();
  const toAdd = useCallback(() => {
    toDetails(orgId, 'add');
  }, [toDetails, orgId]);

  const moreMenuClick = useCallback((key, _, onNext) => {
    switch (key) {
      case 'recycle':
        onNext();
        break;
    }
  }, []);

  const titles = useMemo(
    () => [
      {
        key: 'list',
        title: t('scheduledTaskList'),
        search: true,
        onSearch: listSearch,
        ...allowCreate({
          add: {
            items: [{ key: 'add', text: t('newTimedTask') }],
            callback: toAdd,
          },
        }),
        more: {
          items: [
            {
              key: 'recycle',
              text: t('recycle'),
              prefix: <DeleteOutlined className="icon" />,
            },
          ],
          callback: moreMenuClick,
        },
      },
      {
        key: 'recycle',
        title: t('recycle'),
        back: true,
        search: true,
        onSearch: archivedSearch,
      },
    ],
    [toAdd, moreMenuClick, listSearch, archivedSearch, allowCreate, t],
  );

  return (
    <Wrapper defaultActiveKey="list">
      <ListPane key="list">
        <ListTitle {...titles[0]} />
        <ScheduleList
          orgId={orgId}
          scheduleId={scheduleId}
          list={scheduleList}
        />
      </ListPane>
      <ListPane key="recycle">
        <ListTitle {...titles[1]} />
        <Recycle scheduleId={scheduleId} list={archivedList} />
      </ListPane>
    </Wrapper>
  );
})
Example #14
Source File: index.tsx    From datart with Apache License 2.0 4 votes vote down vote up
Sidebar = memo(
  ({
    width,
    isDragging,
    i18nPrefix,
    sliderVisible,
    handleSliderVisible,
  }: SidebarProps) => {
    const [selectedKey, setSelectedKey] = useState('folder');
    const vizs = useSelector(selectVizs);
    const storyboards = useSelector(selectStoryboards);

    const matchDetail = useRouteMatch<{ vizId: string }>(
      '/organizations/:orgId/vizs/:vizId',
    );
    const vizId = matchDetail?.params.vizId;
    const t = useI18NPrefix(i18nPrefix);
    const selectedFolderId = useMemo(() => {
      if (vizId && vizs) {
        const viz = vizs.find(({ relId }) => relId === vizId);
        return viz && viz.id;
      }
    }, [vizId, vizs]);

    useEffect(() => {
      if (vizId) {
        const viz =
          vizs.find(({ relId }) => relId === vizId) ||
          storyboards.find(({ id }) => id === vizId);
        if (viz) {
          setSelectedKey((viz as Folder).relType ? 'folder' : 'presentation');
        }
      }
    }, [vizId, storyboards, vizs]); // just switch when vizId changed

    const listTitles = useMemo(
      () => [
        { key: 'folder', icon: <FolderAddFilled />, text: t('folder') },
        {
          key: 'presentation',
          icon: <FundProjectionScreenOutlined />,
          text: t('presentation'),
        },
      ],
      [t],
    );

    const switchSelect = useCallback(key => {
      setSelectedKey(key);
    }, []);

    return (
      <Wrapper
        sliderVisible={sliderVisible}
        className={sliderVisible ? 'close' : ''}
        isDragging={isDragging}
        width={width}
      >
        {sliderVisible ? (
          <MenuUnfoldOutlined className="menuUnfoldOutlined" />
        ) : (
          ''
        )}
        <ListSwitch
          titles={listTitles}
          selectedKey={selectedKey}
          onSelect={switchSelect}
        />
        <Folders
          sliderVisible={sliderVisible}
          handleSliderVisible={handleSliderVisible}
          selectedId={selectedFolderId}
          i18nPrefix={i18nPrefix}
          className={classnames({ hidden: selectedKey !== 'folder' })}
        />
        <Storyboards
          sliderVisible={sliderVisible}
          handleSliderVisible={handleSliderVisible}
          selectedId={vizId}
          className={classnames({ hidden: selectedKey !== 'presentation' })}
          i18nPrefix={i18nPrefix}
        />
      </Wrapper>
    );
  },
)