marmelab / react-admin

A frontend Framework for single-page applications on top of REST/GraphQL APIs, using TypeScript, React and Material Design
http://marmelab.com/react-admin
MIT License
24.77k stars 5.22k forks source link

4.0 Roadmap #5933

Closed fzaninotto closed 2 years ago

fzaninotto commented 3 years ago

We're starting to think about the next major milestone for react-admin. It'll mostly be a cleanup release, removing all the deprecated features and the compatibility layers we put in place. It should also be the occasion to use the latest major version of our dependencies.

Breaking Changes

These items didn't make it into the release:

We won't break BC for another year or two after 4.0, so we'd better wait to incorporate the new major releases of our dependencies. This causes the following releases to be blockers:

Timeline

Work on v4 started in September 2021, and is expected to end in early 2022.

Note: Please don't post comments with feature requests that don't need a breaking change here. React-admin releases new features on a monthly basis, and doesn't need a major release for that. This discussion is only for backwards-incompatible changes.

smeng9 commented 3 years ago

Hi I have a question, what drives the decision to replace redux-form to react-final-form during v2->v3 and then switch to formik from v3->v4? License? Render speed?

I know the main interface of form components won't change much, but some of the attributes of the components may get changed.

smeng9 commented 3 years ago

You also mentioned removing redux-saga. Currently there are still a lot of parts related to the saga in the codebase, including handling of authentications and data fetchings.

Is the alternative going to be using react contexts? That is probably the only method to replace saga. Thanks!

smeng9 commented 3 years ago

In terms of this major release, will ra-enterprise version also receive new versions in parallel? I am pretty interested in the paid version so I have so many questions to discuss here.

fzaninotto commented 3 years ago

Hi I have a question, what drives the decision to replace redux-form to react-final-form during v2->v3 and then switch to formik from v3->v4? License? Render speed?

The same reason: library maintenance. redux-form isn't maintained anymore, and react-final-form is taking the same path. some bugs in react-admin can't be fixed because they are caused by bugs in final-form that don't get fixed.

On the other hand, formik is actively maintained and has a positive contribution curve.

Finally, react-final-form has 6k stars on GitHub, while Formik has 26k stars. When we made the choice to go with final-form, they were at the same level.

Currently there are still a lot of parts related to the saga in the codebase, including handling of authentications and data fetchings.

No, 100% of the side effects are handled by pure React side effects and contexts in the curent codebase. The sagas are just here for backwards compatibility.

will ra-enterprise version also receive new versions in parallel?

We'll make re-enterprise modules compatible with 4.0 as soon as it's released. If this can be done without breaking change, then this will be a minor release, otherwise it'll be a major release.

huijiewei commented 3 years ago

react-hook-form

Suggest

djhi commented 3 years ago

It would probably be nice to introduce hooks to trigger side effects which could update the store. It would help implementing custom data providers methods which may have to update the data, delete it, etc.

For example see #5959. With a useDeleteFromStore or similar, it would be trivial to implement

m4theushw commented 3 years ago

The <AutocompleteInput /> could be rewritten to use the <Autocomplete /> from Material-UI. In V5 it will not be in beta anymore.

wmwart commented 3 years ago

Extend the permissions action to more components. In particular, the <Fields> and <Inputs>components. A fairly common task is to restrict user fields based on access. Now, each of my <Fields> and <Inputs> components is wrapped in an accessor function. This makes the components <List>, <Show>, <Edit> and others very cumbersome. It would be nice if as many components as possible support the access property. Or, for example, for example, to be able to specify access in the style of validation of both the form and individual fields.

capJavert commented 3 years ago

Replace react-final-form with formik

Did you think about integrating https://github.com/react-hook-form/react-hook-form instead of formik? react-final-form and formik are crazy slow and unoptimized when working with semi large and large forms (10+ inputs or array input).

react-hook-form is really fast with hundreds of inputs and also isolates rerenders based on the state chunks that changed. Main difference is uncontrolled approach but that can be solved with https://react-hook-form.com/advanced-usage#ControlledmixedwithUncontrolledComponents.

Aside from that APIs are similar (we recently replaced formik with react-hook-form in one of our projects with no issues).

People are already moving from formik based on the reasons above so maybe think about jumping to react-hook-form?

ValentinnDimitroff commented 3 years ago

