Browse Source

Add item edition

Jeremie Pardou-Piquemal 3 years ago
parent
commit
1709524444

+ 21 - 0
src/components/Board/Items/Item/forms/AutoSave.js

@@ -0,0 +1,21 @@
+import React from "react";
+import { FormSpy } from "react-final-form";
+
+const AutoSaveIn = ({ values, save }) => {
+  const [prevValues, setPrevValues] = React.useState(values);
+
+  React.useEffect(() => {
+    if (JSON.stringify(prevValues) !== JSON.stringify(values)) {
+      setPrevValues(values);
+      save(values);
+    }
+  }, [values, save, prevValues]);
+
+  return null;
+};
+
+const AutoSave = (props) => (
+  <FormSpy {...props} subscription={{ values: true }} component={AutoSaveIn} />
+);
+
+export default AutoSave;

+ 21 - 0
src/components/Board/Items/Item/forms/CounterFormFields.js

@@ -0,0 +1,21 @@
+import React from "react";
+import { Field } from "react-final-form";
+
+import Label from "./Label";
+
+const Form = ({ initialValues }) => {
+  return (
+    <>
+      <Label>
+        Label:
+        <Field
+          name="label"
+          component="input"
+          initialValue={initialValues.label}
+        />
+      </Label>
+    </>
+  );
+};
+
+export default Form;

+ 21 - 0
src/components/Board/Items/Item/forms/DiceFormFields.js

@@ -0,0 +1,21 @@
+import React from "react";
+import { Field } from "react-final-form";
+
+import Label from "./Label";
+
+const Form = ({ initialValues }) => {
+  return (
+    <>
+      <Label>
+        Label:
+        <Field
+          name="label"
+          component="input"
+          initialValue={initialValues.label}
+        />
+      </Label>
+    </>
+  );
+};
+
+export default Form;

+ 0 - 33
src/components/Board/Items/Item/forms/ImageForm.js

@@ -1,33 +0,0 @@
-import React from "react";
-import { Form, Field } from "react-final-form";
-
-const ImageForm = ({ initialValues, onSubmit }) => {
-  return (
-    <Form
-      onSubmit={onSubmit}
-      render={({ handleSubmit }) => (
-        <form onSubmit={handleSubmit}>
-          <div style={{ display: "none" }}>
-            <Field
-              name="id"
-              component="input"
-              initialValue={initialValues.id}
-            />
-          </div>
-          <div>
-            <label>Label</label>
-            <Field
-              name="label"
-              component="input"
-              initialValue={initialValues.label}
-            />
-          </div>
-
-          <button type="submit">Submit</button>
-        </form>
-      )}
-    />
-  );
-};
-
-export default ImageForm;

+ 83 - 0
src/components/Board/Items/Item/forms/ImageFormFields.js

@@ -0,0 +1,83 @@
+import React from "react";
+import { Field } from "react-final-form";
+
+import Label from "./Label";
+
+const ImageForm = ({ initialValues }) => {
+  return (
+    <>
+      <Label>
+        Label:
+        <Field
+          name="label"
+          component="input"
+          initialValue={initialValues.label}
+        />
+      </Label>
+      <Label>
+        Text:
+        <Field
+          name="text"
+          component="input"
+          initialValue={initialValues.text}
+        />
+      </Label>
+      <Label>
+        Back Text:
+        <Field
+          name="backText"
+          component="input"
+          initialValue={initialValues.backText}
+        />
+      </Label>
+      <Label>
+        Width:
+        <Field
+          name="width"
+          component="input"
+          initialValue={initialValues.width || initialValues.actualWidth}
+        >
+          {(props) => <input {...props.input} type="number" />}
+        </Field>
+      </Label>
+      <Label>
+        Height:
+        <Field
+          name="height"
+          component="input"
+          initialValue={initialValues.height || initialValues.actualHeight}
+        >
+          {(props) => <input {...props.input} type="number" />}
+        </Field>
+      </Label>
+      <Label>
+        Front image:
+        <Field
+          name="content"
+          component="input"
+          initialValue={initialValues.content}
+        />
+      </Label>
+      <Label>
+        Back image:
+        <Field
+          name="backContent"
+          component="input"
+          initialValue={initialValues.backContent}
+        />
+      </Label>
+      <Label>
+        Overlay image:
+        <Field
+          name="overlay.content"
+          component="input"
+          initialValue={
+            initialValues.overlay ? initialValues.overlay.content : ""
+          }
+        />
+      </Label>
+    </>
+  );
+};
+
+export default ImageForm;

