asyncapi-react icon indicating copy to clipboard operation
asyncapi-react copied to clipboard

DocsUI: Messages Object output

Open mcturco opened this issue 2 years ago • 45 comments

Description

This issue is for the design progress and proposal of the UX/UI updates to the Messages Object documentation output.

Scope

  • [ ] Design
  • [ ] Implementation

See comments below for design progress.

mcturco avatar Jul 01 '22 18:07 mcturco

RFC: Proposal for new UX for Payload documentation output

https://www.loom.com/share/dba7481f296046629b30995628b924e3

Here is a new idea I have that could improve the experience of the Payload component. My inspiration came from browser developer tools where you can toggle all levels of an object with ease and see everything you need in one line.

Some more features that we should add: Need a way to collapse and expand all. Should there be one button to expand and collapse the whole payload? Or should a button like this be available at all Object levels? I guess it depends on the complexity of the payload structure. Let me know what you think!

mcturco avatar Jul 01 '22 18:07 mcturco

@mcturco

Here is a new idea I have that could improve the experience of the Payload component. My inspiration came from browser developer tools where you can toggle all levels of an object with ease and see everything you need in one line.

Yeah, it looks very good, however have in mind that metadata of single property can be very complex. At the moment you render type, name, format and description. We can have also constraints like minLength, maxLength etc, examples for given field, metadata like read-only, write-only, external documentation link (in future also tags). So as you see, render in single line can be very problematic and by this we render in current react-component each metadata under each other.

Need a way to collapse and expand all. Should there be one button to expand and collapse the whole payload? Or should a button like this be available at all Object levels? I guess it depends on the complexity of the payload structure. Let me know what you think!

Yeah, we should have that implemented, button to collapse only one level and all levels. I added suggestion to current design in this PR https://github.com/asyncapi/asyncapi-react/pull/620

magicmatatjahu avatar Jul 04 '22 11:07 magicmatatjahu

@magicmatatjahu Thanks for that feedback! @fmvilas explained the problems with showing the constraints of each property to me during our 1:1 call and how that could become confusing on one line. He also mentioned that we should think about the fact that description in the spec supports markdown, so we need a way to show that as well.

Going to take that information and come up with some other solutions that might work. Thanks! 😄

mcturco avatar Jul 05 '22 16:07 mcturco

Updated Payload Output Design

Hi here is a video explaining the new design iteration for the payload object, would appreciate any feedback you have!

https://www.loom.com/share/7c5b1e5ca14c4b4691eda0080ebe3849

mcturco avatar Jul 12 '22 21:07 mcturco

I love the idea for long descriptions ❤️

derberg avatar Jul 14 '22 08:07 derberg

Hey all! 👋

I have been working on an update for this issue, and wanted to first offer it in video form if that suits you:

https://www.loom.com/share/6d24178eb4fc43b49c30f4696f2761ae

Went back to the drawing board

After presenting the previous idea during the community meeting livestream, I received some great feedback that led me to the conclusion that we needed to head back to the drawing board and address some concerns that were mentioned:

  1. There is not enough space to present various metadatas within schema properties
  2. How are we going to show validations such as if/then/else?

Well, before I felt like I could dive headfirst into ideation on these two issues, I felt like I had to do some background research to better understand JSON schema and the different complexities within.

Along this journey, I started brainstorming in a FigJam file and jotted down some of the "bread and butter" components that is needed for your JSON schema. Click here to open the FigJam -> https://www.figma.com/file/j6UgI3CC6bmzv6NRpaNEtF/JSON-Schema-Brainstorm?node-id=0%3A1

Screen Shot 2022-08-17 at 2 26 02 PM

After defining the 🍞 & 🧈, I felt like I could once again start coming up with a layout that would make sense to build off of.

Screen Shot 2022-08-17 at 2 27 42 PM

From this idea, I began to craft wireframes at a bit higher of a level but not focused so much on UI to see if I can start hammering out an established experience.

Frame 6

And here is this experience put to the test by using some example schemas from the JSON Schema website:

Examples

Link to Figma File -> https://www.figma.com/file/wJHfdNxBeXg4O3jxcqcL9X/JSON-Schema-Wireframes?node-id=7%3A355


