mirror of
https://github.com/shishantbiswas/bknd.git
synced 2026-03-16 12:37:20 +00:00
added format command and added trailing commas to reduce conflicts
This commit is contained in:
@@ -6,7 +6,7 @@ import {
|
||||
type Field,
|
||||
JsonField,
|
||||
JsonSchemaField,
|
||||
RelationField
|
||||
RelationField,
|
||||
} from "data";
|
||||
import { MediaField } from "media/MediaField";
|
||||
import { type ComponentProps, Suspense } from "react";
|
||||
@@ -37,7 +37,7 @@ export function EntityForm({
|
||||
Form,
|
||||
data,
|
||||
className,
|
||||
action
|
||||
action,
|
||||
}: EntityFormProps) {
|
||||
const fields = entity.getFillableFields(action, true);
|
||||
console.log("data", { data, fields });
|
||||
@@ -120,7 +120,7 @@ export function EntityForm({
|
||||
|
||||
type EntityFormFieldProps<
|
||||
T extends keyof JSX.IntrinsicElements = "input",
|
||||
F extends Field = Field
|
||||
F extends Field = Field,
|
||||
> = ComponentProps<T> & {
|
||||
fieldApi: FieldApi<any, any>;
|
||||
field: F;
|
||||
@@ -203,7 +203,7 @@ function EntityMediaFormField({
|
||||
field,
|
||||
entity,
|
||||
entityId,
|
||||
disabled
|
||||
disabled,
|
||||
}: {
|
||||
formApi: FormApi<any>;
|
||||
field: MediaField;
|
||||
@@ -232,7 +232,7 @@ function EntityMediaFormField({
|
||||
entity={{
|
||||
name: entity.name,
|
||||
id: entityId,
|
||||
field: field.name
|
||||
field: field.name,
|
||||
}}
|
||||
/>
|
||||
</Formy.Group>
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
TbChevronsRight,
|
||||
TbSelector,
|
||||
TbSquare,
|
||||
TbSquareCheckFilled
|
||||
TbSquareCheckFilled,
|
||||
} from "react-icons/tb";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
import { Button } from "ui/components/buttons/Button";
|
||||
@@ -58,7 +58,7 @@ export const EntityTable: React.FC<EntityTableProps> = ({
|
||||
perPage = 10,
|
||||
perPageOptions,
|
||||
onClickPerPage,
|
||||
classNames
|
||||
classNames,
|
||||
}) => {
|
||||
select = select && select.length > 0 ? select : entity.getSelect();
|
||||
total = total || data.length;
|
||||
@@ -157,7 +157,7 @@ export const EntityTable: React.FC<EntityTableProps> = ({
|
||||
<Dropdown
|
||||
items={perPageOptions.map((perPage) => ({
|
||||
label: String(perPage),
|
||||
perPage
|
||||
perPage,
|
||||
}))}
|
||||
position="top-end"
|
||||
onClickItem={(item: any) => onClickPerPage?.(item.perPage)}
|
||||
@@ -182,7 +182,7 @@ export const EntityTable: React.FC<EntityTableProps> = ({
|
||||
|
||||
const SortIndicator = ({
|
||||
sort,
|
||||
field
|
||||
field,
|
||||
}: {
|
||||
sort: Pick<EntityTableProps, "sort">["sort"];
|
||||
field: string;
|
||||
@@ -220,7 +220,7 @@ const TableNav: React.FC<TableNavProps> = ({ current, total, onClick }: TableNav
|
||||
{ value: 1, Icon: TbChevronsLeft, disabled: current === 1 },
|
||||
{ value: current - 1, Icon: TbChevronLeft, disabled: current === 1 },
|
||||
{ value: current + 1, Icon: TbChevronRight, disabled: current === total },
|
||||
{ value: total, Icon: TbChevronsRight, disabled: current === total }
|
||||
{ value: total, Icon: TbChevronsRight, disabled: current === total },
|
||||
] as const;
|
||||
|
||||
return navMap.map((nav, key) => (
|
||||
|
||||
@@ -37,7 +37,7 @@ export function EntityTable2({ entity, select, ...props }: EntityTableProps) {
|
||||
console.warn(
|
||||
"Couldn't render value",
|
||||
{ value, property, entity, select, columns, ...props },
|
||||
e
|
||||
e,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ function entitiesToNodes(entities: AppDataConfig["entities"]): Node<TAppDataEnti
|
||||
dragHandle: ".drag-handle",
|
||||
position: { x: 0, y: 0 },
|
||||
sourcePosition: Position.Right,
|
||||
targetPosition: Position.Left
|
||||
targetPosition: Position.Left,
|
||||
};
|
||||
});
|
||||
}
|
||||
@@ -36,46 +36,46 @@ function relationsToEdges(relations: AppDataConfig["relations"]) {
|
||||
source: relation.source,
|
||||
target: relation.target,
|
||||
sourceHandle,
|
||||
targetHandle: relation.target + ":id"
|
||||
targetHandle: relation.target + ":id",
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
const nodeTypes = {
|
||||
entity: EntityTableNode.Component
|
||||
entity: EntityTableNode.Component,
|
||||
} as const;
|
||||
|
||||
export function DataSchemaCanvas() {
|
||||
const {
|
||||
config: { data }
|
||||
config: { data },
|
||||
} = useBknd();
|
||||
const { theme } = useBkndSystemTheme();
|
||||
const nodes = entitiesToNodes(data.entities);
|
||||
const edges = relationsToEdges(data.relations).map((e) => ({
|
||||
...e,
|
||||
style: {
|
||||
stroke: theme === "light" ? "#ccc" : "#666"
|
||||
stroke: theme === "light" ? "#ccc" : "#666",
|
||||
},
|
||||
type: "smoothstep",
|
||||
markerEnd: {
|
||||
type: MarkerType.Arrow,
|
||||
width: 20,
|
||||
height: 20,
|
||||
color: theme === "light" ? "#aaa" : "#777"
|
||||
}
|
||||
color: theme === "light" ? "#aaa" : "#777",
|
||||
},
|
||||
}));
|
||||
|
||||
const nodeLayout = layoutWithDagre({
|
||||
nodes: nodes.map((n) => ({
|
||||
id: n.id,
|
||||
...EntityTableNode.getSize(n.data)
|
||||
...EntityTableNode.getSize(n.data),
|
||||
})),
|
||||
edges,
|
||||
graph: {
|
||||
rankdir: "LR",
|
||||
marginx: 50,
|
||||
marginy: 50
|
||||
}
|
||||
marginy: 50,
|
||||
},
|
||||
});
|
||||
|
||||
nodeLayout.nodes.forEach((node) => {
|
||||
@@ -95,7 +95,7 @@ export function DataSchemaCanvas() {
|
||||
maxZoom={2}
|
||||
fitViewOptions={{
|
||||
minZoom: 0.1,
|
||||
maxZoom: 0.8
|
||||
maxZoom: 0.8,
|
||||
}}
|
||||
>
|
||||
<Panels zoom minimap />
|
||||
|
||||
@@ -47,14 +47,14 @@ function NodeComponent(props: NodeProps<Node<TAppDataEntity & { label: string }>
|
||||
|
||||
const handleStyle = {
|
||||
background: "transparent",
|
||||
border: "none"
|
||||
border: "none",
|
||||
};
|
||||
const TableRow = ({
|
||||
field,
|
||||
table,
|
||||
index,
|
||||
onHover,
|
||||
last
|
||||
last,
|
||||
}: {
|
||||
field: TableField;
|
||||
table: string;
|
||||
@@ -71,7 +71,7 @@ const TableRow = ({
|
||||
className={twMerge(
|
||||
"flex flex-row w-full justify-between font-mono py-1.5 px-2.5 border-b border-primary/15 border-l border-r cursor-auto",
|
||||
last && "rounded-bl-lg rounded-br-lg",
|
||||
"hover:bg-primary/5"
|
||||
"hover:bg-primary/5",
|
||||
)}
|
||||
>
|
||||
{handles && (
|
||||
@@ -108,7 +108,7 @@ const TableRow = ({
|
||||
|
||||
export const HEIGHTS = {
|
||||
header: 30,
|
||||
row: 32.5
|
||||
row: 32.5,
|
||||
};
|
||||
|
||||
export const EntityTableNode = {
|
||||
@@ -118,7 +118,7 @@ export const EntityTableNode = {
|
||||
const field_count = Object.keys(fields).length;
|
||||
return {
|
||||
width: 320,
|
||||
height: HEIGHTS.header + HEIGHTS.row * field_count
|
||||
height: HEIGHTS.header + HEIGHTS.row * field_count,
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
TbPhoto,
|
||||
TbSelector,
|
||||
TbTextCaption,
|
||||
TbToggleLeft
|
||||
TbToggleLeft,
|
||||
} from "react-icons/tb";
|
||||
|
||||
export type TFieldSpec = {
|
||||
@@ -26,55 +26,55 @@ export const fieldSpecs: TFieldSpec[] = [
|
||||
icon: TbTextCaption,
|
||||
addable: false,
|
||||
disabled: ["name"],
|
||||
hidden: ["virtual"]
|
||||
hidden: ["virtual"],
|
||||
},
|
||||
{
|
||||
type: "text",
|
||||
label: "Text",
|
||||
icon: TbTextCaption
|
||||
icon: TbTextCaption,
|
||||
},
|
||||
{
|
||||
type: "number",
|
||||
label: "Number",
|
||||
icon: TbNumber123
|
||||
icon: TbNumber123,
|
||||
},
|
||||
{
|
||||
type: "boolean",
|
||||
label: "Boolean",
|
||||
icon: TbToggleLeft
|
||||
icon: TbToggleLeft,
|
||||
},
|
||||
{
|
||||
type: "date",
|
||||
label: "Date",
|
||||
icon: TbCalendar
|
||||
icon: TbCalendar,
|
||||
},
|
||||
{
|
||||
type: "enum",
|
||||
label: "Enum",
|
||||
icon: TbSelector
|
||||
icon: TbSelector,
|
||||
},
|
||||
{
|
||||
type: "json",
|
||||
label: "JSON",
|
||||
icon: TbBraces
|
||||
icon: TbBraces,
|
||||
},
|
||||
{
|
||||
type: "jsonschema",
|
||||
label: "JSON Schema",
|
||||
icon: TbCodePlus
|
||||
icon: TbCodePlus,
|
||||
},
|
||||
{
|
||||
type: "relation",
|
||||
label: "Relation",
|
||||
icon: TbCirclesRelation,
|
||||
addable: false,
|
||||
hidden: ["virtual"]
|
||||
hidden: ["virtual"],
|
||||
},
|
||||
{
|
||||
type: "media",
|
||||
label: "Media",
|
||||
icon: TbPhoto,
|
||||
addable: false,
|
||||
hidden: ["virtual"]
|
||||
}
|
||||
hidden: ["virtual"],
|
||||
},
|
||||
];
|
||||
|
||||
@@ -39,7 +39,7 @@ export function EntityJsonSchemaFormField({
|
||||
formData={formData}
|
||||
uiSchema={{
|
||||
"ui:globalOptions": { flexDirection: "row" },
|
||||
...field.getJsonUiSchema()
|
||||
...field.getJsonUiSchema(),
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -190,8 +190,15 @@ type PropoverTableProps = Omit<EntityTableProps, "data"> & {
|
||||
container: ResponseObject;
|
||||
query: any;
|
||||
toggle: () => void;
|
||||
}
|
||||
const PopoverTable = ({ container, entity, query, toggle, onClickRow, onClickPage }: PropoverTableProps) => {
|
||||
};
|
||||
const PopoverTable = ({
|
||||
container,
|
||||
entity,
|
||||
query,
|
||||
toggle,
|
||||
onClickRow,
|
||||
onClickPage,
|
||||
}: PropoverTableProps) => {
|
||||
function handleNext() {
|
||||
if (query.limit * query.page < container.meta?.count) {
|
||||
onClickPage?.(query.page + 1);
|
||||
|
||||
@@ -18,21 +18,21 @@ export const ModalActions = ["entity", "relation", "media"] as const;
|
||||
|
||||
export const entitySchema = Type.Composite([
|
||||
Type.Object({
|
||||
name: StringIdentifier
|
||||
name: StringIdentifier,
|
||||
}),
|
||||
entitiesSchema
|
||||
entitiesSchema,
|
||||
]);
|
||||
|
||||
const schemaAction = Type.Union([
|
||||
StringEnum(["entity", "relation", "media"]),
|
||||
Type.String({ pattern: "^template-" })
|
||||
Type.String({ pattern: "^template-" }),
|
||||
]);
|
||||
export type TSchemaAction = Static<typeof schemaAction>;
|
||||
|
||||
const createFieldSchema = Type.Object({
|
||||
entity: StringIdentifier,
|
||||
name: StringIdentifier,
|
||||
field: Type.Array(fieldsSchema)
|
||||
field: Type.Array(fieldsSchema),
|
||||
});
|
||||
export type TFieldCreate = Static<typeof createFieldSchema>;
|
||||
|
||||
@@ -42,30 +42,30 @@ const createModalSchema = Type.Object(
|
||||
initial: Type.Optional(Type.Any()),
|
||||
entities: Type.Optional(
|
||||
Type.Object({
|
||||
create: Type.Optional(Type.Array(entitySchema))
|
||||
})
|
||||
create: Type.Optional(Type.Array(entitySchema)),
|
||||
}),
|
||||
),
|
||||
relations: Type.Optional(
|
||||
Type.Object({
|
||||
create: Type.Optional(Type.Array(Type.Union(relationsSchema)))
|
||||
})
|
||||
create: Type.Optional(Type.Array(Type.Union(relationsSchema))),
|
||||
}),
|
||||
),
|
||||
fields: Type.Optional(
|
||||
Type.Object({
|
||||
create: Type.Optional(Type.Array(createFieldSchema))
|
||||
})
|
||||
)
|
||||
create: Type.Optional(Type.Array(createFieldSchema)),
|
||||
}),
|
||||
),
|
||||
},
|
||||
{
|
||||
additionalProperties: false
|
||||
}
|
||||
additionalProperties: false,
|
||||
},
|
||||
);
|
||||
export type TCreateModalSchema = Static<typeof createModalSchema>;
|
||||
|
||||
export function CreateModal({
|
||||
context,
|
||||
id,
|
||||
innerProps: { initialPath = [], initialState }
|
||||
innerProps: { initialPath = [], initialState },
|
||||
}: ContextModalProps<{ initialPath?: string[]; initialState?: TCreateModalSchema }>) {
|
||||
const [path, setPath] = useState<string[]>(initialPath);
|
||||
console.log("...", initialPath, initialState);
|
||||
@@ -111,7 +111,7 @@ CreateModal.defaultTitle = undefined;
|
||||
CreateModal.modalProps = {
|
||||
withCloseButton: false,
|
||||
size: "xl",
|
||||
padding: 0
|
||||
padding: 0,
|
||||
} satisfies Partial<ModalProps>;
|
||||
|
||||
export { ModalBody, ModalFooter, ModalTitle, useStepContext, relationsSchema };
|
||||
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
IconAugmentedReality,
|
||||
IconBox,
|
||||
IconCirclesRelation,
|
||||
IconInfoCircle
|
||||
IconInfoCircle,
|
||||
} from "@tabler/icons-react";
|
||||
import { ucFirst } from "core/utils";
|
||||
import { useEffect, useState } from "react";
|
||||
@@ -37,8 +37,8 @@ export function StepCreate() {
|
||||
type: "Entity",
|
||||
name: entity.name,
|
||||
json: entity,
|
||||
run: async () => await $data.actions.entity.add(entity.name, entity)
|
||||
}))
|
||||
run: async () => await $data.actions.entity.add(entity.name, entity),
|
||||
})),
|
||||
);
|
||||
}
|
||||
if (state.fields?.create) {
|
||||
@@ -52,8 +52,8 @@ export function StepCreate() {
|
||||
run: async () =>
|
||||
await $data.actions.entity
|
||||
.patch(field.entity)
|
||||
.fields.add(field.name, field.field as any)
|
||||
}))
|
||||
.fields.add(field.name, field.field as any),
|
||||
})),
|
||||
);
|
||||
}
|
||||
if (state.relations?.create) {
|
||||
@@ -64,8 +64,8 @@ export function StepCreate() {
|
||||
type: "Relation",
|
||||
name: `${rel.source} -> ${rel.target} (${rel.type})`,
|
||||
json: rel,
|
||||
run: async () => await $data.actions.relations.add(rel)
|
||||
}))
|
||||
run: async () => await $data.actions.relations.add(rel),
|
||||
})),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ export function StepCreate() {
|
||||
items,
|
||||
states.length,
|
||||
items.length,
|
||||
states.every((s) => s === true)
|
||||
states.every((s) => s === true),
|
||||
);
|
||||
if (items.length === states.length && states.every((s) => s === true)) {
|
||||
b.actions.reload().then(close);
|
||||
@@ -116,7 +116,7 @@ export function StepCreate() {
|
||||
nextLabel="Create"
|
||||
next={{
|
||||
onClick: handleCreate,
|
||||
disabled: submitting
|
||||
disabled: submitting,
|
||||
}}
|
||||
prev={{ onClick: stepBack, disabled: submitting }}
|
||||
debug={{ state }}
|
||||
@@ -142,7 +142,7 @@ const SummaryItem: React.FC<SummaryItemProps> = ({
|
||||
json,
|
||||
state,
|
||||
action,
|
||||
initialExpanded = false
|
||||
initialExpanded = false,
|
||||
}) => {
|
||||
const [expanded, handlers] = useDisclosure(initialExpanded);
|
||||
const error = typeof state !== "undefined" && state !== true;
|
||||
@@ -153,7 +153,7 @@ const SummaryItem: React.FC<SummaryItemProps> = ({
|
||||
className={twMerge(
|
||||
"flex flex-col border border-muted rounded bg-background mb-2",
|
||||
error && "bg-red-500/20",
|
||||
done && "bg-green-500/20"
|
||||
done && "bg-green-500/20",
|
||||
)}
|
||||
>
|
||||
<div className="flex flex-row gap-4 px-2 py-2 items-center">
|
||||
|
||||
@@ -8,7 +8,7 @@ import { MantineSelect } from "ui/components/form/hook-form-mantine/MantineSelec
|
||||
import { useEvent } from "ui/hooks/use-event";
|
||||
import {
|
||||
EntityFieldsForm,
|
||||
type EntityFieldsFormRef
|
||||
type EntityFieldsFormRef,
|
||||
} from "ui/routes/data/forms/entity.fields.form";
|
||||
import { ModalBody, ModalFooter, type TCreateModalSchema, useStepContext } from "./CreateModal";
|
||||
|
||||
@@ -25,9 +25,9 @@ export function StepEntityFields() {
|
||||
fields: defaultFields,
|
||||
config: {
|
||||
sort_field: "id",
|
||||
sort_dir: "asc"
|
||||
}
|
||||
})
|
||||
sort_dir: "asc",
|
||||
},
|
||||
}),
|
||||
);
|
||||
const {
|
||||
control,
|
||||
@@ -35,11 +35,11 @@ export function StepEntityFields() {
|
||||
getValues,
|
||||
handleSubmit,
|
||||
watch,
|
||||
setValue
|
||||
setValue,
|
||||
} = useForm({
|
||||
mode: "onTouched",
|
||||
resolver: typeboxResolver(schema),
|
||||
defaultValues: initial as NonNullable<Schema>
|
||||
defaultValues: initial as NonNullable<Schema>,
|
||||
});
|
||||
|
||||
const values = watch();
|
||||
@@ -58,8 +58,8 @@ export function StepEntityFields() {
|
||||
return {
|
||||
...prev,
|
||||
entities: {
|
||||
create: [getValues() as any]
|
||||
}
|
||||
create: [getValues() as any],
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
@@ -119,7 +119,7 @@ export function StepEntityFields() {
|
||||
<ModalFooter
|
||||
next={{
|
||||
disabled: !isValid,
|
||||
type: "submit"
|
||||
type: "submit",
|
||||
//onClick: handleNext
|
||||
}}
|
||||
prev={{ onClick: stepBack }}
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
ModalFooter,
|
||||
type TCreateModalSchema,
|
||||
entitySchema,
|
||||
useStepContext
|
||||
useStepContext,
|
||||
} from "./CreateModal";
|
||||
|
||||
export function StepEntity() {
|
||||
@@ -18,7 +18,7 @@ export function StepEntity() {
|
||||
const { register, handleSubmit, formState, watch } = useForm({
|
||||
mode: "onTouched",
|
||||
resolver: typeboxResolver(entitySchema),
|
||||
defaultValues: state.entities?.create?.[0] ?? {}
|
||||
defaultValues: state.entities?.create?.[0] ?? {},
|
||||
});
|
||||
/*const data = watch();
|
||||
console.log("state", { isValid });
|
||||
@@ -83,7 +83,7 @@ export function StepEntity() {
|
||||
<ModalFooter
|
||||
next={{
|
||||
type: "submit",
|
||||
disabled: !formState.isValid
|
||||
disabled: !formState.isValid,
|
||||
//onClick:
|
||||
}}
|
||||
prev={{ onClick: stepBack }}
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
StringEnum,
|
||||
StringIdentifier,
|
||||
Type,
|
||||
registerCustomTypeboxKinds
|
||||
registerCustomTypeboxKinds,
|
||||
} from "core/utils";
|
||||
import { ManyToOneRelation, type RelationType, RelationTypes } from "data";
|
||||
import { type ReactNode, startTransition, useEffect } from "react";
|
||||
@@ -32,30 +32,30 @@ const Relations: {
|
||||
{
|
||||
type: RelationTypes.ManyToOne,
|
||||
label: "Many to One",
|
||||
component: ManyToOne
|
||||
component: ManyToOne,
|
||||
},
|
||||
{
|
||||
type: RelationTypes.OneToOne,
|
||||
label: "One to One",
|
||||
component: OneToOne
|
||||
component: OneToOne,
|
||||
},
|
||||
{
|
||||
type: RelationTypes.ManyToMany,
|
||||
label: "Many to Many",
|
||||
component: ManyToMany
|
||||
component: ManyToMany,
|
||||
},
|
||||
{
|
||||
type: RelationTypes.Polymorphic,
|
||||
label: "Polymorphic",
|
||||
component: Polymorphic
|
||||
}
|
||||
component: Polymorphic,
|
||||
},
|
||||
];
|
||||
|
||||
const schema = Type.Object({
|
||||
type: StringEnum(Relations.map((r) => r.type)),
|
||||
source: StringIdentifier,
|
||||
target: StringIdentifier,
|
||||
config: Type.Object({})
|
||||
config: Type.Object({}),
|
||||
});
|
||||
|
||||
type ComponentCtx<T extends FieldValues = FieldValues> = {
|
||||
@@ -75,10 +75,10 @@ export function StepRelation() {
|
||||
formState: { isValid },
|
||||
setValue,
|
||||
watch,
|
||||
control
|
||||
control,
|
||||
} = useForm({
|
||||
resolver: typeboxResolver(schema),
|
||||
defaultValues: (state.relations?.create?.[0] ?? {}) as Static<typeof schema>
|
||||
defaultValues: (state.relations?.create?.[0] ?? {}) as Static<typeof schema>,
|
||||
});
|
||||
const data = watch();
|
||||
|
||||
@@ -88,8 +88,8 @@ export function StepRelation() {
|
||||
return {
|
||||
...prev,
|
||||
relations: {
|
||||
create: [data]
|
||||
}
|
||||
create: [data],
|
||||
},
|
||||
};
|
||||
});
|
||||
console.log("data", data);
|
||||
@@ -131,7 +131,7 @@ export function StepRelation() {
|
||||
data={Object.entries(entities ?? {}).map(([name, entity]) => ({
|
||||
value: name,
|
||||
label: entity.config?.name ?? name,
|
||||
disabled: data.target === name
|
||||
disabled: data.target === name,
|
||||
}))}
|
||||
/>
|
||||
<div className="flex flex-col gap-1">
|
||||
@@ -159,7 +159,7 @@ export function StepRelation() {
|
||||
data={Object.entries(entities ?? {}).map(([name, entity]) => ({
|
||||
value: name,
|
||||
label: entity.config?.name ?? name,
|
||||
disabled: data.source === name
|
||||
disabled: data.source === name,
|
||||
}))}
|
||||
/>
|
||||
</div>
|
||||
@@ -169,7 +169,7 @@ export function StepRelation() {
|
||||
Relations.find((r) => r.type === data.type)?.component({
|
||||
register,
|
||||
control,
|
||||
data
|
||||
data,
|
||||
})}
|
||||
</div>
|
||||
</ModalBody>
|
||||
@@ -177,7 +177,7 @@ export function StepRelation() {
|
||||
next={{
|
||||
type: "submit",
|
||||
disabled: !isValid,
|
||||
onClick: handleNext
|
||||
onClick: handleNext,
|
||||
}}
|
||||
prev={{ onClick: stepBack }}
|
||||
debug={{ state, path, data }}
|
||||
@@ -267,8 +267,8 @@ function OneToOne({
|
||||
data: {
|
||||
source,
|
||||
target,
|
||||
config: { mappedBy, required }
|
||||
}
|
||||
config: { mappedBy, required },
|
||||
},
|
||||
}: ComponentCtx) {
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
ModalFooter,
|
||||
type TCreateModalSchema,
|
||||
type TSchemaAction,
|
||||
useStepContext
|
||||
useStepContext,
|
||||
} from "./CreateModal";
|
||||
import Templates from "./templates/register";
|
||||
|
||||
@@ -70,7 +70,7 @@ export function StepSelect() {
|
||||
<ModalFooter
|
||||
next={{
|
||||
onClick: selected && nextStep(selected),
|
||||
disabled: !selected
|
||||
disabled: !selected,
|
||||
}}
|
||||
prev={{ onClick: stepBack }}
|
||||
prevLabel="Cancel"
|
||||
@@ -87,7 +87,7 @@ const RadioCard = ({
|
||||
onClick,
|
||||
selected,
|
||||
compact = false,
|
||||
disabled = false
|
||||
disabled = false,
|
||||
}: {
|
||||
Icon: IconType;
|
||||
title: string;
|
||||
@@ -104,7 +104,7 @@ const RadioCard = ({
|
||||
"flex gap-3 border border-primary/10 rounded cursor-pointer",
|
||||
compact ? "flex-row p-4 items-center" : "flex-col p-5",
|
||||
selected ? "bg-primary/10 border-primary/50" : "hover:bg-primary/5",
|
||||
disabled && "opacity-50"
|
||||
disabled && "opacity-50",
|
||||
)}
|
||||
>
|
||||
<Icon className="size-10" />
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
StringEnum,
|
||||
StringIdentifier,
|
||||
Type,
|
||||
transformObject
|
||||
transformObject,
|
||||
} from "core/utils";
|
||||
import type { MediaFieldConfig } from "media/MediaField";
|
||||
import { useEffect, useState } from "react";
|
||||
@@ -20,14 +20,14 @@ import {
|
||||
ModalFooter,
|
||||
type TCreateModalSchema,
|
||||
type TFieldCreate,
|
||||
useStepContext
|
||||
useStepContext,
|
||||
} from "../../CreateModal";
|
||||
|
||||
const schema = Type.Object({
|
||||
entity: StringIdentifier,
|
||||
cardinality_type: StringEnum(["single", "multiple"], { default: "multiple" }),
|
||||
cardinality: Type.Optional(Type.Number({ minimum: 1 })),
|
||||
name: StringIdentifier
|
||||
name: StringIdentifier,
|
||||
});
|
||||
type TCreateModalMediaSchema = Static<typeof schema>;
|
||||
|
||||
@@ -38,11 +38,11 @@ export function TemplateMediaComponent() {
|
||||
handleSubmit,
|
||||
formState: { isValid, errors },
|
||||
watch,
|
||||
control
|
||||
control,
|
||||
} = useForm({
|
||||
mode: "onChange",
|
||||
resolver: typeboxResolver(schema),
|
||||
defaultValues: Default(schema, state.initial ?? {}) as TCreateModalMediaSchema
|
||||
defaultValues: Default(schema, state.initial ?? {}) as TCreateModalMediaSchema,
|
||||
});
|
||||
const [forbidden, setForbidden] = useState<boolean>(false);
|
||||
|
||||
@@ -50,7 +50,7 @@ export function TemplateMediaComponent() {
|
||||
const media_enabled = config.media.enabled ?? false;
|
||||
const media_entity = config.media.entity_name ?? "media";
|
||||
const entities = transformObject(config.data.entities ?? {}, (entity, name) =>
|
||||
name !== media_entity ? entity : undefined
|
||||
name !== media_entity ? entity : undefined,
|
||||
);
|
||||
const data = watch();
|
||||
const forbidden_field_names = Object.keys(config.data.entities?.[data.entity]?.fields ?? {});
|
||||
@@ -66,7 +66,7 @@ export function TemplateMediaComponent() {
|
||||
setState((prev) => ({
|
||||
...prev,
|
||||
fields: { create: [field] },
|
||||
relations: { create: [relation] }
|
||||
relations: { create: [relation] },
|
||||
}));
|
||||
|
||||
nextStep("create")();
|
||||
@@ -92,7 +92,7 @@ export function TemplateMediaComponent() {
|
||||
required
|
||||
data={Object.entries(entities).map(([name, entity]) => ({
|
||||
value: name,
|
||||
label: entity.config?.name ?? name
|
||||
label: entity.config?.name ?? name,
|
||||
}))}
|
||||
/>
|
||||
<MantineRadio.Group
|
||||
@@ -141,10 +141,10 @@ export function TemplateMediaComponent() {
|
||||
<ModalFooter
|
||||
next={{
|
||||
type: "submit",
|
||||
disabled: !isValid || !media_enabled || forbidden
|
||||
disabled: !isValid || !media_enabled || forbidden,
|
||||
}}
|
||||
prev={{
|
||||
onClick: stepBack
|
||||
onClick: stepBack,
|
||||
}}
|
||||
debug={{ state, path, data }}
|
||||
/>
|
||||
@@ -169,9 +169,9 @@ function convert(media_entity: string, data: TCreateModalMediaSchema) {
|
||||
hidden: false,
|
||||
mime_types: [],
|
||||
virtual: true,
|
||||
entity: data.entity
|
||||
}
|
||||
}
|
||||
entity: data.entity,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const relation = {
|
||||
@@ -180,8 +180,8 @@ function convert(media_entity: string, data: TCreateModalMediaSchema) {
|
||||
target: media_entity,
|
||||
config: {
|
||||
mappedBy: data.name,
|
||||
targetCardinality: data.cardinality_type === "single" ? 1 : undefined
|
||||
}
|
||||
targetCardinality: data.cardinality_type === "single" ? 1 : undefined,
|
||||
},
|
||||
};
|
||||
|
||||
if (data.cardinality_type === "multiple") {
|
||||
|
||||
@@ -5,5 +5,5 @@ export const TemplateMediaMeta = {
|
||||
id: "template-media",
|
||||
title: "Attach Media",
|
||||
description: "Attach media to an entity",
|
||||
Icon: TbPhoto
|
||||
Icon: TbPhoto,
|
||||
} satisfies StepTemplate;
|
||||
|
||||
@@ -9,7 +9,7 @@ export type StepTemplate = {
|
||||
};
|
||||
|
||||
const Templates: [() => JSX.Element, StepTemplate][] = [
|
||||
[TemplateMediaComponent, TemplateMediaMeta]
|
||||
[TemplateMediaComponent, TemplateMediaMeta],
|
||||
];
|
||||
|
||||
export default Templates;
|
||||
|
||||
Reference in New Issue
Block a user