+ 116 - 9
src/components/Board/Items/Item/forms/ItemFormFactory.js

@@ -1,18 +1,125 @@
 import React from "react";
 
-import ImageForm from "./ImageForm";
+import { Form, Field } from "react-final-form";
+import AutoSave from "./AutoSave";
 
-const ItemFormFactory = ({ item, onSubmitHandler }) => {
-  switch (item.type) {
+import ImageFormFields from "./ImageFormFields";
+import CounterFormFields from "./CounterFormFields";
+import RectFormFields from "./RectFormFields";
+import RoundFormFields from "./RoundFormFields";
+import DiceFormFields from "./DiceFormFields";
+import NoteFormFields from "./NoteFormFields";
+
+import Label from "./Label";
+
+import Slider from "rc-slider";
+import "rc-slider/assets/index.css";
+
+const getFormFieldComponent = (type) => {
+  switch (type) {
+    case "rect":
+      return RectFormFields;
+    case "round":
+      return RoundFormFields;
+    case "dice":
+      return DiceFormFields;
+    case "counter":
+      return CounterFormFields;
+    case "note":
+      return NoteFormFields;
     case "image":
-      return (
-        <ImageForm initialValues={item} onSubmit={onSubmitHandler}></ImageForm>
-      );
+      return ImageFormFields;
     default:
-      return (
-        <ImageForm initialValues={item} onSubmit={onSubmitHandler}></ImageForm>
-      );
+      return () => {
+        return null;
+      };
   }
 };
 
+const ItemFormFactory = ({ item, onSubmitHandler }) => {
+  const FieldsComponent = getFormFieldComponent(item.type);
+  return (
+    <Form
+      onSubmit={onSubmitHandler}
+      render={() => (
+        <div
+          style={{
+            display: "flex",
+            flexDirection: "column",
+          }}
+        >
+          <AutoSave save={onSubmitHandler} />
+          <div style={{ display: "none" }}>
+            <Field name="id" component="input" initialValue={item.id} />
+          </div>
+          <Label>
+            Locked:
+            <Field
+              name="locked"
+              component="input"
+              type="checkbox"
+              initialValue={item.locked}
+            />
+          </Label>
+          <Label>
+            Rotation:
+            <Field name="rotation" initialValue={item.rotation}>
+              {({ input: { onChange, value } }) => {
+                return (
+                  <Slider
+                    defaultValue={0}
+                    value={value}
+                    min={-180}
+                    max={180}
+                    step={5}
+                    included={false}
+                    marks={{
+                      "-45": -45,
+                      "-30": -30,
+                      0: 0,
+                      30: 30,
+                      45: 45,
+                      90: 90,
+                    }}
+                    onChange={onChange}
+                  />
+                );
+              }}
+            </Field>
+          </Label>
+          <Label>
+            Layer:
+            <Field name="layer" initialValue={item.layer}>
+              {({ input: { onChange, value } }) => {
+                return (
+                  <Slider
+                    defaultValue={0}
+                    value={value}
+                    min={-3}
+                    max={3}
+                    step={1}
+                    included={false}
+                    marks={{
+                      "-3": -3,
+                      "-2": -2,
+                      "-1": -1,
+                      0: 0,
+                      "1": 1,
+                      "2": 2,
+                      "3": 3,
+                    }}
+                    onChange={onChange}
+                  />
+                );
+              }}
+            </Field>
+          </Label>
+
+          <FieldsComponent initialValues={item} />
+        </div>
+      )}
+    />
+  );
+};
+
 export default ItemFormFactory;

+ 13 - 0
src/components/Board/Items/Item/forms/Label.js

@@ -0,0 +1,13 @@
+import styled from "styled-components";
+
+export const Label = styled.label`
+  clear: both;
+  padding-bottom: 1.5em;
+  &::after {
+    content: "";
+    display: block;
+    clear: both;
+  }
+`;
+
+export default Label;

+ 21 - 0
src/components/Board/Items/Item/forms/NoteFormFields.js

@@ -0,0 +1,21 @@
+import React from "react";
+import { Field } from "react-final-form";
+
+import Label from "./Label";
+
+const Form = ({ initialValues }) => {
+  return (
+    <>
+      <Label>
+        Label:
+        <Field
+          name="label"
+          component="input"
+          initialValue={initialValues.label}
+        />
+      </Label>
+    </>
+  );
+};
+
+export default Form;

+ 41 - 0
src/components/Board/Items/Item/forms/RectFormFields.js

@@ -0,0 +1,41 @@
+import React from "react";
+import { Field } from "react-final-form";
+
+import Label from "./Label";
+
+const Form = ({ initialValues }) => {
+  return (
+    <>
+      <Label>
+        Label:
+        <Field
+          name="label"
+          component="input"
+          initialValue={initialValues.label}
+        />
+      </Label>
+      <Label>
+        Width:
+        <Field
+          name="width"
+          component="input"
+          initialValue={initialValues.width}
+        >
+          {(props) => <input {...props.input} type="number" />}
+        </Field>
+      </Label>
+      <Label>
+        Height:
+        <Field
+          name="height"
+          component="input"
+          initialValue={initialValues.height}
+        >
+          {(props) => <input {...props.input} type="number" />}
+        </Field>
+      </Label>
+    </>
+  );
+};
+
+export default Form;

+ 31 - 0
src/components/Board/Items/Item/forms/RoundFormFields.js

@@ -0,0 +1,31 @@
+import React from "react";
+import { Field } from "react-final-form";
+
+import Label from "./Label";
+
+const Form = ({ initialValues }) => {
+  return (
+    <>
+      <Label>
+        Label:
+        <Field
+          name="label"
+          component="input"
+          initialValue={initialValues.label}
+        />
+      </Label>
+      <Label>
+        Radius:
+        <Field
+          name="radius"
+          component="input"
+          initialValue={initialValues.radius}
+        >
+          {(props) => <input {...props.input} type="number" />}
+        </Field>
+      </Label>
+    </>
+  );
+};
+
+export default Form;

+ 8 - 89
src/components/SelectedItemsPane.js

@@ -5,8 +5,6 @@ import { useRecoilValue } from "recoil";
 import { useItems } from "./Board/Items";
 import { selectedItemsAtom } from "../components/Board/Selector";
 
-import Slider from "rc-slider";
-import "rc-slider/assets/index.css";
 import ItemFormFactory from "./Board/Items/Item/forms/ItemFormFactory";
 
 import { confirmAlert } from "react-confirm-alert";
@@ -125,93 +123,14 @@ export const SelectedItems = () => {
           <button onClick={onRemove}>{t("Remove all")}</button>
         </div>
       )}
-      {selectedItems.length === 1 && (
-        <ul
-          style={{
-            listStyle: "none",
-          }}
-        >
-          {selectedItemList.map((item, index) => (
-            <li
-              key={item.id}
-              style={{
-                display: "flex",
-                flexDirection: "column",
-                width: "25em",
-              }}
-            >
-              <h2 style={{ lineHeight: "30px" }}>{index}</h2>
-              <ItemFormFactory item={item} onSubmitHandler={onSubmitHandler} />
-              <label>
-                Locked:
-                <input
-                  type="checkbox"
-                  checked={Boolean(item.locked)}
-                  onChange={() =>
-                    updateItem(item.id, (item) => ({
-                      ...item,
-                      locked: !item.locked,
-                    }))
-                  }
-                />
-              </label>
-              <label>
-                Rotation:
-                <Slider
-                  defaultValue={0}
-                  value={item.rotation}
-                  min={-180}
-                  max={180}
-                  step={5}
-                  included={false}
-                  marks={{
-                    "-45": -45,
-                    "-30": -30,
-                    0: 0,
-                    30: 30,
-                    45: 45,
-                    90: 90,
-                  }}
-                  onChange={(value) =>
-                    updateItem(item.id, (item) => ({
-                      ...item,
-                      rotation: parseInt(value, 10),
-                    }))
-                  }
-                />
-              </label>
-              <label>
-                Layer:
-                <Slider
-                  defaultValue={0}
-                  value={item.layer}
-                  min={-3}
-                  max={3}
-                  step={1}
-                  included={false}
-                  marks={{
-                    "-3": -3,
-                    "-2": -2,
-                    "-1": -1,
-                    0: 0,
-                    "1": 1,
-                    "2": 2,
-                    "3": 3,
-                  }}
-                  onChange={(value) =>
-                    updateItem(item.id, (item) => ({
-                      ...item,
-                      layer: parseInt(value, 10),
-                    }))
-                  }
-                />
-              </label>
-
-              <button onClick={onRemove}>{t("Remove")}</button>
-            </li>
-          ))}
-        </ul>
-      )}
+      {selectedItems.length === 1 &&
+        selectedItemList.map((item) => (
+          <div key={item.id}>
+            <h2>{t("Edit item")}</h2>
+            <ItemFormFactory item={item} onSubmitHandler={onSubmitHandler} />
+            <button onClick={onRemove}>{t("Remove")}</button>
+          </div>
+        ))}
     </SelectedPane>
   );
 };