What do you think? Am I on the right track?

Would appreciate some feedback so I can decide how to proceed!

cc: @derberg @magicmatatjahu @jonaslagoni @fmvilas

mcturco avatar Aug 17 '22 18:08 mcturco

Thanks so much for taking the time to record a video 🙏🏼 It helped to check it out quickly 🚀

Only positive feedback, sorry 😄

  • good decision to not take up all the use cases at the same time, but gradually extend design on the way 👏🏼
  • I like a lot the new position of the information about the type. I did not catch it during the video, will they be colored differently depending on the type?
  • I like your approach for more human-readable approach when representing Rules, so you do not just display what is in the schema, for example >0 but actually put a property name next to it age > 0, so readers do not need to exercise brain to visualize that, but it is basically there in the UI. I kinda reminded me of the project I stumbled upon some time ago, maybe will help you in your journey 😄 -> https://coveooss.github.io/json-schema-for-humans/#/Examples (especially interesting is why they are adding a kind of "breadcrumbs" info about the property location inside schema)

IMHO it is going a very good direction 🚀

derberg avatar Aug 18 '22 07:08 derberg

@derberg

Thanks so much for taking the time to record a video 🙏🏼 It helped to check it out quickly 🚀

Yay! Super glad you thought the video presentation was helpful 😄

I like a lot the new position of the information about the type. I did not catch it during the video, will they be colored differently depending on the type?

Yeah at this stage I was more focused on the interactions and layout of how we might present the information, but I definitely was thinking as I was designing this that we could color-code the property types!

I like your approach for more human-readable approach when representing Rules, so you do not just display what is in the schema, for example >0 but actually put a property name next to it age > 0, so readers do not need to exercise brain to visualize that, but it is basically there in the UI.

Yes! Glad you found that helpful and easier to read. I was stuck at this for a while trying to figure out the best human approach, and really was just thinking how people are used to seeing rules in math with variables. Interested to see other opinions on this as well!

I kinda reminded me of the project I stumbled upon some time ago, maybe will help you in your journey 😄 -> https://coveooss.github.io/json-schema-for-humans/#/Examples (especially interesting is why they are adding a kind of "breadcrumbs" info about the property location inside schema)

Bless you for this reference 🙏 As I was working on this, I couldn't help but think that someone must have already done this same kind of thing before but I couldn't find any specific projects similar. I definitely think adding an element like breadcrumbs might be super helpful to keep track of where you are viewing the schema.

IMHO it is going a very good direction 🚀

I SUPER appreciate your quick and thoughtful feedback, Lukasz! Thank you! 😄

mcturco avatar Aug 18 '22 14:08 mcturco

Update! Ideation on if/then/else implementation

Video:

https://www.loom.com/share/65c5b8fd731d4674bd466b4231b16d52

Transcript:

Hey guys, happy Monday. I wanted to just start presenting some more things that I've been coming up with as far as this messages object item in Github.

I have a few ideas for if then, else that I would like to present and get some feedback on if possible.

TL;DW too long didn't watch: basically these are the three options that I have.

This is one where I list the conditions at the bottom outside of the property's object. Listed Conditions


The next one, where I list the conditions on the left side, where you can toggle between them. Tabs on Left - Default


And then the last one where I list on the top, where we can toggle between them as well. Tabs on Top - Default

(For a detailed explanation of these options, view the video on loom which also contains a longer transcript)

mcturco avatar Aug 22 '22 18:08 mcturco

Love it! Have you thought about having tabs inside the property box instead? I mean, when age >= 21, only beverage changes so why not put the tab there? I know multiple properties can be affected by the same condition so what we can do in this case is that if you click on the age >= 21 tab inside beverage it will also switch to the age >= 21 tab in the other fields affected by the condition. Am I making myself understood? I find it hard to explain it 😄

fmvilas avatar Aug 23 '22 09:08 fmvilas

I know multiple properties can be affected by the same condition so what we can do in this case is that if you click on the age >= 21 tab inside beverage it will also switch to the age >= 21 tab in the other fields affected by the condition.

