Dynamics list columns with a lot of work ahead

This commit is contained in:
2025-05-06 00:58:47 +02:00
parent 0613efa846
commit 2fed7fa4e7
7 changed files with 173 additions and 37 deletions

View File

@@ -24,9 +24,9 @@ export const ContractRoutes = () => {
const ListContract = () => {
const columns = [
{ field: "label", headerName: "Label", flex: 1 },
{ field: "label", column: { flex: 1 }},
];
return <List<Contract> resource={`contracts`} columns={columns} />
return <List<Contract> resource={`contracts`} schemaName={"Contract"} columns={columns} />
}
const EditContract = () => {

View File

@@ -29,9 +29,9 @@ export const DraftRoutes = () => {
const ListDraft = () => {
const columns = [
{ field: "label", headerName: "Label", flex: 1 },
{ field: "label", column: { flex: 1 }},
];
return <List<Draft> resource={`contracts/drafts`} columns={columns} />
return <List<Draft> resource={`contracts/drafts`} columns={columns} schemaName={"Contract"} />
}
const EditDraft = () => {

View File

@@ -1,5 +1,4 @@
import { Route, Routes } from "react-router";
import { useTranslation } from "@refinedev/core";
import List from "./base-page/List";
import Edit from "./base-page/Edit";
import New from "./base-page/New";
@@ -22,12 +21,12 @@ export const EntityRoutes = () => {
}
const ListEntity = () => {
const { translate: t } = useTranslation();
const columns = [
{ field: "entity_data", headerName: t("schemas.type"), width: 110, valueFormatter: ({ type }: {type: string}) => type },
{ field: "label", headerName: t("schemas.label"), flex: 1 },
{ field: "entity_data.type", column: { width: 110 }},
{ field: "label", column: { flex: 1 }},
{ field: "updated_at", column: { flex: 1 }},
];
return <List<Entity> resource={`entities`} columns={columns} />
return <List<Entity> resource={`entities`} schemaName={"Entity"} columns={columns} />
}
const EditEntity = () => {

View File

@@ -21,9 +21,9 @@ export const ProvisionRoutes = () => {
const ListProvision = () => {
const columns = [
{ field: "label", headerName: "Label", flex: 1 },
{ field: "label", column: { flex: 1 }},
];
return <List<Provision> resource={`templates/provisions`} columns={columns} />
return <List<Provision> resource={`templates/provisions`} schemaName={"ProvisionTemplate"} columns={columns} />
}
const EditProvision = () => {

View File

@@ -20,9 +20,9 @@ export const TemplateRoutes = () => {
const ListTemplate = () => {
const columns = [
{ field: "label", headerName: "Label", flex: 1 },
{ field: "label", column: { flex: 1 }},
];
return <List<Template> resource={`templates/contracts`} columns={columns} />
return <List<Template> resource={`templates/contracts`} schemaName={"ContractTemplate"} columns={columns} />
}
const EditTemplate = () => {

View File

@@ -1,21 +1,55 @@
import { Link, useNavigate } from "react-router"
import { UiSchema } from "@rjsf/utils";
import { useTranslation } from "@refinedev/core";
import { List as RefineList, useDataGrid } from "@refinedev/mui";
import { DataGrid, GridColDef, GridValidRowModel } from "@mui/x-data-grid";
import { Link, useNavigate } from "react-router"
import React, { useContext } from "react";
import { Button } from "@mui/material";
import { DataGrid, GridColDef, GridValidRowModel, GridColumnVisibilityModel } from "@mui/x-data-grid";
import React, { useContext, useEffect, useState } from "react";
import { Button, CircularProgress } from "@mui/material";
import { FirmContext } from "../../../contexts/FirmContext";
import { jsonschemaProvider } from "../../../lib/crud/providers/jsonschema-provider";
type ListProps<T extends GridValidRowModel> = {
type ListProps = {
resource: string,
columns: GridColDef<T>[],
schemaName?: string,
columns: ColumnDefinition[],
schemaName: string,
uiSchema?: UiSchema,
}
const List = <T extends GridValidRowModel>(props: ListProps<T>) => {
const { resource, columns } = props;
type ColumnSchema<T extends GridValidRowModel> = {
columns: GridColDef<T>[],
columnVisibilityModel: GridColumnVisibilityModel
}
type ColumnDefinition = {
field: string,
column: Partial<GridColDef>,
hide?: boolean
}
function computeColumnSchema<T extends GridValidRowModel>(definitionColumns: ColumnDefinition[], resourceColumns: GridColDef[]): ColumnSchema<T> {
//reorder resourceColumns as in definition
definitionColumns.slice().reverse().forEach(first => {
resourceColumns.sort(function(x,y){ return x.field == first.field ? -1 : y.field == first.field ? 1 : 0; });
})
let visibilityModel: GridColumnVisibilityModel = {}
resourceColumns.forEach((resource, index) =>{
visibilityModel[resource.field] = definitionColumns.some(col => col.field == resource.field && !col.hide)
definitionColumns.forEach((def) => {
if (def.field == resource.field) {
resourceColumns[index] = {...resource, ...def.column};
}
})
})
return {
columns: resourceColumns,
columnVisibilityModel: visibilityModel
}
}
const List = <T extends GridValidRowModel>(props: ListProps) => {
const { resource, columns, schemaName } = props;
const { translate: t } = useTranslation();
const { currentFirm } = useContext(FirmContext);
const resourceBasePath = `firm/${currentFirm.instance}/${currentFirm.firm}`
@@ -25,15 +59,32 @@ const List = <T extends GridValidRowModel>(props: ListProps<T>) => {
});
const navigate = useNavigate();
const cols = React.useMemo<GridColDef<T>[]>(
() => columns,
[],
);
const [columnSchema, setColumnSchema] = useState<ColumnSchema<T>>()
const [schemaLoading, setSchemaLoading] = useState(true);
useEffect(() => {
const fetchSchema = async () => {
try {
const resourceColumns = await jsonschemaProvider.getReadResourceColumns(schemaName)
const definedColumns = computeColumnSchema<T>(columns, resourceColumns)
setColumnSchema(definedColumns);
console.log(resourceColumns);
setSchemaLoading(false);
} catch (error) {
console.error('Error fetching data:', error);
setSchemaLoading(false);
}
};
fetchSchema();
}, []);
const handleRowClick = (params: any, event: any) => {
navigate(`edit/${params.id}`)
}
if (schemaLoading || columnSchema === undefined) {
return <CircularProgress />
}
return (
<RefineList>
<Link to={"create"} >
@@ -41,9 +92,14 @@ const List = <T extends GridValidRowModel>(props: ListProps<T>) => {
</Link>
<DataGrid
{...dataGridProps}
columns={cols}
columns={columnSchema.columns}
onRowClick={handleRowClick}
pageSizeOptions={[10, 15, 20, 50, 100]}
initialState={{
columns: {
columnVisibilityModel: columnSchema.columnVisibilityModel
}
}}
/>
</RefineList>
)