Added reorder feature for default arrays with drag n drop

This commit is contained in:
francesco
2020-11-05 23:36:11 +01:00
parent c50b454417
commit df73ef3e7d
18 changed files with 292 additions and 170 deletions

View File

@@ -1084,6 +1084,13 @@
dependencies:
regenerator-runtime "^0.13.4"
"@babel/runtime@^7.2.0":
version "7.12.1"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.1.tgz#b4116a6b6711d010b2dad3b7b6e43bf1b9954740"
integrity sha512-J5AIf3vPj3UwXaAzb5j1xM4WAQDX3EMgemF8rjCP3SoW09LfRKAXQKt6CoVYl230P6iWdRcBbnLDDdnqWxZSCA==
dependencies:
regenerator-runtime "^0.13.4"
"@babel/template@^7.4.0", "@babel/template@^7.8.3", "@babel/template@^7.8.6":
version "7.8.6"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.6.tgz#86b22af15f828dfb086474f964dcc3e39c43ce2b"
@@ -2072,21 +2079,6 @@
dependencies:
"@types/react" "*"
"@types/react-virtualized@^9.21.10":
version "9.21.10"
resolved "https://registry.yarnpkg.com/@types/react-virtualized/-/react-virtualized-9.21.10.tgz#cd072dc9c889291ace2c4c9de8e8c050da8738b7"
integrity sha512-f5Ti3A7gGdLkPPFNHTrvKblpsPNBiQoSorOEOD+JPx72g/Ng2lOt4MYfhvQFQNgyIrAro+Z643jbcKafsMW2ag==
dependencies:
"@types/prop-types" "*"
"@types/react" "*"
"@types/react-window@^1.8.2":
version "1.8.2"
resolved "https://registry.yarnpkg.com/@types/react-window/-/react-window-1.8.2.tgz#a5a6b2762ce73ffaab7911ee1397cf645f2459fe"
integrity sha512-gP1xam68Wc4ZTAee++zx6pTdDAH08rAkQrWm4B4F/y6hhmlT9Mgx2q8lTCXnrPHXsr15XjRN9+K2DLKcz44qEQ==
dependencies:
"@types/react" "*"
"@types/react@*":
version "16.9.34"
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.34.tgz#f7d5e331c468f53affed17a8a4d488cd44ea9349"
@@ -4326,14 +4318,6 @@ dom-helpers@^5.0.1:
"@babel/runtime" "^7.8.7"
csstype "^2.6.7"
dom-helpers@^5.1.3:
version "5.2.0"
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.0.tgz#57fd054c5f8f34c52a3eeffdb7e7e93cd357d95b"
integrity sha512-Ru5o9+V8CpunKnz5LGgWXkmrH/20cGKwcHwS4m73zIvs54CN9epEmT/HLqFJW3kXpakAFkEdzgy1hzlJe3E4OQ==
dependencies:
"@babel/runtime" "^7.8.7"
csstype "^3.0.2"
dom-serializer@0:
version "0.2.2"
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51"
@@ -9262,7 +9246,7 @@ prompts@^2.0.1:
kleur "^3.0.3"
sisteransi "^1.0.4"
prop-types@^15.0.0, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.0, prop-types@^15.7.2:
prop-types@^15.0.0, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.0, prop-types@^15.7.2:
version "15.7.2"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
@@ -9529,11 +9513,6 @@ react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.0, react-is@^16.8.1, react-is
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
react-lifecycles-compat@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==
react-router-dom@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.2.0.tgz#9e65a4d0c45e13289e66c7b17c7e175d0ea15662"
@@ -9581,6 +9560,15 @@ react-select@>=3:
react-input-autosize "^2.2.2"
react-transition-group "^4.3.0"
react-sortable-hoc@^1.11.0:
version "1.11.0"
resolved "https://registry.yarnpkg.com/react-sortable-hoc/-/react-sortable-hoc-1.11.0.tgz#fe4022362bbafc4b836f5104b9676608a40a278f"
integrity sha512-v1CDCvdfoR3zLGNp6qsBa4J1BWMEVH25+UKxF/RvQRh+mrB+emqtVHMgZ+WreUiKJoEaiwYoScaueIKhMVBHUg==
dependencies:
"@babel/runtime" "^7.2.0"
invariant "^2.2.4"
prop-types "^15.5.7"
react-transition-group@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.3.0.tgz#fea832e386cf8796c58b61874a3319704f5ce683"
@@ -9606,19 +9594,7 @@ react-virtualized-auto-sizer@^1.0.2:
resolved "https://registry.yarnpkg.com/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.2.tgz#a61dd4f756458bbf63bd895a92379f9b70f803bd"
integrity sha512-MYXhTY1BZpdJFjUovvYHVBmkq79szK/k7V3MO+36gJkWGkrXKtyr4vCPtpphaTLRAdDNoYEYFZWE8LjN+PIHNg==
react-virtualized@^9.22.2:
version "9.22.2"
resolved "https://registry.yarnpkg.com/react-virtualized/-/react-virtualized-9.22.2.tgz#217a870bad91e5438f46f01a009e1d8ce1060a5a"
integrity sha512-5j4h4FhxTdOpBKtePSs1yk6LDNT4oGtUwjT7Nkh61Z8vv3fTG/XeOf8J4li1AYaexOwTXnw0HFVxsV0GBUqwRw==
dependencies:
"@babel/runtime" "^7.7.2"
clsx "^1.0.4"
dom-helpers "^5.1.3"
loose-envify "^1.4.0"
prop-types "^15.7.2"
react-lifecycles-compat "^3.0.4"
react-window@^1.8.2, react-window@^1.8.5:
react-window@^1.8.2:
version "1.8.5"
resolved "https://registry.yarnpkg.com/react-window/-/react-window-1.8.5.tgz#a56b39307e79979721021f5d06a67742ecca52d1"
integrity sha512-HeTwlNa37AFa8MDZFZOKcNEkuF2YflA0hpGPiTT9vR7OawEt+GZbfM6wqkBahD3D3pUjIabQYzsnY/BSJbgq6Q==
@@ -11027,6 +11003,11 @@ to-regex@^3.0.1, to-regex@^3.0.2:
regex-not "^1.0.2"
safe-regex "^1.1.0"
toggle-selection@^1.0.6:
version "1.0.6"
resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32"
integrity sha1-bkWxJj8gF/oKzH2J14sVuL932jI=
toidentifier@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553"
@@ -11273,6 +11254,13 @@ url@^0.11.0:
punycode "1.3.2"
querystring "0.2.0"
use-clipboard-hook@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/use-clipboard-hook/-/use-clipboard-hook-1.1.1.tgz#9af992e9b7efebbb12f497c43b328ac3f4098fe9"
integrity sha512-LXaBI25G1qMlSZMOEI2TRwKbrpok2G/udC9SX+QfljWwL+/PcBPJWTbG1+/FoMerGNF7NBWH2HXzWHLv8C/XbQ==
dependencies:
toggle-selection "^1.0.6"
use@^3.1.0:
version "3.1.1"
resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f"

