Skip to content
Snippets Groups Projects
Unverified Commit 51a20b15 authored by Nemanja Glumac's avatar Nemanja Glumac Committed by GitHub
Browse files

SQL in a sidebar prep: `NativeQueryPreview` component (#40268)

* Export named `NativeCodePanel`

* Export named `NativeQueryModal`

* Rename `NativeQueryModal` to `NativeQueryPreview`

* Do not use styled components in the `NativeQueryPreview`
parent 41c9c501
No related branches found
No related tags found
No related merge requests found
Showing
with 116 additions and 150 deletions
......@@ -12,7 +12,7 @@ import type Question from "metabase-lib/v1/Question";
import type { NativeQueryForm } from "metabase-types/api";
import type { QueryBuilderUIControls, State } from "metabase-types/store";
import NativeQueryModal, { useNativeQuery } from "../NativeQueryModal";
import { NativeQueryPreview, useNativeQuery } from "../NativeQueryPreview";
import { createDatasetQuery } from "./utils";
......@@ -62,7 +62,7 @@ const ConvertQueryModal = ({
}, [question, query, onUpdateQuestion, onSetUIControls, onClose]);
return (
<NativeQueryModal
<NativeQueryPreview
title={MODAL_TITLE[engineType]}
query={query}
error={error}
......@@ -74,7 +74,7 @@ const ConvertQueryModal = ({
{BUTTON_TITLE[engineType]}
</Button>
)}
</NativeQueryModal>
</NativeQueryPreview>
);
};
......
......@@ -17,7 +17,7 @@ interface NativeCodePanelProps {
isCopyEnabled?: boolean;
}
const NativeCodePanel = ({
export const NativeCodePanel = ({
value,
isHighlighted,
isCopyEnabled,
......@@ -57,6 +57,3 @@ const useCopyButton = (value: string) => {
return { isCopied, handleCopy };
};
// eslint-disable-next-line import/no-default-export -- deprecated usage
export default NativeCodePanel;
// eslint-disable-next-line import/no-default-export -- deprecated usage
export { default } from "./NativeCodePanel";
export { NativeCodePanel } from "./NativeCodePanel";
import styled from "@emotion/styled";
import IconButtonWrapper from "metabase/components/IconButtonWrapper";
import LoadingSpinner from "metabase/components/LoadingSpinner";
import { color } from "metabase/lib/colors";
import { Icon } from "metabase/ui";
export const ModalRoot = styled.div`
display: flex;
flex-direction: column;
padding: 2rem;
min-width: 40rem;
max-width: 85vw;
min-height: 20rem;
max-height: 90vh;
`;
export const ModalHeader = styled.div`
display: flex;
align-items: center;
margin-bottom: 1.5rem;
`;
interface ModalBodyProps {
isCentered?: boolean;
}
export const ModalBody = styled.div<ModalBodyProps>`
display: flex;
flex: 1 1 auto;
flex-direction: column;
justify-content: ${props => props.isCentered && "center"};
align-items: ${props => props.isCentered && "center"};
min-height: 0;
`;
export const ModalFooter = styled.div`
display: flex;
justify-content: end;
margin-top: 1.5rem;
`;
export const ModalTitle = styled.div`
flex: 1 1 auto;
color: ${color("text-dark")};
font-size: 1.25rem;
line-height: 1.5rem;
font-weight: bold;
`;
export const ModalWarningIcon = styled(Icon)`
flex: 0 0 auto;
color: ${color("error")};
width: 1rem;
height: 1rem;
margin-right: 0.75rem;
`;
export const ModalCloseButton = styled(IconButtonWrapper)`
flex: 0 0 auto;
margin-left: 1rem;
`;
export const ModalCloseIcon = styled(Icon)`
color: ${color("text-light")};
`;
export const ModalLoadingSpinner = styled(LoadingSpinner)`
color: ${color("brand")};
`;
export const ModalDivider = styled.div`
border-top: 1px solid ${color("border")};
margin-bottom: 1.5rem;
`;
import type { ReactNode } from "react";
import { t } from "ttag";
import NativeCodePanel from "../NativeCodePanel";
import {
ModalBody,
ModalCloseButton,
ModalCloseIcon,
ModalDivider,
ModalFooter,
ModalHeader,
ModalLoadingSpinner,
ModalRoot,
ModalTitle,
ModalWarningIcon,
} from "./NativeQueryModal.styled";
interface NativeQueryModalProps {
title: string;
query?: string;
error?: string;
isLoading?: boolean;
children?: ReactNode;
onClose?: () => void;
}
const NativeQueryModal = ({
title,
query,
error,
isLoading,
children,
onClose,
}: NativeQueryModalProps): JSX.Element => {
return (
<ModalRoot>
<ModalHeader>
{error && <ModalWarningIcon name="warning" />}
<ModalTitle>
{error ? t`An error occurred in your query` : title}
</ModalTitle>
<ModalCloseButton>
<ModalCloseIcon name="close" onClick={onClose} />
</ModalCloseButton>
</ModalHeader>
{error && <ModalDivider />}
<ModalBody isCentered={isLoading}>
{isLoading ? (
<ModalLoadingSpinner />
) : error ? (
<NativeCodePanel value={error} isHighlighted />
) : query ? (
<NativeCodePanel value={query} isCopyEnabled />
) : null}
</ModalBody>
{children && <ModalFooter>{children}</ModalFooter>}
</ModalRoot>
);
};
// eslint-disable-next-line import/no-default-export -- deprecated usage
export default NativeQueryModal;
import type { ReactNode } from "react";
import { t } from "ttag";
import { color } from "metabase/lib/colors";
import { rem, Flex, Box, Icon, Loader } from "metabase/ui";
import { NativeCodePanel } from "../NativeCodePanel";
interface NativeQueryPreviewProps {
title: string;
query?: string;
error?: string;
isLoading?: boolean;
children?: ReactNode;
onClose?: () => void;
}
const Header = ({ children }: { children: ReactNode }) => (
<Flex align="center" mb="1.5rem">
{children}
</Flex>
);
const ModalWarningIcon = () => (
<Icon
name="warning"
size="1rem"
color={color("error")}
style={{ flex: "0 0 auto", marginRight: `${rem(12)}` }}
/>
);
const Title = ({ children }: { children: string }) => (
<Box
c={color("text-dark")}
fz={rem(20)}
lh={rem(24)}
fw="bold"
style={{ flex: "1 1 auto" }}
>
{children}
</Box>
);
const CloseButton = ({ onClose }: Pick<NativeQueryPreviewProps, "onClose">) => (
<Flex
align="center"
justify="center"
style={{ borderRadius: `${rem(6)}`, cursor: "pointer" }}
>
<Icon name="close" onClick={onClose} color={color("text-light")} />
</Flex>
);
const Divider = () => (
<Box mb="lg" style={{ borderTop: `1px solid ${color("border")}` }}></Box>
);
const Footer = ({ children }: { children: ReactNode }) => (
<Flex justify="end" mt="lg">
{children}
</Flex>
);
export const NativeQueryPreview = ({
title,
query,
error,
isLoading,
children,
onClose,
}: NativeQueryPreviewProps): JSX.Element => {
return (
<Flex
direction="column"
p="xl"
miw={rem(640)}
maw={rem(1360)}
mih={rem(320)}
mah={rem(1440)}
>
<Header>
{error && <ModalWarningIcon />}
<Title>{error ? t`An error occurred in your query` : title}</Title>
<CloseButton onClose={onClose} />
</Header>
{error && <Divider />}
<Flex
direction="column"
justify={isLoading ? "center" : undefined}
align={isLoading ? "center" : undefined}
mih={0}
style={{ flex: "1 1 auto" }}
>
{isLoading ? (
<Loader c={color("brand")} />
) : error ? (
<NativeCodePanel value={error} isHighlighted />
) : query ? (
<NativeCodePanel value={query} isCopyEnabled />
) : null}
</Flex>
{children && <Footer>{children}</Footer>}
</Flex>
);
};
// eslint-disable-next-line import/no-default-export -- deprecated usage
export { default } from "./NativeQueryModal";
export { NativeQueryPreview } from "./NativeQueryPreview";
export { useNativeQuery } from "./use-native-query";
......@@ -10,7 +10,7 @@ import {
} from "metabase/query_builder/selectors";
import { getShowMetabaseLinks } from "metabase/selectors/whitelabel";
import NativeQueryModal, { useNativeQuery } from "../NativeQueryModal";
import { NativeQueryPreview, useNativeQuery } from "../NativeQueryPreview";
import { ModalExternalLink } from "./PreviewQueryModal.styled";
......@@ -32,7 +32,7 @@ export const PreviewQueryModal = ({
const showMetabaseLinks = useSelector(getShowMetabaseLinks);
return (
<NativeQueryModal
<NativeQueryPreview
title={t`Query preview`}
query={query}
error={error}
......@@ -44,6 +44,6 @@ export const PreviewQueryModal = ({
{t`Learn how to debug SQL errors`}
</ModalExternalLink>
)}
</NativeQueryModal>
</NativeQueryPreview>
);
};
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment