mirror of
https://github.com/bknd-io/bknd/
synced 2026-08-03 00:26:01 +00:00
initial refactor
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
import type { ModalProps } from "@mantine/core";
|
||||
import type { ContextModalProps } from "@mantine/modals";
|
||||
import { type Static, StringEnum, StringIdentifier } from "core/utils";
|
||||
import { entitiesSchema, fieldsSchema, relationsSchema } from "data/data-schema";
|
||||
import { useState } from "react";
|
||||
import { type Modal2Ref, ModalBody, ModalFooter, ModalTitle } from "ui/components/modal/Modal2";
|
||||
@@ -11,58 +10,51 @@ import { StepEntityFields } from "./step.entity.fields";
|
||||
import { StepRelation } from "./step.relation";
|
||||
import { StepSelect } from "./step.select";
|
||||
import Templates from "./templates/register";
|
||||
import * as tbbox from "@sinclair/typebox";
|
||||
const { Type } = tbbox;
|
||||
import { s } from "core/object/schema";
|
||||
|
||||
export type CreateModalRef = Modal2Ref;
|
||||
|
||||
export const ModalActions = ["entity", "relation", "media"] as const;
|
||||
|
||||
export const entitySchema = Type.Composite([
|
||||
Type.Object({
|
||||
name: StringIdentifier,
|
||||
}),
|
||||
entitiesSchema,
|
||||
]);
|
||||
|
||||
const schemaAction = Type.Union([
|
||||
StringEnum(["entity", "relation", "media"]),
|
||||
Type.String({ pattern: "^template-" }),
|
||||
]);
|
||||
export type TSchemaAction = Static<typeof schemaAction>;
|
||||
|
||||
const createFieldSchema = Type.Object({
|
||||
entity: StringIdentifier,
|
||||
name: StringIdentifier,
|
||||
field: Type.Array(fieldsSchema),
|
||||
export const entitySchema = s.object({
|
||||
name: s.string(),
|
||||
...entitiesSchema.properties,
|
||||
});
|
||||
export type TFieldCreate = Static<typeof createFieldSchema>;
|
||||
|
||||
const createModalSchema = Type.Object(
|
||||
{
|
||||
action: schemaAction,
|
||||
initial: Type.Optional(Type.Any()),
|
||||
entities: Type.Optional(
|
||||
Type.Object({
|
||||
create: Type.Optional(Type.Array(entitySchema)),
|
||||
}),
|
||||
),
|
||||
relations: Type.Optional(
|
||||
Type.Object({
|
||||
create: Type.Optional(Type.Array(Type.Union(relationsSchema))),
|
||||
}),
|
||||
),
|
||||
fields: Type.Optional(
|
||||
Type.Object({
|
||||
create: Type.Optional(Type.Array(createFieldSchema)),
|
||||
}),
|
||||
),
|
||||
},
|
||||
{
|
||||
additionalProperties: false,
|
||||
},
|
||||
);
|
||||
export type TCreateModalSchema = Static<typeof createModalSchema>;
|
||||
// @todo: this union is not fully working, just "string"
|
||||
const schemaAction = s.anyOf([
|
||||
s.string({ enum: ["entity", "relation", "media"] }),
|
||||
s.string({ pattern: "^template-" }),
|
||||
]);
|
||||
export type TSchemaAction = s.Static<typeof schemaAction>;
|
||||
|
||||
const createFieldSchema = s.object({
|
||||
entity: s.string(),
|
||||
name: s.string(),
|
||||
field: s.array(fieldsSchema),
|
||||
});
|
||||
export type TFieldCreate = s.Static<typeof createFieldSchema>;
|
||||
|
||||
const createModalSchema = s.strictObject({
|
||||
action: schemaAction,
|
||||
initial: s.any().optional(),
|
||||
entities: s
|
||||
.object({
|
||||
create: s.array(entitySchema).optional(),
|
||||
})
|
||||
.optional(),
|
||||
relations: s
|
||||
.object({
|
||||
create: s.array(s.anyOf(relationsSchema)).optional(),
|
||||
})
|
||||
.optional(),
|
||||
fields: s
|
||||
.object({
|
||||
create: s.array(createFieldSchema).optional(),
|
||||
})
|
||||
.optional(),
|
||||
});
|
||||
export type TCreateModalSchema = s.Static<typeof createModalSchema>;
|
||||
|
||||
export function CreateModal({
|
||||
context,
|
||||
@@ -70,7 +62,6 @@ export function CreateModal({
|
||||
innerProps: { initialPath = [], initialState },
|
||||
}: ContextModalProps<{ initialPath?: string[]; initialState?: TCreateModalSchema }>) {
|
||||
const [path, setPath] = useState<string[]>(initialPath);
|
||||
console.log("...", initialPath, initialState);
|
||||
|
||||
function close() {
|
||||
context.closeModal(id);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { typeboxResolver } from "@hookform/resolvers/typebox";
|
||||
import { type Static, objectCleanEmpty } from "core/utils";
|
||||
//import { typeboxResolver } from "@hookform/resolvers/typebox";
|
||||
import { objectCleanEmpty } from "core/utils";
|
||||
import { type TAppDataEntityFields, entitiesSchema } from "data/data-schema";
|
||||
import { mergeWith } from "lodash-es";
|
||||
import { useRef } from "react";
|
||||
@@ -12,9 +12,10 @@ import {
|
||||
} from "ui/routes/data/forms/entity.fields.form";
|
||||
import { ModalBody, ModalFooter, type TCreateModalSchema, useStepContext } from "./CreateModal";
|
||||
import { useBkndData } from "ui/client/schema/data/use-bknd-data";
|
||||
import type { s } from "core/object/schema";
|
||||
|
||||
const schema = entitiesSchema;
|
||||
type Schema = Static<typeof schema>;
|
||||
type Schema = s.Static<typeof schema>;
|
||||
|
||||
export function StepEntityFields() {
|
||||
const { nextStep, stepBack, state, setState } = useStepContext<TCreateModalSchema>();
|
||||
@@ -40,7 +41,8 @@ export function StepEntityFields() {
|
||||
setValue,
|
||||
} = useForm({
|
||||
mode: "onTouched",
|
||||
resolver: typeboxResolver(schema),
|
||||
// @todo: add resolver
|
||||
//resolver: typeboxResolver(schema),
|
||||
defaultValues: initial as NonNullable<Schema>,
|
||||
});
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { typeboxResolver } from "@hookform/resolvers/typebox";
|
||||
//import { typeboxResolver } from "@hookform/resolvers/typebox";
|
||||
|
||||
import { TextInput, Textarea } from "@mantine/core";
|
||||
import { useFocusTrap } from "@mantine/hooks";
|
||||
@@ -10,7 +10,6 @@ import {
|
||||
entitySchema,
|
||||
useStepContext,
|
||||
} from "./CreateModal";
|
||||
import { MantineSelect } from "ui/components/form/hook-form-mantine/MantineSelect";
|
||||
|
||||
export function StepEntity() {
|
||||
const focusTrapRef = useFocusTrap();
|
||||
@@ -18,7 +17,8 @@ export function StepEntity() {
|
||||
const { nextStep, stepBack, state, setState } = useStepContext<TCreateModalSchema>();
|
||||
const { register, handleSubmit, formState, watch, control } = useForm({
|
||||
mode: "onTouched",
|
||||
resolver: typeboxResolver(entitySchema),
|
||||
// @todo: add resolver
|
||||
//resolver: typeboxResolver(entitySchema),
|
||||
defaultValues: state.entities?.create?.[0] ?? {},
|
||||
});
|
||||
/*const data = watch();
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
import { typeboxResolver } from "@hookform/resolvers/typebox";
|
||||
import { Switch, TextInput } from "@mantine/core";
|
||||
import { TypeRegistry } from "@sinclair/typebox";
|
||||
import { IconDatabase } from "@tabler/icons-react";
|
||||
import { type Static, StringEnum, StringIdentifier, registerCustomTypeboxKinds } from "core/utils";
|
||||
import { ManyToOneRelation, type RelationType, RelationTypes } from "data";
|
||||
import type { ReactNode } from "react";
|
||||
import { type Control, type FieldValues, type UseFormRegister, useForm } from "react-hook-form";
|
||||
@@ -14,11 +11,7 @@ import { MantineSelect } from "ui/components/form/hook-form-mantine/MantineSelec
|
||||
import { useStepContext } from "ui/components/steps/Steps";
|
||||
import { useEvent } from "ui/hooks/use-event";
|
||||
import { ModalBody, ModalFooter, type TCreateModalSchema } from "./CreateModal";
|
||||
import * as tbbox from "@sinclair/typebox";
|
||||
const { Type } = tbbox;
|
||||
|
||||
// @todo: check if this could become an issue
|
||||
registerCustomTypeboxKinds(TypeRegistry);
|
||||
import { s, stringIdentifier } from "core/object/schema";
|
||||
|
||||
const Relations: {
|
||||
type: RelationType;
|
||||
@@ -47,11 +40,11 @@ const Relations: {
|
||||
},
|
||||
];
|
||||
|
||||
const schema = Type.Object({
|
||||
type: StringEnum(Relations.map((r) => r.type)),
|
||||
source: StringIdentifier,
|
||||
target: StringIdentifier,
|
||||
config: Type.Object({}),
|
||||
const schema = s.strictObject({
|
||||
type: s.string({ enum: Relations.map((r) => r.type) }),
|
||||
source: stringIdentifier,
|
||||
target: stringIdentifier,
|
||||
config: s.object({}),
|
||||
});
|
||||
|
||||
type ComponentCtx<T extends FieldValues = FieldValues> = {
|
||||
@@ -73,8 +66,9 @@ export function StepRelation() {
|
||||
watch,
|
||||
control,
|
||||
} = useForm({
|
||||
resolver: typeboxResolver(schema),
|
||||
defaultValues: (state.relations?.create?.[0] ?? {}) as Static<typeof schema>,
|
||||
// @todo: implement resolver
|
||||
//resolver: typeboxResolver(schema),
|
||||
defaultValues: (state.relations?.create?.[0] ?? {}) as s.Static<typeof schema>,
|
||||
});
|
||||
const data = watch();
|
||||
|
||||
|
||||
+12
-12
@@ -1,6 +1,5 @@
|
||||
import { typeboxResolver } from "@hookform/resolvers/typebox";
|
||||
import { Radio, TextInput } from "@mantine/core";
|
||||
import { Default, type Static, StringEnum, StringIdentifier, transformObject } from "core/utils";
|
||||
import { transformObject } from "core/utils";
|
||||
import type { MediaFieldConfig } from "media/MediaField";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
@@ -15,16 +14,15 @@ import {
|
||||
type TFieldCreate,
|
||||
useStepContext,
|
||||
} from "../../CreateModal";
|
||||
import * as tbbox from "@sinclair/typebox";
|
||||
const { Type } = tbbox;
|
||||
import { s, stringIdentifier } from "core/object/schema";
|
||||
|
||||
const schema = Type.Object({
|
||||
entity: StringIdentifier,
|
||||
cardinality_type: StringEnum(["single", "multiple"], { default: "multiple" }),
|
||||
cardinality: Type.Optional(Type.Number({ minimum: 1 })),
|
||||
name: StringIdentifier,
|
||||
const schema = s.object({
|
||||
entity: stringIdentifier,
|
||||
cardinality_type: s.string({ enum: ["single", "multiple"], default: "multiple" }),
|
||||
cardinality: s.number({ minimum: 1 }).optional(),
|
||||
name: stringIdentifier,
|
||||
});
|
||||
type TCreateModalMediaSchema = Static<typeof schema>;
|
||||
type TCreateModalMediaSchema = s.Static<typeof schema>;
|
||||
|
||||
export function TemplateMediaComponent() {
|
||||
const { stepBack, setState, state, path, nextStep } = useStepContext<TCreateModalSchema>();
|
||||
@@ -36,8 +34,10 @@ export function TemplateMediaComponent() {
|
||||
control,
|
||||
} = useForm({
|
||||
mode: "onChange",
|
||||
resolver: typeboxResolver(schema),
|
||||
defaultValues: Default(schema, state.initial ?? {}) as TCreateModalMediaSchema,
|
||||
// @todo: add resolver
|
||||
//resolver: typeboxResolver(schema),
|
||||
defaultValues: schema.template(state.initial ?? {}) as TCreateModalMediaSchema,
|
||||
//defaultValues: Default(schema, state.initial ?? {}) as TCreateModalMediaSchema,
|
||||
});
|
||||
const [forbidden, setForbidden] = useState<boolean>(false);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user