add submit handler to withCustomCell HOC

This commit is contained in:
Sidney Alcantara
2020-02-21 18:33:57 +11:00
parent 62845dddfd
commit bcdc0f4dd9
8 changed files with 147 additions and 47 deletions

View File

@@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@date-io/date-fns": "^1.3.11",
"@date-io/date-fns": "1.x",
"@material-ui/core": "^4.9.2",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "^4.0.0-alpha.42",
@@ -25,7 +25,7 @@
"@types/react-router-dom": "^4.3.5",
"algoliasearch": "^3.34.0",
"csv-parse": "^4.4.6",
"date-fns": "^2.0.0-beta.5",
"date-fns": "^2.9.0",
"file-saver": "^2.0.2",
"firebase": "^6.6.0",
"formik": "^2.1.4",

View File

@@ -0,0 +1,66 @@
import React from "react";
import withCustomCell, { CustomCellProps } from "./withCustomCell";
import { makeStyles, createStyles, InputAdornment } from "@material-ui/core";
import { FieldType, DateIcon, DateTimeIcon } from "constants/fields";
import { DATE_FORMAT, DATE_TIME_FORMAT } from "constants/dates";
import DateFnsUtils from "@date-io/date-fns";
import {
MuiPickersUtilsProvider,
KeyboardDatePicker,
KeyboardDateTimePicker,
} from "@material-ui/pickers";
const useStyles = makeStyles(theme =>
createStyles({
input: {
...theme.typography.body2,
fontSize: "0.75rem",
color: theme.palette.text.secondary,
},
icon: {
color: theme.palette.text.secondary,
},
"@global": {
".rdg-editor-container": { display: "none" },
},
})
);
function Date({ column, value, onSubmit }: CustomCellProps) {
const classes = useStyles();
const transformedValue = value && "toDate" in value ? value.toDate() : null;
const fieldType = (column as any).type;
const Picker =
fieldType === FieldType.date ? KeyboardDatePicker : KeyboardDateTimePicker;
const Icon = fieldType === FieldType.date ? DateIcon : DateTimeIcon;
const handleDateChange = (date: Date | null) => onSubmit(date);
return (
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<Picker
value={transformedValue}
onChange={handleDateChange}
format={fieldType === FieldType.date ? DATE_FORMAT : DATE_TIME_FORMAT}
// emptyLabel="Select a date"
fullWidth
InputProps={{
disableUnderline: true,
classes: { input: classes.input },
startAdornment: (
<InputAdornment position="start">
<Icon className={classes.icon} />
</InputAdornment>
),
}}
/>
</MuiPickersUtilsProvider>
);
}
export default withCustomCell(Date);

View File

@@ -0,0 +1,12 @@
import React from "react";
import withCustomCell, { CustomCellProps } from "./withCustomCell";
function Url({ value }: CustomCellProps) {
return (
<a href={value} target="_blank" rel="noopener noreferrer">
{value}
</a>
);
}
export default withCustomCell(Url);

View File

@@ -2,17 +2,33 @@ import React, { Suspense } from "react";
import { FormatterProps } from "react-data-grid";
import ErrorBoundary from "components/ErrorBoundary";
import { useFiretableContext } from "../../../contexts/firetableContext";
export type CustomCellProps = FormatterProps & { value: any };
export type CustomCellProps = FormatterProps & {
value: any;
onSubmit: (value: any) => void;
};
const withCustomCell = (Component: React.ComponentType<CustomCellProps>) => (
props: FormatterProps
) => (
<ErrorBoundary>
<Suspense fallback={<div />}>
<Component {...props} value={props.row[props.column.key]} />
</Suspense>
</ErrorBoundary>
);
) => {
const { updateCell } = useFiretableContext();
const handleSubmit = (value: any) => {
if (updateCell) updateCell(props.row.ref, props.column.key, value);
};
return (
<ErrorBoundary>
<Suspense fallback={<div />}>
<Component
{...props}
value={props.row[props.column.key]}
onSubmit={handleSubmit}
/>
</Suspense>
</ErrorBoundary>
);
};
export default withCustomCell;

View File

