PromucFlow_constructor/app/client/src/pages/Editor/WidgetSidebar.tsx

205 lines
5.9 KiB
TypeScript
Raw Normal View History

import React, { useRef, useEffect, useState } from "react";
import { useSelector } from "react-redux";
2019-10-18 08:16:26 +00:00
import WidgetCard from "./WidgetCard";
import styled from "styled-components";
2019-11-25 05:07:27 +00:00
import { WidgetCardProps } from "widgets/BaseWidget";
import {
getCurrentApplicationId,
getCurrentPageId,
getWidgetCards,
} from "selectors/editorSelectors";
import { getColorWithOpacity } from "constants/DefaultTheme";
import { IPanelProps, Icon, Classes } from "@blueprintjs/core";
import { Colors } from "constants/Colors";
import ExplorerSearch from "./Explorer/ExplorerSearch";
import { debounce } from "lodash";
import produce from "immer";
import { createMessage, WIDGET_SIDEBAR_CAPTION } from "constants/messages";
2020-12-30 07:31:20 +00:00
import Boxed from "components/editorComponents/Onboarding/Boxed";
import { OnboardingStep } from "constants/OnboardingConstants";
import { getCurrentStep, getCurrentSubStep } from "sagas/OnboardingSagas";
import { BUILDER_PAGE_URL } from "constants/routes";
import OnboardingIndicator from "components/editorComponents/Onboarding/Indicator";
2019-10-18 08:16:26 +00:00
const MainWrapper = styled.div`
text-transform: capitalize;
padding: 10px 10px 20px 10px;
height: 100%;
overflow-y: auto;
2020-12-24 04:32:25 +00:00
scrollbar-color: ${(props) => props.theme.colors.paneCard}
${(props) => props.theme.colors.paneBG};
scrollbar-width: thin;
&::-webkit-scrollbar {
width: 8px;
}
&::-webkit-scrollbar-track {
box-shadow: inset 0 0 6px
2020-12-24 04:32:25 +00:00
${(props) => getColorWithOpacity(props.theme.colors.paneBG, 0.3)};
}
&::-webkit-scrollbar-thumb {
2020-12-24 04:32:25 +00:00
background-color: ${(props) => props.theme.colors.paneCard};
outline: 1px solid ${(props) => props.theme.paneText};
border-radius: ${(props) => props.theme.radii[1]}px;
}
2019-10-18 08:16:26 +00:00
`;
const CardsWrapper = styled.div`
display: grid;
grid-template-columns: 1fr 1fr 1fr;
2020-12-24 04:32:25 +00:00
grid-gap: ${(props) => props.theme.spaces[1]}px;
2019-10-18 08:16:26 +00:00
justify-items: stretch;
align-items: stretch;
`;
const CloseIcon = styled(Icon)`
&&.${Classes.ICON} {
cursor: pointer;
display: flex;
justify-content: center;
opacity: 0.6;
&:hover {
opacity: 1;
}
}
`;
const Header = styled.div`
display: grid;
grid-template-columns: 7fr 1fr;
`;
const Info = styled.div`
display: flex;
flex-direction: column;
justify-content: center;
align-items: space-around;
text-transform: none;
h4 {
margin-top: 0px;
}
p {
opacity: 0.6;
}
`;
function WidgetSidebar(props: IPanelProps) {
const cards = useSelector(getWidgetCards);
const [filteredCards, setFilteredCards] = useState(cards);
const searchInputRef = useRef<HTMLInputElement | null>(null);
const filterCards = (keyword: string) => {
let filteredCards = cards;
if (keyword.trim().length > 0) {
2020-12-24 04:32:25 +00:00
filteredCards = produce(cards, (draft) => {
cards.forEach((card, index) => {
if (card.widgetCardName.toLowerCase().indexOf(keyword) === -1) {
delete draft[index];
}
});
});
}
setFilteredCards(filteredCards);
};
const clearSearchInput = () => {
if (searchInputRef.current) {
searchInputRef.current.value = "";
}
filterCards("");
};
// For onboarding
const currentStep = useSelector(getCurrentStep);
const currentSubStep = useSelector(getCurrentSubStep);
const applicationId = useSelector(getCurrentApplicationId);
const pageId = useSelector(getCurrentPageId);
const onCanvas =
BUILDER_PAGE_URL(applicationId, pageId) === window.location.pathname;
useEffect(() => {
if (currentStep === OnboardingStep.DEPLOY && !onCanvas) {
props.closePanel();
}
}, [currentStep, onCanvas]);
const search = debounce((e: any) => {
filterCards(e.target.value.toLowerCase());
}, 300);
useEffect(() => {
const el: HTMLInputElement | null = searchInputRef.current;
el?.addEventListener("keydown", search);
el?.addEventListener("cleared", search);
return () => {
el?.removeEventListener("keydown", search);
el?.removeEventListener("cleared", search);
};
}, [searchInputRef, search]);
const showTableWidget = currentStep >= OnboardingStep.RUN_QUERY_SUCCESS;
const showInputWidget = currentStep >= OnboardingStep.ADD_INPUT_WIDGET;
return (
<>
<Boxed step={OnboardingStep.DEPLOY}>
<ExplorerSearch
autoFocus
clear={clearSearchInput}
placeholder="Search widgets..."
ref={searchInputRef}
/>
</Boxed>
<MainWrapper>
<Header>
<Info>
<p>{createMessage(WIDGET_SIDEBAR_CAPTION)}</p>
</Info>
<CloseIcon
className="t--close-widgets-sidebar"
color={Colors.WHITE}
icon="cross"
iconSize={16}
onClick={props.closePanel}
/>
</Header>
<CardsWrapper>
{filteredCards.map((card: WidgetCardProps) => (
2020-12-30 07:31:20 +00:00
<Boxed
key={card.key}
show={
(card.type === "TABLE_WIDGET" && showTableWidget) ||
(card.type === "INPUT_WIDGET" && showInputWidget)
}
step={OnboardingStep.DEPLOY}
2020-12-30 07:31:20 +00:00
>
<OnboardingIndicator
className="onboarding-widget-menu"
hasButton={false}
show={
(card.type === "TABLE_WIDGET" &&
currentStep === OnboardingStep.RUN_QUERY_SUCCESS) ||
(card.type === "INPUT_WIDGET" &&
currentSubStep === 0 &&
currentStep === OnboardingStep.ADD_INPUT_WIDGET)
}
step={
OnboardingStep.RUN_QUERY_SUCCESS ||
OnboardingStep.ADD_INPUT_WIDGET
}
width={100}
>
<WidgetCard details={card} />
</OnboardingIndicator>
2020-12-30 07:31:20 +00:00
</Boxed>
))}
</CardsWrapper>
</MainWrapper>
</>
);
}
2019-10-18 08:16:26 +00:00
WidgetSidebar.displayName = "WidgetSidebar";
export default WidgetSidebar;