Skip to content

Commit

Permalink
Warn user when deleted stage would affect a form submit button
Browse files Browse the repository at this point in the history
  • Loading branch information
kalilsn committed Oct 7, 2024
1 parent c8d1949 commit ab45882
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 8 deletions.
8 changes: 7 additions & 1 deletion core/app/c/[communitySlug]/stages/manage/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,21 @@ export const createStage = defineServerAction(async function createStage(
export const deleteStage = defineServerAction(async function deleteStage(stageId: StagesId) {
// TODO: add authorization check

let result: {
formName: string;
}[] = [];
try {
await removeStages([stageId]).executeTakeFirstOrThrow();
result = await removeStages([stageId]).execute();
} catch (error) {
return {
error: "Failed to delete stage",
cause: error,
};
} finally {
revalidateTagsForCommunity(["stages", "PubsInStages"]);
if (result.length) {
return result.map(({ formName }) => formName).join(", ");
}
}
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import ReactFlow, {
import "reactflow/dist/style.css";

import type { StagesId } from "db/public";
import { useToast } from "ui/use-toast";
import { expect } from "utils";

import type { CommunityStage } from "~/lib/server/stages";
Expand Down Expand Up @@ -151,6 +152,7 @@ export const StageEditorGraph = () => {
const store = useStoreApi().getState();
const [nodes, setNodes, onNodesChange] = useNodesState(layout.nodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(layout.edges);
const { toast } = useToast();

const onNodeContextMenu: NodeMouseHandler = (_, node) =>
store.addSelectedNodes([...selectedStages.map((stage) => stage.id), node.id]);
Expand All @@ -165,8 +167,13 @@ export const StageEditorGraph = () => {
);

const onNodesDelete = useCallback(
(nodes: Node[]) => {
deleteStages(nodes.map((node) => node.id as StagesId));
async (nodes: Node[]) => {
const formNames = await deleteStages(nodes.map((node) => node.id as StagesId));
// TODO: fix the grammar here if multiple stages are deleted
toast({
title: "Warning",
description: `The stage was deleted succesfully, but it was referenced by a submit button in the "${formNames}" form. You may wish to update that button.`,
});
},
[deleteStages]
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,34 @@
"use client";

import { Button } from "ui/button";
import { useToast } from "ui/use-toast";

import type { ClientException } from "~/lib/serverActions";

type Props = {
onDelete(): void;
onDelete: () => Promise<
| string
| ClientException
| {
error: string;
cause: any;
}
| undefined
>;
};

export const StagePanelOverviewManagement = (props: Props) => {
const onDeleteClick = () => {
props.onDelete();
const { toast } = useToast();

const onDeleteClick = async () => {
const formName = await props.onDelete();
if (formName) {
console.log(formName);

Check failure on line 26 in core/app/c/[communitySlug]/stages/manage/components/panel/StagePanelOverviewManagement.tsx

View workflow job for this annotation

GitHub Actions / ci / ci

Unexpected console statement
toast({
title: "Warning",
description: `The stage was deleted succesfully, but it was referenced by a submit button in the "${formName}" form. You may wish to update that button.`,
});
}
};
return (
<>
Expand Down
12 changes: 10 additions & 2 deletions core/lib/server/stages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ export const createStage = (props: NewStages) =>
export const updateStage = (stageId: StagesId, props: StagesUpdate) =>
autoRevalidate(db.updateTable("stages").set(props).where("id", "=", stageId));

// Returns the name of any forms where the submit button pointed to one of the deleted stages
export const removeStages = (stageIds: StagesId[]) =>
autoRevalidate(
db
Expand All @@ -159,8 +160,15 @@ export const removeStages = (stageIds: StagesId[]) =>
.where("id", "in", stageIds as StagesId[])
.returning("id")
)
.deleteFrom("PubsInStages")
.where("stageId", "in", (eb) => eb.selectFrom("deleted_stages").select("id"))
.with("deleted_pub_connections", (db) =>
db
.deleteFrom("PubsInStages")
.where("stageId", "in", (eb) => eb.selectFrom("deleted_stages").select("id"))
)
.selectFrom("deleted_stages")
.innerJoin("form_elements", "form_elements.stageId", "deleted_stages.id")
.innerJoin("forms", "forms.id", "form_elements.formId")
.select("forms.name as formName")
);

export const createMoveConstraint = (props: NewMoveConstraint) =>
Expand Down

0 comments on commit ab45882

Please sign in to comment.