rare-sapphire
rare-sapphireโ€ข2y ago

Custom ID in table

Hi, I have a table that have a unique ID column that isn't "id", as DatGrid expects. I'm getting an error that suggests I use getRowId prop to specify a custom id, but I'm not sure how to use it in the MuiInferencer. It might be related to this post but I'm not sure: https://discord.com/channels/837692625737613362/1066115332240056431
35 Replies
yammering-amber
yammering-amberโ€ข2y ago
Hey @YechiamTK, Inferencer doesn't support for changing the ID, right now. However, you can copy the generated code and then create your own page with copied code and change the parts related to the ID. Additionally, Inferencer doesn't recommended to use production. You can find more information about Inferencer: https://refine.dev/docs/tutorial/getting-started/mui/generate-crud-pages/ And you can see to how to create resource pages with generated code by Inferencer: https://refine.dev/docs/tutorial/adding-crud-pages/mui/index/
rare-sapphire
rare-sapphireOPโ€ข2y ago
Oh that's a shame. Thought I found the perfect library for my use case ๐Ÿ˜ฆ Was trying to provide a generic dashboard for our many different apis, so the Inferencer would've been the perfect option. Thanks anyway
Omer
Omerโ€ข2y ago
Hey @YechiamTK , @pankod/refine-inferencer is a package that provides a way to automatically generate views for resources based on the data structure. The aim is to reduce the amount of time spent on creating views for resources by generating the code automatically that can be customized easily.
rare-sapphire
rare-sapphireOPโ€ข2y ago
I know I know, thought I can hack my way around creating generic components myself using this Inferencer My problem is that I don't want to build a specified board for each api, but provide a generic code that generates a board for each api (without any further customizations) But I get it, the inferencers are usually only to generate the code in order for the devs to take it and use it themselves, same as in react-admin
Omer
Omerโ€ข2y ago
wow that's impressive because we thought people would only use it for development
yammering-amber
yammering-amberโ€ข2y ago
Maybe, we can make it into a form that can respond to @YechiamTK's requests in the future @Omer ๐Ÿ™‚
Omer
Omerโ€ข2y ago
Can you share your API structure and the details of your applications?
rare-sapphire
rare-sapphireOPโ€ข2y ago
Yeah it's an idea that came up in our team because we have many different applications that use the same CRUD-based api schemas and we need to give our business owners the ability to easily manipulate data, so I thought why not create a generic board. Looking through the available libraries they all come very close to my specific needs but not exactly :/ Unfortunately I don't think I am allowed toshare the api structure. But I can perhaps provide a general schema That would be awesome; I'll probably start implementing it on our structure myself if I won't find anything else, I might be able to share insights Say, what is "idFromProps" in the MuiInferencer? I thought it might be related
yammering-amber
yammering-amberโ€ข2y ago
By default, Inferencer gets the value of ID from the URL in edit pages and show pages. If you want to use Inferencer any custom page without query params on URL, you need to pass id props to Inferencer component. The id provides to fetch a record detail using getOne method that passed to dataProvider Unfortunately, it does not provide a solution for you ๐Ÿ˜•
rare-sapphire
rare-sapphireOPโ€ข2y ago
Meaning passing id prop will generate the api request as ".../resource?id=1" instead of ".../resource/1"?
yammering-amber
yammering-amberโ€ข2y ago
No, it will be like ".../resource/123" instead of ".../resource/1". Sorry, I phrased it wrong by saying query parameters.
rare-sapphire
rare-sapphireOPโ€ข2y ago
Also, I'm console logging the fields (via fieldTransformer) and I see some fields are recognized as "regular" fields (e.g. with key and type) and some have more properties like canRelate, priority, multiple, relation, resource. How is the field recognition works? How does it figure out if the field presents a relation? (because, for example, I have a field that it misinterprets as relational when it is not so) Ah I see, like force-selecting the specific record I want
Omer
Omerโ€ข2y ago
Inferencer | refine
@pankod/refine-inferencer is a package that provides a way to automatically generate views for resources based on the data structure. The aim is to reduce the amount of time spent on creating views for resources by generating the code automatically that can be customized easily.
rare-sapphire
rare-sapphireOPโ€ข2y ago
OK yeah that's what I thought, of course a field that doesn't really have a relation ends with "Id" in our table ๐Ÿ™‚ Although, according to the docs if the api requests fails then the relation should be deleted; is it deleted after the fieldTransformer method and I simply don't catch it in my logging? Oh and, which property in the field does the datagrid takes as the unique id? Or is it something added dynamically inside the Inferencer?
yammering-amber
yammering-amberโ€ข2y ago
It actually uses the value you pass as params in the URL as the ID. If you use Inferencer on ".../posts/custom-id" page. Inferencer sends params to getOne method like below:
dataProvider.getOne({
resource: "posts",
id: "custom-id",
});
dataProvider.getOne({
resource: "posts",
id: "custom-id",
});
rare-sapphire
rare-sapphireOPโ€ข2y ago
Ah, interesting. I'll try to check if I can manipulate that OK just letting you know in case someone else is trying this - for now I've implemented an axios adapter to modify the data I'm getting and changing the custom id property to be "id". This solved it for now, I'll see if it works on all of my use-cases. For an in-library fix, I saw that the Inferencer has "item.id === value" - a simple change to get the id dynamically instead of writing it statically will probably achieve the same result (and in a much better way) I hope I don't miss anything using a custom axios instance - I'll check the instance you're using internally and see if there's anything special that I'll need to copy
yammering-amber
yammering-amberโ€ข2y ago
Tomorrow we will discuss this with the team and as soon as possible we'll inform you. Don't worry about it. I don't thin it will be a problem
rare-sapphire
rare-sapphireOPโ€ข2y ago
Great, thank you for the responsiveness! Hi there ๐Ÿ‘‹ I stumbled upon a different issue but I think it's better to keep it in this conversation. My fields relations are mostly one-to-one relationships, not one-to-many. I see that when the Inferencer attempts to create the relation it creates a useMany request and expects an array, but only one record is return, not in an array but as the record object. Is there any way to reconcile this? Can I perhaps force the Inferencer to use useOne instead of useMany? Update: may have misunderstood my mistake; I think the useMany does find the proper object, but for some reason what I get is the object itself instead of the React component? i.e. the render function in renderCell is returning an object rather than a ReactNode, from looking at the generated code I don't really understand how the BaseRecord is suppose to turn into a ReactNode OK sorry, second update: for some reason the relation field did not get an accessor property. I added it manually with fieldTransformer. Any idea on why it didn't got one automatically?
afraid-scarlet
afraid-scarletโ€ข2y ago
Hey @YechiamTK sorry for the late response. Can you give us more info about the fields you've encountered those issues with their types and structure? Looks like, inferencer is failing to find the proper accessor values and end up using it like a primitive value ๐Ÿค”
rare-sapphire
rare-sapphireOPโ€ข2y ago
Hi, so the flow that happens is Inferencer sees a field that ends with "Id" and tries to find a relation. One of those fields actually has a relation - and it finds the correct resource. But, when it tries to aquire the value from that resource it either doesn't find an accessor, or, when I specifically give it an accessor, it builds the field aceess incorrectly (in valueGetter). It might be related to my previous issue, which is why I stayed in this discussion - in this table I also have a custom pk that I force-change in the axios interceptor. So let's say I have resource A with FK of customId, which refers to resource B with pk of this customId. In the first case the renderCell will successfully find data.customId === value, but it isn't the value but the object - the value will be data.customId.customId (because it took resource B as the data). The second case will generate a getterValue which will unsuccessfully attempt to get the value from data.customId.id (because "id" is the accessor), which is not an existing property in this data (in this case data is resource A). I hope I managed to clarify the problem Hi @Omer and @gremlin5957 ๐Ÿ™‚ Just wanted to ping you to check if there's any update on the custom id. Also, again might be a too-specific request, but I don't really see a way around it - can we get an option to pass along to the Inferencer to not render the CodeViewerComponent? (or, perhaps, move it out of the Inferencer and to the Layout component, in such a way that I can create my custom Layout without it?)
afraid-scarlet
afraid-scarletโ€ข2y ago
Hey @YechiamTK, about the custom ID issue, can you please open up an issue on GitHub? It will be a more clear and easier to follow place for us to track that ๐Ÿ™ About the CodeViewer, since the inferencer package is designed to be a development only feature, we currently don't have any plans to make that removable. Its best to copy-paste the generated code and edit it by your needs, not just because of the customization but also for the performance reasons ๐Ÿ˜…
rare-sapphire
rare-sapphireOPโ€ข2y ago
@aliemirs sorry, missed the message. I see, I'll open an issue about the custom id. About CodeViewer - as I've said at the start of this discussion copying the generated code is a no-go for my use-case as I'm relying on the Inferencer to actually be used in production. If there's no way to add a remove option (even only for the rendering of the component - I don't have much care for performance in my case), I'll need to find a workaround. Thanks anyway ๐Ÿ™‚
afraid-scarlet
afraid-scarletโ€ข2y ago
You can create your own from copy-pasting from one of the existing inferencers source codes, we export the createInferencer function from the package. You will also be able to generate the code as you like (for the preview) and also pass an empty component as the code viewer to remove it from the bottom right Or you know, you can do a css workaround to hide it maybe? ๐Ÿ˜…
rare-sapphire
rare-sapphireOPโ€ข2y ago
If I recall correctly, when looking at createInferencer I remember the CodeViewer wasn't passed to it but rather created inside of it? Perhaps I don't remember correctly haha. Anyway I'll check it out, this will most probably solve this issue if it works as you've said. And yeah the css workaround was the way I thought to go ๐Ÿ™ˆ And fyi here's the issue I've opened, let me know if there's anything else needed (on my personal account as my workplace doesn't use github ๐Ÿ™ƒ ) - https://github.com/refinedev/refine/issues/3486
GitHub
[FEAT] Custom ID for resources ยท Issue #3486 ยท refinedev/refine
Is your feature request related to a problem? Please describe. Hi, Most of my resources have their PKs not as "id", but as some other custom "x-id", like &qu...
afraid-scarlet
afraid-scarletโ€ข2y ago
GitHub
refine/list.tsx at next ยท refinedev/refine
Build your React-based CRUD applications, without constraints. - refine/list.tsx at next ยท refinedev/refine
afraid-scarlet
afraid-scarletโ€ข2y ago
I will assign the issue to myself and get back to you as soon as possible
rare-sapphire
rare-sapphireOPโ€ข2y ago
Great! Thank you ๐Ÿ™‚ Hi ๐Ÿ™‚ So I'm trying to use the exported createInferencer and I'm having some import issues. The function itself is indeed exported, but there are things like /utilities and the /mui components that aren't exported (or, more precisely, aren't exported from the refine-inferencer package in the package.json's exports). I might be wrong here and might've tried to import it incorrectly. Do you perhaps have an example of another user who used the createInferencer directly? Just wanted to update that I'm currently simply copying the needed utils to my workspace and importing them locally. Let me know if you perhaps can export them as well so that the Inferencer can truly be imported and customize. For now this will probably solve all of my problems because I can customize the id as well, as I'm controlling the renderer function now
afraid-scarlet
afraid-scarletโ€ข2y ago
Hey @YechiamTK sorry for the late response ๐Ÿ™ Just noticed that. We're missing the exports of the utilities we've used in inferencer components. Created a PR for it here https://github.com/refinedev/refine/pull/3502 We'll release an update soon, so you'll be able to use them from the package instead of copying. Sorry for the issue ๐Ÿ™
GitHub
feat(inferencer): export inferencer utilities by aliemir ยท Pull Req...
Exported utility functions used in inferencers to let users use it when they're using createInferencer function to create their own inferencer components. Self Check before Merge Please check a...
rare-sapphire
rare-sapphireOPโ€ข2y ago
Awesome! Thanks again for the responsiveness ๐Ÿ™‚ Also note that I can't import the inferencers themselves (show/list/edit etc). Can they be added to the exports as well?
afraid-scarlet
afraid-scarletโ€ข2y ago
They actually are exported ๐Ÿค” Like;
import { MuiCreateInferencer } from "@pankod/refine-inferencer/mui";
import { MuiCreateInferencer } from "@pankod/refine-inferencer/mui";
Do you have issues using it like this?
rare-sapphire
rare-sapphireOPโ€ข2y ago
This encapsulates ListInferencer/ShowInferencer/etc, and those are the components that I need (to edit the renderer function)
afraid-scarlet
afraid-scarletโ€ข2y ago
Hey @YechiamTK sorry for the delay ๐Ÿคฆโ€โ™‚๏ธ Just released @pankod/refine-inferencer@2.4.0 with utility exports and also included the renderer functions (exported like AntdListRenderer, etc.) Hope this will let you customize a inferencer easily ๐Ÿ™
rare-sapphire
rare-sapphireOPโ€ข2y ago
Awesome! Thanks ๐Ÿ™‚ Hi ๐Ÿ™‚ Question - why is the filtering/sorting in the datagrid done using api requests, instead of the regular datagrid client-side behavior? Can it be overridden?
afraid-scarlet
afraid-scarletโ€ข2y ago
Hey @YechiamTK, we think this is a missing feature on our side and that's why we've added this to our v4 roadmap! We're hoping to release it by the end of this month. If you like to check the changes we're going to make and how we're going to handle those, please see https://github.com/refinedev/refine/discussions/3527 We'd love to hear your feedback and suggestions ๐Ÿ™ For now, you can pass props and customize your DataGrid to handle them client-side
rare-sapphire
rare-sapphireOPโ€ข2y ago
Thanks! Yeah I saw the announcement and was very excited ๐Ÿ™‚ I'll check the roadmap and pass suggestions if I have any. Also yeah I saw that I can override the DataGridProps, this is also how I got the custom id working ๐Ÿ™ƒ Obviously the most important line for me is: "We're going to expose more options and controls to the user to not have any hardcoded values and logic in the core." Which is awesome. I do want to add that, although it might be a bit difficult, perhaps giving a fetching-library agnostic approach will be beneficial. E.g. in my company we have a library that encapsulates the regular Fetch API with our needed interceptors. The fact that the library necessitates usage of axios forced me to build a custom instance with the needed interceptors, instead of using our library ๐Ÿ™‚