Improving props drilling for resources and resources path

This commit is contained in:
2025-04-21 15:43:53 +02:00
parent 484246bd5d
commit ee9eb97262
10 changed files with 58 additions and 56 deletions

View File

@@ -7,11 +7,13 @@ import { useForm } from "@refinedev/core";
import CrudTextWidget from "./widgets/crud-text-widget"; import CrudTextWidget from "./widgets/crud-text-widget";
import UnionEnumField from "./fields/union-enum"; import UnionEnumField from "./fields/union-enum";
import { CircularProgress } from "@mui/material"; import { CircularProgress } from "@mui/material";
import { ResourceContext } from "../contexts/ResourceContext";
type CrudFormProps = { type CrudFormProps = {
schemaName: string, schemaName: string,
uiSchema?: UiSchema, uiSchema?: UiSchema,
resource: string, resource: string,
resourceBasePath?: string,
id?: string, id?: string,
//onSubmit: (data: IChangeEvent, event: FormEvent<any>) => void //onSubmit: (data: IChangeEvent, event: FormEvent<any>) => void
onSuccess?: (data: any) => void onSuccess?: (data: any) => void
@@ -26,9 +28,9 @@ const customFields: RegistryFieldsType = {
} }
export const CrudForm: React.FC<CrudFormProps> = (props) => { export const CrudForm: React.FC<CrudFormProps> = (props) => {
const { schemaName, uiSchema, resource, id, onSuccess } = props; const { schemaName, uiSchema, resourceBasePath="" ,resource, id, onSuccess } = props;
const { onFinish, query, formLoading } = useForm({ const { onFinish, query, formLoading } = useForm({
resource: resource, resource: `${resourceBasePath}/${resource}`,
action: id === undefined ? "create" : "edit", action: id === undefined ? "create" : "edit",
redirect: "show", redirect: "show",
id, id,
@@ -61,16 +63,18 @@ export const CrudForm: React.FC<CrudFormProps> = (props) => {
} }
return ( return (
<Form <ResourceContext.Provider value={{basePath: resourceBasePath}} >
schema={schema} <Form
uiSchema={uiSchema === undefined ? {} : uiSchema} schema={schema}
formData={record} uiSchema={uiSchema === undefined ? {} : uiSchema}
onChange={(e) => setFormData(e.formData)} formData={record}
onSubmit={(e) => onFinish(e.formData)} onChange={(e) => setFormData(e.formData)}
validator={validator} onSubmit={(e) => onFinish(e.formData)}
omitExtraData={true} validator={validator}
widgets={customWidgets} omitExtraData={true}
fields={customFields} widgets={customWidgets}
/> fields={customFields}
/>
</ResourceContext.Provider>
) )
} }

View File

@@ -0,0 +1,9 @@
import React, { createContext, PropsWithChildren } from 'react';
type ResourceContextType = {
basePath: string,
}
export const ResourceContext = createContext<ResourceContextType>(
{} as ResourceContextType
);

View File

@@ -1,6 +1,4 @@
import { Route, Routes } from "react-router"; import { Route, Routes } from "react-router";
import React, { useContext } from "react";
import { FirmContext } from "../../contexts/FirmContext";
import List from "./base-page/List"; import List from "./base-page/List";
import Edit from "./base-page/Edit"; import Edit from "./base-page/Edit";
import New from "./base-page/New"; import New from "./base-page/New";
@@ -21,19 +19,16 @@ export const ContractRoutes = () => {
} }
const ListContract = () => { const ListContract = () => {
const { currentFirm } = useContext(FirmContext);
const columns = [ const columns = [
{ field: "label", headerName: "Label", flex: 1 }, { field: "label", headerName: "Label", flex: 1 },
]; ];
return <List<Contract> resource={`firm/${currentFirm.instance}/${currentFirm.firm}/contracts`} columns={columns} /> return <List<Contract> resource={`contracts`} columns={columns} />
} }
const EditContract = () => { const EditContract = () => {
const { currentFirm } = useContext(FirmContext); return <Edit<Contract> resource={`contracts`} schemaName={"ContractUpdate"} />
return <Edit<Contract> resource={`firm/${currentFirm.instance}/${currentFirm.firm}/contracts`} schemaName={"ContractUpdate"} />
} }
const CreateContract = () => { const CreateContract = () => {
const { currentFirm } = useContext(FirmContext); return <New<Contract> resource={`contracts`} schemaName={"ContractCreate"} />
return <New<Contract> resource={`firm/${currentFirm.instance}/${currentFirm.firm}/contracts`} schemaName={"ContractCreate"} />
} }

View File

@@ -1,6 +1,4 @@
import { Route, Routes } from "react-router"; import { Route, Routes } from "react-router";
import React, { useContext } from "react";
import { FirmContext } from "../../contexts/FirmContext";
import List from "./base-page/List"; import List from "./base-page/List";
import Edit from "./base-page/Edit"; import Edit from "./base-page/Edit";
import New from "./base-page/New"; import New from "./base-page/New";
@@ -21,19 +19,16 @@ export const DraftRoutes = () => {
} }
const ListDraft = () => { const ListDraft = () => {
const { currentFirm } = useContext(FirmContext);
const columns = [ const columns = [
{ field: "label", headerName: "Label", flex: 1 }, { field: "label", headerName: "Label", flex: 1 },
]; ];
return <List<Draft> resource={`firm/${currentFirm.instance}/${currentFirm.firm}/contracts/drafts`} columns={columns} /> return <List<Draft> resource={`contracts/drafts`} columns={columns} />
} }
const EditDraft = () => { const EditDraft = () => {
const { currentFirm } = useContext(FirmContext); return <Edit<Draft> resource={`contracts/drafts`} schemaName={"ContractDraftUpdate"} />
return <Edit<Draft> resource={`firm/${currentFirm.instance}/${currentFirm.firm}/contracts/drafts`} schemaName={"ContractDraftUpdate"} />
} }
const CreateDraft = () => { const CreateDraft = () => {
const { currentFirm } = useContext(FirmContext); return <New<Draft> resource={`contracts/drafts`} schemaName={"ContractDraftCreate"} />
return <New<Draft> resource={`firm/${currentFirm.instance}/${currentFirm.firm}/contracts/drafts`} schemaName={"ContractDraftCreate"} />
} }

View File

@@ -1,6 +1,4 @@
import { Route, Routes } from "react-router"; import { Route, Routes } from "react-router";
import React, { useContext } from "react";
import { FirmContext } from "../../contexts/FirmContext";
import List from "./base-page/List"; import List from "./base-page/List";
import Edit from "./base-page/Edit"; import Edit from "./base-page/Edit";
import New from "./base-page/New"; import New from "./base-page/New";
@@ -23,20 +21,17 @@ export const EntityRoutes = () => {
} }
const ListEntity = () => { const ListEntity = () => {
const { currentFirm } = useContext(FirmContext);
const columns = [ const columns = [
{ field: "label", headerName: "Label", flex: 1 }, { field: "label", headerName: "Label", flex: 1 },
{ field: "entity_data", headerName: "Type", flex: 1, valueFormatter: ({ type }: {type: string}) => type } { field: "entity_data", headerName: "Type", flex: 1, valueFormatter: ({ type }: {type: string}) => type }
]; ];
return <List<Entity> resource={`firm/${currentFirm.instance}/${currentFirm.firm}/entities`} columns={columns} /> return <List<Entity> resource={`entities`} columns={columns} />
} }
const EditEntity = () => { const EditEntity = () => {
const { currentFirm } = useContext(FirmContext); return <Edit<Entity> resource={`entities`} schemaName={"EntityUpdate"} />
return <Edit<Entity> resource={`firm/${currentFirm.instance}/${currentFirm.firm}/entities`} schemaName={"EntityUpdate"} />
} }
const CreateEntity = () => { const CreateEntity = () => {
const { currentFirm } = useContext(FirmContext); return <New<Entity> resource={`entities`} schemaName={"EntityCreate"} />
return <New<Entity> resource={`firm/${currentFirm.instance}/${currentFirm.firm}/entities`} schemaName={"EntityCreate"} />
} }

View File

@@ -1,6 +1,4 @@
import { Route, Routes } from "react-router"; import { Route, Routes } from "react-router";
import React, { useContext } from "react";
import { FirmContext } from "../../contexts/FirmContext";
import List from "./base-page/List"; import List from "./base-page/List";
import Edit from "./base-page/Edit"; import Edit from "./base-page/Edit";
import New from "./base-page/New"; import New from "./base-page/New";
@@ -22,19 +20,16 @@ export const ProvisionRoutes = () => {
} }
const ListProvision = () => { const ListProvision = () => {
const { currentFirm } = useContext(FirmContext);
const columns = [ const columns = [
{ field: "label", headerName: "Label", flex: 1 }, { field: "label", headerName: "Label", flex: 1 },
]; ];
return <List<Provision> resource={`firm/${currentFirm.instance}/${currentFirm.firm}/templates/provisions`} columns={columns} /> return <List<Provision> resource={`templates/provisions`} columns={columns} />
} }
const EditProvision = () => { const EditProvision = () => {
const { currentFirm } = useContext(FirmContext); return <Edit<Provision> resource={`templates/provisions`} schemaName={"ProvisionTemplateUpdate"} />
return <Edit<Provision> resource={`firm/${currentFirm.instance}/${currentFirm.firm}/templates/provisions`} schemaName={"ProvisionTemplateUpdate"} />
} }
const CreateProvision = () => { const CreateProvision = () => {
const { currentFirm } = useContext(FirmContext); return <New<Provision> resource={`templates/provisions`} schemaName={"ProvisionTemplateCreate"} />
return <New<Provision> resource={`firm/${currentFirm.instance}/${currentFirm.firm}/templates/provisions`} schemaName={"ProvisionTemplateCreate"} />
} }