Hey @fmvilas thanks for leaving feedback 😄 Yes, I understand exactly what you are saying. However, say that the payload consists of more than just two properties, maybe something like 8 properties. My fear is that if someone clicks on the condition tab under beverage they will fail to notice the changes that occur in every other property. This is a potential problem that I noticed with the ReDoc example. Having the tabs on top or to to the side of the whole payload might be a clearer experience. Here is the user journey that I was thinking would happen: Developer wants to see payload under specific condition --> Developer selects a condition tab --> Developer can view entire payload under that condition

Whereas the other journey might look like: Developer wants to see payload under specific condition --> Searches through properties for different conditions --> Selects a condition at the property level --> Scrolls back up to see changes reflected based on that condition selection (Potentially misses out on noticing what has changed)

mcturco avatar Aug 23 '22 13:08 mcturco

@mcturco Awesome designs as usual ❤️ However I have some doubts looking on examples. I know that it's on early stage and you experiment with some cases, but I see some problems that you sooner or later will catch and you will end up with redesign everything 😅 Trust me, the amount of curses I have uttered over JSON Schema and its flexibility is large enough that I consider myself an expert 🤣 Ok, so:

  • you put type of given field on the left. It's nice, however sooner or later you will notice that JSON Schema can be defined as union, so given field can be string or number. I think that it will be problem, how to render that union types? I think that tabs (for particular field) should be better - user will choose between string and number and we will render rules for particular type (e.g. for string, min length of string, for number min, max value etc). That left rendered type is good, but only for "simple" schemas, so please consider to render that type next to the name of field (as ReDoc does it). We can discuss it of course :)

    Union can be defined in two ways, by defining type as array or using oneOf, so below examples are same (in sense of validation) but described in two ways:

    {
      type: ['string', 'number']
    }
    
    {
      oneOf: [
        { type: string }
        { type: number }
      ]
    }
    
  • now you focus only on objects as root schema and message's payload (I guess) in 99% cases is described as object so it's fine, however people can also define given payload as normal string or number, or even array, so we should have some idea to render that standalone simple schema.

  • about conditions: I like that idea with tabs, but you need to understand that some conditions will be better to render in "root" tabs but some only in given place. If a given field of type number is greater than 10 then it must be a multiple of 5, but if smaller then it must be a multiple of 2. I know silly example but it shows that you can define this in JSON Schema, very complex example but it is possible. In that case it is better to render such conditions as tabs for the field level, not at global tabs.

Let me know if you understand everything I wrote about or if I should describe something more, These problems and edge cases with JSON Schema are a lot. I don't want to scare you but to show that it is a difficult task to make designs for it. Other places like servers etc will be much, much easier, trust me :)

magicmatatjahu avatar Aug 23 '22 15:08 magicmatatjahu

Wouldn't they also struggle to find what has changed if the tab is on top? I mean, if we have 8 properties and say 4 change. How do you spot them anyway?

Two more suggestions/questions:

  • What if the condition is on the age property instead?
  • What if we briefly highlight the properties that have changed? Can be done with a subtle drop shadow animation that runs for 2 or 3 seconds and fades away slowly.

Oh, BTW, the term you're looking for in the video is discriminator 😄

fmvilas avatar Aug 23 '22 15:08 fmvilas

SOOO thankful for everyone's feedback, I feel like we are really starting to get somewhere promising!

I recorded a video feedback if that is okay with you guys.

https://www.loom.com/share/540e392a2c9e4235ae1afd7c5048f458

@magicmatatjahu, I addressed your concerns in the video 😄

What if the condition is on the age property instead?

@fmvilas so we would add the conditions/rules under age and not on beverage at all?

What if we briefly highlight the properties that have changed? Can be done with a subtle drop shadow animation that runs for 2 or 3 seconds and fades away slowly.

Great idea, I have built upon that idea in the video 😄

Oh, BTW, the term you're looking for in the video is discriminator 😄

THANK YOU! I forgot what the word was hahaha

mcturco avatar Aug 24 '22 21:08 mcturco

Yeah, my suggestion is that if it's a condition in age it might make sense to have a dropdown in age that lets you choose that condition. Once it's selected, the rest of the fields can change with the visual feedback. My only concern about this approach is that some of the conditions may involve multiple properties so we probably gotta make it clear somehow.