View File

@@ -48,6 +48,8 @@
"material-ui-popup-state": "^1.6.1",
"object-hash": "^2.0.3",
"react-base-table": "^1.12.0",
"react-dnd": "^11.1.3",
"react-dnd-html5-backend": "^11.1.3",
"react-dropzone": "^11.2.0",
"react-router-dom": "^5.2.0",
"react-select": ">=3",

View File

@@ -1,4 +1,5 @@
import React, { useEffect } from "react";
import React, { useCallback, useEffect, useRef, useState } from "react";
import { HTML5Backend } from "react-dnd-html5-backend";
import {
Box,
Button,
@@ -47,6 +48,7 @@ import { AuthContext, AuthProvider } from "./auth";
import { SnackbarProvider } from "./snackbar_controller";
import { CMSRoute } from "./routes/CMSRoute";
import EntityDetailDialog from "./routes/SideCMSRoute";
import { DndProvider } from "react-dnd";
const drawerWidth = 240;
@@ -335,17 +337,17 @@ export function CMSApp({
<img className={classes.logo} src={logo}/>}
</Box>
<Button variant="contained"
color="primary"
onClick={authContext.googleSignIn}>
Google login
</Button>
<Button variant="contained"
color="primary"
onClick={authContext.googleSignIn}>
Google login
</Button>
{skipLoginButtonEnabled &&
<Box m={2}>
<Box m={2}>
<Button onClick={authContext.skipLogin}>Skip
login</Button>
</Box>
</Box>
}
<Grid item xs={12}>
@@ -475,23 +477,27 @@ export function CMSApp({
return (
<ThemeProvider theme={theme}>
<MuiPickersUtilsProvider utils={DateFnsUtils}>
{firebaseConfigError ?
<Box>
It seems like the provided Firebase config
is not correct. If you are using the
credentials provided automatically by
Firebase Hosting, make sure you link your
Firebase app to Firebase Hosting.
</Box> :
(
authContext.authLoading ? (
<CircularProgressCenter/>
) : (!authenticationEnabled || authContext.loggedUser || authContext.loginSkipped) ? (
renderMainView()
) : (
renderLoginView()
)
)}
<DndProvider backend={HTML5Backend}>
{firebaseConfigError ?
<Box>
It seems like the provided Firebase
config
is not correct. If you are using the
credentials provided automatically by
Firebase Hosting, make sure you link
your
Firebase app to Firebase Hosting.
</Box> :
(
authContext.authLoading ? (
<CircularProgressCenter/>
) : (!authenticationEnabled || authContext.loggedUser || authContext.loginSkipped) ? (
renderMainView()
) : (
renderLoginView()
)
)}
</DndProvider>
</MuiPickersUtilsProvider>
</ThemeProvider>
);

View File

@@ -1,4 +1,6 @@
import * as firebase from "firebase";
import * as firebase from "firebase/app";
import "firebase/auth";
import { auth, User } from "firebase";
import React, { useContext, useEffect } from "react";
import { Authenticator } from "./authenticator";

View File

@@ -10,7 +10,7 @@ import {
} from "@material-ui/core";
import { Entity, EntitySchema, EntityStatus, EntityValues } from "../models";
import { Form, Formik, FormikHelpers } from "formik";
import { createCustomIdField, createFormField } from "./index";
import { createCustomIdField, createFormField, FormFieldProps } from "./index";
import { initEntityValues } from "../firebase/firestore";
import { getYupObjectSchema } from "./validation";
import deepEqual from "deep-equal";
@@ -87,6 +87,7 @@ export default function EntityForm<S extends EntitySchema>({
onDiscard,
onModified
}: EntityFormProps<S>) {
const classes = useStyles();
const [customId, setCustomId] = React.useState<string | undefined>(undefined);
@@ -229,7 +230,15 @@ export default function EntityForm<S extends EntitySchema>({
&& Object.keys(underlyingChanges).includes(key)
&& !!touched[key];
const formField = createFormField(key, property, true, underlyingValueHasChanged, schema);
const formField = createFormField(
{
name : key,
property,
includeDescription:true ,
underlyingValueHasChanged,
entitySchema:schema,
partOfArray: false
});
return <Grid item
xs={12}

View File

@@ -17,6 +17,7 @@ import { Add, Remove } from "@material-ui/icons";
import { formStyles } from "../../styles";
import { CMSFieldProps } from "../form_props";
import { FieldDescription } from "../../components";
import { FormFieldProps } from "../index";
type ArrayMapFieldProps<T> = CMSFieldProps<T[]>;
@@ -68,11 +69,15 @@ export default function ArrayMapField<T>({
return (
<TableCell
key={`field_${arrayKey}`}>
{createFormField(`${field.name}[${index}].${arrayKey}`,
childProperty,
includeDescription,
underlyingValueHasChanged,
entitySchema)}
{createFormField(
{
name:`${field.name}[${index}].${arrayKey}`,
property:childProperty,
includeDescription,
underlyingValueHasChanged,
entitySchema,
partOfArray: false
})}
</TableCell>
);
})}

View File

@@ -50,11 +50,15 @@ export default function ArrayShapedField<T>({
return <Grid item
xs={12}
key={`array-shape-${field.name}-${index}`}>
{createFormField(`${field.name}[${index}]`,
childProperty,
includeDescription,
underlyingValueHasChanged,
entitySchema)}
{createFormField(
{
name:`${field.name}[${index}]`,
property:childProperty,
includeDescription,
underlyingValueHasChanged,
entitySchema,
partOfArray: false
})}
</Grid>;
}
)}

View File

@@ -14,7 +14,6 @@ export default function DateTimeField({
field,
form: { isSubmitting, errors, touched, setFieldValue, setFieldTouched },
property,
createFormField,
includeDescription,
}: DateTimeFieldProps) {

View File

@@ -92,11 +92,15 @@ export default function MapField<S extends EntitySchema>({
.map(([entryKey, childProperty], index) => {
return <Grid item sm={12} xs={12}
key={`map-${field.name}-${index}`}>
{createFormField(`${field.name}[${entryKey}]`,
childProperty,
includeDescription,
underlyingValueHasChanged,
entitySchema)}
{createFormField(
{
name:`${field.name}[${entryKey}]`,
property:childProperty,
includeDescription,
underlyingValueHasChanged,
entitySchema,
partOfArray: false
})}
</Grid>;
}
)}

View File

@@ -1,4 +1,9 @@
import { Entity, EntitySchema, FilterValues } from "../../models";
import {
Entity,
EntitySchema,
FilterValues,
ReferenceProperty
} from "../../models";
import { getIn } from "formik";
import {
Box,
@@ -60,7 +65,8 @@ export default function ReferenceField<S extends EntitySchema>({
form: { isSubmitting, errors, touched, setFieldValue, setFieldTouched },
property,
includeDescription,
entitySchema
entitySchema,
partOfArray
}: ReferenceFieldProps<S>) {
@@ -81,20 +87,18 @@ export default function ReferenceField<S extends EntitySchema>({
return (
<FormControl error={showError} fullWidth>
<FormHelperText filled
required={property.validation?.required}>
<LabelWithIcon scaledIcon={true} property={property}/>
</FormHelperText>
<Box className={`${classes.root}`}>
<ReferenceDialog value={value}
title={title}
property={property}
collectionPath={property.collectionPath}
schema={property.schema === "self" ? entitySchema : property.schema}
initialFilter={property.filter}
previewProperties={property.previewProperties}
textSearchDelegate={property.textSearchDelegate}
onEntityClick={handleEntityClick}
partOfArray={partOfArray}
entitySchema={entitySchema}/>
</Box>
@@ -116,6 +120,8 @@ export interface ReferenceDialogProps<S extends EntitySchema<Key>, Key extends s
title?: string,
property: ReferenceProperty;
/**
* Absolute collection path
*/
@@ -138,6 +144,8 @@ export interface ReferenceDialogProps<S extends EntitySchema<Key>, Key extends s
onEntityClick(entity?: Entity<S>): void;
entitySchema: EntitySchema;
partOfArray:boolean
}
@@ -146,12 +154,14 @@ export function ReferenceDialog<S extends EntitySchema>(
onEntityClick,
value,
title,
property,
schema,
initialFilter,
previewProperties,
textSearchDelegate,
collectionPath,
entitySchema
entitySchema,
partOfArray
}: ReferenceDialogProps<S>) {
const classes = useStyles();
@@ -233,23 +243,25 @@ export function ReferenceDialog<S extends EntitySchema>(
flexDirection={"column"}
flexGrow={1}
m={1}>
{listProperties && listProperties.map((key, index) => {
const property = schema.properties[key as string];
const propertyKey = schema.properties[key as string];
return (
<Box key={"ref_prev_" + key + index}
m={1}>
mt={0.5}
mb={0.5}>
<ErrorBoundary>{
entity ?
React.createElement(PreviewComponent, {
name: key as string,
value: entity.values[key as string],
property: property,
property: propertyKey,
size: "tiny",
entitySchema: entitySchema
})
:
<SkeletonComponent
property={property}
property={propertyKey}
size={"tiny"}/>}
</ErrorBoundary>
</Box>
@@ -263,7 +275,21 @@ export function ReferenceDialog<S extends EntitySchema>(
<Box onClick={handleClickOpen}
display="flex">
{body}
<Box display={"flex"}
flexDirection={"column"}
flexGrow={1}>
<Tooltip title={value.path}>
<FormHelperText filled
required={property.validation?.required}>
<LabelWithIcon scaledIcon={true}
property={property}/>
</FormHelperText>
</Tooltip>
{body}
</Box>
{!missingEntity && <Box>
<Tooltip title="See details">
@@ -274,14 +300,14 @@ export function ReferenceDialog<S extends EntitySchema>(
</Tooltip>
</Box>}
<Box>
{!partOfArray && <Box>
<Tooltip title="Clear">
<IconButton
onClick={clearValue}>
<ClearIcon/>
</IconButton>
</Tooltip>
</Box>
</Box>}
</Box>
);
}
@@ -292,7 +318,7 @@ export function ReferenceDialog<S extends EntitySchema>(
{value && buildEntityView()}
{!value &&
<Box p={2}
<Box p={1}
onClick={handleClickOpen}
justifyContent="center"
display="flex">

View File

@@ -21,7 +21,6 @@ export default function Select<T extends EnumType>({
field,
form: { isSubmitting, errors, touched, setFieldValue, setFieldTouched },
property,
createFormField,
includeDescription,
}: SelectProps<T>) {

View File

@@ -36,7 +36,6 @@ export default React.forwardRef(function SwitchField({
form: { isSubmitting, errors, touched, setFieldValue, setFieldTouched },
property,
includeDescription,
createFormField,
}: SwitchFieldProps, ref) {
const classes = useStyles();

View File

@@ -29,7 +29,6 @@ export default function TextField({
property,
includeDescription,
allowInfinity,
createFormField,
entitySchema,
}: TextFieldProps) {

View File

@@ -1,23 +1,27 @@
import { EntitySchema, Property } from "../models";
import { ReactElement } from "react";
import { FieldProps as FormikFieldProps } from "formik/dist/Field";
import { FormFieldProps } from "./index";
interface BaseCMSFieldProps<T> extends FormikFieldProps<T> {
name: string,
property: Property<T>,
includeDescription: boolean,
createFormField: (name: string,
property: Property,
includeDescription: boolean,
underlyingValueHasChanged: boolean,
entitySchema: EntitySchema) => ReactElement,
createFormField: ({
name,
property,
includeDescription,
underlyingValueHasChanged,
entitySchema
}: FormFieldProps) => ReactElement,
underlyingValueHasChanged: boolean;
/**
* Full schema of the entity
*/
entitySchema: EntitySchema,
[key: string]: any
partOfArray: boolean,
}
export type CMSFieldProps<T> = any & BaseCMSFieldProps<T>;

View File

@@ -11,7 +11,7 @@ import {
Tooltip
} from "@material-ui/core";
import { Entity, EntitySchema, EntityStatus, Property } from "../models";
import { ErrorMessage, Field, FieldProps } from "formik";
import { ErrorMessage, FastField, FieldProps } from "formik";
import OpenInNewIcon from "@material-ui/icons/OpenInNew";
import Select from "./fields/Select";
@@ -31,54 +31,26 @@ import { FirebaseConfigContext } from "../contexts";
import { useClipboard } from "use-clipboard-hook";
import { useSnackbarContext } from "../snackbar_controller";
function buildField<P extends Property<T>, T = any>(name: string,
property: P,
includeDescription: boolean,
component: React.ComponentType<CMSFieldProps<T>>,
underlyingValueHasChanged: boolean,
entitySchema: EntitySchema
) {
const additionalFieldProps: any = property.config?.fieldProps;
return (
<Field
required={property.validation?.required}
name={`${name}`}
>
{(fieldProps: FieldProps<T>) => (
<React.Fragment>
{React.createElement(component, {
...fieldProps,
...additionalFieldProps,
name: fieldProps.field.name,
includeDescription,
property,
createFormField,
underlyingValueHasChanged,
entitySchema
})}
{underlyingValueHasChanged && !fieldProps.form.isSubmitting &&
<FormHelperText>
This value has been updated in Firestore
</FormHelperText>}
</React.Fragment>)
}
</Field>);
export interface FormFieldProps {
name: string,
property: Property,
includeDescription: boolean,
underlyingValueHasChanged: boolean,
entitySchema: EntitySchema,
partOfArray: boolean,
}
export function createFormField<T>(name: string,
property: Property,
includeDescription: boolean,
underlyingValueHasChanged: boolean,
entitySchema: EntitySchema): JSX.Element {
export function createFormField<T>({
name,
property,
includeDescription,
underlyingValueHasChanged,
entitySchema,
partOfArray
}: FormFieldProps): JSX.Element {
if (property.disabled) {
return buildField(name, property, includeDescription, DisabledField, underlyingValueHasChanged, entitySchema);
return buildFieldInternal(name, property, includeDescription, DisabledField, underlyingValueHasChanged, entitySchema, partOfArray);
}
let component: React.ComponentType<CMSFieldProps<T>> | undefined;
@@ -122,13 +94,55 @@ export function createFormField<T>(name: string,
}
}
if (component)
return buildField(name, property, includeDescription, component, underlyingValueHasChanged, entitySchema);
return buildFieldInternal(name, property, includeDescription, component, underlyingValueHasChanged, entitySchema, partOfArray);
return (
<div>{`Currently the field ${property.dataType} is not supported`}</div>
);
}
function buildFieldInternal<P extends Property<T>, T = any>(name: string,
property: P,
includeDescription: boolean,
component: React.ComponentType<CMSFieldProps<T>>,
underlyingValueHasChanged: boolean,
entitySchema: EntitySchema,
partOfArray:boolean
) {
const additionalFieldProps: any = property.config?.fieldProps;
return (
<FastField
required={property.validation?.required}
name={`${name}`}
>
{(fieldProps: FieldProps<T>) => (
<React.Fragment>
{React.createElement(component, {
...fieldProps,
...additionalFieldProps,
name: fieldProps.field.name,
includeDescription,
property,
createFormField,
underlyingValueHasChanged,
entitySchema,
partOfArray
})}
{underlyingValueHasChanged && !fieldProps.form.isSubmitting &&
<FormHelperText>
This value has been updated in Firestore
</FormHelperText>}
</React.Fragment>)
}
</FastField>);
}
export function createCustomIdField<S extends EntitySchema>(schema: EntitySchema, formType: EntityStatus, onChange: Function, error: boolean, entity: Entity<S> | undefined) {
@@ -137,11 +151,11 @@ export function createCustomIdField<S extends EntitySchema>(schema: EntitySchema
const hasEnumValues = typeof schema.customId === "object";
const snackbarContext = useSnackbarContext();
const {ref, copy, cut} = useClipboard({
onSuccess: (text) => snackbarContext.open({
const { ref, copy, cut } = useClipboard({
onSuccess: (text) => snackbarContext.open({
type: "success",
message: `Copied ${text}`
}),
})
});
const inputProps = entity ? {
@@ -182,7 +196,7 @@ export function createCustomIdField<S extends EntitySchema>(schema: EntitySchema
name: "id",
type: null,
value: entity ? entity.id : undefined,
variant: "filled",
variant: "filled"
};
return (
<FormControl fullWidth error={error}

View File

@@ -286,9 +286,10 @@ export function EntityFormRoute<S extends EntitySchema>({
message: e?.message
});
}
history.goBack();
}
history.goBack();
})
.catch((e) => {

View File

@@ -1,9 +1,3 @@
/* add css module styles here (optional) */
.test {
margin: 2em;
padding: 0.5em;
border: 2px solid #000;
font-size: 2em;
text-align: center;
body {
margin: 0;
}

View File

@@ -2816,6 +2816,21 @@
resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570"
integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=
"@react-dnd/asap@^4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/@react-dnd/asap/-/asap-4.0.0.tgz#b300eeed83e9801f51bd66b0337c9a6f04548651"
integrity sha512-0XhqJSc6pPoNnf8DhdsPHtUhRzZALVzYMTzRwV4VI6DJNJ/5xxfL9OQUwb8IH5/2x7lSf7nAZrnzUD+16VyOVQ==
"@react-dnd/invariant@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@react-dnd/invariant/-/invariant-2.0.0.tgz#09d2e81cd39e0e767d7da62df9325860f24e517e"
integrity sha512-xL4RCQBCBDJ+GRwKTFhGUW8GXa4yoDfJrPbLblc3U09ciS+9ZJXJ3Qrcs/x2IODOdIE5kQxvMmE2UKyqUictUw==
"@react-dnd/shallowequal@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@react-dnd/shallowequal/-/shallowequal-2.0.0.tgz#a3031eb54129f2c66b2753f8404266ec7bf67f0a"
integrity sha512-Pc/AFTdwZwEKJxFJvlxrSmGe/di+aAOBn60sremrpLo6VI/6cmiUYNNwlI5KNYttg7uypzA3ILPMPgxB2GYZEg==
"@rollup/plugin-alias@^3.0.1":
version "3.1.0"
resolved "https://registry.yarnpkg.com/@rollup/plugin-alias/-/plugin-alias-3.1.0.tgz#4f7bc9d15e030d75da9224aaa5105129c54a3ffd"
@@ -3151,6 +3166,14 @@
resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.5.tgz#527d20ef68571a4af02ed74350164e7a67544860"
integrity sha512-wLD/Aq2VggCJXSjxEwrMafIP51Z+13H78nXIX0ABEuIGhmB5sNGbR113MOKo+yfw+RDo1ZU3DM6yfnnRF/+ouw==
"@types/hoist-non-react-statics@^3.3.1":
version "3.3.1"
resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f"
integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==
dependencies:
"@types/react" "*"
hoist-non-react-statics "^3.3.0"
"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0":
version "2.0.1"
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#42995b446db9a48a11a07ec083499a860e9138ff"
@@ -5784,6 +5807,15 @@ dir-glob@^3.0.1:
dependencies:
path-type "^4.0.0"
dnd-core@^11.1.3:
version "11.1.3"
resolved "https://registry.yarnpkg.com/dnd-core/-/dnd-core-11.1.3.tgz#f92099ba7245e49729d2433157031a6267afcc98"
integrity sha512-QugF55dNW+h+vzxVJ/LSJeTeUw9MCJ2cllhmVThVPEtF16ooBkxj0WBE5RB+AceFxMFo1rO6bJKXtqKl+JNnyA==
dependencies:
"@react-dnd/asap" "^4.0.0"
"@react-dnd/invariant" "^2.0.0"
redux "^4.0.4"
dns-equal@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d"
@@ -7859,6 +7891,11 @@ immer@1.10.0:
resolved "https://registry.yarnpkg.com/immer/-/immer-1.10.0.tgz#bad67605ba9c810275d91e1c2a47d4582e98286d"
integrity sha512-O3sR1/opvCDGLEVcvrGTMtLac8GJ5IwZC4puPrLuRj3l7ICKvkmA0vGuU9OW8mV9WIBRnaxp5GJh9IEAaNOoYg==
immutability-helper@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/immutability-helper/-/immutability-helper-3.1.1.tgz#2b86b2286ed3b1241c9e23b7b21e0444f52f77b7"
integrity sha512-Q0QaXjPjwIju/28TsugCHNEASwoCcJSyJV3uO1sOIQGI0jKgm9f41Lvz0DZj3n46cNCyAZTsEYoY4C2bVRUzyQ==
import-cwd@^2.0.0, import-cwd@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9"
@@ -11875,6 +11912,23 @@ react-dev-utils@^10.2.1:
strip-ansi "6.0.0"
text-table "0.2.0"
react-dnd-html5-backend@^11.1.3:
version "11.1.3"
resolved "https://registry.yarnpkg.com/react-dnd-html5-backend/-/react-dnd-html5-backend-11.1.3.tgz#2749f04f416ec230ea193f5c1fbea2de7dffb8f7"
integrity sha512-/1FjNlJbW/ivkUxlxQd7o3trA5DE33QiRZgxent3zKme8DwF4Nbw3OFVhTRFGaYhHFNL1rZt6Rdj1D78BjnNLw==
dependencies:
dnd-core "^11.1.3"
react-dnd@^11.1.3:
version "11.1.3"
resolved "https://registry.yarnpkg.com/react-dnd/-/react-dnd-11.1.3.tgz#f9844f5699ccc55dfc81462c2c19f726e670c1af"
integrity sha512-8rtzzT8iwHgdSC89VktwhqdKKtfXaAyC4wiqp0SywpHG12TTLvfOoL6xNEIUWXwIEWu+CFfDn4GZJyynCEuHIQ==
dependencies:
"@react-dnd/shallowequal" "^2.0.0"
"@types/hoist-non-react-statics" "^3.3.1"
dnd-core "^11.1.3"
hoist-non-react-statics "^3.3.0"
react-dom@^16.13.1:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.13.1.tgz#c1bd37331a0486c078ee54c4740720993b2e0e7f"
@@ -12147,6 +12201,14 @@ recursive-readdir@2.2.2:
dependencies:
minimatch "3.0.4"
redux@^4.0.4:
version "4.0.5"
resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.5.tgz#4db5de5816e17891de8a80c424232d06f051d93f"
integrity sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w==
dependencies:
loose-envify "^1.4.0"
symbol-observable "^1.2.0"
regenerate-unicode-properties@^8.2.0:
version "8.2.0"
resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec"
@@ -13497,6 +13559,11 @@ svgo@^1.0.0, svgo@^1.2.2:
unquote "~1.1.1"
util.promisify "~1.0.0"
symbol-observable@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"
integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==
symbol-tree@^3.2.2:
version "3.2.4"
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"