1

I am working on a project with the refine framework for user registry management. In this application, it is possible to create dedicated processes for each user, and for each process, I can associate dashboards and specific users. On the Edit page for processes, I've built two dropdown menus with an autocomplete function that are populated by data from two API calls, fetchUsers() and fetchDashboards(). Up to this point, everything works perfectly. Now, since each process potentially already contains users or associated dashboards, I would like the dropdown menus to have these values pre-filled in the respective menus. This last part doesn't seem to work because when I refresh the page, the menus are empty, despite the arrays being correctly populated. How can I get the data for users already associated with the process processDetails?.dashboards.map((dashboard) => dashboard.title) and for the dashboards associated with the process processDetails?.users.map((user) => user.email) and pre-fill them in the corresponding menus?

This is my component:

import React, { useEffect, useState } from "react";
import axios from "axios";

import { useForm } from "@refinedev/react-hook-form";
import { Controller } from "react-hook-form";
import { useParams } from "react-router-dom";

import Autocomplete from "@mui/material/Autocomplete";

import { Create } from "@refinedev/mui";
import { Box, TextField, Typography } from "@mui/material";

const API_URL = "http://localhost:3500/api/v1";

export const ProcessEdit = () => {
  const {
    control,
    saveButtonProps,
    refineCore: { formLoading },
    formState: { errors },
  } = useForm();

  const { id } = useParams();

  const [users, setUsers] = useState([]);
  const [dashboards, setDashboards] = useState([]);
  const [processDetails, setProcessDetails] = useState(null);

  useEffect(() => {
    const fetchUsers = async () => {
      try {
        const response = await axios.get(`${API_URL}/users`);
        const usersData = response.data.data.map((user) => ({
          label: user.email,
        }));
        setUsers(usersData);
      } catch (error) {
        console.error("Fetching error", error);
      }
    };

    fetchUsers();

    const fetchDashboards = async () => {
      try {
        const response = await axios.get(`${API_URL}/dashboards`);
        const dashboardsData = response.data.data.map((dashboard) => ({
          label: dashboard.title,
        }));
        setDashboards(dashboardsData);
      } catch (error) {
        console.error("Fetching error", error);
      }
    };

    fetchDashboards();

    const fetchProcessDetails = async () => {
      try {
        const response = await axios.get(`${API_URL}/processes/${id}`);
        setProcessDetails(response.data.data);
      } catch (error) {
        console.error(
          "Fetching error",
          error
        );
      }
    };

    fetchProcessDetails();
  }, []);

  console.log(
    processDetails?.users.map((user) => ({
      label: user.email,
    }))
  );
  console.log(
    processDetails?.dashboards.map((dashboard) => ({
      label: dashboard.title,
    }))
  );
  console.log(users);
  console.log(dashboards);

  return (
    <Create
      isLoading={formLoading}
      saveButtonProps={saveButtonProps}
      title={<Typography variant="h5">Modify Process</Typography>}
    >
      <Box
        component="form"
        sx={{ display: "flex", flexDirection: "column" }}
        autoComplete="off"
      >
        <Controller
          name="name"
          control={control}
          defaultValue=""
          rules={{ required: "This field must not be empty" }}
          render={({ field, fieldState: { error } }) => (
            <TextField
              {...field}
              label="Process name"
              margin="normal"
              fullWidth
              error={!!error}
              helperText={error ? error.message : null}
            />
          )}
        />
        <Controller
          name="description"
          control={control}
          defaultValue=""
          render={({ field, fieldState: { error } }) => (
            <TextField
              {...field}
              label="Process description"
              margin="normal"
              fullWidth
              error={!!error}
              helperText={error ? error.message : null}
            />
          )}
        />
        <Controller
          name="users"
          control={control}
          render={({ field }) => (
            <Autocomplete
              {...field}
              multiple
              id="users-autocomplete"
              options={users}
              defaultValue={
                processDetails
                  ? processDetails?.users.map((user) => ({
                      label: user.email,
                    }))
                  : []
              }
              getOptionLabel={(option) => option.label}
              value={users.filter((email) =>   field.value.includes(email.label))}
              onChange={(_, data) => {
                const newValue = data.map((d) => d.label);
                field.onChange(newValue);
              }}
              renderInput={(params) => (
                <TextField
                  {...params}
                  label="Users"
                  margin="normal"
                  error={!!errors.users}
                  helperText={errors.users?.message}
                />
              )}
            />
          )}
        />
        <Controller
          name="dashboards"
          control={control}
          render={({ field }) => (
            <Autocomplete
              {...field}
              multiple
              id="dashboards-autocomplete"
              options={dashboards}
              defaultValue={
                processDetails
                  ? processDetails?.dashboards.map((dashboard) => ({
                      label: dashboard.title,
                    }))
                  : []
              }
              getOptionLabel={(option) => option.label}
              value={dashboards.filter((dashboard) =>
                field.value.includes(dashboard.label)
              )}
              onChange={(_, data) => {
                const newValue = data.map((d) => d.label);
                field.onChange(newValue);
              }}
              renderInput={(params) => (
                <TextField
                  {...params}
                  label="Dashboards"
                  margin="normal"
                  error={!!errors.dashboards}
                  helperText={errors.dashboards?.message}
                />
              )}
            />
          )}
        />
      </Box>
    </Create>
  );
};

If I click on the menus, I actually see the list of user's emails [{label: "[email protected]"},{},...] and the titles of the dashboards [{label: "Sales"},{},...], but I do not see the pre-filled values that are already associated with the process. From console.log, the arrays of values that should be pre-filled also have the same structure: [{label: "[email protected]"},{},...] and [{label: "currentDashboard"},{},...].

0