Also, with the current approach of putting a dropdown, what if a property is only present when a specific condition is met? You can't select the condition because the property will not be present, right? Maybe the best way to do it after all is to put conditions at a global level 😄

fmvilas avatar Aug 25 '22 09:08 fmvilas

Yeah, my suggestion is that if it's a condition in age it might make sense to have a dropdown in age that lets you choose that condition. Once it's selected, the rest of the fields can change with the visual feedback. My only concern about this approach is that some of the conditions may involve multiple properties so we probably gotta make it clear somehow.

Yeah I had the same concern when you were showing me offline how the conditions work in ReDoc. It's cool, but I think it still has some problems that we would need to address.

Also, with the current approach of putting a dropdown, what if a property is only present when a specific condition is met? You can't select the condition because the property will not be present, right? Maybe the best way to do it after all is to put conditions at a global level 😄

Yeah that's what I was thinking before when I had the tabs at the global level. I was thinking that it might be easier to discover the "new payload" when that condition is met if we just switched the whole payload based on a tab. However, is there a possibility to have conditions within an object property within payload? It seems like you can, so maybe we have to keep these tabs available at each object level... but that could get confusing. Hmmmmm 🤔

mcturco avatar Aug 25 '22 13:08 mcturco

@fmvilas

Also, with the current approach of putting a dropdown, what if a property is only present when a specific condition is met? You can't select the condition because the property will not be present, right? Maybe the best way to do it after all is to put conditions at a global level 😄

In JSON Schema you can't influence the "shape" of JSON Schema from the child's point of view, the parent can it, so I don't think it's problematic.

For example, you can influence what is required because of some condition:

type: object
properties:
  a: ...
  b: ...
if:
  properties:
    a:
      const: 'something'
then:
  required: [b]

so it means that if a property is equal to something, then b property is required - you have condition on the root of some object, but you cannot influence on b from a point of view like there:

type: object
properties:
  a:
    if:
      const: 'something'
    then:
      # how to "see" b property from parent schema?
  b: ...

I think that approach of Redoc maybe isn't perfect but it renders correctly conditions, in the schema level where conditions are.

magicmatatjahu avatar Aug 26 '22 11:08 magicmatatjahu

@mcturco Sorry for making you crying at the beginning of video 😆 Sorry also for delay.


For first part of union type: I don't know how often people write union as type: [string, number], because as I know people usually use oneOf for unions (like in my examples), but JSON Schema also supports that array of type.

I very like that idea with string or number - as I know Stoplight render union in similar way, but I have one suggestion. Could we render union type with tabs? I mean something like that, if you have string or number (or even more types in the union) we can render one tab for string and one tab for number. For example (I will show my idea in markdown 😆 ), take schema:

type: [string, number]
minLength: 1 # related to the string type
format: email
maxValue: 5 # related to the number type

When string is active

age [string] [number]

{desription of age field}

Rules

The string must have a minimum of 1 character.
Format: email

When number is active:

age [string] [number]

{desription of age field}

Rules

Value can have a maximum value of 5.

For second part about standalone simple schema:

yeah, it's make sense to indicate in some way that you have object, string etc. Maybe we should have option to "hide" the property name and only render the type of schema? By this we can reuse the component for objects rendering and render only one property, but you know, with hack that we don't render property of object but simple schema. WDYT? if I am difficult to understand here then let me know.


Third part about conditions:

Yeah 😆 It was a stupid example, but I answered to Fran's comment about conditions and JSON Schema has big restriction here https://github.com/asyncapi/asyncapi-react/issues/618#issuecomment-1228396976 In general, it is not possible to change the condition of a "parent" schema in a sub schemas, as I wrote in the example, and so the conditions should be rendered where they are defined - these conditions can affect deeper schemas but no longer on higher ones (their parents). Let me know if this is clear, we can meet and I'll explain it to you with a dozen examples.

Or... as you show at the end of video with that conditional tab. I like it, really. It's fine, easy to understand (for me) and we only show what should change with certain condition, not everything.

Conditions are very difficult to render but we are getting better and better.


