Skip to content

Commit

Permalink
bug: adding element of array like in as a form state (#60)
Browse files Browse the repository at this point in the history
  • Loading branch information
LunaTK committed Nov 8, 2023
1 parent 101ba22 commit 12fdb5e
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 18 deletions.
5 changes: 5 additions & 0 deletions .changeset/lemon-scissors-attend.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"protobuf-auto-form": patch
---

bug: add element of array-like as a form state
81 changes: 70 additions & 11 deletions packages/core/src/AutoForm.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const MockApp: React.FC<MockAppProps> = (props) => {
afterEach(cleanup);

describe("AutoForm", () => {
it("Add map item", async () => {
it("Add repeated item", async () => {
const namespace = protobuf.parse(`
syntax = "proto3";
Expand All @@ -44,16 +44,8 @@ describe("AutoForm", () => {
}
`).root;

const handleSubmit = vi.fn();
const dom = render(
<MockApp
onSubmit={handleSubmit}
namespace={namespace}
messageType="RepeatedString"
>
<button id="submit" />
</MockApp>
);
const { handleSubmit, dom } = renderAutoForm(namespace, "RepeatedString");

fireEvent.click(dom.queryByTestId("add-btn")!);
await vi.waitUntil(() => dom.queryByTestId("delete-btn") !== null);
fireEvent.click(dom.container.querySelector("#submit")!);
Expand All @@ -69,4 +61,71 @@ describe("AutoForm", () => {
"repeated element should be added"
).toEqual([{ children: [""] }]);
});

it('Add repeated item', async () => {
const namespace = protobuf.parse(`
syntax = "proto3";
message Child {
map<string, string> val = 1;
}
message Parent {
repeated Child children = 1;
}
`).root;

const { handleSubmit, dom } = renderAutoForm(namespace, "Parent");

fireEvent.click(dom.queryByTestId("add-btn")!);
await vi.waitUntil(() => dom.queryByTestId("delete-btn") !== null);
fireEvent.click(dom.container.querySelector("#submit")!);
await waitFor(() => handleSubmit.mock.calls.length === 1);

expect(
handleSubmit.mock.calls[0],
"repeated element with map should work"
).toEqual([{ children: [{ val: {} }] }]);
})


it('Add nested map', async () => {
const namespace = protobuf.parse(`
syntax = "proto3";
message Child {
map<string, string> val = 1;
}
message Parent {
map<string, Child> children = 1;
}
`).root;

const { handleSubmit, dom } = renderAutoForm(namespace, "Parent");

fireEvent.click(dom.queryByTestId("add-btn")!);
await vi.waitUntil(() => dom.queryByTestId("delete-btn") !== null);
fireEvent.click(dom.container.querySelector("#submit")!);
await waitFor(() => handleSubmit.mock.calls.length === 1);

expect(
handleSubmit.mock.calls[0],
"repeated element with map should work"
).toEqual([{ children: {"": {"val": {}}} }]);
})
});

function renderAutoForm(namespace: protobuf.Namespace, messageType: string) {
const handleSubmit = vi.fn();
const dom = render(
<MockApp
onSubmit={handleSubmit}
namespace={namespace}
messageType={messageType}
>
<button id="submit" />
</MockApp>
);
return { handleSubmit, dom };
}
3 changes: 1 addition & 2 deletions packages/core/src/protobuf/conversion/convert.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { describe, expect, it } from 'vitest';
import protobuf from 'protobufjs';
import { AutoFormContext } from '../../context';
import { proto2Form } from './proto2Form';
import { form2Proto, pruneUnselectedOneofValues } from './form2Proto';
import { form2Proto, proto2Form, pruneUnselectedOneofValues } from './';
import { fillInitialValues } from './initial';

describe('Protobuf Conversion', () => {
Expand Down
9 changes: 7 additions & 2 deletions packages/core/src/protobuf/input/arrayLike/Map.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { FieldOptions } from '../../../models';
import { useChildFields } from '../../../hooks';
import { getInitialValue } from '../../conversion/initial';
import ArrayLike from './ArrayLike';
import { useAutoFormCtx } from '../../../context';
import { proto2Form } from '../../conversion';

interface MapProps {
name: string;
Expand Down Expand Up @@ -35,7 +37,7 @@ const MapKeyValueInput: React.FC<{
const valueLabel = valueOptions?.label ?? 'Value';

return (
<div className="af-repeat-ele flex-1 flex flex-col my-2 p-2">
<div className="flex flex-col flex-1 p-2 my-2 af-repeat-ele">
<div className="label">
<span className="label-text">{keyLabel}</span>
</div>
Expand Down Expand Up @@ -66,11 +68,14 @@ const MapInput: React.FC<MapProps> = ({ name, field, keyType, options }) => {
name,
rules: options?.rules,
});
const ctx = useAutoFormCtx();

const add = () => {
const value = getInitialValue(field, { ignoreArrayLike: true });
const $value = proto2Form(ctx)(value, field.resolvedType, options);
append({
$key: '',
$value: getInitialValue(field, { ignoreArrayLike: true }),
$value,
});
};

Expand Down
11 changes: 8 additions & 3 deletions packages/core/src/protobuf/input/arrayLike/Repeated.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { FieldOptions } from '../../../models';
import { useChildFields } from '../../../hooks';
import { getInitialValue } from '../../conversion/initial';
import ArrayLike from './ArrayLike';
import { useAutoFormCtx } from '../../../context';
import { proto2Form } from '../../conversion';

interface Props {
name: string;
Expand All @@ -21,12 +23,15 @@ const RepeatedInput: React.FC<Props> = ({ field, name, options }) => {
name,
rules: options?.rules,
});
const ctx = useAutoFormCtx();

return (
<ArrayLike
onAdd={() =>
append({ $value: getInitialValue(field, { ignoreArrayLike: true }) })
}
onAdd={() => {
const value = getInitialValue(field, { ignoreArrayLike: true });
const $value = proto2Form(ctx)(value, field.resolvedType, options);
append({ $value });
}}
onRemove={remove}
fields={fields}
render={({ idx }) => (
Expand Down

0 comments on commit 12fdb5e

Please sign in to comment.