View File

@@ -1,6 +1,4 @@
import { Route, Routes } from "react-router"; import { Route, Routes } from "react-router";
import React, { useContext } from "react";
import { FirmContext } from "../../contexts/FirmContext";
import List from "./base-page/List"; import List from "./base-page/List";
import Edit from "./base-page/Edit"; import Edit from "./base-page/Edit";
import New from "./base-page/New"; import New from "./base-page/New";
@@ -21,19 +19,16 @@ export const TemplateRoutes = () => {
} }
const ListTemplate = () => { const ListTemplate = () => {
const { currentFirm } = useContext(FirmContext);
const columns = [ const columns = [
{ field: "label", headerName: "Label", flex: 1 }, { field: "label", headerName: "Label", flex: 1 },
]; ];
return <List<Template> resource={`firm/${currentFirm.instance}/${currentFirm.firm}/templates/contracts`} columns={columns} /> return <List<Template> resource={`templates/contracts`} columns={columns} />
} }
const EditTemplate = () => { const EditTemplate = () => {
const { currentFirm } = useContext(FirmContext); return <Edit<Template> resource={`templates/contracts`} schemaName={"ContractTemplateUpdate"} />
return <Edit<Template> resource={`firm/${currentFirm.instance}/${currentFirm.firm}/templates/contracts`} schemaName={"ContractTemplateUpdate"} />
} }
const CreateTemplate = () => { const CreateTemplate = () => {
const { currentFirm } = useContext(FirmContext); return <New<Template> resource={`templates/contracts`} schemaName={"ContractTemplateCreate"} />
return <New<Template> resource={`firm/${currentFirm.instance}/${currentFirm.firm}/templates/contracts`} schemaName={"ContractTemplateCreate"} />
} }

