mirror of
https://github.com/rowyio/rowy.git
synced 2025-12-29 00:16:39 +01:00
Merge branch 'data-layer-rewrite' of https://github.com/rowyio/rowy into data-layer-rewrite
This commit is contained in:
6
src/assets/icons/ChevronDown.tsx
Normal file
6
src/assets/icons/ChevronDown.tsx
Normal file
@@ -0,0 +1,6 @@
|
||||
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
|
||||
import { SvgIconProps } from "@mui/material/SvgIcon";
|
||||
|
||||
export function ChevronDown(props: SvgIconProps) {
|
||||
return <ExpandMoreIcon fontSize="small" {...props} />;
|
||||
}
|
||||
6
src/assets/icons/ChevronRight.tsx
Normal file
6
src/assets/icons/ChevronRight.tsx
Normal file
@@ -0,0 +1,6 @@
|
||||
import ChevronRightIcon from "@mui/icons-material/ChevronRight";
|
||||
import { SvgIconProps } from "@mui/material/SvgIcon";
|
||||
|
||||
export function ChevronRight(props: SvgIconProps) {
|
||||
return <ChevronRightIcon fontSize="small" {...props} />;
|
||||
}
|
||||
@@ -2,7 +2,7 @@ import SvgIcon, { SvgIconProps } from "@mui/material/SvgIcon";
|
||||
|
||||
export function Clear(props: SvgIconProps) {
|
||||
return (
|
||||
<SvgIcon {...props}>
|
||||
<SvgIcon viewBox="-1 0 24 24" {...props}>
|
||||
<path d="M20 6v12a2 2 0 0 1-2 2H7l-6-8 6-8h11a2 2 0 0 1 2 2Zm-2.001-.001h-10l-4.5 6 4.5 6h10v-12ZM9.12 7.71 7.71 9.12 10.59 12l-2.88 2.88 1.41 1.41L12 13.41l2.88 2.88 1.41-1.41L13.41 12l2.88-2.88-1.41-1.41L12 10.59" />
|
||||
</SvgIcon>
|
||||
);
|
||||
|
||||
@@ -85,7 +85,12 @@ export { CarBrakeAlert as Critical };
|
||||
import { LanguageMarkdownOutline } from "mdi-material-ui";
|
||||
export { LanguageMarkdownOutline as Markdown };
|
||||
|
||||
import { TableRow } from "mdi-material-ui";
|
||||
export { TableRow as Row };
|
||||
|
||||
export * from "./AddRow";
|
||||
export * from "./ChevronDown";
|
||||
export * from "./ChevronRight";
|
||||
export * from "./Clear";
|
||||
export * from "./ConnectTable";
|
||||
export * from "./Copy";
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
import { atom } from "jotai";
|
||||
import { atomWithReducer, atomWithHash } from "jotai/utils";
|
||||
import {
|
||||
uniqBy,
|
||||
sortBy,
|
||||
findIndex,
|
||||
cloneDeep,
|
||||
unset,
|
||||
orderBy,
|
||||
} from "lodash-es";
|
||||
import { uniqBy, findIndex, cloneDeep, unset, orderBy } from "lodash-es";
|
||||
|
||||
import {
|
||||
TableSettings,
|
||||
@@ -166,11 +159,8 @@ export const tableRowsLocalAtom = atomWithReducer(
|
||||
export const tableRowsDbAtom = atom<TableRow[]>([]);
|
||||
/** Combine tableRowsLocal and tableRowsDb */
|
||||
export const tableRowsAtom = atom<TableRow[]>((get) =>
|
||||
sortBy(
|
||||
uniqBy(
|
||||
[...get(tableRowsLocalAtom), ...get(tableRowsDbAtom)],
|
||||
"_rowy_ref.path"
|
||||
),
|
||||
uniqBy(
|
||||
[...get(tableRowsLocalAtom), ...get(tableRowsDbAtom)],
|
||||
"_rowy_ref.path"
|
||||
)
|
||||
);
|
||||
|
||||
@@ -111,3 +111,7 @@ export function InlineErrorFallback(props: IErrorFallbackProps) {
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function NonFullScreenErrorFallback(props: IErrorFallbackProps) {
|
||||
return <ErrorFallback {...props} fullScreen={false} />;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import { WIKI_LINKS } from "@src/constants/externalLinks";
|
||||
import useUpdateCheck from "@src/hooks/useUpdateCheck";
|
||||
import { runRoutes } from "@src/constants/runRoutes";
|
||||
import RegionSelect from "@src/components/Settings/RegionSelect";
|
||||
|
||||
export default function RowyRun({
|
||||
settings,
|
||||
updateSettings,
|
||||
@@ -191,22 +192,17 @@ export default function RowyRun({
|
||||
</Grid>
|
||||
</Grid>
|
||||
</div>
|
||||
<div>
|
||||
<Grid container spacing={1} alignItems="center" direction="row">
|
||||
<Grid item>
|
||||
<RegionSelect
|
||||
label={"Cloud functions Region"}
|
||||
value={settings.region}
|
||||
onChange={(v) => updateSettings({ region: v || "" })}
|
||||
fullWidth
|
||||
/>
|
||||
</Grid>
|
||||
<Typography variant="caption">
|
||||
Select the region where your Cloud Functions are deployed. All new
|
||||
deployments of Rowy cloud functions will be deployed to this region.
|
||||
</Typography>
|
||||
</Grid>
|
||||
</div>
|
||||
|
||||
<RegionSelect
|
||||
label="Cloud Functions region"
|
||||
value={settings.region}
|
||||
onChange={(v) => updateSettings({ region: v || "" })}
|
||||
fullWidth
|
||||
TextFieldProps={{
|
||||
helperText:
|
||||
"All new deployments of Rowy Cloud Functions will be deployed to this region",
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { sortBy } from "lodash-es";
|
||||
|
||||
import MultiSelect from "@rowy/multiselect";
|
||||
import { Grid } from "@mui/material";
|
||||
import LeafIcon from "@src/assets/icons/Leaf";
|
||||
|
||||
import _sortBy from "lodash-es/sortBy";
|
||||
import { CLOUD_RUN_REGIONS } from "@src/constants/regions";
|
||||
const REGIONS = _sortBy(CLOUD_RUN_REGIONS, ["group", "value"]);
|
||||
|
||||
const REGIONS = sortBy(CLOUD_RUN_REGIONS, ["group", "value"]);
|
||||
|
||||
export interface ICloudRunRegionSelectProps {
|
||||
value: string;
|
||||
@@ -28,7 +30,7 @@ export default function CloudRunRegionSelect({
|
||||
options={REGIONS}
|
||||
clearable={false}
|
||||
itemRenderer={(option: any) => (
|
||||
<Grid container spacing={0} sx={{ my: 0.5, maxWidth: 300 }}>
|
||||
<Grid container spacing={0} sx={{ my: 0.5 }}>
|
||||
<Grid item xs>
|
||||
{option.value}
|
||||
</Grid>
|
||||
@@ -54,7 +56,6 @@ export default function CloudRunRegionSelect({
|
||||
{...({
|
||||
AutocompleteProps: { groupBy: (option: any) => option.group },
|
||||
} as any)}
|
||||
TextFieldProps={{ style: { maxWidth: 364 }, ...props.TextFieldProps }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { useAtom } from "jotai";
|
||||
import { ErrorBoundary } from "react-error-boundary";
|
||||
import { NonFullScreenErrorFallback } from "@src/components/ErrorFallback";
|
||||
|
||||
import { Menu } from "@mui/material";
|
||||
import MenuContents from "./MenuContents";
|
||||
@@ -22,13 +24,11 @@ export default function ContextMenu() {
|
||||
onClose={handleClose}
|
||||
anchorOrigin={{ vertical: "bottom", horizontal: "left" }}
|
||||
transformOrigin={{ vertical: "top", horizontal: "left" }}
|
||||
// sx={{
|
||||
// "& .MuiMenu-paper": {
|
||||
// backgroundColor: "background.default",
|
||||
// },
|
||||
// }}
|
||||
sx={{ "& .MuiMenu-paper": { minWidth: 150 } }}
|
||||
>
|
||||
<MenuContents onClose={handleClose} />
|
||||
<ErrorBoundary FallbackComponent={NonFullScreenErrorFallback}>
|
||||
<MenuContents onClose={handleClose} />
|
||||
</ErrorBoundary>
|
||||
</Menu>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { useState } from "react";
|
||||
|
||||
import {
|
||||
ListItemIcon,
|
||||
ListItemSecondaryAction,
|
||||
@@ -6,9 +8,9 @@ import {
|
||||
MenuItemProps,
|
||||
Typography,
|
||||
Menu,
|
||||
Divider,
|
||||
} from "@mui/material";
|
||||
import ArrowRightIcon from "@mui/icons-material/ArrowRight";
|
||||
import { useState } from "react";
|
||||
import { ChevronRight as ChevronRightIcon } from "@src/assets/icons";
|
||||
|
||||
export interface IContextMenuItem extends Partial<MenuItemProps> {
|
||||
onClick?: () => void;
|
||||
@@ -16,6 +18,7 @@ export interface IContextMenuItem extends Partial<MenuItemProps> {
|
||||
label: string;
|
||||
disabled?: boolean;
|
||||
hotkeyLabel?: string;
|
||||
divider?: boolean;
|
||||
}
|
||||
|
||||
export interface IContextMenuItemProps extends IContextMenuItem {
|
||||
@@ -29,29 +32,42 @@ export default function ContextMenuItem({
|
||||
subItems,
|
||||
...props
|
||||
}: IContextMenuItemProps) {
|
||||
const [subMenu, setSubMenu] = useState<EventTarget | null>(null);
|
||||
const [subMenu, setSubMenu] = useState<HTMLElement | null>(null);
|
||||
|
||||
if (subItems && subItems.length > 0) {
|
||||
return (
|
||||
<>
|
||||
<MenuItem onClick={(e) => setSubMenu(e.target)}>
|
||||
{label}
|
||||
<ListItemSecondaryAction style={{ pointerEvents: "none" }}>
|
||||
<ArrowRightIcon style={{ display: "block" }} />
|
||||
<MenuItem onClick={(e) => setSubMenu(e.currentTarget)}>
|
||||
<ListItemIcon>{icon}</ListItemIcon>
|
||||
<ListItemText>{label}</ListItemText>
|
||||
<ListItemSecondaryAction
|
||||
sx={{
|
||||
pointerEvents: "none",
|
||||
position: "static",
|
||||
transform: "none",
|
||||
ml: 1,
|
||||
mr: -1,
|
||||
}}
|
||||
>
|
||||
<ChevronRightIcon color="action" style={{ display: "block" }} />
|
||||
</ListItemSecondaryAction>
|
||||
</MenuItem>
|
||||
{subMenu && (
|
||||
<Menu
|
||||
anchorEl={subMenu as any}
|
||||
id={`${label}-sub-menu`}
|
||||
anchorOrigin={{ vertical: "top", horizontal: "right" }}
|
||||
transformOrigin={{ vertical: "top", horizontal: "left" }}
|
||||
open
|
||||
onClose={() => setSubMenu(null)}
|
||||
sx={{ "& .MuiPaper-root": { mt: -0.5 } }}
|
||||
>
|
||||
{subItems?.map((itemProps) => (
|
||||
<MenuItem {...itemProps}>
|
||||
|
||||
<Menu
|
||||
anchorEl={subMenu}
|
||||
id={`${label}-sub-menu`}
|
||||
anchorOrigin={{ vertical: "top", horizontal: "right" }}
|
||||
transformOrigin={{ vertical: "top", horizontal: "left" }}
|
||||
open={Boolean(subMenu)}
|
||||
onClose={() => setSubMenu(null)}
|
||||
sx={{ "& .MuiPaper-root": { mt: -0.5 } }}
|
||||
PaperProps={{ elevation: 16 }}
|
||||
>
|
||||
{subItems.map((itemProps) =>
|
||||
itemProps.divider ? (
|
||||
<Divider variant="middle" />
|
||||
) : (
|
||||
<MenuItem key={itemProps.label} {...itemProps}>
|
||||
<ListItemIcon>{itemProps.icon}</ListItemIcon>
|
||||
<ListItemText>{itemProps.label}</ListItemText>
|
||||
{itemProps.hotkeyLabel && (
|
||||
@@ -60,12 +76,12 @@ export default function ContextMenuItem({
|
||||
</Typography>
|
||||
)}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Menu>
|
||||
)}
|
||||
)
|
||||
)}
|
||||
</Menu>
|
||||
</>
|
||||
);
|
||||
} else
|
||||
} else {
|
||||
return (
|
||||
<MenuItem {...props} onClick={onClick}>
|
||||
<ListItemIcon>{icon}</ListItemIcon>
|
||||
@@ -77,4 +93,5 @@ export default function ContextMenuItem({
|
||||
)}
|
||||
</MenuItem>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,23 @@
|
||||
import { Fragment } from "react";
|
||||
import { useAtom, useSetAtom } from "jotai";
|
||||
import { getFieldProp } from "@src/components/fields";
|
||||
import { find } from "lodash-es";
|
||||
|
||||
import { Divider } from "@mui/material";
|
||||
import {
|
||||
Copy as CopyIcon,
|
||||
CopyCells as DuplicateIcon,
|
||||
Clear as ClearIcon,
|
||||
Row as RowIcon,
|
||||
} from "@src/assets/icons";
|
||||
import DeleteIcon from "@mui/icons-material/DeleteOutlined";
|
||||
import OpenIcon from "@mui/icons-material/OpenInNewOutlined";
|
||||
|
||||
import MenuItem from "./MenuItem";
|
||||
import ContextMenuItem, { IContextMenuItem } from "./ContextMenuItem";
|
||||
|
||||
import {
|
||||
globalScope,
|
||||
projectIdAtom,
|
||||
altPressAtom,
|
||||
tableAddRowIdTypeAtom,
|
||||
confirmDialogAtom,
|
||||
@@ -27,7 +32,6 @@ import {
|
||||
deleteRowAtom,
|
||||
updateFieldAtom,
|
||||
} from "@src/atoms/tableScope";
|
||||
import { IContextMenuItem } from "./MenuItem";
|
||||
import { FieldType } from "@src/constants/fields";
|
||||
|
||||
interface IMenuContentsProps {
|
||||
@@ -35,6 +39,7 @@ interface IMenuContentsProps {
|
||||
}
|
||||
|
||||
export default function MenuContents({ onClose }: IMenuContentsProps) {
|
||||
const [projectId] = useAtom(projectIdAtom, globalScope);
|
||||
const [altPress] = useAtom(altPressAtom, globalScope);
|
||||
const [addRowIdType] = useAtom(tableAddRowIdTypeAtom, globalScope);
|
||||
const confirm = useSetAtom(confirmDialogAtom, globalScope);
|
||||
@@ -84,6 +89,7 @@ export default function MenuContents({ onClose }: IMenuContentsProps) {
|
||||
label: altPress ? "Clear value" : "Clear value…",
|
||||
color: "error",
|
||||
icon: <ClearIcon />,
|
||||
disabled: selectedColumn.editable === false,
|
||||
onClick: altPress
|
||||
? handleClearValue
|
||||
: () => {
|
||||
@@ -104,41 +110,79 @@ export default function MenuContents({ onClose }: IMenuContentsProps) {
|
||||
const handleDelete = () => deleteRow(row._rowy_ref.path);
|
||||
const rowActions = [
|
||||
{
|
||||
label: "Duplicate row",
|
||||
icon: <DuplicateIcon />,
|
||||
disabled: tableSettings.tableType === "collectionGroup",
|
||||
onClick: () => {
|
||||
addRow({
|
||||
row,
|
||||
setId: addRowIdType === "custom" ? "decrement" : addRowIdType,
|
||||
});
|
||||
onClose();
|
||||
},
|
||||
},
|
||||
{
|
||||
label: altPress ? "Delete row" : "Delete row…",
|
||||
color: "error",
|
||||
icon: <DeleteIcon />,
|
||||
onClick: altPress
|
||||
? handleDelete
|
||||
: () => {
|
||||
confirm({
|
||||
title: "Delete row?",
|
||||
body: (
|
||||
<>
|
||||
Row path:
|
||||
<br />
|
||||
<code style={{ userSelect: "all", wordBreak: "break-all" }}>
|
||||
{row._rowy_ref.path}
|
||||
</code>
|
||||
</>
|
||||
),
|
||||
confirm: "Delete",
|
||||
confirmColor: "error",
|
||||
handleConfirm: handleDelete,
|
||||
label: "Row",
|
||||
icon: <RowIcon />,
|
||||
subItems: [
|
||||
{
|
||||
label: "Copy ID",
|
||||
icon: <CopyIcon />,
|
||||
onClick: () => {
|
||||
navigator.clipboard.writeText(row._rowy_ref.id);
|
||||
onClose();
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "Copy path",
|
||||
icon: <CopyIcon />,
|
||||
onClick: () => {
|
||||
navigator.clipboard.writeText(row._rowy_ref.path);
|
||||
onClose();
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "Open in Firebase Console",
|
||||
icon: <OpenIcon />,
|
||||
onClick: () => {
|
||||
window.open(
|
||||
`https://console.firebase.google.com/project/${projectId}/firestore/data/~2F${row._rowy_ref.path.replace(
|
||||
/\//g,
|
||||
"~2F"
|
||||
)}`
|
||||
);
|
||||
onClose();
|
||||
},
|
||||
},
|
||||
{ label: "Divider", divider: true },
|
||||
{
|
||||
label: "Duplicate",
|
||||
icon: <DuplicateIcon />,
|
||||
disabled: tableSettings.tableType === "collectionGroup",
|
||||
onClick: () => {
|
||||
addRow({
|
||||
row,
|
||||
setId: addRowIdType === "custom" ? "decrement" : addRowIdType,
|
||||
});
|
||||
onClose();
|
||||
},
|
||||
},
|
||||
{
|
||||
label: altPress ? "Delete" : "Delete…",
|
||||
color: "error",
|
||||
icon: <DeleteIcon />,
|
||||
onClick: altPress
|
||||
? handleDelete
|
||||
: () => {
|
||||
confirm({
|
||||
title: "Delete row?",
|
||||
body: (
|
||||
<>
|
||||
Row path:
|
||||
<br />
|
||||
<code
|
||||
style={{ userSelect: "all", wordBreak: "break-all" }}
|
||||
>
|
||||
{row._rowy_ref.path}
|
||||
</code>
|
||||
</>
|
||||
),
|
||||
confirm: "Delete",
|
||||
confirmColor: "error",
|
||||
handleConfirm: handleDelete,
|
||||
});
|
||||
onClose();
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
actionGroups.push(rowActions);
|
||||
@@ -147,12 +191,15 @@ export default function MenuContents({ onClose }: IMenuContentsProps) {
|
||||
return (
|
||||
<>
|
||||
{actionGroups.map((items, groupIndex) => (
|
||||
<>
|
||||
<Fragment key={groupIndex}>
|
||||
{groupIndex > 0 && <Divider variant="middle" />}
|
||||
{items.map((item, index: number) => (
|
||||
<MenuItem key={`contextMenu-${groupIndex}-${index}`} {...item} />
|
||||
<ContextMenuItem
|
||||
key={`contextMenu-${groupIndex}-${index}`}
|
||||
{...item}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
</Fragment>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -4,7 +4,7 @@ import { ColorPicker, toColor } from "react-color-palette";
|
||||
import "react-color-palette/lib/css/styles.css";
|
||||
|
||||
import { ButtonBase, Box, Collapse } from "@mui/material";
|
||||
import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown";
|
||||
import { ChevronDown } from "@src/assets/icons";
|
||||
|
||||
import { fieldSx, getFieldId } from "@src/components/SideDrawer/utils";
|
||||
|
||||
@@ -60,7 +60,7 @@ export default function Color({
|
||||
|
||||
<div style={{ flexGrow: 1 }}>{value?.hex ?? "Choose a color…"}</div>
|
||||
|
||||
<ArrowDropDownIcon
|
||||
<ChevronDown
|
||||
color="action"
|
||||
sx={{
|
||||
transition: (theme) => theme.transitions.create("transform"),
|
||||
|
||||
@@ -2,7 +2,7 @@ import { forwardRef } from "react";
|
||||
import { IPopoverInlineCellProps } from "@src/components/fields/types";
|
||||
|
||||
import { ButtonBase, Grid, Chip } from "@mui/material";
|
||||
import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown";
|
||||
import { ChevronDown } from "@src/assets/icons";
|
||||
|
||||
import ChipList from "@src/components/Table/formatters/ChipList";
|
||||
import { get } from "lodash-es";
|
||||
@@ -38,13 +38,13 @@ export const ConnectService = forwardRef(function ConnectService(
|
||||
</ChipList>
|
||||
|
||||
{!disabled && (
|
||||
<ArrowDropDownIcon
|
||||
<ChevronDown
|
||||
className="row-hover-iconButton"
|
||||
sx={{
|
||||
flexShrink: 0,
|
||||
mr: 0.5,
|
||||
borderRadius: 1,
|
||||
p: (32 - 24) / 2 / 8,
|
||||
p: (32 - 20) / 2 / 8,
|
||||
boxSizing: "content-box !important",
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -2,7 +2,7 @@ import { forwardRef } from "react";
|
||||
import { IPopoverInlineCellProps } from "@src/components/fields/types";
|
||||
|
||||
import { ButtonBase, Grid, Chip } from "@mui/material";
|
||||
import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown";
|
||||
import { ChevronDown } from "@src/assets/icons";
|
||||
|
||||
import ChipList from "@src/components/Table/formatters/ChipList";
|
||||
|
||||
@@ -50,13 +50,13 @@ export const ConnectTable = forwardRef(function ConnectTable(
|
||||
</ChipList>
|
||||
|
||||
{!disabled && (
|
||||
<ArrowDropDownIcon
|
||||
<ChevronDown
|
||||
className="row-hover-iconButton"
|
||||
sx={{
|
||||
flexShrink: 0,
|
||||
mr: 0.5,
|
||||
borderRadius: 1,
|
||||
p: (32 - 24) / 2 / 8,
|
||||
p: (32 - 20) / 2 / 8,
|
||||
boxSizing: "content-box !important",
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -2,7 +2,7 @@ import { forwardRef } from "react";
|
||||
import { IPopoverInlineCellProps } from "@src/components/fields/types";
|
||||
|
||||
import { ButtonBase, Grid, Chip } from "@mui/material";
|
||||
import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown";
|
||||
import { ChevronDown } from "@src/assets/icons";
|
||||
|
||||
import ChipList from "@src/components/Table/formatters/ChipList";
|
||||
import { get } from "lodash-es";
|
||||
@@ -39,13 +39,13 @@ export const Connector = forwardRef(function Connector(
|
||||
</ChipList>
|
||||
|
||||
{!disabled && (
|
||||
<ArrowDropDownIcon
|
||||
<ChevronDown
|
||||
className="row-hover-iconButton"
|
||||
sx={{
|
||||
flexShrink: 0,
|
||||
mr: 0.5,
|
||||
borderRadius: 1,
|
||||
p: (32 - 24) / 2 / 8,
|
||||
p: (32 - 20) / 2 / 8,
|
||||
boxSizing: "content-box !important",
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -2,11 +2,11 @@ import { ISideDrawerFieldProps } from "@src/components/fields/types";
|
||||
|
||||
import DatePicker from "@mui/lab/DatePicker";
|
||||
import { TextField } from "@mui/material";
|
||||
import { ChevronDown } from "@src/assets/icons";
|
||||
|
||||
import { getFieldId } from "@src/components/SideDrawer/utils";
|
||||
import { transformValue, sanitizeValue } from "./utils";
|
||||
import { DATE_FORMAT } from "@src/constants/dates";
|
||||
import { DateIcon } from ".";
|
||||
|
||||
export interface IDateProps extends ISideDrawerFieldProps {}
|
||||
|
||||
@@ -36,12 +36,6 @@ export default function Date_({
|
||||
label=""
|
||||
hiddenLabel
|
||||
aria-label={column.name as string}
|
||||
InputProps={{
|
||||
...props.InputProps,
|
||||
endAdornment: props.InputProps?.endAdornment || (
|
||||
<DateIcon color="action" />
|
||||
),
|
||||
}}
|
||||
sx={{
|
||||
"& .MuiInputBase-input": { fontVariantNumeric: "tabular-nums" },
|
||||
"& .MuiInputAdornment-root": { m: 0 },
|
||||
@@ -59,8 +53,11 @@ export default function Date_({
|
||||
inputFormat={format}
|
||||
mask={format.replace(/[A-Za-z]/g, "_")}
|
||||
clearable
|
||||
OpenPickerButtonProps={{ size: "small" }}
|
||||
components={{ OpenPickerIcon: DateIcon }}
|
||||
OpenPickerButtonProps={{
|
||||
size: "small",
|
||||
sx: { width: 32, height: 32 },
|
||||
}}
|
||||
components={{ OpenPickerIcon: ChevronDown }}
|
||||
disableOpenPicker={false}
|
||||
disabled={disabled}
|
||||
/>
|
||||
|
||||
@@ -3,11 +3,11 @@ import { IHeavyCellProps } from "@src/components/fields/types";
|
||||
|
||||
import DatePicker from "@mui/lab/DatePicker";
|
||||
import { TextField } from "@mui/material";
|
||||
import { ChevronDown } from "@src/assets/icons";
|
||||
|
||||
import { transformValue, sanitizeValue } from "./utils";
|
||||
import { DATE_FORMAT } from "@src/constants/dates";
|
||||
import BasicCell from "./BasicCell";
|
||||
import { DateIcon } from ".";
|
||||
|
||||
export default function Date_({
|
||||
column,
|
||||
@@ -43,20 +43,6 @@ export default function Date_({
|
||||
label=""
|
||||
hiddenLabel
|
||||
aria-label={column.name as string}
|
||||
InputProps={{
|
||||
...props.InputProps,
|
||||
endAdornment: props.InputProps?.endAdornment || (
|
||||
<DateIcon
|
||||
className="row-hover-iconButton"
|
||||
sx={{
|
||||
borderRadius: 1,
|
||||
p: (32 - 24) / 2 / 8,
|
||||
boxSizing: "content-box",
|
||||
mr: 0.5,
|
||||
}}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
className="cell-collapse-padding"
|
||||
sx={{
|
||||
width: "100%",
|
||||
@@ -107,9 +93,9 @@ export default function Date_({
|
||||
size: "small",
|
||||
className: "row-hover-iconButton",
|
||||
edge: false,
|
||||
sx: { mr: 0.5 },
|
||||
sx: { mr: 3 / 8, width: 32, height: 32 },
|
||||
}}
|
||||
components={{ OpenPickerIcon: DateIcon }}
|
||||
components={{ OpenPickerIcon: ChevronDown }}
|
||||
disableOpenPicker={false}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -3,13 +3,13 @@ import { setSeconds } from "date-fns";
|
||||
|
||||
import DateTimePicker from "@mui/lab/DateTimePicker";
|
||||
import { TextField } from "@mui/material";
|
||||
import { ChevronDown } from "@src/assets/icons";
|
||||
|
||||
import {
|
||||
transformValue,
|
||||
sanitizeValue,
|
||||
} from "@src/components/fields/Date/utils";
|
||||
import { DATE_TIME_FORMAT } from "@src/constants/dates";
|
||||
import { DateTimeIcon } from ".";
|
||||
import { getFieldId } from "@src/components/SideDrawer/utils";
|
||||
|
||||
export interface IDateProps extends ISideDrawerFieldProps {}
|
||||
@@ -40,12 +40,6 @@ export default function Date_({
|
||||
label=""
|
||||
hiddenLabel
|
||||
aria-label={column.name as string}
|
||||
InputProps={{
|
||||
...props.InputProps,
|
||||
endAdornment: props.InputProps?.endAdornment || (
|
||||
<DateTimeIcon color="action" />
|
||||
),
|
||||
}}
|
||||
sx={{
|
||||
"& .MuiInputBase-input": { fontVariantNumeric: "tabular-nums" },
|
||||
"& .MuiInputAdornment-root": { m: 0 },
|
||||
@@ -63,8 +57,11 @@ export default function Date_({
|
||||
inputFormat={format}
|
||||
mask={format.replace(/[A-Za-z]/g, "_")}
|
||||
clearable
|
||||
OpenPickerButtonProps={{ size: "small" }}
|
||||
components={{ OpenPickerIcon: DateTimeIcon }}
|
||||
OpenPickerButtonProps={{
|
||||
size: "small",
|
||||
sx: { width: 32, height: 32 },
|
||||
}}
|
||||
components={{ OpenPickerIcon: ChevronDown }}
|
||||
disableOpenPicker={false}
|
||||
disabled={disabled}
|
||||
/>
|
||||
|
||||
@@ -4,6 +4,7 @@ import { setSeconds } from "date-fns";
|
||||
|
||||
import DateTimePicker from "@mui/lab/DateTimePicker";
|
||||
import { TextField } from "@mui/material";
|
||||
import { ChevronDown } from "@src/assets/icons";
|
||||
|
||||
import {
|
||||
transformValue,
|
||||
@@ -11,7 +12,6 @@ import {
|
||||
} from "@src/components/fields/Date/utils";
|
||||
import { DATE_TIME_FORMAT } from "@src/constants/dates";
|
||||
import BasicCell from "./BasicCell";
|
||||
import { DateTimeIcon } from ".";
|
||||
|
||||
export default function DateTime({
|
||||
column,
|
||||
@@ -48,20 +48,6 @@ export default function DateTime({
|
||||
label=""
|
||||
hiddenLabel
|
||||
aria-label={column.name as string}
|
||||
InputProps={{
|
||||
...props.InputProps,
|
||||
endAdornment: props.InputProps?.endAdornment || (
|
||||
<DateTimeIcon
|
||||
className="row-hover-iconButton"
|
||||
sx={{
|
||||
borderRadius: 1,
|
||||
p: (32 - 24) / 2 / 8,
|
||||
boxSizing: "content-box",
|
||||
mr: 0.5,
|
||||
}}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
className="cell-collapse-padding"
|
||||
sx={{
|
||||
width: "100%",
|
||||
@@ -112,9 +98,9 @@ export default function DateTime({
|
||||
size: "small",
|
||||
className: "row-hover-iconButton",
|
||||
edge: false,
|
||||
sx: { mr: 0.5 },
|
||||
sx: { mr: 3 / 8, width: 32, height: 32 },
|
||||
}}
|
||||
components={{ OpenPickerIcon: DateTimeIcon }}
|
||||
components={{ OpenPickerIcon: ChevronDown }}
|
||||
disableOpenPicker={false}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -2,8 +2,8 @@ import { useAtom } from "jotai";
|
||||
import { find, get } from "lodash-es";
|
||||
import { useSnackbar } from "notistack";
|
||||
|
||||
import ReEvalIcon from "@mui/icons-material/Replay";
|
||||
import EvalIcon from "@mui/icons-material/PlayCircle";
|
||||
import ReEvalIcon from "@mui/icons-material/ReplayOutlined";
|
||||
import EvalIcon from "@mui/icons-material/PlayCircleOutline";
|
||||
|
||||
import { globalScope, rowyRunAtom } from "@src/atoms/globalScope";
|
||||
import {
|
||||
|
||||
@@ -2,14 +2,16 @@ import { useAtom } from "jotai";
|
||||
import { find, get } from "lodash-es";
|
||||
import { useSnackbar } from "notistack";
|
||||
|
||||
import Thumbnail from "@src/components/Thumbnail";
|
||||
import OpenIcon from "@mui/icons-material/OpenInNewOutlined";
|
||||
import { Copy } from "@src/assets/icons";
|
||||
|
||||
import {
|
||||
tableScope,
|
||||
tableSchemaAtom,
|
||||
tableRowsAtom,
|
||||
} from "@src/atoms/tableScope";
|
||||
import { IFieldConfig } from "@src/components/fields/types";
|
||||
import OpenIcon from "@mui/icons-material/OpenInNewOutlined";
|
||||
|
||||
export interface IContextMenuActions {
|
||||
label: string;
|
||||
@@ -23,78 +25,83 @@ export const ContextMenuActions: IFieldConfig["contextMenuActions"] = (
|
||||
) => {
|
||||
const [tableSchema] = useAtom(tableSchemaAtom, tableScope);
|
||||
const [tableRows] = useAtom(tableRowsAtom, tableScope);
|
||||
const { enqueueSnackbar, closeSnackbar } = useSnackbar();
|
||||
const { enqueueSnackbar } = useSnackbar();
|
||||
|
||||
const selectedCol = tableSchema.columns?.[selectedCell.columnKey];
|
||||
if (!selectedCol) return [];
|
||||
|
||||
const selectedRow = find(tableRows, ["_rowy_ref.path", selectedCell.path]);
|
||||
const cellValue = get(selectedRow, selectedCol.fieldName);
|
||||
const cellValue = get(selectedRow, selectedCol.fieldName) || [];
|
||||
|
||||
const isEmpty =
|
||||
cellValue === "" ||
|
||||
cellValue === null ||
|
||||
cellValue === undefined ||
|
||||
cellValue.length === 0;
|
||||
if (isEmpty)
|
||||
return [
|
||||
{
|
||||
label: "Copy Image URL",
|
||||
icon: <Copy />,
|
||||
disabled: true,
|
||||
onClick: () => {},
|
||||
},
|
||||
{
|
||||
label: "View Image",
|
||||
icon: <OpenIcon />,
|
||||
onClick: () => {},
|
||||
disabled: true,
|
||||
},
|
||||
];
|
||||
const isSingleValue = isEmpty || cellValue?.length === 1;
|
||||
|
||||
const handleCopyImageURL = (imgObj: RowyFile) => () => {
|
||||
navigator.clipboard.writeText(imgObj.downloadURL);
|
||||
enqueueSnackbar("Copied image URL to clipboard", {
|
||||
variant: "success",
|
||||
});
|
||||
enqueueSnackbar("Copied image URL");
|
||||
reset();
|
||||
};
|
||||
const handleViewImage = (imgObj: RowyFile) => () => {
|
||||
window.open(imgObj.downloadURL, "_blank");
|
||||
reset();
|
||||
};
|
||||
|
||||
if (cellValue.length === 1)
|
||||
return [
|
||||
{
|
||||
label: "Copy Image URL",
|
||||
icon: <Copy />,
|
||||
onClick: handleCopyImageURL(cellValue[0]),
|
||||
},
|
||||
{
|
||||
label: "View Image",
|
||||
icon: <OpenIcon />,
|
||||
onClick: handleViewImage(cellValue[0]),
|
||||
},
|
||||
];
|
||||
else
|
||||
return [
|
||||
{
|
||||
label: "Copy Image URL",
|
||||
//onClick: handleCopyImageURL,
|
||||
subItems: cellValue.map((imgObj: RowyFile, index: number) => ({
|
||||
label: "Image " + (index + 1),
|
||||
icon: <Copy />,
|
||||
onClick: handleCopyImageURL(imgObj),
|
||||
})),
|
||||
},
|
||||
{
|
||||
label: "View Image",
|
||||
subItems: cellValue.map((imgObj: RowyFile, index: number) => ({
|
||||
label: "Image " + (index + 1),
|
||||
icon: <OpenIcon />,
|
||||
onClick: handleViewImage(imgObj),
|
||||
})),
|
||||
},
|
||||
];
|
||||
return [
|
||||
{
|
||||
label: "Copy image URL",
|
||||
icon: <Copy />,
|
||||
onClick: isSingleValue ? handleCopyImageURL(cellValue[0]) : undefined,
|
||||
disabled: isEmpty,
|
||||
subItems: isSingleValue
|
||||
? []
|
||||
: cellValue.map((imgObj: RowyFile, index: number) => ({
|
||||
label: imgObj.name || "Image " + (index + 1),
|
||||
icon: (
|
||||
<Thumbnail
|
||||
imageUrl={imgObj.downloadURL}
|
||||
size="100x100"
|
||||
objectFit="contain"
|
||||
sx={{
|
||||
width: 24,
|
||||
height: 24,
|
||||
boxShadow: (theme) =>
|
||||
`0 0 0 1px ${theme.palette.divider} inset`,
|
||||
}}
|
||||
/>
|
||||
),
|
||||
onClick: handleCopyImageURL(imgObj),
|
||||
})),
|
||||
},
|
||||
{
|
||||
label: "View image",
|
||||
icon: <OpenIcon />,
|
||||
onClick: isSingleValue ? handleViewImage(cellValue[0]) : undefined,
|
||||
disabled: isEmpty,
|
||||
subItems: isSingleValue
|
||||
? []
|
||||
: cellValue.map((imgObj: RowyFile, index: number) => ({
|
||||
label: imgObj.name || "Image " + (index + 1),
|
||||
icon: (
|
||||
<Thumbnail
|
||||
imageUrl={imgObj.downloadURL}
|
||||
size="100x100"
|
||||
objectFit="contain"
|
||||
sx={{
|
||||
width: 24,
|
||||
height: 24,
|
||||
boxShadow: (theme) =>
|
||||
`0 0 0 1px ${theme.palette.divider} inset`,
|
||||
}}
|
||||
/>
|
||||
),
|
||||
onClick: handleViewImage(imgObj),
|
||||
})),
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
export default ContextMenuActions;
|
||||
|
||||
@@ -87,7 +87,6 @@ const deleteImgHoverSx = {
|
||||
|
||||
export default function Image_({
|
||||
column,
|
||||
row,
|
||||
value,
|
||||
onSubmit,
|
||||
disabled,
|
||||
|
||||
@@ -2,7 +2,7 @@ import { forwardRef } from "react";
|
||||
import { IPopoverInlineCellProps } from "@src/components/fields/types";
|
||||
|
||||
import { ButtonBase, Grid } from "@mui/material";
|
||||
import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown";
|
||||
import { ChevronDown } from "@src/assets/icons";
|
||||
|
||||
import { sanitiseValue } from "./utils";
|
||||
import ChipList from "@src/components/Table/formatters/ChipList";
|
||||
@@ -43,13 +43,13 @@ export const MultiSelect = forwardRef(function MultiSelect(
|
||||
</ChipList>
|
||||
|
||||
{!disabled && (
|
||||
<ArrowDropDownIcon
|
||||
<ChevronDown
|
||||
className="row-hover-iconButton"
|
||||
sx={{
|
||||
flexShrink: 0,
|
||||
mr: 0.5,
|
||||
borderRadius: 1,
|
||||
p: (32 - 24) / 2 / 8,
|
||||
p: (32 - 20) / 2 / 8,
|
||||
boxSizing: "content-box !important",
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -2,7 +2,7 @@ import { forwardRef } from "react";
|
||||
import { IPopoverInlineCellProps } from "@src/components/fields/types";
|
||||
|
||||
import { ButtonBase } from "@mui/material";
|
||||
import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown";
|
||||
import { ChevronDown } from "@src/assets/icons";
|
||||
|
||||
import { sanitiseValue } from "./utils";
|
||||
|
||||
@@ -33,13 +33,13 @@ export const SingleSelect = forwardRef(function SingleSelect(
|
||||
</div>
|
||||
|
||||
{!disabled && (
|
||||
<ArrowDropDownIcon
|
||||
<ChevronDown
|
||||
className="row-hover-iconButton"
|
||||
sx={{
|
||||
flexShrink: 0,
|
||||
mr: 0.5,
|
||||
borderRadius: 1,
|
||||
p: (32 - 24) / 2 / 8,
|
||||
p: (32 - 20) / 2 / 8,
|
||||
boxSizing: "content-box !important",
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -2,7 +2,7 @@ import { forwardRef, useMemo } from "react";
|
||||
import { IPopoverInlineCellProps } from "@src/components/fields/types";
|
||||
|
||||
import { ButtonBase } from "@mui/material";
|
||||
import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown";
|
||||
import { ChevronDown } from "@src/assets/icons";
|
||||
import getLabel from "./utils/getLabelHelper";
|
||||
|
||||
export const StatusSingleSelect = forwardRef(function StatusSingleSelect(
|
||||
@@ -51,13 +51,13 @@ export const StatusSingleSelect = forwardRef(function StatusSingleSelect(
|
||||
<div style={{ flexGrow: 1, overflow: "hidden" }}>{label}</div>
|
||||
|
||||
{!disabled && (
|
||||
<ArrowDropDownIcon
|
||||
<ChevronDown
|
||||
className="row-hover-iconButton"
|
||||
sx={{
|
||||
flexShrink: 0,
|
||||
mr: 0.5,
|
||||
borderRadius: 1,
|
||||
p: (32 - 24) / 2 / 8,
|
||||
p: (32 - 20) / 2 / 8,
|
||||
boxSizing: "content-box !important",
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -2,7 +2,6 @@ import { FieldType } from "@src/constants/fields";
|
||||
import { FormatterProps, EditorProps } from "react-data-grid";
|
||||
import { Control, UseFormReturn } from "react-hook-form";
|
||||
import { PopoverProps } from "@mui/material";
|
||||
import { WhereFilterOp } from "firebase/firestore";
|
||||
import {
|
||||
ColumnConfig,
|
||||
TableRow,
|
||||
@@ -10,7 +9,7 @@ import {
|
||||
TableFilter,
|
||||
} from "@src/types/table";
|
||||
import { SelectedCell } from "@src/atoms/tableScope";
|
||||
import { IContextMenuItem } from "@src/components/Table/ContextMenu/MenuItem";
|
||||
import { IContextMenuItem } from "@src/components/Table/ContextMenu/ContextMenuItem";
|
||||
|
||||
export { FieldType };
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import { useLocation } from "react-router-dom";
|
||||
import { List, ListItemIcon, ListItemText, Collapse } from "@mui/material";
|
||||
import FolderIcon from "@mui/icons-material/FolderOutlined";
|
||||
import FavoriteIcon from "@mui/icons-material/FavoriteBorder";
|
||||
import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown";
|
||||
import { ChevronRight } from "@src/assets/icons";
|
||||
import NavItem from "./NavItem";
|
||||
|
||||
import { TableSettings } from "@src/types/table";
|
||||
@@ -43,7 +43,7 @@ export default function NavTableSection({
|
||||
|
||||
<ListItemText primary={section} style={{ textAlign: "left" }} />
|
||||
|
||||
<ArrowDropDownIcon
|
||||
<ChevronRight
|
||||
sx={{
|
||||
color: "action.active",
|
||||
mr: -0.5,
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
Grow,
|
||||
} from "@mui/material";
|
||||
import AccountCircleIcon from "@mui/icons-material/AccountCircleOutlined";
|
||||
import ArrowRightIcon from "@mui/icons-material/ArrowRight";
|
||||
import { ChevronRight as ChevronRightIcon } from "@src/assets/icons";
|
||||
|
||||
import {
|
||||
globalScope,
|
||||
@@ -31,7 +31,7 @@ import { ROUTES } from "@src/constants/routes";
|
||||
export default function UserMenu(props: IconButtonProps) {
|
||||
const anchorEl = useRef<HTMLButtonElement>(null);
|
||||
const [open, setOpen] = useState(false);
|
||||
const [themeSubMenu, setThemeSubMenu] = useState<EventTarget | null>(null);
|
||||
const [themeSubMenu, setThemeSubMenu] = useState<HTMLElement | null>(null);
|
||||
|
||||
const [projectId] = useAtom(projectIdAtom, globalScope);
|
||||
const [userSettings] = useAtom(userSettingsAtom, globalScope);
|
||||
@@ -117,43 +117,41 @@ export default function UserMenu(props: IconButtonProps) {
|
||||
|
||||
<Divider variant="middle" sx={{ mt: 0.5, mb: 0.5 }} />
|
||||
|
||||
<MenuItem onClick={(e) => setThemeSubMenu(e.target)}>
|
||||
<MenuItem onClick={(e) => setThemeSubMenu(e.currentTarget)}>
|
||||
Theme
|
||||
<ListItemSecondaryAction style={{ pointerEvents: "none" }}>
|
||||
<ArrowRightIcon style={{ display: "block" }} />
|
||||
<ChevronRightIcon style={{ display: "block" }} color="action" />
|
||||
</ListItemSecondaryAction>
|
||||
</MenuItem>
|
||||
|
||||
{themeSubMenu && (
|
||||
<Menu
|
||||
anchorEl={themeSubMenu as any}
|
||||
id="theme-sub-menu"
|
||||
anchorOrigin={{ vertical: "top", horizontal: "left" }}
|
||||
transformOrigin={{ vertical: "top", horizontal: "right" }}
|
||||
open
|
||||
onClose={() => setThemeSubMenu(null)}
|
||||
sx={{ "& .MuiPaper-root": { mt: -0.5 } }}
|
||||
<Menu
|
||||
anchorEl={themeSubMenu}
|
||||
id="theme-sub-menu"
|
||||
anchorOrigin={{ vertical: "top", horizontal: "left" }}
|
||||
transformOrigin={{ vertical: "top", horizontal: "right" }}
|
||||
open={Boolean(themeSubMenu)}
|
||||
onClose={() => setThemeSubMenu(null)}
|
||||
sx={{ "& .MuiPaper-root": { mt: -0.5 } }}
|
||||
>
|
||||
<MenuItem
|
||||
onClick={() => changeTheme("system")}
|
||||
selected={!themeOverridden}
|
||||
>
|
||||
<MenuItem
|
||||
onClick={() => changeTheme("system")}
|
||||
selected={!themeOverridden}
|
||||
>
|
||||
System
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
onClick={() => changeTheme("light")}
|
||||
selected={themeOverridden && theme === "light"}
|
||||
>
|
||||
Light
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
onClick={() => changeTheme("dark")}
|
||||
selected={themeOverridden && theme === "dark"}
|
||||
>
|
||||
Dark
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
)}
|
||||
System
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
onClick={() => changeTheme("light")}
|
||||
selected={themeOverridden && theme === "light"}
|
||||
>
|
||||
Light
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
onClick={() => changeTheme("dark")}
|
||||
selected={themeOverridden && theme === "dark"}
|
||||
>
|
||||
Dark
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
|
||||
<MenuItem
|
||||
component={Link}
|
||||
|
||||
@@ -8,6 +8,7 @@ import RadioIcon from "@src/theme/RadioIcon";
|
||||
import CheckboxIcon from "@src/theme/CheckboxIcon";
|
||||
import CheckboxIndeterminateIcon from "@src/theme/CheckboxIndeterminateIcon";
|
||||
import AddCircleIcon from "@mui/icons-material/AddCircleOutline";
|
||||
import { ChevronDown as ChevronDownIcon } from "@src/assets/icons";
|
||||
import { SvgIcon } from "@mui/material";
|
||||
import CircularProgressOptical from "@src/components/CircularProgressOptical";
|
||||
|
||||
@@ -440,6 +441,9 @@ export const components = (theme: Theme): ThemeOptions => {
|
||||
},
|
||||
|
||||
MuiSelect: {
|
||||
defaultProps: {
|
||||
IconComponent: ChevronDownIcon,
|
||||
},
|
||||
styleOverrides: {
|
||||
select: {
|
||||
// If Select option is a MenuItem, don’t add spacing
|
||||
|
||||
15
src/theme/space-grotesk.css
Normal file
15
src/theme/space-grotesk.css
Normal file
@@ -0,0 +1,15 @@
|
||||
@font-face {
|
||||
font-family: "Space Grotesk";
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: url("@src/assets/SpaceGrotesk-Bold.woff2") format("woff2");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Space Grotesk";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url("@src/assets/SpaceGrotesk-Regular.woff2") format("woff2");
|
||||
}
|
||||
@@ -4,6 +4,8 @@ import {
|
||||
TypographyStyleOptions,
|
||||
} from "@mui/material/styles/createTypography";
|
||||
|
||||
import "./space-grotesk.css";
|
||||
|
||||
declare module "@mui/material/styles/createTypography" {
|
||||
interface FontStyle {
|
||||
fontFamilyMono: string;
|
||||
|
||||
Reference in New Issue
Block a user