import React, { useEffect } from "react"; import styled from "styled-components"; import * as Sentry from "@sentry/react"; import { Classes, ControlGroup } from "@blueprintjs/core"; import { debounce, noop } from "lodash"; import { Switch, Route, useRouteMatch } from "react-router-dom"; import SearchInput, { SearchVariant } from "components/ads/SearchInput"; import TemplateList from "./TemplateList"; import TemplateView from "./TemplateView"; import Filters from "pages/Templates/Filters"; import { useDispatch, useSelector } from "react-redux"; import { setHeaderMeta } from "actions/themeActions"; import { getAllTemplates, setTemplateSearchQuery, } from "actions/templateActions"; import { getSearchedTemplateList, getTemplateFiltersLength, getTemplateSearchQuery, isFetchingTemplatesSelector, } from "selectors/templatesSelectors"; import { fetchDefaultPlugins } from "actions/pluginActions"; import { editorInitializer } from "utils/EditorUtils"; import { AppState } from "reducers"; import { getIsFetchingApplications, getUserApplicationsOrgsList, } from "selectors/applicationSelectors"; import { getAllApplications } from "actions/applicationActions"; import { getTypographyByKey } from "constants/DefaultTheme"; import { Colors } from "constants/Colors"; import { createMessage, SEARCH_TEMPLATES } from "@appsmith/constants/messages"; const SentryRoute = Sentry.withSentryRouting(Route); const PageWrapper = styled.div` margin-top: ${(props) => props.theme.homePage.header}px; display: flex; height: calc(100vh - ${(props) => props.theme.homePage.header}px); `; export const TemplateListWrapper = styled.div` padding-top: ${(props) => props.theme.spaces[11]}px; width: calc(100% - ${(props) => props.theme.homePage.sidebar}px); height: calc(100vh - ${(props) => props.theme.headerHeight}); overflow: auto; `; export const ResultsCount = styled.div` ${(props) => getTypographyByKey(props, "h1")} color: ${Colors.CODE_GRAY}; margin-top: ${(props) => props.theme.spaces[5]}px; margin-left: ${(props) => props.theme.spaces[12]}px; padding-bottom: ${(props) => props.theme.spaces[11]}px; `; const Loader = styled(TemplateListWrapper)` height: 100vh; .results-count { height: 20px; width: 100px; } `; const LoadingTemplateList = styled.div` margin-top: ${(props) => props.theme.spaces[11]}px; // 200 is to have some space at the bottom height: calc(100% - 200px); margin-right: ${(props) => props.theme.spaces[9]}px; margin-left: ${(props) => props.theme.spaces[12] + 2}px; `; const SearchWrapper = styled.div` margin-left: ${(props) => props.theme.spaces[11]}px; `; function TemplateRoutes() { const { path } = useRouteMatch(); const dispatch = useDispatch(); const organizationListLength = useSelector( (state: AppState) => getUserApplicationsOrgsList(state).length, ); const pluginListLength = useSelector( (state: AppState) => state.entities.plugins.defaultPluginList.length, ); const templatesCount = useSelector( (state: AppState) => state.ui.templates.templates.length, ); useEffect(() => { dispatch(setHeaderMeta(true, true)); // Generate the widget config list editorInitializer(); }, []); useEffect(() => { if (!templatesCount) { dispatch(getAllTemplates()); } }, [templatesCount]); useEffect(() => { if (!organizationListLength) { dispatch(getAllApplications()); } }, [organizationListLength]); useEffect(() => { if (!pluginListLength) { dispatch(fetchDefaultPlugins()); } }, [pluginListLength]); return ( ); } function TemplateListLoader() { return ( ); } function Templates() { const templates = useSelector(getSearchedTemplateList); const templateSearchQuery = useSelector(getTemplateSearchQuery); const isFetchingApplications = useSelector(getIsFetchingApplications); const isFetchingTemplates = useSelector(isFetchingTemplatesSelector); const filterCount = useSelector(getTemplateFiltersLength); const dispatch = useDispatch(); let resultsText = templates.length > 1 ? `Showing all ${templates.length} templates` : templates.length === 1 ? "Showing 1 template" : "No templates to show"; if (templates.length) { resultsText += filterCount > 1 ? ` matching ${filterCount} filters` : filterCount === 1 ? " matching 1 filter" : ""; } const isLoading = isFetchingApplications || isFetchingTemplates; const onChange = (query: string) => { dispatch(setTemplateSearchQuery(query)); }; const debouncedOnChange = debounce(onChange, 250, { maxWait: 1000 }); return ( {isLoading ? ( ) : ( <> {resultsText} )} ); } export default TemplateRoutes;