Skip to content

Commit c493b25

Browse files
authored
Merge pull request #767 from gadget-inc/feature/shadcn-autohasmanyforms
Feature/Shadcn-AutoHasManyForms
2 parents c3c35f5 + aa3ee53 commit c493b25

File tree

15 files changed

+663
-199
lines changed

15 files changed

+663
-199
lines changed

packages/react/cypress/component/auto/form/PolarisAutoHasManyForm.cy.tsx renamed to packages/react/cypress/component/auto/form/AutoHasManyForm.cy.tsx

Lines changed: 166 additions & 166 deletions
Original file line numberDiff line numberDiff line change
@@ -1,206 +1,206 @@
11
import React from "react";
2-
import { PolarisAutoForm } from "../../../../src/auto/polaris/PolarisAutoForm.js";
3-
import { PolarisAutoInput } from "../../../../src/auto/polaris/inputs/PolarisAutoInput.js";
4-
import { PolarisAutoHasManyForm } from "../../../../src/auto/polaris/inputs/relationships/PolarisAutoHasManyForm.js";
5-
import { PolarisAutoSubmit } from "../../../../src/auto/polaris/submit/PolarisAutoSubmit.js";
6-
import { PolarisSubmitResultBanner } from "../../../../src/auto/polaris/submit/PolarisSubmitResultBanner.js";
72
import { get } from "../../../../src/utils.js";
83
import { api } from "../../../support/api.js";
9-
import { PolarisWrapper } from "../../../support/auto.js";
4+
import { describeForEachAutoAdapter } from "../../../support/auto.js";
105

116
const originalGizmosLinkedToWidget = [
127
{ id: "1", name: "Gizmo 1", orientation: "up" },
138
{ id: "2", name: "Gizmo 2", orientation: "up" },
149
];
1510

