Compare commits
3 Commits
49317e905b
...
2ff15cdef4
| Author | SHA1 | Date | |
|---|---|---|---|
| 2ff15cdef4 | |||
| 72b6f26ebc | |||
| b06ce4eefd |
@@ -42,7 +42,7 @@ class ProvisionTemplateReference(BaseModel):
|
|||||||
|
|
||||||
provision_template_id: PydanticObjectId = ForeignKey(
|
provision_template_id: PydanticObjectId = ForeignKey(
|
||||||
"templates/provisions",
|
"templates/provisions",
|
||||||
"TemplateProvision",
|
"ProvisionTemplate",
|
||||||
['title', 'body'],
|
['title', 'body'],
|
||||||
props={"parametrized": True},
|
props={"parametrized": True},
|
||||||
title="Template de clause"
|
title="Template de clause"
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
import { useEffect, useState } from "react";
|
|
||||||
import { jsonschemaProvider } from "../providers/jsonschema-provider";
|
|
||||||
import { Accordion, AccordionDetails, AccordionSummary, CircularProgress } from "@mui/material";
|
import { Accordion, AccordionDetails, AccordionSummary, CircularProgress } from "@mui/material";
|
||||||
import FilterForm from "../../filter-form/components/filter-form";
|
import FilterForm from "../../filter-form/components/filter-form";
|
||||||
import TextField from "@mui/material/TextField";
|
import TextField from "@mui/material/TextField";
|
||||||
import { useSearchParams } from "react-router";
|
|
||||||
import { GridExpandMoreIcon } from "@mui/x-data-grid";
|
import { GridExpandMoreIcon } from "@mui/x-data-grid";
|
||||||
|
import { useResourceFilter } from "../hook";
|
||||||
|
|
||||||
export type OnChangeValue = {
|
export type OnChangeValue = {
|
||||||
search: string | null
|
search: string | null
|
||||||
@@ -19,24 +17,7 @@ type CrudFiltersProps = {
|
|||||||
|
|
||||||
const CrudFilters = (props: CrudFiltersProps) => {
|
const CrudFilters = (props: CrudFiltersProps) => {
|
||||||
const { resourceName, resourcePath, onChange } = props
|
const { resourceName, resourcePath, onChange } = props
|
||||||
|
const { hasSearch, filtersSchema, filtersLoading } = useResourceFilter(resourceName, resourcePath)
|
||||||
const [hasSearch, setHasSearch] = useState(false)
|
|
||||||
const [filtersSchema, setFiltersSchema] = useState<any[]>([])
|
|
||||||
const [filtersLoading, setFiltersLoading] = useState(true);
|
|
||||||
useEffect(() => {
|
|
||||||
const fetchSchema = async () => {
|
|
||||||
try {
|
|
||||||
setHasSearch(await jsonschemaProvider.hasSearch(resourcePath))
|
|
||||||
const resourceFilters = await jsonschemaProvider.getListFilters(resourceName, resourcePath)
|
|
||||||
setFiltersSchema(resourceFilters);
|
|
||||||
setFiltersLoading(false);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error fetching data:', error);
|
|
||||||
setFiltersLoading(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
fetchSchema();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
if (filtersLoading) {
|
if (filtersLoading) {
|
||||||
return <CircularProgress />
|
return <CircularProgress />
|
||||||
@@ -81,8 +62,6 @@ type SearchFilter = {
|
|||||||
|
|
||||||
const SearchFilter = (props: SearchFilter) => {
|
const SearchFilter = (props: SearchFilter) => {
|
||||||
const {value, onChange} = props;
|
const {value, onChange} = props;
|
||||||
const [searchParams, setSearchParams] = useSearchParams();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TextField
|
<TextField
|
||||||
label="schemas.search"
|
label="schemas.search"
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
import { ReactNode, useEffect, useState } from "react";
|
import { ReactNode } from "react";
|
||||||
import { CircularProgress } from "@mui/material";
|
import { CircularProgress } from "@mui/material";
|
||||||
import { useForm } from "@refinedev/core";
|
|
||||||
import { UiSchema } from "@rjsf/utils";
|
import { UiSchema } from "@rjsf/utils";
|
||||||
import { jsonschemaProvider } from "../providers/jsonschema-provider";
|
|
||||||
import { BaseForm } from "./base-form";
|
import { BaseForm } from "./base-form";
|
||||||
|
import { useResourceSchema } from "../hook";
|
||||||
|
|
||||||
type CrudFormProps = {
|
type CrudFormProps = {
|
||||||
schemaName: string,
|
schemaName: string,
|
||||||
@@ -18,31 +17,8 @@ type CrudFormProps = {
|
|||||||
|
|
||||||
export const CrudForm: React.FC<CrudFormProps> = (props) => {
|
export const CrudForm: React.FC<CrudFormProps> = (props) => {
|
||||||
const { schemaName, uiSchema, record, resourceBasePath, defaultValue, children, onSubmit=(data: any) => {}, card=false } = props;
|
const { schemaName, uiSchema, record, resourceBasePath, defaultValue, children, onSubmit=(data: any) => {}, card=false } = props;
|
||||||
|
const type = record === undefined ? "create" : card ? "card" : "update"
|
||||||
const [schema, setSchema] = useState({});
|
const { schema, schemaLoading } = useResourceSchema(schemaName, type);
|
||||||
const [schemaLoading, setSchemaLoading] = useState(true);
|
|
||||||
useEffect(() => {
|
|
||||||
const fetchSchema = async () => {
|
|
||||||
try {
|
|
||||||
let resourceSchema
|
|
||||||
if (record === undefined) {
|
|
||||||
resourceSchema = await jsonschemaProvider.getCreateResourceSchema(schemaName);
|
|
||||||
} else {
|
|
||||||
if (card) {
|
|
||||||
resourceSchema = await jsonschemaProvider.getCardResourceSchema(schemaName);
|
|
||||||
} else {
|
|
||||||
resourceSchema = await jsonschemaProvider.getUpdateResourceSchema(schemaName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setSchema(resourceSchema);
|
|
||||||
setSchemaLoading(false);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error fetching data:', error);
|
|
||||||
setSchemaLoading(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
fetchSchema();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
if(schemaLoading) {
|
if(schemaLoading) {
|
||||||
return <CircularProgress />
|
return <CircularProgress />
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
|
import { CircularProgress } from "@mui/material";
|
||||||
import { DataGrid, GridColDef, GridColumnVisibilityModel, GridValidRowModel } from "@mui/x-data-grid";
|
import { DataGrid, GridColDef, GridColumnVisibilityModel, GridValidRowModel } from "@mui/x-data-grid";
|
||||||
import { UiSchema } from "@rjsf/utils";
|
import { UiSchema } from "@rjsf/utils";
|
||||||
import React, { useEffect, useState } from "react";
|
import { useResourceColumns } from "../hook";
|
||||||
import { jsonschemaProvider } from "../providers/jsonschema-provider";
|
|
||||||
import { CircularProgress } from "@mui/material";
|
|
||||||
|
|
||||||
type CrudListProps = {
|
type CrudListProps = {
|
||||||
schemaName: string,
|
schemaName: string,
|
||||||
@@ -32,24 +31,9 @@ const CrudList = <T extends GridValidRowModel>(props: CrudListProps) => {
|
|||||||
columnDefinitions
|
columnDefinitions
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const [columnSchema, setColumnSchema] = useState<ColumnSchema<T>>()
|
const { columnSchema, columnLoading } = useResourceColumns<T>(schemaName, columnDefinitions);
|
||||||
const [schemaLoading, setSchemaLoading] = useState(true);
|
|
||||||
useEffect(() => {
|
|
||||||
const fetchSchema = async () => {
|
|
||||||
try {
|
|
||||||
const resourceColumns = await jsonschemaProvider.getReadResourceColumns(schemaName)
|
|
||||||
const definedColumns = computeColumnSchema<T>(columnDefinitions, resourceColumns)
|
|
||||||
setColumnSchema(definedColumns);
|
|
||||||
setSchemaLoading(false);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error fetching data:', error);
|
|
||||||
setSchemaLoading(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
fetchSchema();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
if (schemaLoading || columnSchema === undefined) {
|
if (columnLoading || columnSchema === undefined) {
|
||||||
return <CircularProgress />
|
return <CircularProgress />
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,26 +53,4 @@ const CrudList = <T extends GridValidRowModel>(props: CrudListProps) => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default CrudList;
|
export default CrudList;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { createContext, PropsWithChildren } from 'react';
|
import { createContext } from 'react';
|
||||||
|
|
||||||
type ResourceContextType = {
|
type ResourceContextType = {
|
||||||
basePath: string,
|
basePath: string,
|
||||||
|
|||||||
109
gui/rpk-gui/src/lib/crud/hook/index.tsx
Normal file
109
gui/rpk-gui/src/lib/crud/hook/index.tsx
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { jsonschemaProvider } from "../providers/jsonschema-provider";
|
||||||
|
import { GridColDef, GridColumnVisibilityModel, GridValidRowModel } from "@mui/x-data-grid";
|
||||||
|
|
||||||
|
type ResourceSchemaType = "create" | "update" | "card";
|
||||||
|
|
||||||
|
export function useResourceSchema(schemaName: string, type: ResourceSchemaType) {
|
||||||
|
const [schema, setSchema] = useState({});
|
||||||
|
const [schemaLoading, setSchemaLoading] = useState(true);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchSchema = async () => {
|
||||||
|
try {
|
||||||
|
let resourceSchema
|
||||||
|
if (type == "create") {
|
||||||
|
resourceSchema = await jsonschemaProvider.getCreateResourceSchema(schemaName);
|
||||||
|
} else if (type == "update") {
|
||||||
|
resourceSchema = await jsonschemaProvider.getCardResourceSchema(schemaName);
|
||||||
|
} else {
|
||||||
|
resourceSchema = await jsonschemaProvider.getUpdateResourceSchema(schemaName);
|
||||||
|
}
|
||||||
|
setSchema(resourceSchema);
|
||||||
|
setSchemaLoading(false);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error while retrieving schema: ${schemaName} `, error);
|
||||||
|
setSchemaLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fetchSchema();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return { schema, schemaLoading }
|
||||||
|
}
|
||||||
|
|
||||||
|
type ColumnSchema<T extends GridValidRowModel> = {
|
||||||
|
columns: GridColDef<T>[],
|
||||||
|
columnVisibilityModel: GridColumnVisibilityModel
|
||||||
|
}
|
||||||
|
|
||||||
|
type ColumnDefinition = {
|
||||||
|
field: string,
|
||||||
|
column: Partial<GridColDef>,
|
||||||
|
hide?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useResourceColumns<T extends GridValidRowModel>(schemaName: string, columnDefinitions: ColumnDefinition[]) {
|
||||||
|
const [columnSchema, setColumnSchema] = useState<ColumnSchema<T>>()
|
||||||
|
const [columnLoading, setColumnLoading] = useState(true);
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchSchema = async () => {
|
||||||
|
try {
|
||||||
|
const resourceColumns = await jsonschemaProvider.getReadResourceColumns(schemaName)
|
||||||
|
const definedColumns = computeColumnSchema<T>(columnDefinitions, resourceColumns)
|
||||||
|
setColumnSchema(definedColumns);
|
||||||
|
setColumnLoading(false);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error while retrieving columns schema:', error);
|
||||||
|
setColumnLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fetchSchema();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return { columnSchema, columnLoading }
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useResourceFilter(resourceName: string, resourcePath: string) {
|
||||||
|
const [hasSearch, setHasSearch] = useState(false)
|
||||||
|
const [filtersSchema, setFiltersSchema] = useState<any[]>([])
|
||||||
|
const [filtersLoading, setFiltersLoading] = useState(true);
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchSchema = async () => {
|
||||||
|
try {
|
||||||
|
setHasSearch(await jsonschemaProvider.hasSearch(resourcePath))
|
||||||
|
const resourceFilters = await jsonschemaProvider.getListFilters(resourceName, resourcePath)
|
||||||
|
setFiltersSchema(resourceFilters);
|
||||||
|
setFiltersLoading(false);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error while retrieving filter schema:', error);
|
||||||
|
setFiltersLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fetchSchema();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return { hasSearch, filtersSchema, filtersLoading }
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user