It is not a huge difference but I was wondering why do you depend on classnames when material-ui (and probably some others) already depend on clsx ?

Passed my mind when thought about reducing dependencies list.

fzaninotto commented 3 years ago

@ValentinnDimitroff No idea when they migrated to clsx. When we started using material-ui, they were using classnames.

I guess we focus more on backwards compatibility and they prefer to move fast and break things ;)

andrico1234 commented 3 years ago

You mention that you plan on removing redux-saga and saga-based side effects. While I don't pass through any customSagas to the Admin component yet, I am looking at ways to dispatch notification actions from whenever a specific event occurs. For instances like this useNotify isn't a viable option.

Is there a migration strategy for those that are using customSagas in such a way, or will the customSagas property still be supported?

fzaninotto commented 3 years ago

I am looking at ways to dispatch notification actions whenever a specific event occurs

Do like we do in the react-admin codebase: combine useNotify and useEffect.

henrik-d commented 3 years ago

Remove redux-saga and saga-based side effects

May I ask what lead to the decision to remove redux-saga? What was it used for and how is it replaced now?

fzaninotto commented 3 years ago

It was used for side effects, and we now use useSideEffect for that. Besides, when we first built react-admin, Redux was the cornerstone of the state and change management. Today, Redux isn't so central, and some newer parts of the framework simply don't rely on it at all (e.g. authentication).

As an example, the react-admin demo doesn't use saga at all.

fzaninotto commented 3 years ago

@sidescraper please don't post feature requests here. We're adding new features in minor versions. 4.0 will probably add no new feature, but just change the underlying layers that have become a problem. It's all about breaking backwards compatibility.

rassie commented 3 years ago

Does moving to formik mean that any custom forms will need to be rewritten more or less from scratch? Or will there be a compatibility layer for a couple of versions?

fzaninotto commented 3 years ago

The move to formik will be a breaking change, but for most custom forms, the required change will reduce to changing the package name as the APIs are mostly compatible:

-import { Form, Field } from 'react-final-form'; 
+import { Form, Field } from 'formik';
zero-shubham commented 3 years ago

what does the community think about react-hook-form ? I think it's more user friendly when compared to formik.

smeng9 commented 3 years ago

I would prefer formik since it it introduces minimal breaking change

EDIT 8/3/2021: After more evaluation of react-hook-form 5 month later after the initial post, it seems the react-hook-form's development is more active, and it also has smaller bundle size. We have already switched to react-hook-form on some other projects.

lukin commented 3 years ago

What do you think about removing extra styles? This change will make the components more clearer and compatible with the Material-UI API.

I will try to explain in more detail.

For example, when using <SearchInput />, I expect the position on the page to be similar to the <TextField />, without additional margin.

Or when using <SelectInput />, responsiveness sometimes breaks on small screens due to min-width.

Other components have similar additional styles. makeStyles can be overridden, but it seems to me that in some cases the components would be more convenient without them.

fzaninotto commented 3 years ago

@Lukin I don't understand the problem you're trying to solve. Could you elaborate?

fzaninotto commented 3 years ago

@Lukin If I understand your suggestion correctly this would break the default FormLayouts. Or do you expect these layouts to inject the custom styles?

lukin commented 3 years ago

@fzaninotto Yes, that's right. I often have to use custom complex form layouts. By injecting these styles into included layouts (e.g. SimpleForm, TabbedForm), field and input components would be more flexible.

andrico1234 commented 3 years ago

Extend the permissions action to more components. In particular, the <Fields> and <Inputs>components. A fairly common task is to restrict user fields based on access. Now, each of my <Fields> and <Inputs> components is wrapped in an accessor function. This makes the components <List>, <Show>, <Edit> and others very cumbersome. It would be nice if as many components as possible support the access property. Or, for example, for example, to be able to specify access in the style of validation of both the form and individual fields.

@wmwart I know this isn't the best place for this message, but I just open sourced this handy package to do just that: https://github.com/andrico1234/ra-acl. It's inspired by Marmelab's ra-auth-acl, and adds hooks and declarative components.

DataHippo93 commented 3 years ago

Please make HRM work with React-Admin!

https://github.com/marmelab/react-admin/issues/495

VinayaSathyanarayana commented 3 years ago

Please support next-auth as authentication provider

fzaninotto commented 3 years ago