16-
describe("PolarisAutoHasManyForm", () => {
17-
const interceptModelUpdateActionMetadata = () => {
18-
cy.intercept({ method: "POST", url: `${api.connection.endpoint}?operation=ModelActionMetadata` }, RealWidgetMetadata).as(
19-
"ModelCreateActionMetadata"
20-
);
21-
};
11+
describeForEachAutoAdapter(
12+
"AutoHasManyForm",
13+
({ name, adapter: { AutoForm, AutoInput, AutoSubmit, SubmitResultBanner, AutoHasManyForm }, wrapper }) => {
14+
const interceptModelUpdateActionMetadata = () => {
15+
cy.intercept({ method: "POST", url: `${api.connection.endpoint}?operation=ModelActionMetadata` }, RealWidgetMetadata).as(
16+
"ModelCreateActionMetadata"
17+
);
18+
};
2219

23-
const expectUpdateActionSubmissionVariables = (expectedQueryValue?: any) => {
24-
cy.intercept({ method: "POST", url: `${api.connection.endpoint}?operation=updateWidget` }, (req) => {
25-
// eslint-disable-next-line
26-
expect(req.body.variables).to.deep.equal(expectedQueryValue);
20+
const expectUpdateActionSubmissionVariables = (expectedQueryValue?: any) => {
21+
cy.intercept({ method: "POST", url: `${api.connection.endpoint}?operation=updateWidget` }, (req) => {
22+
// eslint-disable-next-line
23+
expect(req.body.variables).to.deep.equal(expectedQueryValue);
2724

28-
// The response content doesn't matter for the tests __typename: "UpdateWidgetResult",
29-
req.reply({ data: { updateWidget: { success: true, errors: null, x: {} } } });
30-
}).as("updateWidget");
31-
};
25+
// The response content doesn't matter for the tests __typename: "UpdateWidgetResult",
26+
req.reply({ data: { updateWidget: { success: true, errors: null, x: {} } } });
27+
}).as("updateWidget");
28+
};
3229

33-
const interceptWidgetQuery = () => {
34-
cy.intercept({ method: "POST", url: `${api.connection.endpoint}?operation=widget` }, (req) => {
35-
req.reply({
36-
data: {
37-
widget: {
38-
__typename: "Widget",
39-
id: "42",
40-
name: "test record",
41-
gizmos: {
42-
edges: originalGizmosLinkedToWidget.map((gizmo) => ({ node: gizmo })),
43-
__typename: "GizmoConnection",
30+
const interceptWidgetQuery = () => {
31+
cy.intercept({ method: "POST", url: `${api.connection.endpoint}?operation=widget` }, (req) => {
32+
req.reply({
33+
data: {
34+
widget: {
35+
__typename: "Widget",
36+
id: "42",
37+
name: "test record",
38+
gizmos: {
39+
edges: originalGizmosLinkedToWidget.map((gizmo) => ({ node: gizmo })),
40+
__typename: "GizmoConnection",
41+
},
4442
},
4543
},
46-
},
47-
});
48-
}).as("widget");
49-
};
44+
});
45+
}).as("widget");
46+
};
5047

51-
const interceptGizmosOptionsQuery = (sectionCount: number) => {
52-
const gizmos: any[] = [];
53-
for (let i = 1; i <= sectionCount; i++) {
54-
gizmos.push({
55-
cursor: "eyJpZCI6IjEwODgifQ==",
56-
node: {
57-
__typename: "Gizmo",
58-
id: `${i}`,
59-
createdAt: "2023-09-07T19:18:50.742Z",
60-
name: `Gizmo ${i}`,
61-
otherField: `Gizmo ${i} other field`,
62-
orientation: "right side up",
63-
updatedAt: "2024-07-09T14:42:20.788Z",
64-
},
65-
__typename: "GizmoEdge",
66-
});
67-
}
48+
const interceptGizmosOptionsQuery = (sectionCount: number) => {
49+
const gizmos: any[] = [];
50+
for (let i = 1; i <= sectionCount; i++) {
51+
gizmos.push({
52+
cursor: "eyJpZCI6IjEwODgifQ==",
53+
node: {
54+
__typename: "Gizmo",
55+
id: `${i}`,
56+
createdAt: "2023-09-07T19:18:50.742Z",
57+
name: `Gizmo ${i}`,
58+
otherField: `Gizmo ${i} other field`,
59+
orientation: "right side up",
60+
updatedAt: "2024-07-09T14:42:20.788Z",
61+
},
62+
__typename: "GizmoEdge",
63+
});
64+
}
6865

69-
cy.intercept(
70-
{
71-
method: "POST",
72-
url: `${api.connection.endpoint}?operation=gizmos`,
73-
},
74-
(req) => {
75-
const queryIsForSelectedRecords = get(req.body.variables, "filter.widgetId.equals") === "42";
66+
cy.intercept(
67+
{
68+
method: "POST",
69+
url: `${api.connection.endpoint}?operation=gizmos`,
70+
},
71+
(req) => {
72+
const queryIsForSelectedRecords = get(req.body.variables, "filter.widgetId.equals") === "42";
7673

77-
req.reply({
78-
data: {
79-
gizmos: {
80-
pageInfo: {
81-
hasNextPage: false,
82-
hasPreviousPage: false,
83-
startCursor: "eyJpZCI6IjEifQ==",
84-
endCursor: "eyJpZCI6IjIifQ==",
85-
__typename: "PageInfo",
74+
req.reply({
75+
data: {
76+
gizmos: {
77+
pageInfo: {
78+
hasNextPage: false,
79+
hasPreviousPage: false,
80+
startCursor: "eyJpZCI6IjEifQ==",
81+
endCursor: "eyJpZCI6IjIifQ==",
82+
__typename: "PageInfo",
83+
},
84+
edges: queryIsForSelectedRecords
85+
? gizmos.slice(0, 2) // First 2 gizmos when the query is for the already selected records
86+
: gizmos, // All gizmos when the query is for the options
87+
__typename: "SectionConnection",
8688
},
87-
edges: queryIsForSelectedRecords
88-
? gizmos.slice(0, 2) // First 2 gizmos when the query is for the already selected records
89-
: gizmos, // All gizmos when the query is for the options
90-
__typename: "SectionConnection",
91-
},
92-
gadgetMeta: {
93-
hydrations: {
94-
createdAt: "DateTime",
95-
updatedAt: "DateTime",
89+
gadgetMeta: {
90+
hydrations: {
91+
createdAt: "DateTime",
92+
updatedAt: "DateTime",
93+
},
94+
__typename: "GadgetApplicationMeta",
9695
},
97-
__typename: "GadgetApplicationMeta",
9896
},
99-
},
100-
});
101-
}
102-
).as("sections");
103-
};
97+
});
98+
}
99+
).as("sections");
100+
};
104101

105-
beforeEach(() => {
106-
cy.viewport("macbook-13");
102+
beforeEach(() => {
103+
cy.viewport("macbook-13");
107104

108-
interceptModelUpdateActionMetadata();
109-
interceptGizmosOptionsQuery(5);
110-
interceptWidgetQuery();
111-
});
105+
interceptModelUpdateActionMetadata();
106+
interceptGizmosOptionsQuery(5);
107+
interceptWidgetQuery();
108+
});
112109

113-
it("renders nested form fields for related records", () => {
114-
cy.mountWithWrapper(
115-
<PolarisAutoForm action={api.widget.update} findBy="42">
116-
<PolarisSubmitResultBanner />
117-
<PolarisAutoHasManyForm field="gizmos" primaryLabel="name" secondaryLabel="orientation">
118-
<PolarisAutoInput field="name" />
119-
<PolarisAutoInput field="orientation" />
120-
<PolarisAutoInput field="attachment" />
121-
</PolarisAutoHasManyForm>
122-
<PolarisAutoSubmit id="submit" />
123-
</PolarisAutoForm>,
124-
PolarisWrapper
125-
);
110+
it("renders nested form fields for related records", () => {
111+
cy.mountWithWrapper(
112+
<AutoForm action={api.widget.update} findBy="42">
113+
<SubmitResultBanner />
114+
<AutoHasManyForm field="gizmos" primaryLabel="name" secondaryLabel="orientation">
115+
<AutoInput field="name" />
116+
<AutoInput field="orientation" />
117+
<AutoInput field="attachment" />
118+
</AutoHasManyForm>
119+
<AutoSubmit id="submit" />
120+
</AutoForm>,
121+
wrapper
122+
);
126123

127-
cy.wait("@ModelCreateActionMetadata");
128-
cy.wait("@widget");
124+
cy.wait("@ModelCreateActionMetadata");
125+
cy.wait("@widget");
129126

130-
cy.get('[id="gizmos.0"]').click();
131-
cy.get('input[id="widget.gizmos.0.name"]').should("exist").click().type(" - updated");
132-
cy.get('input[id="widget.gizmos.0.orientation"]').should("exist").click().type(" - updated");
127+
cy.get('[id="gizmos.0"]').click();
128+
cy.get('input[id="widget.gizmos.0.name"]').should("exist").click().type(" - updated");
129+
cy.get('input[id="widget.gizmos.0.orientation"]').should("exist").click().type(" - updated");
133130

134-
cy.contains("Add Gizmo").click();
135-
cy.get('input[id="widget.gizmos.2.name"]').should("exist").click().type("New gizmo");
136-
cy.get('input[id="widget.gizmos.2.orientation"]').should("exist").click().type("New orientation");
137-
cy.contains("Confirm").click();
131+
cy.contains("Add Gizmo").click();
132+
cy.get('input[id="widget.gizmos.2.name"]').should("exist").click().type("New gizmo");
133+
cy.get('input[id="widget.gizmos.2.orientation"]').should("exist").click().type("New orientation");
134+
cy.contains("Confirm").click();
138135

139-
cy.get('[id="gizmos.1"]').click();
140-
cy.contains("Delete").click();
141-
cy.contains("Confirm").click();
136+
cy.get('[id="gizmos.1"]').click();
137+
cy.contains("Delete").click();
138+
cy.contains("Confirm").click();
142139

143-
expectUpdateActionSubmissionVariables({
144-
id: "42",
145-
widget: {
146-
gizmos: [
147-
{ update: { attachment: null, id: "1", name: "Gizmo 1 - updated", orientation: "up - updated" } },
148-
{ delete: { id: "2" } },
149-
{ create: { attachment: null, name: "New gizmo", orientation: "New orientation" } },
150-
],
151-
},
140+
expectUpdateActionSubmissionVariables({
141+
id: "42",
142+
widget: {
143+
gizmos: [
144+
{ update: { attachment: null, id: "1", name: "Gizmo 1 - updated", orientation: "up - updated" } },
145+
{ delete: { id: "2" } },
146+
{ create: { attachment: null, name: "New gizmo", orientation: "New orientation" } },
147+
],
148+
},
149+
});
150+
cy.get('[id="submit"]').click();
151+
cy.wait("@updateWidget");
152152
});
153-
cy.get('[id="submit"]').click();
154-
cy.wait("@updateWidget");
155-
});
156153

157-
it("supports nested has-many relationships", () => {
158-
cy.mountWithWrapper(
159-
<PolarisAutoForm action={api.widget.update} findBy="42">
160-
<PolarisAutoHasManyForm field="gizmos">
161-
<PolarisAutoInput field="name" />
162-
<PolarisAutoHasManyForm field="doodads">
163-
<PolarisAutoInput field="name" />
164-
<PolarisAutoInput field="weight" />
165-
</PolarisAutoHasManyForm>
166-
</PolarisAutoHasManyForm>
167-
<PolarisAutoSubmit id="submit" />
168-
</PolarisAutoForm>,
169-
PolarisWrapper
170-
);
154+
it("supports nested has-many relationships", () => {
155+
cy.mountWithWrapper(
156+
<AutoForm action={api.widget.update} findBy="42">
157+
<SubmitResultBanner />
158+
<AutoHasManyForm field="gizmos">
159+
<AutoInput field="name" />
160+
<AutoHasManyForm field="doodads">
161+
<AutoInput field="name" />
162+
<AutoInput field="weight" />
163+
</AutoHasManyForm>
164+
</AutoHasManyForm>
165+
<AutoSubmit id="submit" />
166+
</AutoForm>,
167+
wrapper
168+
);
169+
170+
cy.wait("@ModelCreateActionMetadata");
171+
cy.wait("@widget");
171172

172-
cy.wait("@ModelCreateActionMetadata");
173-
cy.wait("@widget");
173+
cy.get('[id="gizmos.0"]').click();
174174

175-
cy.get('[id="gizmos.0"]').click();
176-
cy.get('input[id="widget.gizmos.0.name"]').should("exist").click().type(" - updated");
175+
cy.clickAndType('input[id="widget.gizmos.0.name"]', "Gizmo 1 - updated", true);
177176

178-
cy.contains("Add Doodad").should("exist").parent().click();
177+
cy.contains("Add Doodad").should("exist").parent().click();
179178

180-
cy.get("input[id='widget.gizmos.0.doodads.0.name']").should("exist").click().type(" - updated");
181-
cy.get("button[id='confirmButton_gizmos.doodads.0']").should("exist").click();
182-
cy.contains("Confirm").click();
179+
cy.get("input[id='widget.gizmos.0.doodads.0.name']").should("exist").click().type(" - updated");
180+
cy.get("button[id='confirmButton_gizmos.doodads.0']").should("exist").click();
181+
cy.contains("Confirm").click();
183182

184-
expectUpdateActionSubmissionVariables({
185-
id: "42",
186-
widget: {
187-
gizmos: [
188-
{
189-
update: {
190-
doodads: [{ create: { name: " - updated", weight: null } }],
191-
id: "1",
192-
name: "Gizmo 1 - updated",
193-
orientation: "up",
183+
expectUpdateActionSubmissionVariables({
184+
id: "42",
185+
widget: {
186+
gizmos: [
187+
{
188+
update: {
189+
doodads: [{ create: { name: " - updated", weight: null } }],
190+
id: "1",
191+
name: "Gizmo 1 - updated",
192+
orientation: "up",
193+
},
194194
},
195-
},
196-
{ update: { doodads: null, id: "2", name: "Gizmo 2", orientation: "up" } },
197-
],
198-
},
195+
{ update: { doodads: null, id: "2", name: "Gizmo 2", orientation: "up" } },
196+
],
197+
},
198+
});
199+
cy.get('[id="submit"]').click();
200+
cy.wait("@updateWidget");
199201
});
200-
cy.get('[id="submit"]').click();
201-
cy.wait("@updateWidget");
202-
});
203-
});
202+
}
203+
);
204204

205205
const RealWidgetMetadata = {
206206
data: {

packages/react/cypress/support/auto.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ const ONLY_RUN_SUITES = {
3434
"AutoForm - Upsert Action",
3535
"AutoHasOneForm",
3636
"AutoBelongsToForm",
37+
"AutoHasManyForm",
3738
"AutoFormDateTimePicker",
3839
"AutoFormJSONInput",
3940
"AutoPasswordInput",

packages/react/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
"@radix-ui/react-checkbox": "^1.1.3",
7979
"@radix-ui/react-dropdown-menu": "^2.1.5",
8080
"@radix-ui/react-dialog": "^1.1.5",
81+
"@radix-ui/react-accordion": "^1.2.2",
8182
"@radix-ui/react-label": "^2.1.1",
8283
"@radix-ui/react-popover": "^1.1.5",
8384
"@radix-ui/react-scroll-area": "^1.2.2",

0 commit comments

Comments
 (0)