123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- import React from "react";
- import { useTranslation } from "react-i18next";
- import { useRecoilValue } from "recoil";
- import Slider from "rc-slider";
- import { Form, Field } from "react-final-form";
- import AutoSave from "../../ui/formUtils/AutoSave";
- import { ItemMapAtom, selectedItemsAtom } from "../Board/";
- import { useItems } from "../Board/Items";
- import Label from "../../ui/formUtils/Label";
- import Hint from "../../ui/formUtils/Hint";
- import ActionsField from "./ActionsField";
- import {
- getFormFieldComponent,
- getDefaultActionsFromItem,
- getAvailableActionsFromItem,
- } from ".";
- const ItemFormFactory = () => {
- const { t } = useTranslation();
- const { batchUpdateItems } = useItems();
- const selectedItems = useRecoilValue(selectedItemsAtom);
- const itemMap = useRecoilValue(ItemMapAtom);
- const item = itemMap[selectedItems[0]];
- const [defaultActions] = React.useState(getDefaultActionsFromItem(item));
- const [availableActions] = React.useState(getAvailableActionsFromItem(item));
- let FieldsComponent;
- if (selectedItems.length === 1) {
- FieldsComponent = getFormFieldComponent(item.type);
- } else {
- const types = new Set(selectedItems.map((itemId) => itemMap[itemId].type));
- if (types.size === 1) {
- FieldsComponent = getFormFieldComponent(Array.from(types)[0]);
- } else {
- FieldsComponent = () => null;
- }
- }
- let initialValues;
- // Set initial values to item values if only one element selected
- // Empty object otherwise
- if (selectedItems.length === 1) {
- initialValues = { ...item };
- initialValues.actions = initialValues.actions || defaultActions;
- } else {
- initialValues = {};
- }
- const onSubmitHandler = React.useCallback(
- (formValues) => {
- batchUpdateItems(selectedItems, (item) => ({
- ...item,
- ...formValues,
- }));
- },
- [batchUpdateItems, selectedItems]
- );
- return (
- <Form
- onSubmit={onSubmitHandler}
- render={() => (
- <div
- style={{
- display: "flex",
- flexDirection: "column",
- }}
- >
- <AutoSave save={onSubmitHandler} />
- <Label>
- <Field
- name="locked"
- component="input"
- type="checkbox"
- initialValue={initialValues.locked}
- />
- <span className="checkable">{t("Locked?")}</span>
- <Hint>{t("Lock action help")}</Hint>
- </Label>
- <Label>
- {t("Rotation")}
- <Field name="rotation" initialValue={initialValues.rotation}>
- {({ input: { onChange, value } }) => {
- return (
- <Slider
- defaultValue={0}
- value={value}
- min={-180}
- max={180}
- step={5}
- included={false}
- marks={{
- "-90": -90,
- "-45": -45,
- "-30": -30,
- 0: 0,
- 30: 30,
- 45: 45,
- 90: 90,
- }}
- onChange={onChange}
- />
- );
- }}
- </Field>
- </Label>
- <Label>
- {t("Layer")}
- <Field name="layer" initialValue={initialValues.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={initialValues} />
- <h3>{t("Snap to grid")}</h3>
- <Label>
- {t("Grid type")}
- <Field
- name="grid.type"
- initialValue={initialValues.grid?.type}
- component="select"
- >
- <option value="">{t("None")}</option>
- <option value="grid">{t("Grid")}</option>
- <option value="hexH">{t("Horizontal hexagons")}</option>
- <option value="hexV">{t("Vertical hexagons")}</option>
- </Field>
- </Label>
- <Label>
- {t("Size")}
- <Field
- name="grid.size"
- component="input"
- initialValue={initialValues.grid?.size}
- >
- {(props) => <input {...props.input} type="number" />}
- </Field>
- </Label>
- <h3>{t("Available actions")}</h3>
- <Label>
- <Field name="actions" initialValue={initialValues.actions}>
- {({ input: { onChange, value } }) => (
- <ActionsField
- onChange={onChange}
- value={value}
- availableActions={availableActions}
- />
- )}
- </Field>
- </Label>
- </div>
- )}
- />
- );
- };
- export default React.memo(ItemFormFactory);
|