View File

@@ -1,6 +1,8 @@
import { CrudForm } from "../../../lib/crud/components/crud-form"; import { CrudForm } from "../../../lib/crud/components/crud-form";
import { UiSchema } from "@rjsf/utils"; import { UiSchema } from "@rjsf/utils";
import { useParams } from "react-router"; import { useParams } from "react-router";
import { useContext } from "react";
import { FirmContext } from "../../../contexts/FirmContext";
type EditProps = { type EditProps = {
resource: string, resource: string,
@@ -10,12 +12,15 @@ type EditProps = {
const Edit = <T,>(props: EditProps) => { const Edit = <T,>(props: EditProps) => {
const { schemaName, resource, uiSchema } = props; const { schemaName, resource, uiSchema } = props;
const { currentFirm } = useContext(FirmContext);
const resourceBasePath = `firm/${currentFirm.instance}/${currentFirm.firm}`
const { record_id } = useParams(); const { record_id } = useParams();
return ( return (
<CrudForm <CrudForm
schemaName={schemaName} schemaName={schemaName}
uiSchema={uiSchema} uiSchema={uiSchema}
resourceBasePath={resourceBasePath}
resource={resource} resource={resource}
id={record_id} id={record_id}
/> />

View File

@@ -2,8 +2,9 @@ import { UiSchema } from "@rjsf/utils";
import { List as RefineList, useDataGrid } from "@refinedev/mui"; import { List as RefineList, useDataGrid } from "@refinedev/mui";
import { DataGrid, GridColDef, GridValidRowModel } from "@mui/x-data-grid"; import { DataGrid, GridColDef, GridValidRowModel } from "@mui/x-data-grid";
import { Link, useNavigate } from "react-router" import { Link, useNavigate } from "react-router"
import React from "react"; import React, { useContext } from "react";
import { Button } from "@mui/material"; import { Button } from "@mui/material";
import { FirmContext } from "../../../contexts/FirmContext";
type ListProps<T extends GridValidRowModel> = { type ListProps<T extends GridValidRowModel> = {
resource: string, resource: string,
@@ -13,8 +14,11 @@ type ListProps<T extends GridValidRowModel> = {
} }
const List = <T extends GridValidRowModel>(props: ListProps<T>) => { const List = <T extends GridValidRowModel>(props: ListProps<T>) => {
const { schemaName, resource, uiSchema, columns } = props; const { resource, columns } = props;
const { dataGridProps } = useDataGrid<T>({resource: resource}); const { currentFirm } = useContext(FirmContext);
const resourceBasePath = `firm/${currentFirm.instance}/${currentFirm.firm}`
const { dataGridProps } = useDataGrid<T>({resource: `${resourceBasePath}/${resource}`});
const navigate = useNavigate(); const navigate = useNavigate();
const cols = React.useMemo<GridColDef<T>[]>( const cols = React.useMemo<GridColDef<T>[]>(

View File

@@ -1,5 +1,7 @@
import { CrudForm } from "../../../lib/crud/components/crud-form"; import { CrudForm } from "../../../lib/crud/components/crud-form";
import { UiSchema } from "@rjsf/utils"; import { UiSchema } from "@rjsf/utils";
import { useContext } from "react";
import { FirmContext } from "../../../contexts/FirmContext";
type NewProps = { type NewProps = {
resource: string, resource: string,
@@ -9,11 +11,14 @@ type NewProps = {
const New = <T,>(props: NewProps) => { const New = <T,>(props: NewProps) => {
const { schemaName, resource, uiSchema } = props; const { schemaName, resource, uiSchema } = props;
const { currentFirm } = useContext(FirmContext);
const resourceBasePath = `firm/${currentFirm.instance}/${currentFirm.firm}`
return ( return (
<CrudForm <CrudForm
schemaName={schemaName} schemaName={schemaName}
uiSchema={uiSchema} uiSchema={uiSchema}
resourceBasePath={resourceBasePath}
resource={resource} resource={resource}
/> />
) )