@@ -11,11 +11,11 @@ import SideDrawerEditor from "./editors/SideDrawerEditor";
const { AutoComplete } = Editors;
const MultiSelect = lazy(() => import("../Fields/MultiSelect"));
const DateField = lazy(() => import("../Fields/Date"));
const Date = lazy(() => import("./formatters/Date"));
const Rating = lazy(() => import("../Fields/Rating"));
const Number = lazy(() => import("../Fields/Number"));
const CheckBox = lazy(() => import("../Fields/CheckBox"));
const UrlLink = lazy(() => import("../Fields/UrlLink"));
const Url = lazy(() => import("./formatters/Url"));
const Image = lazy(() => import("../Fields/Image"));
const File = lazy(() => import("../Fields/File"));
const LongText = lazy(() => import("./formatters/LongText"));
@@ -52,20 +52,19 @@ export const editable = (fieldType: FieldType) => {
export const onSubmit = (key: string, row: any, uid?: string) => async (
value: any
) => {
const collection = row.ref.parent.path;
const data = { collection, id: row.ref.id, doc: { [key]: value } };
if (value !== null || value !== undefined) {
const _ft_updatedAt = new Date();
const _ft_updatedBy = uid ?? "";
row.ref.update({
[key]: value,
_ft_updatedAt,
updatedAt: _ft_updatedAt,
// _ft_updatedBy,
// updatedBy: _ft_updatedBy,
});
}
// const collection = row.ref.parent.path;
// const data = { collection, id: row.ref.id, doc: { [key]: value } };
// if (value !== null || value !== undefined) {
// const _ft_updatedAt = new Date();
// const _ft_updatedBy = uid ?? "";
// row.ref.update({
// [key]: value,
// _ft_updatedAt,
// updatedAt: _ft_updatedAt,
// // _ft_updatedBy,
// // updatedBy: _ft_updatedBy,
// });
// }
};
export const onGridRowsUpdated = (event: any) => {
@@ -89,16 +88,7 @@ export const cellFormatter = (column: any) => {
switch (type) {
case FieldType.date:
case FieldType.dateTime:
return (props: any) => (
<CellWrapper>
<DateField
{...props}
value={props.row[key]}
onSubmit={onSubmit(key, props.row)}
fieldType={type}
/>
</CellWrapper>
);
return Date;
case FieldType.rating:
return (props: any) => (
@@ -140,11 +130,8 @@ export const cellFormatter = (column: any) => {
</CellWrapper>
);
case FieldType.url:
return (props: any) => (
<CellWrapper>
<UrlLink {...props} value={props.row[key]} />
</CellWrapper>
);
return Url;
case FieldType.action:
return (props: any) => (
<CellWrapper>
@@ -252,6 +239,8 @@ export const getEditor = (column: any) => {
switch (type) {
// Can be edited without double-clicking
case FieldType.date:
case FieldType.dateTime:
case FieldType.checkbox:
case FieldType.rating:
case FieldType.image:
@@ -268,8 +257,6 @@ export const getEditor = (column: any) => {
// Supports double-click editor, but not implemented yet
case FieldType.number:
case FieldType.date:
case FieldType.dateTime:
case FieldType.color:
return NullEditor;

View File

@@ -0,0 +1,2 @@
export const DATE_FORMAT = "yyyy/MM/dd";
export const DATE_TIME_FORMAT = DATE_FORMAT + " h:mm aaaa";

View File

@@ -3,7 +3,7 @@ import _groupBy from "lodash/groupBy";
import { Column } from "react-data-grid";
import { PopoverProps } from "@material-ui/core";
import firebase from "firebase/app";
import useFiretable, {
FiretableActions,
FiretableState,
@@ -91,7 +91,24 @@ export const FiretableContextProvider: React.FC = ({ children }) => {
}
}, [currentUser]);
const updateCell = (fieldName: string, row: any) => {};
const updateCell = (
ref: firebase.firestore.DocumentReference,
fieldName: string,
value: any
) => {
if (value === null || value === undefined) return;
const _ft_updatedAt = new Date();
const _ft_updatedBy = currentUser?.uid ?? "";
ref.update({
[fieldName]: value,
_ft_updatedAt,
updatedAt: _ft_updatedAt,
_ft_updatedBy,
updatedBy: _ft_updatedBy,
});
};
return (
<firetableContext.Provider
value={{

View File

@@ -923,7 +923,7 @@
resolved "https://registry.yarnpkg.com/@date-io/core/-/core-1.3.13.tgz#90c71da493f20204b7a972929cc5c482d078b3fa"
integrity sha512-AlEKV7TxjeK+jxWVKcCFrfYAk8spX9aCyiToFIiLPtfQbsjmRGLIhb5VZgptQcJdHtLXo7+m0DuurwFgUToQuA==
"@date-io/date-fns@^1.3.11":
"@date-io/date-fns@1.x":
version "1.3.13"
resolved "https://registry.yarnpkg.com/@date-io/date-fns/-/date-fns-1.3.13.tgz#7798844041640ab393f7e21a7769a65d672f4735"
integrity sha512-yXxGzcRUPcogiMj58wVgFjc9qUYrCnnU9eLcyNbsQCmae4jPuZCDoIBR21j8ZURsM7GRtU62VOw5yNd4dDHunA==
@@ -3998,7 +3998,7 @@ datauri@^2.0.0:
image-size "^0.7.3"
mimer "^1.0.0"
date-fns@^2.0.0-beta.5:
date-fns@^2.9.0:
version "2.9.0"
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.9.0.tgz#d0b175a5c37ed5f17b97e2272bbc1fa5aec677d2"
integrity sha512-khbFLu/MlzLjEzy9Gh8oY1hNt/Dvxw3J6Rbc28cVoYWQaC1S3YI4xwkF9ZWcjDLscbZlY9hISMr66RFzZagLsA==