Skip to content

Commit

Permalink
Use mudder rank instead of order in form builder
Browse files Browse the repository at this point in the history
  • Loading branch information
kalilsn committed Feb 25, 2025
1 parent d2fe54b commit 44bac3f
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useMemo } from "react";
import { zodResolver } from "@hookform/resolvers/zod";
import mudder from "mudder";
import { useForm, useFormContext } from "react-hook-form";
import { z } from "zod";

Expand Down Expand Up @@ -27,7 +28,7 @@ import { ChevronDown } from "ui/icon";
import { Input } from "ui/input";
import { cn } from "utils";

import type { ButtonElement, FormBuilderSchema } from "../types";
import type { FormBuilderSchema } from "../types";
import { useCommunity } from "../../providers/CommunityProvider";
import { useFormBuilder } from "../FormBuilderContext";
import { ButtonOption } from "../SubmissionSettings";
Expand All @@ -48,7 +49,7 @@ export const ButtonConfigurationForm = ({
// This uses the parent's form context to get the most up to date version of 'elements'
const { getValues } = useFormContext<FormBuilderSchema>();
// Derive some initial values based on the state of the parent form when this panel was opened
const { button, buttonIndex, otherButtons, numElements } = useMemo(() => {
const { button, buttonIndex, otherButtons, numElements, elements } = useMemo(() => {
const elements = getValues()["elements"];
// Because a button might not have an ID yet (if it wasn't saved to the db yet) fall back to its label as an identifier
const buttonIndex = buttonIdentifier
Expand All @@ -66,7 +67,7 @@ export const ButtonConfigurationForm = ({
e.elementId !== buttonIdentifier &&
e.label !== buttonIdentifier
);
return { button, buttonIndex, otherButtons, numElements: elements.length };
return { button, buttonIndex, otherButtons, numElements: elements.length, elements };
}, []);

const schema = z.object({
Expand Down Expand Up @@ -102,7 +103,11 @@ export const ButtonConfigurationForm = ({
const onSubmit = (values: z.infer<typeof schema>) => {
const index = buttonIndex === -1 ? numElements : buttonIndex;
update(index, {
order: null,
rank: mudder.base62.mudder(
elements[index - 1]?.rank ?? "",
elements[index + 1]?.rank ?? "",
1
)[0],
type: ElementType.button,
elementId: button?.elementId,
label: values.label,
Expand Down
14 changes: 9 additions & 5 deletions core/app/components/FormBuilder/ElementPanel/SelectElement.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import mudder from "mudder";
import { useFormContext } from "react-hook-form";
import { defaultComponent, SCHEMA_TYPES_WITH_ICONS } from "schemas";
import { defaultComponent } from "schemas";

import { ElementType, StructuralFormElement } from "db/public";
import { Button } from "ui/button";
import { Type } from "ui/icon";
import { Input } from "ui/input";
import { usePubFieldContext } from "ui/pubFields";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "ui/tabs";
Expand All @@ -18,9 +18,9 @@ export const SelectElement = ({ panelState }: { panelState: PanelState }) => {

const { elementsCount, dispatch, addElement } = useFormBuilder();
const { getValues } = useFormContext();
const elements: FormElementData[] = getValues()["elements"];

const fieldButtons = Object.values(fields).map((field) => {
const elements: FormElementData[] = getValues()["elements"];
const usedFields = elements.map((e) => e.fieldId);
if (
usedFields.includes(field.id) ||
Expand Down Expand Up @@ -49,7 +49,7 @@ export const SelectElement = ({ panelState }: { panelState: PanelState }) => {
fieldId: field.id,
required: true,
type: ElementType.pubfield,
order: elementsCount,
rank: mudder.base62.mudder(elements[elementsCount].rank, "", 1)[0],
configured: false,
label: field.name,
component,
Expand Down Expand Up @@ -130,7 +130,11 @@ export const SelectElement = ({ panelState }: { panelState: PanelState }) => {
addElement({
element: elementType,
type: ElementType.structural,
order: elementsCount,
rank: mudder.base62.mudder(
elements[elementsCount].rank,
"",
1
)[0],
configured: false,
});
dispatch({
Expand Down
29 changes: 25 additions & 4 deletions core/app/components/FormBuilder/FormBuilder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,14 @@ import { DndContext } from "@dnd-kit/core";
import { restrictToParentElement, restrictToVerticalAxis } from "@dnd-kit/modifiers";
import { SortableContext, verticalListSortingStrategy } from "@dnd-kit/sortable";
import { zodResolver } from "@hookform/resolvers/zod";
import { createPortal } from "react-dom";
import mudder from "mudder";
import { useFieldArray, useForm } from "react-hook-form";

import type { Stages } from "db/public";
import { logger } from "logger";
import { Button } from "ui/button";
import { Form, FormControl, FormField, FormItem } from "ui/form";
import { useUnsavedChangesWarning } from "ui/hooks";
import { CircleCheck, X } from "ui/icon";
import { CircleCheck } from "ui/icon";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "ui/tabs";
import { TokenProvider } from "ui/tokens";
import { toast } from "ui/use-toast";
Expand All @@ -27,7 +26,7 @@ import { didSucceed, useServerAction } from "~/lib/serverActions";
import { PanelHeader, PanelWrapper, SidePanel } from "../SidePanel";
import { saveForm } from "./actions";
import { ElementPanel } from "./ElementPanel";
import { FormBuilderProvider, useFormBuilder } from "./FormBuilderContext";
import { FormBuilderProvider } from "./FormBuilderContext";
import { FormElement } from "./FormElement";
import { formBuilderSchema, isButtonElement } from "./types";

Expand Down Expand Up @@ -266,6 +265,28 @@ export function FormBuilder({ pubForm, id, stages }: Props) {
activeIndex !== undefined &&
overIndex !== undefined
) {
const activeElem =
elements[activeIndex];
const aboveRank =
elements[overIndex + 1]
?.rank ?? "";
const belowRank =
elements[overIndex - 1]
?.rank ?? "";
const [rank] =
mudder.base62.mudder(
belowRank,
aboveRank,
1
);
form.setValue(
`elements.${activeIndex}`,
{
...activeElem,
rank,
updated: true,
}
);
move(activeIndex, overIndex);
}
}
Expand Down
3 changes: 1 addition & 2 deletions core/app/components/FormBuilder/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,12 @@ export const saveForm = defineServerAction(async function saveForm(form: FormBui
} else if (!element.elementId) {
// Newly created elements have no elementId
acc.upserts.push(formElementsInitializerSchema.parse({ formId, ...element }));
} else if (element.updated || element.order !== index + 1) {
} else if (element.updated) {
acc.upserts.push(
formElementsInitializerSchema.parse({
...element,
formId,
id: element.elementId,
order: index + 1,
})
); // TODO: only update changed columns
}
Expand Down
2 changes: 1 addition & 1 deletion core/app/components/FormBuilder/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
const baseElementSchema = z.object({
id: z.string().optional(), // react-hook-form assigned ID, meaningless in our DB
elementId: formElementsIdSchema.optional(),
order: z.number().int().nullable(),
rank: z.string(),
deleted: z.boolean().default(false),
updated: z.boolean().default(false),
configured: z.boolean().default(true),
Expand Down
4 changes: 2 additions & 2 deletions core/lib/server/form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export const getForm = (
"form_elements.fieldId",
"form_elements.component",
eb.fn.coalesce("form_elements.config", sql`'{}'`).as("config"),
"form_elements.order",
"form_elements.rank",
"form_elements.label",
"form_elements.content",
"form_elements.element",
Expand All @@ -66,7 +66,7 @@ export const getForm = (
"pub_fields.isRelation",
])
.$narrowType<FormElements>()
.orderBy("form_elements.order")
.orderBy("form_elements.rank")
).as("elements")
)
);
Expand Down

0 comments on commit 44bac3f

Please sign in to comment.