@VinayaSathyanarayana Please don't post comments with feature requests that don't need a breaking change here. React-admin releases new features on a daily basis, and doesn't need a major release for that. This discussion is only for backwards-incompatible changes.

VinayaSathyanarayana commented 3 years ago

Thanks for the clarification @fzaninotto. Apologies as I failed to note this thread was only for backward compatibility issues.

Mattia-Longhin commented 3 years ago

Do you think that it would be possible to add stronger typing to resources (Resource<MyResourceType>) instead of using Record everywhere (which is based on [key: string]: any)?

fzaninotto commented 3 years ago

Same remark as above: this doesn't imply a BC break, please don't use this conversation for feature requests.

Mattia-Longhin commented 3 years ago

@fzaninotto, ok.

It seems difficult to me to say what implies a BC and what doesn't. It seemed to me that this modification would deeply change the way RA is used. Maybe I'm missing something.

I'll post this in a separate feature request.

mhmnemati commented 3 years ago

@fzaninotto, What do you think about using react-query or swr instead of using redux ?

fzaninotto commented 3 years ago

@ckoliber What do you think these libs would bring to react-admin that it doesn't already have?

fzaninotto commented 3 years ago

I'm adding one possible breaking change: updating the format of the filters parameter passed to getList.

Currently, the filters are passed as key: value, e.g.:

{ filter: { name: "John Doe" } }

Which doesn't allow an operator. When developers want to use operators like greater than, includes, not equal, they currently have no standard way of doing so. We've got around this in demos by appending operators to the key name, but that's neither standard or explicit:

{ filter: { name_neq: "John Doe" } }

We should pass filters as an array of conditions, each condition being a field, an operator, and a value.

{ filter: [{ key: "name", operator: "NOT_EQUALS", value: "John Doe" }] }

dataProviders would then do what they want to convert that to their API syntax.

Cons: This would significantly increase the difficulty to build a dataProvider, and break all existing providers. Besides, not all backends support such operators, so basing a feature on the existence of these operators (like a date interval filter) would exclude some backends.

What do you think?

mhmnemati commented 3 years ago

@fzaninotto Using redux as a server state library, causes the increasing of codebase and increasing the bugs caused by reimplemening the wheel from scratch, and also there are a lot of features that you never need to reimplement them like:

  1. Pausing queries
  2. Dependent queries
  3. Parallel queries
  4. Query retries
  5. etc
mhmnemati commented 3 years ago

@fzaninotto A great and common way of writing queries in JSON or Object format is using MongoDB Query Language, handling where conditions using nested objects Currently these dataProviders are using this structure for handling filters, and I think the current state of react-admin filters is great and no need to change

  1. ra-data-hasura
  2. react-admin-lb4
capJavert commented 3 years ago

In regards to filters I also think it is better to keep them simple and everyone can implement their own layer for advanced filtering. This also keeps initial learning curve nice and easy.

fzaninotto commented 3 years ago

Using redux as a server state library, causes the increasing of codebase

Our internal data store, implemented with Redux, provides optimistic rendering in CRUD actions. No other library provides that type of abstraction. So yes, the codebase is larger than a simple query builder, because it does much more than that.

and increasing the bugs caused by reimplemening the wheel from scratch,

I disagree. We haven't recreated redux-libray or swr libraries from scratch ; they were created after react-admin. Also, what bugs are you talking about?

and also there are a lot of features that you never need to reimplement them like:

  1. Pausing queries
  2. Dependent queries
  3. Parallel queries
  4. Query retries
  5. etc

Features 2, and 3 already exist. If you need the other features, please open an RFC and we'll discuss whether it's relevant in the case of react-admin.

TCM5 commented 3 years ago

Someone already mentioned this an a issue in the past, but I see it as an option.

The MenuItemLink or the Resource could have a boolean prop like filters-reset that when a user enteres a list resource, the previous filters will not be considered. I know that the URL is the single source of truth, but this prop could trigger an URL param that could be used by ListContext in order to ignore persisted filters of that resource when rendering the list.

TCM5 commented 3 years ago

I'm adding one possible breaking change: updating the format of the filters parameter passed to getList.

Currently, the filters are passed as key: value, e.g.:

{ filter: { name: "John Doe" } }

Which doesn't allow an operator. When developers want to use operators like greater than, includes, not equal, they currently have no standard way of doing so. We've got around this in demos by appending operators to the key name, but that's neither standard or explicit:

