 Hello everyone, so My name is Martin as you probably heard and I will be today telling you something about data during forums and Something about data to an approach when they are trying to generate some piece of UI from some some data, right? I should probably introduce myself. I work here at Red Hat in Bernal For almost three years now. I started working as a UI developer from the start The first project I was working on is CloudForms and then a lot of people from CloudForms moved to the insights Which is not called Cloud, but Red Hat.com or Cloud Services or whatever you want to call it I've been developing UI for as long as I can remember I think the first piece of code that I written at high school that are just something all simple JavaScript applications For some projects and honestly at that time I really didn't really didn't like the UI and mostly because of the JavaScript because I Felt that the language was really clunky like the prototyping instead of classes. That was just completely Insane for me because I also used to write, you know, Java code and in Java every every classes and everything is really nice You know, you've got all these interfaces and types and stuff like that And then you write something like that in JavaScript and you just can't believe what's going on there But you know that mostly changed when the ES6 specification came. I felt like that the language really grew a lot and the syntax especially was much more Java like I guess which really Interested me and I know it's not that true, but at a time I really believe that And also the movement towards the functional programming Was really, you know, big thing for me because I personally believe that's the way to go So maybe something, you know about my personal life, I love dogs. I just recently bought a flat So I got mortgage for 30 years. If somebody wants to sponsor me Yeah, and that's about it, that's about myself and let's move toward something we call data-driven forms so Data-driven forms is a react library that we have written I will be talking about it But that doesn't mean that you can't you know applies these rules, you know and approach to other languages or libraries or whatever We try to design this library to be designed for UI and for components not for react and not for specific project so What's it all about? Stop working Great So what's it all about? Data-driven forms is a react component Which takes a JSON input and renders a form from that? It takes care of all about of all the form state management. It has validations Synchronous asynchronous it depends what you want to use you've got some conditional fields You've got you know data types and typecasting as you probably know that In HTML forms everything is string Excel for checkboxes So you need that for your APIs? We also design it to to be design system independent And so that means that you can use any component library you want really we are using mostly pattern fly Free and for that. You know if you're using something else you can do that also all the components are fully customizable and You are not locked down to just specific set of components like if you need some Very strange component just for that one form. You can just develop it and register it into the into the For render and use it So that's you know quick summary of data-driven forms is but I would like you to explain Why did we even decide to create library right? It's not the only one out there There are other libraries that do to practically the same thing that we found out that there are some limitations and issues with them So We did not use them So why would you even try to use like data to an approach? Why would you generate your UI from some data? Why wouldn't you just write it out? Well, and in small-scale projects that doesn't really make sense I mean if you have application with four pages and you will spend more time, you know developing some of these tools Rather than you just sit down and write write the markup and write the logic But you know when the scale is growing when you have for instance 100s and hundreds of forms like we did in cloud forms, you know doing everything manually. It's not really that easy Right, so if you have some data to an approach UI is more stable. You can make any you test it only one place You know that with the same input you will always get the same result You don't have to worry about some strange side effect and stuff like that One thing that I should mention we did not development statement library We are using react line form to take care of the state management We did not feel that this is necessary. I mean, it's a very good library. It's you that are needs and Again, if you are using something else in your applications and you would like to use data to inform You can easily take all of these ideas and approaches and just apply them to your specific desktop You don't even have to use to react, right? So there was the question. So why did we develop this? So we had this use case, right? You know manager came and said we need to generate forms from some data We don't we will have dynamic forms based on some parameters You will send something to API and it will send you some data. You have to render it We also That's for the cloud services like in cloud forms. There was also the issues that we have hundreds of forms They were not tested everything was behaving completely differently and we needed to fix that and there was the Another issue that we will have to migrate from bottom fly free to bottom fly work If you don't know what that fly is when flies is a design system used used in redhead in all their applications and We have two versions right now free and for the free and fly free is based on boots Good strap and the bottom fly for has been built on ground up and eventually every application should probably migrate to the latest version So obviously the first thing I did I went on the internet and I written data to inform us in the search And I get a lot of results, you know libraries like react Apollo or react Jason schema or SQL Even some library for generating forms from SQL which I found kind of strange But it's okay We specifically used in the cloud services to open API if you don't know what up API is open API is space of the Specifications for API as it defines the endpoints you can use it for generate some clients documentation and stuff like that and You know after I like a couple of days one of our back-end guys came and he said hey There's this library react Jason schema form and it can generate forms from the open API scheme And I was like great, you know work is finished everything is fine, but as it turned out it really really wasn't So generating UI from data isn't Like there's a lot of a lot of libraries out there even if you have ever written Some list that is generated from your API response. You are basically did you know data do an approach? So why create another one? I will try to Explain this using GraphQL example and using the libraries that I listed All these libraries have one Similarity and that is they are not developed for UI They are you they are the chem technologies All of them and they are used to specify you know entities tables API's and whatever But the thing is now them Consider the same use cases the same Attributes or other stuff that you have to consider when you are developing UI When you have your API endpoint and you expect the string You expect the string if something else comes you just throw an error play If the back-end developers are nice and kind you will get you know for a hundred response bother request They don't care about it. They would just let the server blow up and you get 500 That's not good enough for the UI and even graphql Which was built specifically for UI because Facebook had issues with their mobile versions of fate of the Facebook app It's still not good enough because it's still a specification for an API. It's a query language It doesn't consider all the stuff that you have to consider when you are building UI, right? So I will try to oh By the way, I'm not trying to say that you should not use these things, right? I I Think that for a lot of you, you know libraries like the Apollo graphql forms would be enough The issue will be apparent when you have when you have some complex UX and When you get some strange tasks from the customers that they will specifically tell you I need this This is not standard and all of these libraries are not very well prepared for that so let me show an example and We as I said we did use open API, but I think the example using the appeal is much more It's much better because the limitations of the graph kill and which are even when it comes to the generating You are are even bigger than open API So this is your standard, you know graphql entity specification. It's just a simple user. You've got four attributes name a city, etc And if you look at this, you know, and if back and back and guys come to you Hey, this is entity we need form for this and generate this, please You just look at it. Okay string. That's going to be text input integer. That's going to be number input city text, etc, etc So you do your job, you know you create a form You send it to JIRA or Sherlock, whatever you are using you mark it as done and you move on with your date Well, then the UX comes in they look at a screenshot and they say But the bio thing like that has to be a text error I say, okay, that sounds reasonable. So how do I do this? I've got this entity API has been using for months. They have it clearly defined What do I do about it? The database stores it as exactly the same field like it's But hard to 555 whatever But the UX said that it has to be an extra because they would want it that way and it's reasonable So we say, okay. Well, how do I do this? Well For graphql, I have to create another type because that's the only thing that differentiates these things So I created another type bio and I know that every time I get a bio type. I will have to render the text around and Then you get another request the age That's going to be input type range Why? Don't ask me. I would never do that and add another another field with your skills And it's not an integer So you write back to the UX person and you tell him this is completely stupid like why would age field be a rage Why would be a slider and the response will be well the user is going to pay us 10 billion billion dollars and give us dogs We all love dogs. So you're going to do that. Obviously So you create another type of age and if something is going to be type of age, you will render into type of French and Then they will need a enum for the city and that's actually reasonable. You don't want to just You just pick from the selection. Why not? and Then the back end guy comes to work and he see what you did to the graphql specification and And it breaks absolutely everything right tests are gone, you know They're QA. They are just everything is on fire You can't you can't do that by the way. You can't just change your models, you know your database tables and You know tell them well, I need is to render the UI. This is not a good idea. This is going to break everything so you get in a huge fight, you know and You start shouting at each other and in the middle of that great conversation UX comes again, and they will tell you I need is to be wizard and on the first step And they will be name and kids second step dress and the first step that it will be nice summary With a crazy video guy riding bicycle How do I'm supposed to generate that from the graphql or type? This is how you feel about it So what was the problem here, and I can tell you that we've got an API is slightly Slightly easier because you know you get stuff like titles and you get stuff like, you know if the field is three only and What node you can even hide there are there are even some attributes which tell you to hide some fields But at the end of the day you will have the same issue So why do you have this issue? Look at look at let's look at the biofield for instance, right? From the UI perspective, there is nothing that tells you what to render and how to use it The only thing that is clear is the name of that field and based on the explanation mark that it's required And what are the another, you know Attributes, what about labels? What about placeholders, you know, what about the validation message? How am I supposed to store all of these things into just a simple data thing into just a simple string and The question then the answer to that is you don't like creating new types that doesn't work We are going to break everything and you can argue well, we will create the second schema just for the UI Well, why would you use craft your specification for that? so Another thing is you might have an API which Is consumed by ten different UIs and every single UI is using different design system and different wording and some are translated some are not So you can't really justify using peck and technologies to render from them, right? I Put this slide here. Maybe some of you won't agree with me But personally I feel that if you want to sell something some type of application You better have some pretty good that UX because that's going that that is what's going to sell that thing Not the features like nobody cares about the features anymore. I feel like I take for instance trial, right? Everybody knows trial. It's a nice You know task management system or combat system, whatever you want to call it But at its core it's just few lists and you drag and drop stuff between that and that's it Like yes, you can you can add tags and dates But there are many many other you know management task management systems which are much more complex and can do much more things But nobody uses them because everybody's using chelo because everybody can use you just you know sit a guy in front of a computer You know Open the chelo page and he'll be like master of task management in five minutes because it's so simple to use and the UX is great But you know, this wasn't good enough for us We needed some genetic some UI generation and something for these forums We couldn't write in manually because we didn't but the use case was specific You will get some payload and you will have to render render that from the from the payload And also we had some legacy project which has as I said hundreds and hundreds of forms and doing that manually like you at At that time at that point we were behind several years of migrating them to new technologies And nobody wants to code forms. I mean let's be honest like forms are boring Every form you know every form behaves basically the same way so Why the data don't forms be any different Well, the first difference is that the data doing forms as I said were designed from ground up With you are in mind and not just you are but also components. We did not Focus on any specific library. We did not focus on any specific applications And after some iterations, these are basically the main rules that I Kind of came up with when trying to write the library from the ground up And the first rule that I am personally You know very well equating with is do not limit the developer like if the UX Sent you some if the UX designer will send you some crazy Crazy looking UI you have to be able to do that, right? You can't just tell them I can't do that because the library that I'm using doesn't allow me to That's not going to be good enough They did a lot of research and they designed it They know that the customers wants the customer wants in that way. So you have to be able to do that The second thing is when you have the schema and it kind of depends on the first rule the schema has to be open because The UI will change You can have two forums with same fields But the fields can be completely different you can use completely different components with completely different attributes So you can't be just locked down to Set of I don't know 50 attributes that you can use for your components But at same at the same time the scheme has to be also defined If you will just design something then that has no you know rules and limitation eventually that's going to break And you will end up in the same place You know as if you would when you'll be writing all these code all these you I saw all these forms manually And the third rule is don't lock the user or the developer to just one design system That that comes back to what I said earlier We are using kind of like fee free and for and we want to migrate to kind of fly for so obviously we need this flexibility to To do this so after we had this rule is let's say We needed some you know main building blocks of the library So obviously we want to render something from data. So we have to somehow specify the schema in order to Let the developers to create some new components and customize them we Came up with something called component mapping I will get through later and Then there is this form render itself which basically takes the schema and the components and then renders the UI So let's look at this these things separately So this is a very very basic example of The schema is always an object and then has to always be in fields right and every single object in the fields right is the component so First thing is the name. I mean if you have input with some name in the form You have to have it somewhere and then there's the component feel. I mean the component feel Exactly defines what kind of component component you are going to use in this case It's text feel it can be select it can be wizard It can be tabs checkboxes or whatever other component that you have at your disposal and Compared to the graphql for instance, there was just a string That is just this type string and I'm supposed to guess from that type everything that I need to know Well, we decided I mean it's Nice that we know that the type is string, but it doesn't help us in DUI everything is string and forms So we will just use this definition of the component and this constant will always pick or define the correct component I have to use there is no ambiguity nothing like that and Then you start adding stuff. There's label text color full wave But at its core all of these other special stuff There are just component props from react And now you might say well Which props I'm supposed to use How do I know that my component uses like one instead of instead of title? and These props and these attributes name are picked specifically from the component your component API defines How the field or how the schema looks? If your component uses label props label prop, you can add this key if your component uses options prop you will add the options key with the correct value and This is I believe that how we achieved that the schema is open But and yet at the same time is defined I mean if you take a red hat for instance every UI developer knows or at least should know pattern fly and If they know pattern fly they can look at a schema and they can instantly say what kind of component it is And what kind of props it has and how it will look and how we how it will behave So even though that the schema is fairly open every single developer in red hat will know what kind of you I will be and what it will do And and that applies to you know any other company that has some design system and that has some component libraries, right? So then there is the form render the form render is Basically just the big rendering loop that goes through That goes through the schema It also hooks The components through the form state if you want it to be to the component state It goes through those it goes through the schema it picks the components it adds some necessary props You know like your own change functions your own broader functions. It adds some metadata to it You know if there is the field valley Is it not is there some error message? Did you touch it? Is it active? All these good things come from the react file form library, and I guess that the other libraries have some equivalence to it And once the component is put together it just renders it to DIY But on its own the form renderer doesn't really know anything about the components It's supposed to render right if you would try to just you know use the schema pass it to the renderer It would just crash because it has no idea how to how to render them Now that is taken care of by the component mapping The component mapping itself these are just you know objects and each key Or each value in that object has a key and a value obviously and the key has the same It's the same constant that you use for the component field So if you have a text field in your schema, you must have a text field key in your component matters and base and you know value of that component component that where is React component and that's all the limitations you have if you want to use your application as a field in the If you want to use your application as a field in the form you can do that I mean, we don't restrict you to any component sets, you know or component types You will use whatever you need to use you will use whatever you are using right now in your application and just Registrate under some name So right now there are two component markers Actually, we kind of decided that the next major version version of the library is going to be only one For some reason we decided to split to layout mappers and form fields mappers But as it turned out, it doesn't really make sense. There is no reason Why you should split these things so but right now there is a layout number and in lab number You will use your static, you know components for the forms For instance the whole form wrapper or basically just a form talking on HTML Buttons we have some four groups and stuff like that We had even more before but you know as we were developing and using it and iterating We kind of discovered that you don't really need that much and basically you don't even need these buttons You know you can render them on your own The only thing from the layout mapper that you really need right now is the form tag Well, and then there's the form fields mapper It does the implementation for your inputs for a checkboxes selects, etc So this is how the component mapper looks like I will be using the text field example and As you can see it's just simple implementation of react component and There is a form fields mapper. It's just a text field The is just a constant of text field and there is the value of that component and This is how it kind of works and I will show specific this specific example in a minute I will do some coding and You take the component mappers you take the schemas you put it into render render picks all the stuff It means it will connect the field to the state. It will pass the props to it and then this one so Let's give you some examples Hopefully everything will work. I Will show you some basic code that you can do and What you would probably do when you would start, you know, writing with datas and forms and then I will show you some More complex stuff that we are using right now in our applications on cloud services so There's some code So I created completely empty project which has been bootstrapped with the Create react app from Facebook As you can see there's nothing special about this Just the empty project I did pre-installed the dependencies. I did pre-install the data transforms and Also material UI because I didn't want You to wait for it So let's just start there is a lot of useless stuff that we don't need to this moment. I will just delete all of this And delete all this. We don't need this And also delete all this Right All that we need started And there is an empty react application By the way, I think it's way too small So you would start as with any library in react which is And I will use our amazing documentation And we start create some So as I said in layout mappers, they are right now just fine predefined component types Form vapor buttons title and stuff like that. We'll just create two of them. I Will copy these Constants Components so to create just the form wrapper All you really need Form tag Children to it So in these probes, you basically just find the handle submit function or on submit rather and Obviously the children of the form Prepare the button Which has a label? It has a variant and There's some other stuff Mostly, you know again the handle submit some types etc etc. So it's just going to be normal button With label, let's give it some styling. It's going to be very basic. Let's give it a background Primary it's going to be red Otherwise it's going to be It's going to be very pretty No And for the rest of the stuff, they are just containers for some various pieces So we'll just use fragment for that Obviously If you would ever use it in your application, you would probably want to style the thing So let's now use the form render. Let's get it The layout wrapper and we don't have any schema right now. It would probably fail if I tried trying Oh, yeah, you get nice error that you are missing the schema So let's create in the schema We need to fields array and in the fields array. We will create a text field You don't need any other prop site now We'll just add label Why not? Let's file the schema to the form and let's give it some Submit function Just come the luck is good enough for now Now it's going to crash Because we don't have any form fields mapper So let's create that and right now it's just going to be an empty because we don't have any form components defined So this would be the basic setup You would need to start but obviously we are missing the components to render Really and I seem to miss Layout mapper Form fields mapper. I throw this on typos. Yes. So now it's telling me That I'm trying to render text field component, but there isn't any so Let's implement that and I'm going to create some very simple example and then I'm going to show you If you have an existing design system, how easy it is to actually reuse it. So Create a text field. It will get two new props that you don't specify in The schema and those are input and meta and in the input property will get your own change You will get your value. You will get your own blur focus and stuff like that Basically the things that will change the form state and in the meta attribute, you will get your error message You will get your other meta tags like if the field is valid, etc And then you will get anything that you want. So let's say our text field is going to have label Let's say it's going to placeholder. Let's say it's going to have Helper texts and let's say that we want it to be required So let's create that input field. It's going to be a diff Let's give it some style. Let's make it flex because why not and make it In a column Let's do the label and we will use label HTML for oops input.name Now let's use the Let's actually define the input and maybe a good thing would be to have a type of that Let's give it all the input drops that we get from the form state Let's give it a type and let's give it a placeholder and then let's use if we have some helper text Let's give it another So I just defined a very basic component and I will now take the constant of that component Give it to the form fields method and use the component as a value and it's there In sudden lanes render, so Let's also give some State so you can actually see what you have written inside of that thing And whether whenever we submit the values Just set them George state So I can now type my name inside of here and I will get it in the form state. So this is the outcome Now this is very basic example Let's say that we want to add some validation Required validation is good enough for this example. I think Let's get the required validator I will just copy and paste it from the docs and use this And I also added the required prop in our text field Now one important thing to mention like this validate field only does the validation It doesn't change to look of that component. So if you want to add, you know, some asterisks and stuff like that You will have to specify that specifically for that component now the reason why we did this is that We didn't want to go through all the validators and then some create some magic attribute Because a lot of material UI for instance uses required, you know pattern fly uses is required And your different component can use different type of flag for that And we have a lot of different Validations like for maximum and minimum one field validation for reg X URLs, etc So going through, you know Go going through all these validations and coming up with different attributes and kind of guessing what kind of attributes your Component are using is not really an option So this is another thing that we didn't wanted to dictate the API's of your component. You will just use your own things so My field is now required If I save this and if I try to submit it You see that nothing happens, but only the field gets focused. I would also probably want to see the validation message of that Of that error So the validation message is hidden in the net attack. So if there is an error, I Will use New element, oops, which will render that error message. I messed something up. Yeah, I did So It doesn't work for some reason I don't know why can somebody see the issue I Don't well, I'm not gonna get bothered with them right now because I don't want to Debug it It's probably something Where No, no, no, it should be in the meta object Yeah Oh, there is an error There is a big error Look at that Meta attribute Let's see it That is the error message. I don't know why it's not showing up. You see it here Oh Yeah, this is this is why live demos are the best always Well Oh, it is It works after all So There it is. You've got your validation But this is very ugly. You wouldn't really want to use that anywhere So I pre-install a material UI To showcase How easy it is to use existing components in your component appers React core Text field so For the material UI Well We don't need any of this You can just delete it. You just use the text field We will give it The input props label We will give it Error required It sure used to be required And type Why not Oh, and suddenly there's material UI input Which works exactly the same If I use A helper text, I can give it a helper text Or use the Meta Not error To render So this is how it works You can see if you have already predefined components is very simple And you don't really have to do that much coding. You just have to, you know, connect this component to the forum state So rather than just showing you these simple examples, I will just move on Towards something that we are using right now in the cloud services So this is a sources page Basically, what this means you use some Cloud services provide like amazon and open ship. You connect it to your You connect it to your tenant or group or whatever And you can then order some stuff. You can monitor it, etc It's not really that important for this showcase I click wrong button So when you want to add a new source, you are going to be Showing this wizard and everything is this wizard is done via data during forums So let's look at some of the features So then now you have some page You can choose your application for which you want to use this source. So let's say I want to do catalog and Only available source type for catalog is sensible tower Okay, then let's go to the next step You need to add some name You need to add some password and you can see that If the this you know sub form is not valid, you can't move to the next page or next step You can't click to the next step Let's give it some something else You can do some more parameters You know URLs, etc. Well, this is not a URL. I can't go somewhere else. Oh, I guess we'll have to give it Something else Whatever It's still on URL. Well, let's use this thing So the validation is quite solid And you know valid for validation you can use asynchronous validation. You can use custom functions, whatever you need You can you've got not this nice summary page. You can go back You can choose the you know different applications you want you you want to use You know everything you have to you know, everything is a member You can also say that, you know, whatever the feel is gone from the from the DOM. You can delete all stuff And you can imagine there's actually quite a lot of logic You know behind this component And you know anytime, you know, you want to use wizard you don't have to write anything You just have to write. Okay. I want these components to be in this step I want these validations, you know, and when I select the type to be x I want to go this route or I want to go another route. So this is kind of nice nice example The another one I can show you Is How does it work with dynamic data fetching versus my ghost? So in different application in catalog You can run playbooks from ansible tower If you don't know what that means you have basically some scenario somewhere written that will tell you I want to install, you know, new operating system and I want to use 10 cpus for that And I want it to run, you know, every five minutes or whatever And it seems that the site is down, which is amazing As always like the most are the best There it is So how we do that so you can, you know, create these groups of items inside catalog You say I won't have these job templates and based on that job templates when you want to run that thing You will get a form And the site is down again Or the connection is really slow. Well, how does it basically Works is that you send the request a server It will send you the schema and from that schema you are going through and read There are also another features like you can take that schema you can modify it inside the application You know, you can change your validation messages. You can change your names labels, etc And you can customize it to your needs like for one user You want to show just half of the attributes because you don't want them to customize the number of cpus Because that's going to cost a lot of money. You want them, you know, to customize maybe just You know the time send playbook is supposed to run and stuff like that And you can see right now doing that manually. It's not really possible You kind of need some sort of engine which will render these UIs for you Well, I was kind of hoping that I could show that to you, but I guess I won't Well, you have to be connected to vpn and stuff like that, but I don't think that This might not work Something is happening Network changed Yeah, I I I don't want to get bogged down with this stuff So you're gonna have to just take my word for it It works and that's about it I would like to thank you for your attention if you are interested In the data uniforms, there are some contacts you can use definitely check out the github repo We are always looking for some help You can check out the docs And if you need to get in contact with me specifically you can use the email or I'm always at the github Well always and I'm not sleeping so You can contact me there and if you have any questions just go ahead and I would love to answer them, please Yeah, so the question was if I have any links to the examples that I was showing at the this thing you mean So We have Examples for all the components that we use at the data zoom forums documentation So if you want to see a wizard We'll just see a wizard Well If the connection actually works But we don't have specific examples, you know To these components because obviously they are used in the cloud services In the cloud services application So I think there are some pictures. Yeah, you can try it out over here. You can see some of the schemas for the wizard I think there are even some Pictures here. Yes. I think this is taken directly for the cloud services So most of the stuff that I was showing you here today Is taken from our documentation. So if you want to check that out, you can go through it You will find a lot of you know food stuff there Anybody else Yes, so Yes, so the question was the reason of this library is that you can generate the schema And if you need to write it manually, there is You know, no point of doing that just writing the j6 That's a very good point And we are actually working on an editor when you can just drag and drop All these components and it will generate the schema for you and then you can use that thing you know writing that manually is A little bit painful. I definitely agree with that But it will still take away the necessity of many of you know managing the state on your own That that is the editor is going to be Included very soon. We actually have to work an example in the cloud services. We just need to flesh out some, you know Yes Yes So the comment from the audience was that They see the main benefit that you have some functions which will generate the schema for you And that is exactly the case for the wizard that you saw like writing that schema manually to be insane There's like 50 different fields and branches and all the paths go around What we do there We are you know fetching all of these partials from server and then we use these functions to create the schema You know to kind of bound it all together and then you can render that You know fairly complex form if you ask me Another question Well, I guess that's it. So It was great talking to you and I hope you liked it. I hope you Will try that library and if not, I will hope you that whenever you need to write some, you know generated ui you will remember that Sometimes the backend technology is not enough even though that your team is going to try you to otherwise And thank you for our intention and it was pleasure speaking to you