Repository: refinedev/refine
File: packages/mui/src/hooks/useDataGrid/index.ts (TypeScript)

Code before:
    return {
      paginationMode: "client" as const,
    };
  };

  const { mutate, isLoading: formLoading } = useUpdate();

  const processRowUpdate = async (newRow: TData, oldRow: TData) => {
    try {
      await new Promise((resolve, reject) => {
        mutate(
          {
            resource: resourceFromProp as string,
            id: newRow.id as string,
            values: newRow,
          },
          {
            onError: (error) => {
              reject(error);
            },
            onSuccess: (data) => {
              resolve(data);
            },
          },
        );
      });
      return newRow;
    } catch (error) {
      return oldRow;
    }
  };

  return {
    tableQueryResult,
    dataGridProps: {
      disableRowSelectionOnClick: true,
      rows: data?.data || [],
      loading: liveMode === "auto" ? isLoading : !isFetched,
      rowCount: data?.total || 0,
      ...dataGridPaginationValues(),
      sortingMode: isServerSideSortingEnabled ? "server" : "client",
      sortModel: transformCrudSortingToSortModel(
        differenceWith(sorters, preferredPermanentSorters, isEqual),
      ),
      onSortModelChange: handleSortModelChange,
      filterMode: isServerSideFilteringEnabled ? "server" : "client",
      filterModel: transformCrudFiltersToFilterModel(
        differenceWith(muiCrudFilters, preferredPermanentFilters, isEqual),
        columnsTypes,
      ),
      onFilterModelChange: handleFilterModelChange,

Review comment (suggestion):
Check out the docs from Material UI [here](https://mui.com/x/react-data-grid/editing/#server-side-validation). Returning old or new data will close the edit state and update the row (if new data is returned). Rejecting the promise will keep the edit state. 

Let's update this code with returning a promise, `onSuccess` can `resolve(newRow)` and `onError` can `reject(error)`. By default if user has provided any notification provider, Refine's `useUpdate` will display an error notification. In this case, it will be better to keep the edit state rather than closing it with old data. 

Code after:
        },
      };
    }

    return {
      paginationMode: "client" as const,
    };
  };

  const { mutate } = useUpdate<TData, TError, TData>({
    mutationOptions: updateMutationOptions,
  });

  const processRowUpdate = async (newRow: TData, oldRow: TData) => {
    if (!editable) {
      return Promise.resolve(oldRow);
    }

    if (!identifier) {
      return Promise.reject(new Error("Resource is not defined"));
    }

    return new Promise((resolve, reject) => {
      mutate(
        {
          resource: identifier,
          id: newRow.id as string,
          values: newRow,
        },
        {
          onError: (error) => {
            reject(error);
          },
          onSuccess: (data) => {
            resolve(newRow);
          },
        },
      );
    });
  };

  return {
    tableQueryResult,
    dataGridProps: {
      disableRowSelectionOnClick: true,
      rows: data?.data || [],
      loading: liveMode === "auto" ? isLoading : !isFetched,
      rowCount: data?.total || 0,
      ...dataGridPaginationValues(),
      sortingMode: isServerSideSortingEnabled ? "server" : "client",
      sortModel: transformCrudSortingToSortModel(