BTW. I wonder if we should write some library that would simplify given schema to simplifier form, for example removing if/then/else and create based on condition some union available of schemas. WDYT? Missy would have an easier work with designs and the implementation itself in the future of the Schema React component would be easier. However, I don't know if such logic is possible, but we can try. cc @fmvilas

Great work Missy! 🚀

magicmatatjahu avatar Aug 26 '22 12:08 magicmatatjahu

@magicmatatjahu Thank you for your thoughtful and detailed feedback!!! Left some comments below:

@mcturco Sorry for making you crying at the beginning of video 😆 Sorry also for delay.

🤣

I very like that idea with string or number - as I know Stoplight render union in similar way, but I have one suggestion. Could we render union type with tabs? I mean something like that, if you have string or number (or even more types in the union) we can render one tab for string and one tab for number.

So I originally thought about designing it like this with tabs, but then I was thinking: let's say the property has type: [number, integer] and every other rule is the same (like there is no differing validation between number and integer.) Would it then be weird to have tabs for this case? Maybe we can render tabs if the validation is different depending on type but if the validation is the same for each type then we just render the types like number or integer. What do you think?


For second part about standalone simple schema:

yeah, it's make sense to indicate in some way that you have object, string etc. Maybe we should have option to "hide" the property name and only render the type of schema? By this we can reuse the component for objects rendering and render only one property, but you know, with hack that we don't render property of object but simple schema. WDYT? if I am difficult to understand here then let me know.

Not sure that I fully understand what you mean here 😅 I know what you mean by showing simple schemas, but wouldn't the property name still have to exist? Unless the payload ends up being something like:

messages:
  OrderReceived:
    payload:
      type: string
      description: Message sent when the order has been received

Then in that case, yeah, maybe we just simply hide the property name. I can definitely think about this more too and see what other ways we can render this!


Third part about conditions:

In general, it is not possible to change the condition of a "parent" schema in a sub schemas, as I wrote in the example, and so the conditions should be rendered where they are defined - these conditions can affect deeper schemas but no longer on higher ones (their parents)

Yep, I understand what you are saying here. I think the more challenging problem is the fact that a condition on one property can affect a sibling property, and that could be above or below the property with the condition depending on how someone writes their schema. Which you would hope that someone would be aware that they should probably keep properties with conditions closer to the top, but that might not always be the case. That's why I was thinking having a tab at the global level might make sense, but we can play with some more options. Maybe it would be good just to start with something initially and then see how it works in the application, then iterate on different solutions.


BTW. I wonder if we should write some library that would simplify given schema to simplifier form, for example removing if/then/else and create based on condition some union available of schemas. WDYT? Missy would have an easier work with designs and the implementation itself in the future of the Schema React component would be easier. However, I don't know if such logic is possible, but we can try. cc @fmvilas

I don't think I understand what you mean here. Do you mean separating the conditions from the normal schema shape?


Great work Missy! 🚀

Thank you so much 😄 Having fun with this problem!

mcturco avatar Aug 29 '22 16:08 mcturco

Just filmed an update video! Would love your thoughts/feedback! We are getting super close to solving this problem 🙏

https://www.loom.com/share/5713a828b5ad478794ce5647f53e34ce

cc: @fmvilas @magicmatatjahu @derberg

mcturco avatar Sep 07 '22 17:09 mcturco

First of all, I love how the discussion is going 👏 I feel that we're really thinking about the problem right now, and that's awesome.

So, following your examples with age and beverage, I also like the version that has the "Conditional logic" tab on beverage instead of age. However, a potential limitation came to my mind: say, for instance, beverage doesn't exist by default and it can only be specified when age is >= 21. How do you overcome this limitation? The beverage property will not be there so the Conditional Logic tab would not be rendered either 🤔 Should we maybe aim for a Conditional Logic tab at payload level instead?

fmvilas avatar Sep 08 '22 15:09 fmvilas

First of all, I love how the discussion is going 👏 I feel that we're really thinking about the problem right now, and that's awesome.

I agree!! And I am so appreciative that we are having this conversation as it keeps me from being blocked in my design process!

So, following your examples with age and beverage, I also like the version that has the "Conditional logic" tab on beverage instead of age.

