mirror of
https://github.com/rowyio/rowy.git
synced 2025-12-28 16:06:41 +01:00
fix wizards styling
This commit is contained in:
@@ -19,7 +19,7 @@
|
||||
"@mui/material": "^5.0.0-rc.1",
|
||||
"@mui/styles": "^5.0.0-rc.1",
|
||||
"@rowy/form-builder": "^0.1.1",
|
||||
"@rowy/multiselect": "^0.1.4",
|
||||
"@rowy/multiselect": "^0.1.5",
|
||||
"@tinymce/tinymce-react": "^3.4.0",
|
||||
"algoliasearch": "^4.8.6",
|
||||
"ansi-to-react": "^6.1.5",
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
DialogContentProps,
|
||||
} from "@mui/material";
|
||||
|
||||
const MemoizedDialogContent = memo(function MemoizedDialogContent({
|
||||
const MemoizedDialogContent = memo(function MemoizedDialogContent_({
|
||||
setRef,
|
||||
...props
|
||||
}: DialogContentProps & { setRef: any }) {
|
||||
|
||||
@@ -18,7 +18,9 @@ const useStyles = makeStyles((theme) =>
|
||||
listbox: {},
|
||||
option: {
|
||||
"$listbox &": {
|
||||
padding: theme.spacing(0, 2),
|
||||
padding: 0,
|
||||
paddingLeft: "0 !important",
|
||||
borderRadius: 0,
|
||||
marginBottom: -1,
|
||||
|
||||
"&::after": { content: "none" },
|
||||
|
||||
@@ -22,7 +22,7 @@ const useStyles = makeStyles((theme) =>
|
||||
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
padding: theme.spacing(0, 1.5),
|
||||
padding: theme.spacing(0, 1.25),
|
||||
|
||||
...theme.typography.body2,
|
||||
fontSize: "0.75rem",
|
||||
@@ -37,7 +37,7 @@ const useStyles = makeStyles((theme) =>
|
||||
|
||||
value: {
|
||||
width: "100%",
|
||||
maxHeight: 43,
|
||||
height: 43,
|
||||
|
||||
display: "flex",
|
||||
justifyContent: "flex-start",
|
||||
|
||||
@@ -15,7 +15,7 @@ const useStyles = makeStyles((theme) =>
|
||||
border: `1px solid ${theme.palette.divider}`,
|
||||
backgroundColor: theme.palette.background.default,
|
||||
|
||||
padding: theme.spacing(0, 1, 0, 1.5),
|
||||
padding: theme.spacing(0, 1),
|
||||
|
||||
color: theme.palette.text.secondary,
|
||||
"&:hover": { color: theme.palette.text.primary },
|
||||
@@ -50,6 +50,7 @@ const useStyles = makeStyles((theme) =>
|
||||
overflow: "hidden",
|
||||
},
|
||||
columnName: {
|
||||
fontWeight: theme.typography.fontWeightMedium,
|
||||
lineHeight: "44px",
|
||||
display: "block",
|
||||
|
||||
@@ -94,7 +95,7 @@ export default function Column({
|
||||
<Typography
|
||||
component={Grid}
|
||||
item
|
||||
variant="subtitle2"
|
||||
variant="caption"
|
||||
noWrap
|
||||
className={classes.columnName}
|
||||
>
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
import React from "react";
|
||||
import clsx from "clsx";
|
||||
|
||||
import { makeStyles, createStyles } from "@mui/styles";
|
||||
|
||||
const useStyles = makeStyles((theme) =>
|
||||
createStyles({
|
||||
listWrapper: {
|
||||
position: "relative",
|
||||
|
||||
"&::after": {
|
||||
content: '""',
|
||||
display: "block",
|
||||
pointerEvents: "none",
|
||||
|
||||
position: "absolute",
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
|
||||
height: theme.spacing(3),
|
||||
backgroundImage: `linear-gradient(to top, ${theme.palette.background.paper}, transparent)`,
|
||||
},
|
||||
},
|
||||
list: {
|
||||
listStyleType: "none",
|
||||
margin: 0,
|
||||
padding: theme.spacing(1.5, 0, 3),
|
||||
|
||||
height: 400,
|
||||
overflowY: "overlay" as any,
|
||||
|
||||
"& li": { margin: theme.spacing(0.5, 0) },
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
export interface IFadeListProps {
|
||||
children?: React.ReactNode | React.ElementType[];
|
||||
classes?: Partial<ReturnType<typeof useStyles>>;
|
||||
}
|
||||
|
||||
export const FadeList = React.forwardRef<HTMLDivElement, IFadeListProps>(
|
||||
function FadeList_({ children, classes: classesProp }, ref) {
|
||||
const classes = useStyles();
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx(classes.listWrapper, classesProp?.listWrapper)}
|
||||
ref={ref}
|
||||
>
|
||||
<ul className={clsx(classes.list, classesProp?.list)}>{children}</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export default FadeList;
|
||||
@@ -18,7 +18,7 @@ import {
|
||||
import ArrowIcon from "@mui/icons-material/ArrowForward";
|
||||
|
||||
import { IStepProps } from ".";
|
||||
import FadeList from "../FadeList";
|
||||
import FadeList from "../ScrollableList";
|
||||
import Column from "../Column";
|
||||
|
||||
import { useProjectContext } from "contexts/ProjectContext";
|
||||
@@ -48,15 +48,15 @@ const useStyles = makeStyles((theme) =>
|
||||
backgroundColor: theme.palette.background.default,
|
||||
border: `1px solid ${theme.palette.divider}`,
|
||||
borderRadius: 0,
|
||||
boxShadow: "none",
|
||||
height: 44,
|
||||
|
||||
...theme.typography.subtitle2,
|
||||
color: theme.palette.text.secondary,
|
||||
transition: theme.transitions.create("color", {
|
||||
duration: theme.transitions.duration.short,
|
||||
}),
|
||||
"&:hover": {
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
boxShadow: "none",
|
||||
},
|
||||
|
||||
"&::before": { content: "none" },
|
||||
@@ -64,16 +64,12 @@ const useStyles = makeStyles((theme) =>
|
||||
},
|
||||
noneSelected: { color: theme.palette.text.disabled },
|
||||
multiSelectInputLabel: {
|
||||
padding: theme.spacing(0, 2),
|
||||
height: 44 - 2,
|
||||
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
},
|
||||
newColumnChip: {
|
||||
marginLeft: theme.spacing(1),
|
||||
marginLeft: theme.spacing(1) + " !important",
|
||||
backgroundColor: theme.palette.action.focus,
|
||||
...theme.typography.overline,
|
||||
pointerEvents: "none",
|
||||
},
|
||||
})
|
||||
@@ -168,13 +164,13 @@ export default function Step1Columns({
|
||||
<Grid container spacing={7}>
|
||||
{!isXs && (
|
||||
<Grid item xs={12} sm={6}>
|
||||
<Typography variant="overline" gutterBottom component="h2">
|
||||
<Typography variant="subtitle2" gutterBottom component="h2">
|
||||
Select Columns ({config.pairs.length} of {csvData.columns.length})
|
||||
</Typography>
|
||||
</Grid>
|
||||
)}
|
||||
<Grid item xs={12} sm={6}>
|
||||
<Typography variant="overline" gutterBottom component="h2">
|
||||
<Typography variant="subtitle2" gutterBottom component="h2">
|
||||
Table Columns
|
||||
</Typography>
|
||||
</Grid>
|
||||
|
||||
@@ -7,7 +7,7 @@ import { Grid, Typography, Divider, ButtonBase } from "@mui/material";
|
||||
import ChevronRightIcon from "@mui/icons-material/ChevronRight";
|
||||
|
||||
import { IStepProps } from ".";
|
||||
import FadeList from "../FadeList";
|
||||
import FadeList from "../ScrollableList";
|
||||
import Column from "../Column";
|
||||
import Cell from "../Cell";
|
||||
import FieldsDropdown from "components/Table/ColumnMenu/FieldsDropdown";
|
||||
@@ -24,10 +24,9 @@ const useStyles = makeStyles((theme) =>
|
||||
textAlign: "left",
|
||||
},
|
||||
|
||||
typeHeading: { margin: theme.spacing(5, 0, 1) },
|
||||
typeHeading: { margin: theme.spacing(52 / 8, 0, 1) },
|
||||
|
||||
previewDivider: { marginBottom: theme.spacing(2) },
|
||||
previewList: { paddingTop: 0 },
|
||||
previewSpacer: { width: theme.spacing(3) },
|
||||
cellContainer: { overflow: "hidden" },
|
||||
})
|
||||
@@ -60,7 +59,7 @@ export default function Step2NewColumns({
|
||||
<div>
|
||||
<Grid container spacing={2} className={classes.typeSelectRow}>
|
||||
<Grid item xs={12} sm={6}>
|
||||
<Typography variant="overline" gutterBottom component="h2">
|
||||
<Typography variant="subtitle2" gutterBottom component="h2">
|
||||
New Table Columns
|
||||
</Typography>
|
||||
<Divider />
|
||||
@@ -87,7 +86,7 @@ export default function Step2NewColumns({
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={6}>
|
||||
<Typography
|
||||
variant="overline"
|
||||
variant="subtitle2"
|
||||
noWrap
|
||||
component="h2"
|
||||
className={classes.typeHeading}
|
||||
@@ -109,13 +108,13 @@ export default function Step2NewColumns({
|
||||
<Grid container spacing={3}>
|
||||
{!isXs && (
|
||||
<Grid item xs={12} sm={6}>
|
||||
<Typography variant="overline" gutterBottom component="h2">
|
||||
<Typography variant="subtitle2" gutterBottom component="h2">
|
||||
Raw Data
|
||||
</Typography>
|
||||
</Grid>
|
||||
)}
|
||||
<Grid item xs={12} sm={6}>
|
||||
<Typography variant="overline" gutterBottom component="h2">
|
||||
<Typography variant="subtitle2" gutterBottom component="h2">
|
||||
Column Preview
|
||||
</Typography>
|
||||
</Grid>
|
||||
@@ -137,7 +136,7 @@ export default function Step2NewColumns({
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<FadeList classes={{ list: classes.previewList }}>
|
||||
<FadeList listSx={{ pt: 0 }}>
|
||||
{rowData.slice(0, 20).map((cell, i) => (
|
||||
<Grid container key={i} wrap="nowrap">
|
||||
{!isXs && (
|
||||
|
||||
@@ -14,35 +14,14 @@ const useStyles = makeStyles((theme) =>
|
||||
createStyles({
|
||||
root: {
|
||||
position: "relative",
|
||||
minHeight: 300,
|
||||
height: "calc(100% - 80px)",
|
||||
},
|
||||
|
||||
"&::after": {
|
||||
content: '""',
|
||||
display: "block",
|
||||
pointerEvents: "none",
|
||||
|
||||
position: "absolute",
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
|
||||
height: theme.spacing(3),
|
||||
backgroundImage: `linear-gradient(to top, ${theme.palette.background.paper}, transparent)`,
|
||||
},
|
||||
|
||||
"&::before": {
|
||||
content: '""',
|
||||
display: "block",
|
||||
pointerEvents: "none",
|
||||
zIndex: 1,
|
||||
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
right: 0,
|
||||
|
||||
width: theme.spacing(3),
|
||||
backgroundImage: `linear-gradient(to left, ${theme.palette.background.paper}, transparent)`,
|
||||
},
|
||||
container: {
|
||||
height: "100%",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
},
|
||||
|
||||
spacer: {
|
||||
@@ -54,7 +33,7 @@ const useStyles = makeStyles((theme) =>
|
||||
header: { overflowX: "hidden" },
|
||||
data: {
|
||||
overflow: "scroll",
|
||||
height: 300,
|
||||
flexGrow: 1,
|
||||
},
|
||||
|
||||
column: {
|
||||
@@ -84,7 +63,7 @@ export default function Step4Preview({ csvData, config }: IStepProps) {
|
||||
return (
|
||||
<div className={classes.root}>
|
||||
<ScrollSync vertical={false} proportional={false}>
|
||||
<div>
|
||||
<div className={classes.container}>
|
||||
<ScrollSyncPane>
|
||||
<Grid container wrap="nowrap" className={classes.header}>
|
||||
{columns.map(({ key, name, type }) => (
|
||||
|
||||
@@ -3,9 +3,14 @@ import { useSnackbar } from "notistack";
|
||||
import _mergeWith from "lodash/mergeWith";
|
||||
import _find from "lodash/find";
|
||||
|
||||
import { useTheme, useMediaQuery, Typography, Link } from "@mui/material";
|
||||
import Alert from "@mui/material/Alert";
|
||||
import AlertTitle from "@mui/material/AlertTitle";
|
||||
import {
|
||||
useTheme,
|
||||
useMediaQuery,
|
||||
Typography,
|
||||
Link,
|
||||
Alert,
|
||||
AlertTitle,
|
||||
} from "@mui/material";
|
||||
|
||||
import WizardDialog from "../WizardDialog";
|
||||
import Step1Columns from "./Step1Columns";
|
||||
@@ -116,15 +121,16 @@ export default function ImportCsvWizard({
|
||||
</Typography>
|
||||
<Alert severity="warning">
|
||||
<AlertTitle>Importing dates?</AlertTitle>
|
||||
Make sure your dates are in UTC time and{" "}
|
||||
Make sure they’re in UTC time and{" "}
|
||||
<Link
|
||||
href="https://date-fns.org/v2.16.1/docs/parseJSON"
|
||||
rel="noopener"
|
||||
target="_blank"
|
||||
color="inherit"
|
||||
>
|
||||
a supported format
|
||||
</Link>
|
||||
. If they’re not, you will need to re-import your CSV data.
|
||||
. If they’re not, you’ll need to re-import your CSV data.
|
||||
</Alert>
|
||||
</>
|
||||
),
|
||||
@@ -142,7 +148,7 @@ export default function ImportCsvWizard({
|
||||
config.newColumns.length > 0 && {
|
||||
title: "Set Column Types",
|
||||
description:
|
||||
"Set the type of each column to display your data correctly. Some column types have been suggested based off your data.",
|
||||
"Set the type of each column to display your data correctly. Some column types have been suggested based on your data.",
|
||||
content: (
|
||||
<Step2NewColumns
|
||||
csvData={csvData}
|
||||
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
import DragHandleIcon from "@mui/icons-material/DragHandle";
|
||||
|
||||
import { IStepProps } from ".";
|
||||
import FadeList from "../FadeList";
|
||||
import FadeList from "../ScrollableList";
|
||||
import Column from "../Column";
|
||||
import EmptyState from "components/EmptyState";
|
||||
import AddColumnIcon from "assets/icons/AddColumn";
|
||||
@@ -107,7 +107,7 @@ export default function Step1Columns({ config, setConfig }: IStepProps) {
|
||||
return (
|
||||
<Grid container spacing={3}>
|
||||
<Grid item xs={12} sm={6}>
|
||||
<Typography variant="overline" gutterBottom component="h2">
|
||||
<Typography variant="subtitle2" gutterBottom component="h2">
|
||||
Select Columns ({selectedFields.length} of {allFields.length})
|
||||
</Typography>
|
||||
<Divider />
|
||||
@@ -126,18 +126,14 @@ export default function Step1Columns({ config, setConfig }: IStepProps) {
|
||||
color="default"
|
||||
/>
|
||||
}
|
||||
label={
|
||||
<Typography variant="subtitle2" color="textSecondary">
|
||||
Select all
|
||||
</Typography>
|
||||
}
|
||||
label="Select all"
|
||||
classes={{
|
||||
root: classes.formControlLabel,
|
||||
label: classes.columnLabel,
|
||||
}}
|
||||
style={{ height: 44 }}
|
||||
/>
|
||||
</li>
|
||||
<li className={classes.spacer} />
|
||||
|
||||
{allFields.map((field) => (
|
||||
<li key={field}>
|
||||
@@ -162,7 +158,7 @@ export default function Step1Columns({ config, setConfig }: IStepProps) {
|
||||
</FadeList>
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={6}>
|
||||
<Typography variant="overline" gutterBottom component="h2">
|
||||
<Typography variant="subtitle2" gutterBottom component="h2">
|
||||
Sort Table Columns
|
||||
</Typography>
|
||||
<Divider />
|
||||
|
||||
@@ -14,7 +14,7 @@ import EditIcon from "@mui/icons-material/Edit";
|
||||
import DoneIcon from "@mui/icons-material/Done";
|
||||
|
||||
import { IStepProps } from ".";
|
||||
import FadeList from "../FadeList";
|
||||
import FadeList from "../ScrollableList";
|
||||
import Column from "../Column";
|
||||
|
||||
const useStyles = makeStyles((theme) =>
|
||||
@@ -65,13 +65,13 @@ export default function Step2Rename({
|
||||
<Grid container spacing={3}>
|
||||
{!isXs && (
|
||||
<Grid item xs={12} sm={6}>
|
||||
<Typography variant="overline" gutterBottom component="h2">
|
||||
<Typography variant="subtitle2" gutterBottom component="h2">
|
||||
Field Names
|
||||
</Typography>
|
||||
</Grid>
|
||||
)}
|
||||
<Grid item xs={12} sm={6}>
|
||||
<Typography variant="overline" gutterBottom component="h2">
|
||||
<Typography variant="subtitle2" gutterBottom component="h2">
|
||||
Set Column Names
|
||||
</Typography>
|
||||
</Grid>
|
||||
|
||||
@@ -5,7 +5,7 @@ import { Grid, Typography, Divider, ButtonBase } from "@mui/material";
|
||||
import ChevronRightIcon from "@mui/icons-material/ChevronRight";
|
||||
|
||||
import { IStepProps } from ".";
|
||||
import FadeList from "../FadeList";
|
||||
import FadeList from "../ScrollableList";
|
||||
import Column from "../Column";
|
||||
import Cell from "../Cell";
|
||||
import FieldsDropdown from "components/Table/ColumnMenu/FieldsDropdown";
|
||||
@@ -23,10 +23,9 @@ const useStyles = makeStyles((theme) =>
|
||||
textAlign: "left",
|
||||
},
|
||||
|
||||
typeHeading: { margin: theme.spacing(5, 0, 1) },
|
||||
typeHeading: { margin: theme.spacing(52 / 8, 0, 1) },
|
||||
|
||||
previewDivider: { marginBottom: theme.spacing(2) },
|
||||
previewList: { paddingTop: 0 },
|
||||
previewSpacer: { width: theme.spacing(3) },
|
||||
cellContainer: { overflow: "hidden" },
|
||||
})
|
||||
@@ -45,7 +44,7 @@ export default function Step3Types({ config, updateConfig, isXs }: IStepProps) {
|
||||
<div>
|
||||
<Grid container spacing={2} className={classes.typeSelectRow}>
|
||||
<Grid item xs={12} sm={6}>
|
||||
<Typography variant="overline" gutterBottom component="h2">
|
||||
<Typography variant="subtitle2" gutterBottom component="h2">
|
||||
Table Columns
|
||||
</Typography>
|
||||
<Divider />
|
||||
@@ -74,7 +73,7 @@ export default function Step3Types({ config, updateConfig, isXs }: IStepProps) {
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={6}>
|
||||
<Typography
|
||||
variant="overline"
|
||||
variant="subtitle2"
|
||||
noWrap
|
||||
component="h2"
|
||||
className={classes.typeHeading}
|
||||
@@ -94,13 +93,13 @@ export default function Step3Types({ config, updateConfig, isXs }: IStepProps) {
|
||||
<Grid container spacing={3}>
|
||||
{!isXs && (
|
||||
<Grid item xs={12} sm={6}>
|
||||
<Typography variant="overline" gutterBottom component="h2">
|
||||
<Typography variant="subtitle2" gutterBottom component="h2">
|
||||
Raw Data
|
||||
</Typography>
|
||||
</Grid>
|
||||
)}
|
||||
<Grid item xs={12} sm={6}>
|
||||
<Typography variant="overline" gutterBottom component="h2">
|
||||
<Typography variant="subtitle2" gutterBottom component="h2">
|
||||
Column Preview
|
||||
</Typography>
|
||||
</Grid>
|
||||
@@ -122,7 +121,7 @@ export default function Step3Types({ config, updateConfig, isXs }: IStepProps) {
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<FadeList classes={{ list: classes.previewList }}>
|
||||
<FadeList listSx={{ pt: 0 }}>
|
||||
{tableState!.rows!.slice(0, 20).map((row) => (
|
||||
<Grid container key={row.id} wrap="nowrap">
|
||||
{!isXs && (
|
||||
|
||||
@@ -13,35 +13,14 @@ const useStyles = makeStyles((theme) =>
|
||||
createStyles({
|
||||
root: {
|
||||
position: "relative",
|
||||
minHeight: 300,
|
||||
height: "calc(100% - 80px)",
|
||||
},
|
||||
|
||||
"&::after": {
|
||||
content: '""',
|
||||
display: "block",
|
||||
pointerEvents: "none",
|
||||
|
||||
position: "absolute",
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
|
||||
height: theme.spacing(3),
|
||||
backgroundImage: `linear-gradient(to top, ${theme.palette.background.paper}, transparent)`,
|
||||
},
|
||||
|
||||
"&::before": {
|
||||
content: '""',
|
||||
display: "block",
|
||||
pointerEvents: "none",
|
||||
zIndex: 1,
|
||||
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
right: 0,
|
||||
|
||||
width: theme.spacing(3),
|
||||
backgroundImage: `linear-gradient(to left, ${theme.palette.background.paper}, transparent)`,
|
||||
},
|
||||
container: {
|
||||
height: "100%",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
},
|
||||
|
||||
spacer: {
|
||||
@@ -53,7 +32,7 @@ const useStyles = makeStyles((theme) =>
|
||||
header: { overflowX: "hidden" },
|
||||
data: {
|
||||
overflow: "scroll",
|
||||
height: 300,
|
||||
flexGrow: 1,
|
||||
},
|
||||
|
||||
column: {
|
||||
@@ -73,7 +52,7 @@ export default function Step4Preview({ config }: IStepProps) {
|
||||
return (
|
||||
<div className={classes.root}>
|
||||
<ScrollSync vertical={false} proportional={false}>
|
||||
<div>
|
||||
<div className={classes.container}>
|
||||
<ScrollSyncPane>
|
||||
<Grid container wrap="nowrap" className={classes.header}>
|
||||
{Object.entries(config).map(([field, { name, type }]) => (
|
||||
|
||||
@@ -103,7 +103,7 @@ export default function ImportWizard() {
|
||||
{
|
||||
title: "Set Column Types",
|
||||
description:
|
||||
"Set the type of each column to display your data correctly. Some column types have been suggested based off your data.",
|
||||
"Set the type of each column to display your data correctly. Some column types have been suggested based on your data.",
|
||||
content: (
|
||||
<Step3Types
|
||||
config={config}
|
||||
|
||||
59
src/components/Wizards/ScrollableList.tsx
Normal file
59
src/components/Wizards/ScrollableList.tsx
Normal file
@@ -0,0 +1,59 @@
|
||||
import { memo, ReactNode, ElementType } from "react";
|
||||
import useScrollInfo from "react-element-scroll-hook";
|
||||
|
||||
import { styled, Divider, DividerProps } from "@mui/material";
|
||||
|
||||
const MemoizedList = memo(
|
||||
styled("ul")(({ theme }) => ({
|
||||
listStyleType: "none",
|
||||
margin: 0,
|
||||
padding: theme.spacing(1.5, 0, 3),
|
||||
|
||||
height: 400,
|
||||
overflowY: "auto",
|
||||
|
||||
"& li": { margin: theme.spacing(0.5, 0) },
|
||||
}))
|
||||
);
|
||||
|
||||
export interface IFadeListProps {
|
||||
children?: ReactNode | ElementType[];
|
||||
disableTopDivider?: boolean;
|
||||
disableBottomDivider?: boolean;
|
||||
dividerSx?: DividerProps["sx"];
|
||||
topDividerSx?: DividerProps["sx"];
|
||||
bottomDividerSx?: DividerProps["sx"];
|
||||
listSx?: DividerProps["sx"];
|
||||
}
|
||||
|
||||
export default function FadeList({
|
||||
children,
|
||||
disableTopDivider = true,
|
||||
disableBottomDivider = false,
|
||||
dividerSx,
|
||||
topDividerSx,
|
||||
bottomDividerSx,
|
||||
listSx,
|
||||
}: IFadeListProps) {
|
||||
const [scrollInfo, setRef] = useScrollInfo();
|
||||
|
||||
return (
|
||||
<>
|
||||
{!disableTopDivider &&
|
||||
scrollInfo.y.percentage !== null &&
|
||||
scrollInfo.y.percentage > 0 && (
|
||||
<Divider sx={{ ...dividerSx, ...topDividerSx }} />
|
||||
)}
|
||||
|
||||
<MemoizedList ref={setRef} sx={listSx}>
|
||||
{children}
|
||||
</MemoizedList>
|
||||
|
||||
{!disableBottomDivider &&
|
||||
scrollInfo.y.percentage !== null &&
|
||||
scrollInfo.y.percentage < 1 && (
|
||||
<Divider sx={{ ...dividerSx, ...bottomDividerSx }} />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,142 +1,47 @@
|
||||
import React, { useState } from "react";
|
||||
import clsx from "clsx";
|
||||
import { ReactNode, useState } from "react";
|
||||
|
||||
import { makeStyles, createStyles } from "@mui/styles";
|
||||
import {
|
||||
useTheme,
|
||||
useMediaQuery,
|
||||
Dialog,
|
||||
DialogProps,
|
||||
Stack,
|
||||
DialogTitle,
|
||||
Grid,
|
||||
Typography,
|
||||
IconButton,
|
||||
MobileStepper,
|
||||
DialogContent,
|
||||
DialogActions,
|
||||
Button,
|
||||
Slide,
|
||||
} from "@mui/material";
|
||||
import { alpha } from "@mui/material/styles";
|
||||
import CloseIcon from "@mui/icons-material/Close";
|
||||
import ChevronRightIcon from "@mui/icons-material/ChevronRight";
|
||||
import ChevronLeftIcon from "@mui/icons-material/ChevronLeft";
|
||||
|
||||
import { SlideTransitionMui } from "components/Modal/SlideTransition";
|
||||
|
||||
const useStyles = makeStyles((theme) =>
|
||||
createStyles({
|
||||
root: {
|
||||
"--dialog-spacing": theme.spacing(3),
|
||||
"--dialog-contents-spacing": theme.spacing(3),
|
||||
|
||||
[theme.breakpoints.down("md")]: {
|
||||
"--dialog-spacing": theme.spacing(2),
|
||||
},
|
||||
},
|
||||
|
||||
paper: {
|
||||
userSelect: "none",
|
||||
overflowX: "hidden",
|
||||
|
||||
padding: "var(--dialog-spacing)",
|
||||
paddingBottom: "var(--dialog-contents-spacing)",
|
||||
},
|
||||
|
||||
closeButton: {
|
||||
alignSelf: "flex-end",
|
||||
margin:
|
||||
"calc(var(--dialog-spacing) * -1) calc(var(--dialog-spacing) * -1) 0 0",
|
||||
},
|
||||
|
||||
titleRow: { paddingBottom: "var(--dialog-spacing)" },
|
||||
titleContainer: { padding: 0 },
|
||||
title: {
|
||||
...theme.typography.h5,
|
||||
[theme.breakpoints.down("md")]: theme.typography.h6,
|
||||
},
|
||||
|
||||
stepper: {
|
||||
padding: 0,
|
||||
background: "none",
|
||||
marginRight: theme.spacing(-10 / 8),
|
||||
|
||||
marginBottom: theme.spacing(-0.5),
|
||||
[theme.breakpoints.down("md")]: { marginBottom: theme.spacing(-0.75) },
|
||||
},
|
||||
stepperButton: { padding: theme.spacing(0.5) },
|
||||
|
||||
stepperDot: {
|
||||
margin: theme.spacing(0, 0.5),
|
||||
backgroundColor: theme.palette.primary.main,
|
||||
},
|
||||
stepperDotActive: {
|
||||
margin: theme.spacing(0, 0.5),
|
||||
"& ~ $stepperDot": { backgroundColor: theme.palette.action.disabled },
|
||||
},
|
||||
|
||||
content: {
|
||||
padding: "0 var(--dialog-spacing)",
|
||||
margin: "0 calc(var(--dialog-spacing) * -1)",
|
||||
|
||||
...theme.typography.body1,
|
||||
|
||||
// https://codepen.io/evank/pen/wWbRNO
|
||||
background: `
|
||||
linear-gradient(
|
||||
var(--bg-paper) 50%,
|
||||
${alpha(theme.palette.background.paper, 0)}
|
||||
),
|
||||
linear-gradient(
|
||||
${alpha(theme.palette.background.paper, 0)},
|
||||
var(--bg-paper) 50%
|
||||
) 0 100%,
|
||||
linear-gradient(
|
||||
to top, ${theme.palette.divider} 1px,
|
||||
${alpha(theme.palette.divider, 0)}
|
||||
),
|
||||
linear-gradient(to top,
|
||||
${theme.palette.divider} 1px,
|
||||
${alpha(theme.palette.divider, 0)}
|
||||
) 0 calc(100% - 0.5px)`,
|
||||
backgroundRepeat: "no-repeat",
|
||||
backgroundColor: "var(--bg-paper)",
|
||||
backgroundSize: "100% 2px, 100% 3px, 100% 1px, 100% 1px",
|
||||
backgroundAttachment: "local, local, scroll, scroll",
|
||||
|
||||
"&:last-child": {
|
||||
marginBottom: "calc(var(--dialog-contents-spacing) * -1)",
|
||||
paddingBottom: "var(--dialog-contents-spacing)",
|
||||
},
|
||||
|
||||
"& > * + *": { marginTop: "var(--dialog-contents-spacing)" },
|
||||
},
|
||||
|
||||
actions: {
|
||||
paddingTop: "var(--dialog-contents-spacing)",
|
||||
"& button": { minWidth: 100 },
|
||||
},
|
||||
})
|
||||
);
|
||||
import ScrollableDialogContent from "components/Modal/ScrollableDialogContent";
|
||||
|
||||
export interface IWizardDialogProps extends DialogProps {
|
||||
title: string;
|
||||
steps: {
|
||||
title: string;
|
||||
description?: React.ReactNode;
|
||||
content: React.ReactNode;
|
||||
description?: ReactNode;
|
||||
content: ReactNode;
|
||||
disableNext?: boolean;
|
||||
}[];
|
||||
onFinish: () => void;
|
||||
fullHeight?: boolean;
|
||||
}
|
||||
|
||||
export default function WizardDialog({
|
||||
title,
|
||||
steps,
|
||||
onFinish,
|
||||
fullHeight = true,
|
||||
...props
|
||||
}: IWizardDialogProps) {
|
||||
const classes = useStyles();
|
||||
const theme = useTheme();
|
||||
const isXs = useMediaQuery(theme.breakpoints.down("sm"));
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
|
||||
|
||||
const [step, setStep] = useState(0);
|
||||
const currentStep = steps[step];
|
||||
@@ -148,67 +53,66 @@ export default function WizardDialog({
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
TransitionComponent={SlideTransitionMui}
|
||||
fullWidth
|
||||
fullScreen={isMobile}
|
||||
TransitionComponent={isMobile ? Slide : SlideTransitionMui}
|
||||
TransitionProps={isMobile ? ({ direction: "up" } as any) : undefined}
|
||||
aria-labelledby="wizard-title"
|
||||
aria-describedby="wizard-step-description"
|
||||
fullWidth
|
||||
maxWidth="md"
|
||||
fullScreen={isXs}
|
||||
{...props}
|
||||
classes={{
|
||||
root: clsx(classes.root, props.classes?.root),
|
||||
paper: clsx(classes.paper, props.classes?.paper),
|
||||
...(props.classes ?? {}),
|
||||
}}
|
||||
sx={
|
||||
fullHeight
|
||||
? {
|
||||
...props.sx,
|
||||
"& .MuiDialog-paper": {
|
||||
height: "100%",
|
||||
...props.sx?.["& .MuiDialog-paper"],
|
||||
},
|
||||
}
|
||||
: props.sx
|
||||
}
|
||||
>
|
||||
<IconButton
|
||||
aria-label="Close"
|
||||
onClick={props.onClose as any}
|
||||
className={classes.closeButton}
|
||||
color="secondary"
|
||||
<Stack
|
||||
direction={isMobile ? "column-reverse" : "row"}
|
||||
alignItems={isMobile ? "flex-end" : "flex-start"}
|
||||
>
|
||||
<CloseIcon />
|
||||
</IconButton>
|
||||
<DialogTitle
|
||||
id="wizard-title"
|
||||
sx={{
|
||||
flexGrow: 1,
|
||||
flexShrink: isMobile ? 0 : 1,
|
||||
userSelect: "none",
|
||||
pt: isMobile ? { xs: 0 } : undefined,
|
||||
mt: isMobile ? -1.5 : 0,
|
||||
width: isMobile ? "100%" : undefined,
|
||||
}}
|
||||
>
|
||||
{title}
|
||||
{currentStep.title && `: ${currentStep.title}`}
|
||||
</DialogTitle>
|
||||
|
||||
<Grid
|
||||
container
|
||||
spacing={3}
|
||||
alignItems="flex-end"
|
||||
className={classes.titleRow}
|
||||
>
|
||||
<Grid item xs>
|
||||
<DialogTitle
|
||||
color="textPrimary"
|
||||
id="wizard-title"
|
||||
className={classes.titleContainer}
|
||||
>
|
||||
<Typography
|
||||
className={classes.title}
|
||||
component="h2"
|
||||
color="textPrimary"
|
||||
>
|
||||
{title}
|
||||
{currentStep.title && `: ${currentStep.title}`}
|
||||
</Typography>
|
||||
</DialogTitle>
|
||||
</Grid>
|
||||
|
||||
<Grid item>
|
||||
<Stack
|
||||
direction="row"
|
||||
alignItems="flex-start"
|
||||
style={{ flexShrink: 0 }}
|
||||
>
|
||||
<MobileStepper
|
||||
variant="dots"
|
||||
position="static"
|
||||
steps={steps.length}
|
||||
activeStep={step}
|
||||
classes={{
|
||||
root: classes.stepper,
|
||||
dot: classes.stepperDot,
|
||||
dotActive: classes.stepperDotActive,
|
||||
sx={{
|
||||
p: 0,
|
||||
m: { xs: 1, sm: 1.5 },
|
||||
background: "none",
|
||||
|
||||
"& .MuiMobileStepper-dot": { mx: 0.5 },
|
||||
}}
|
||||
nextButton={
|
||||
<IconButton
|
||||
aria-label="Next"
|
||||
onClick={handleNext}
|
||||
className={classes.stepperButton}
|
||||
disabled={currentStep.disableNext}
|
||||
>
|
||||
<ChevronRightIcon />
|
||||
@@ -219,51 +123,54 @@ export default function WizardDialog({
|
||||
aria-label="Back"
|
||||
onClick={handleBack}
|
||||
disabled={step <= 0}
|
||||
className={classes.stepperButton}
|
||||
>
|
||||
<ChevronLeftIcon />
|
||||
</IconButton>
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<DialogContent className={classes.content}>
|
||||
<IconButton
|
||||
onClick={props.onClose as any}
|
||||
aria-label="Close"
|
||||
sx={{
|
||||
m: { xs: 1, sm: 1.5 },
|
||||
ml: { xs: -1, sm: -1 },
|
||||
}}
|
||||
className="dialog-close"
|
||||
>
|
||||
<CloseIcon />
|
||||
</IconButton>
|
||||
</Stack>
|
||||
</Stack>
|
||||
|
||||
<ScrollableDialogContent>
|
||||
{currentStep.description && (
|
||||
<Typography
|
||||
color="textSecondary"
|
||||
variant="body1"
|
||||
id="wizard-step-description"
|
||||
component={
|
||||
typeof currentStep.description === "string" ? "p" : "div"
|
||||
}
|
||||
paragraph
|
||||
>
|
||||
{currentStep.description}
|
||||
</Typography>
|
||||
)}
|
||||
|
||||
{currentStep.content}
|
||||
</DialogContent>
|
||||
</ScrollableDialogContent>
|
||||
|
||||
<Grid
|
||||
container
|
||||
spacing={2}
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
className={classes.actions}
|
||||
>
|
||||
<Grid item>
|
||||
<Button onClick={handleBack}>{step > 0 ? "Back" : "Cancel"}</Button>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={handleNext}
|
||||
disabled={currentStep.disableNext}
|
||||
>
|
||||
{step === steps.length - 1 ? "Finish" : "Continue"}
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<DialogActions>
|
||||
<Button onClick={handleBack}>{step > 0 ? "Back" : "Cancel"}</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={handleNext}
|
||||
disabled={currentStep.disableNext}
|
||||
>
|
||||
{step === steps.length - 1 ? "Finish" : "Continue"}
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ export enum routes {
|
||||
jwtAuth = "/jwtAuth",
|
||||
signOut = "/signOut",
|
||||
authSetup = "/authSetup",
|
||||
setup = "/setup",
|
||||
|
||||
table = "/table",
|
||||
tableGroup = "/tableGroup",
|
||||
|
||||
@@ -796,6 +796,15 @@ export const components = (theme: Theme): ThemeOptions => {
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
MuiAlertTitle: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
...theme.typography.subtitle2,
|
||||
lineHeight: "1.5rem",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
@@ -2672,10 +2672,10 @@
|
||||
use-debounce "^3.4.3"
|
||||
yup "^0.32.9"
|
||||
|
||||
"@rowy/multiselect@^0.1.4":
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@rowy/multiselect/-/multiselect-0.1.4.tgz#b95045ed56949a1560a8439f269529cd50908dfb"
|
||||
integrity sha512-jhDq2oRiV3cGMJ4nRzIkWKGxrbtQBKecGssOlOJjLqqR/O4FNKO1UwR4PA7WsX69zuo18sC7ndqr7M0gN6sEHw==
|
||||
"@rowy/multiselect@^0.1.5":
|
||||
version "0.1.5"
|
||||
resolved "https://registry.yarnpkg.com/@rowy/multiselect/-/multiselect-0.1.5.tgz#2d8d6ccc70e4c5264644804a319626db0f7b2158"
|
||||
integrity sha512-tOPrq87mlAHcw41OnqbmoiPTYJfIHZlKoRHyBrUwrwuAC51wfwYakeg8owScVbLcO+rIFrs4b2Ak5/Bme9vQ9Q==
|
||||
|
||||
"@sindresorhus/is@^0.14.0":
|
||||
version "0.14.0"
|
||||
|
||||
Reference in New Issue
Block a user