Migrating foreign-key to his new fish tank

This commit is contained in:
2025-04-21 20:24:43 +02:00
parent 9e823d003e
commit 7b6ca62d9a

View File

@@ -1,11 +1,11 @@
import {FormContextType, RJSFSchema, StrictRJSFSchema, WidgetProps} from '@rjsf/utils';
import { Autocomplete } from "@mui/material";
import { useState, useEffect } from "react";
import TextField from "@mui/material/TextField";
import {BaseRecord, useList, useOne} from "@refinedev/core";
import {FormContextType, RJSFSchema, WidgetProps} from '@rjsf/utils';
import { Autocomplete, CircularProgress, TextField } from "@mui/material";
import React, { useState, useEffect, useContext } from "react";
import { useList, useOne } from "@refinedev/core";
import { ResourceContext } from "../../contexts/ResourceContext";
type ForeignKeySchema = RJSFSchema & {
foreign_key?: {
foreignKey?: {
reference: {
resource: string,
label: string
@@ -16,59 +16,90 @@ type ForeignKeySchema = RJSFSchema & {
export default function ForeignKeyWidget<T = any, S extends ForeignKeySchema = ForeignKeySchema, F extends FormContextType = any>(
props: WidgetProps<T, S, F>
) {
if (props.schema.foreign_key === undefined) {
if (props.schema.foreignKey === undefined) {
return;
}
const resource = props.schema.foreign_key.reference.resource
const labelField = props.schema.foreign_key.reference.label
const { onChange, value: originalValue } = props;
const [initialState, setInitialState] = useState(true);
if (originalValue != null && initialState) {
return <InitialValue {...props} onClear={() => {setInitialState(false); onChange(null)}}/>
}
const valueResult = useOne({
resource: resource,
id: props.value != null ? props.value : undefined
return (
<RealAutocomplete {...props}/>
)
};
const InitialValue = <T = any, S extends ForeignKeySchema = ForeignKeySchema, F extends FormContextType = any>(
props: WidgetProps<T, S, F> & { onClear: () => void }
) => {
const { onClear, value } = props;
if (props.schema.foreignKey === undefined) {
return;
}
const { resource, label: labelField = "label" } = props.schema.foreignKey.reference
const { basePath } = useContext(ResourceContext)
const { data, isLoading } = useOne({
resource: `${basePath}/${resource}`,
id: value
});
const empty_option: BaseRecord = {
id: undefined
}
empty_option[labelField] = "(None)"
const [inputValue, setInputValue] = useState<string>("");
const [selectedValue, setSelectedValue] = useState(valueResult.data?.data || null);
const [debouncedInputValue, setDebouncedInputValue] = useState<string>(inputValue);
useEffect(() => {
const handler = setTimeout(() => setDebouncedInputValue(inputValue), 300); // Adjust debounce delay as needed
return () => clearTimeout(handler);
}, [inputValue]);
const listResult = useList({
resource: resource,
pagination: { current: 1, pageSize: 10 },
filters: [{ field: "name", operator: "contains", value: debouncedInputValue }],
sorters: [{ field: "name", order: "asc" }],
});
const options = listResult.data?.data || [];
if (! props.required) {
options.unshift(empty_option);
}
const isLoading = listResult.isLoading || valueResult.isLoading;
if(! selectedValue && valueResult.data) {
setSelectedValue(valueResult.data?.data)
if (isLoading || data === undefined) {
return <CircularProgress />
}
return (
<Autocomplete
value={selectedValue}
onChange={(event, newValue) => {
setSelectedValue(newValue ? newValue : empty_option);
props.onChange(newValue ? newValue.id : null);
value={data.data}
onChange={() => onClear()}
onInputChange={() => onClear()}
options={[data.data]}
getOptionLabel={(option) => option ? option[labelField] : ""}
loading={isLoading}
renderInput={(params) => (
<TextField {...params} label={ props.label } variant="outlined" />
)}
/>
)
}
const RealAutocomplete = <T = any, S extends ForeignKeySchema = ForeignKeySchema, F extends FormContextType = any>(
props: WidgetProps<T, S, F>
) => {
if (props.schema.foreignKey === undefined) {
return;
}
const { onChange } = props
const [searchString, setSearchString] = useState<string>("");
const [debouncedInputValue, setDebouncedInputValue] = useState<string>();
useEffect(() => {
const handler = setTimeout(() => setDebouncedInputValue(searchString), 300); // Adjust debounce delay as needed
return () => clearTimeout(handler);
}, [searchString]);
const { resource, label: labelField = "label" } = props.schema.foreignKey.reference
const { basePath } = useContext(ResourceContext)
const { data, isLoading } = useList({
resource: `${basePath}/${resource}`,
pagination: { current: 1, pageSize: 10, mode: "server" },
filters: [{ field: "label", operator: "contains", value: debouncedInputValue }],
sorters: [{ field: "label", order: "asc" }],
});
return (
<Autocomplete
onChange={(event, value) => {
onChange(value ? value.id : null);
return true;
}}
//inputValue={inputValue}
onInputChange={(event, newInputValue) => setInputValue(newInputValue)}
options={options}
onInputChange={(event, newInputValue) => {
setSearchString(newInputValue)
console.log(newInputValue)
}}
options={data ? data.data : []}
getOptionLabel={(option) => option ? option[labelField] : ""}
loading={isLoading}
renderInput={(params) => (
@@ -76,4 +107,4 @@ export default function ForeignKeyWidget<T = any, S extends ForeignKeySchema = F
)}
/>
);
};
}