Cool, so we are all in agreement that this is a good solution for conditions on properties that affect themselves? (not even sure if that statement makes sense haha)

However, a potential limitation came to my mind: say, for instance, beverage doesn't exist by default and it can only be specified when age is >= 21. How do you overcome this limitation? The beverage property will not be there so the Conditional Logic tab would not be rendered either 🤔 Should we maybe aim for a Conditional Logic tab at payload level instead?

Good point. Here's what I am thinking: On a left-hand sticky sidebar, we list all the rules and allow the user to click on each rule and view how it affects the entire payload. Changes might be highlighted briefly in the UI for visibility.

Demo: https://www.loom.com/share/a8a320510987480ca7c06cb413474b8c

mcturco avatar Sep 09 '22 14:09 mcturco

I love the concept but I'm afraid we may not have enough horizontal space to have sticky conditions, payload, and examples. And also, potentially, sidebar navigation (when downloaded). What if we render a sticky button near the payload and when you click on it, it displays the conditions panel? Like a sticky menu maybe? Or maybe the whole payload can be contained inside a panel with a toolbar on top. This toolbar would have Conditions button and also a button to display the raw JSON Schema that's being rendered. What do you think?

fmvilas avatar Sep 11 '22 12:09 fmvilas

I love the concept but I'm afraid we may not have enough horizontal space to have sticky conditions, payload, and examples. And also, potentially, sidebar navigation (when downloaded).

Good point!

What if we render a sticky button near the payload and when you click on it, it displays the conditions panel? Like a sticky menu maybe? Or maybe the whole payload can be contained inside a panel with a toolbar on top. This toolbar would have Conditions button and also a button to display the raw JSON Schema that's being rendered. What do you think?

LOVE this idea. Going to explore this in the wireframes this week and then I will touch back!

mcturco avatar Sep 12 '22 15:09 mcturco

Okay so I started crafting a layout for the sticky tabs idea that @fmvilas mentioned above, and I think it is starting to come together! The only thing I am unsure of just yet is how to present the conditions at the payload level. Will think through some possible solutions for this, but if you guys have any input here that would be great!

Here is a quick demo: https://www.loom.com/share/2931451036e0434ea8e54a4724a4d5f5

And here is the figma prototype link if you want to check it out there: https://www.figma.com/proto/wJHfdNxBeXg4O3jxcqcL9X/JSON-Schema-Wireframes?node-id=105%3A1529&scaling=scale-down&page-id=2%3A29&starting-point-node-id=105%3A1529&show-proto-sidebar=1

mcturco avatar Sep 12 '22 23:09 mcturco

This issue has been automatically marked as stale because it has not had recent activity :sleeping:

It will be closed in 120 days if no further activity occurs. To unstale this issue, add a comment with a detailed explanation.

There can be many reasons why some specific issue has no activity. The most probable cause is lack of time, not lack of interest. AsyncAPI Initiative is a Linux Foundation project not owned by a single for-profit company. It is a community-driven initiative ruled under open governance model.

Let us figure out together how to push this issue forward. Connect with us through one of many communication channels we established here.

Thank you for your patience :heart:

github-actions[bot] avatar Jan 12 '23 00:01 github-actions[bot]

Keep it open, dear bot.

fmvilas avatar Jan 13 '23 05:01 fmvilas

This issue has been automatically marked as stale because it has not had recent activity :sleeping:

It will be closed in 120 days if no further activity occurs. To unstale this issue, add a comment with a detailed explanation.

There can be many reasons why some specific issue has no activity. The most probable cause is lack of time, not lack of interest. AsyncAPI Initiative is a Linux Foundation project not owned by a single for-profit company. It is a community-driven initiative ruled under open governance model.

Let us figure out together how to push this issue forward. Connect with us through one of many communication channels we established here.

Thank you for your patience :heart:

github-actions[bot] avatar May 14 '23 00:05 github-actions[bot]

Querido GitHub Actions, I hope this message finds you well. Please, kindly wait a bit more for this issue to be solved. Yours faithfully, Fran.

fmvilas avatar May 30 '23 07:05 fmvilas

Hey @mcturco

I'm interested to work on this issue!

ConnectBhawna avatar Jun 01 '23 09:06 ConnectBhawna