Migrating foreign-key to his new fish tank
This commit is contained in:
@@ -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
|
||||
)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user