{ filter: { name_neq: "John Doe" } }

We should pass filters as an array of conditions, each condition being a field, an operator, and a value.

{ filter: [{ key: "name", operator: "NOT_EQUALS", value: "John Doe" }] }

dataProviders would then do what they want to convert that to their API syntax.

Cons: This would significantly increase the difficulty to build a dataProvider, and break all existing providers. Besides, not all backends support such operators, so basing a feature on the existence of these operators (like a date interval filter) would exclude some backends.

What do you think?

That looks a great idea! Currently in order to bypass this missing feature, our team creates pseudo sources keys, like source="gte#createDate" and then they are parsed inside the logic of data provider in order to transform to something like createDate <= <value>.

This feature could avoid this workaround and add some filter capabilities

ValentinnDimitroff commented 3 years ago

I'm adding one possible breaking change: updating the format of the filters parameter passed to getList.

Currently, the filters are passed as key: value, e.g.:

{ filter: { name: "John Doe" } }

Which doesn't allow an operator. When developers want to use operators like greater than, includes, not equal, they currently have no standard way of doing so. We've got around this in demos by appending operators to the key name, but that's neither standard or explicit:

{ filter: { name_neq: "John Doe" } }

We should pass filters as an array of conditions, each condition being a field, an operator, and a value.

{ filter: [{ key: "name", operator: "NOT_EQUALS", value: "John Doe" }] }

dataProviders would then do what they want to convert that to their API syntax.

Cons: This would significantly increase the difficulty to build a dataProvider, and break all existing providers. Besides, not all backends support such operators, so basing a feature on the existence of these operators (like a date interval filter) would exclude some backends.

What do you think?

@fzaninotto I have faced the issue already and even handled it successfully. Making such a huge change with all the consequences seems a little bit too much to me. May I propose my solution:

Everything is managed on the backend when parsing filter keys.

And in this way everybody decides what operators he will support and how. Maybe not the neatest solution but at least not introducing BC.

fzaninotto commented 3 years ago

Someone already mentioned this an a issue in the past, but I see it as an option.

The MenuItemLink or the Resource could have a boolean prop like filters-reset that when a user enteres a list resource, the previous filters will not be considered. I know that the URL is the single source of truth, but this prop could trigger an URL param that could be used by ListContext in order to ignore persisted filters of that resource when rendering the list.

You don't need to wait for 4.0, or for any other version for that matter, to do this.

 <Link to="/posts?filter=%7B%7D">Filter</Link>

Links to an unfiltered list of posts.

bitlab-code commented 3 years ago

@fzaninotto is formik the final choose or you can consider react-hook-form?

fzaninotto commented 3 years ago

react-hook-form is still an option. We'll make the decision by comparing the feature list (and community) when we start the work.

DataHippo93 commented 3 years ago

I have an interesting one...

Feature request: Enable pinyin first letter search for autocomplete inputs.

Why: Chinese users often don't want to actually type the characters when searching they just want to type the first letter of each character in a string.

E.g. The simplified Chinese Characters for Hello is 你好 (pinyin: ni hao) . Chinese users want to find this by typing 'nh' in the autocomplete search bar.

Currently in my admin app we handle the search on the database side but it doesn't work for autocomplete inputs in ra due to the filterToQuery not supporting this.

See this package https://www.npmjs.com/package/pinyin-firstletter

Wondering how / if you would want to implement this. I think the main functionality we need is to be able to pass some function to the filterToQuery prop to transform the filtered data.

I would be happy to make a PR if it had chance of being merged.

fzaninotto commented 3 years ago

@DataHippo93 You can already transform the user input to a custom query parameter, so this is already possible in react-admin. Please do not post "how to" questions in this thread.

infilos commented 3 years ago

Support multiple dashboard components, please.

djhi commented 3 years ago

@infilos Can you be a little more specific?

panfiva commented 3 years ago

Ability to pass custom attributes to REST API data provider from components. This attribute could, for example, be used to define fields to be returned by REST API. This can be done by extending getXyzParams to include dataOptions attribute that is passed to data provider from standard react-admin components.

For example:

export interface GetListParams {
    pagination: PaginationPayload;
    sort: SortPayload;
    filter: any;
    dataOptions: any;
}