import { useDisclosure } from "@mantine/hooks"; import { IconAlignJustified, IconAugmentedReality, IconBox, IconCirclesRelation, IconInfoCircle } from "@tabler/icons-react"; import { ucFirst } from "core/utils"; import { useEffect, useState } from "react"; import { twMerge } from "tailwind-merge"; import { useBknd } from "ui/client/bknd"; import { useBkndData } from "ui/client/schema/data/use-bknd-data"; import { IconButton, type IconType } from "ui/components/buttons/IconButton"; import { JsonViewer } from "ui/components/code/JsonViewer"; import { ModalBody, ModalFooter } from "ui/components/modal/Modal2"; import { useStepContext } from "ui/components/steps/Steps"; import type { TCreateModalSchema } from "ui/modules/data/components/schema/create-modal/CreateModal"; type ActionItem = SummaryItemProps & { run: () => Promise; }; export function StepCreate() { const { stepBack, state, close } = useStepContext(); const [states, setStates] = useState<(boolean | string)[]>([]); const [submitting, setSubmitting] = useState(false); const $data = useBkndData(); const b = useBknd(); const items: ActionItem[] = []; if (state.entities?.create) { items.push( ...state.entities.create.map((entity) => ({ action: "add", Icon: IconBox, type: "Entity", name: entity.name, json: entity, run: async () => await $data.actions.entity.add(entity.name, entity) })) ); } if (state.fields?.create) { items.push( ...state.fields.create.map((field) => ({ action: "add", Icon: IconAlignJustified, type: "Field", name: field.name, json: field, run: async () => await $data.actions.entity .patch(field.entity) .fields.add(field.name, field.field as any) })) ); } if (state.relations?.create) { items.push( ...state.relations.create.map((rel) => ({ action: "add", Icon: IconCirclesRelation, type: "Relation", name: `${rel.source} -> ${rel.target} (${rel.type})`, json: rel, run: async () => await $data.actions.relations.add(rel) })) ); } async function handleCreate() { setSubmitting(true); for (const item of items) { try { const res = await item.run(); setStates((prev) => [...prev, res]); if (res !== true) { // make sure to break out break; } } catch (e) { setStates((prev) => [...prev, (e as any).message]); } } } useEffect(() => { console.log( "states", states, items, states.length, items.length, states.every((s) => s === true) ); if (items.length === states.length && states.every((s) => s === true)) { b.actions.reload().then(close); //close(); } else { setSubmitting(false); } }, [states]); return ( <>
This is what will be created. Please confirm by clicking "Next".
{items.map((item, i) => ( ))}
{/*
{submitting ? "submitting" : "idle"}
{states.length}/{items.length}
*/}
); } type SummaryItemProps = { Icon: IconType; action: "add" | string; type: string; name: string; json?: object; state?: boolean | string; initialExpanded?: boolean; }; const SummaryItem: React.FC = ({ Icon, type, name, json, state, action, initialExpanded = false }) => { const [expanded, handlers] = useDisclosure(initialExpanded); const error = typeof state !== "undefined" && state !== true; const done = state === true; return (
{json && ( )}
{json && expanded && (
)} {error && typeof state === "string" &&
{state}
}
); }; const Desc = ({ type, name }) => (
{ucFirst(type)}
{name}
);