[FEATURE] UI: introduce new `Progress\Bar` component.
Hi @Amstutz and @klees,
I have picked up @chfsx's work from #7597 and want to introduce a new Progress\Bar component with this PR.
Before you review the interface, I would like to share some of my thoughts on this. Note, I will refer to the ILIAS\UI\Component\ namespace with the abbreviation C\.
- I have introduced a new
C\Progress\namespace. When trying to "fit in" the progress bar interface definition into an existing hierarchy level, I noticed that it does not quite fit in anywhere. The closest match would have beenC\Chart, for one because the progress bar could be thought of as a bar chart, but mostly because theC\ProgressMeter\namespace is also settled there. However, I was looking for other components that are used to represent a users progress or advancement in something, and found that theC\Chart\ProgressMeter\andC\Listing\Workflow\namespace could actually be relocated to a dedicatedC\Progress\namespace as well. I therefore went ahead and introduced it. I did not yet migrate the other components, because this would have been out of scope - I can create a roadmap entry for this, if you agree with me. - This PR has multiple similarities with another open PR for introducing a
C\Promptnamespace and component (#7045):- The referenced PR introduced a roadmap entry, which describes the future use and declaration of internal UI components. I think the progress bar also fits into this category of components, because it does not have strong semantic when looked at as a standalone component.
- The progress bar also needs to be (able to be) updated using an endpoint. @klees and I have already talked about the concept of "HTML over the wire", and the referenced PR introduces this concept for the new
C\Prompt\Promptcomponent. For the progress bar, I did the same, by introducingC\Progress\Instruction\Instruction's, which must be used by consumers to order the clientside progress bar to perform a desired update.
- The progress bar - as mentioned before - will most likely be an internal component someday. With this in mind, the usability of this component is not the most consumer-friendly one; consumers need at least some knowledge about the workflow and internals of the progress bar component. This is primarily because we need to couple the progress bar to some kind of trigger, which "kicks off" the progress bar. This is not unlike other components we have, but in this case the consumer needs some knowledge about the JavaScript facilities they need to use. This becomes visible when looking at the two examples I have provided.
- The progress bar is also a rather "dumb" component. It does not have much knowledge about its context and simply updates to whatever update is given to it (push). When provided with an asynchronous endpoint, the progress bar should also fetch updates from there automatically (pull), but I am not entirely sure if this should actually be the responsibility of the progress bar. Consumer could very easily write their own wrapper which pulls data from an endpoint and feeds it to the progress bar. However, this would be problematic for two reasons: consistency, and the ability to shift the request handling closer to the UI framework. Thats why the proposal also contains a concept to achieve this (instructions).
I am looking forward to your review! If you have any ad-hoc questions, feel free to contact me on Discord.
Kind regards, @thibsy
Hi Thibeau,
thanks a lot for this PR. Nicely worked out. However, there are some questions and suggestions, as usual!
Please change:
- [x] Minor Corrections: Please change typos and spelling according to @klees' review
Please change or indicate why not:
- [x] A11y: Add some A11y rules for the Progress Bar, enforcing it the be usable and understandable without any graphical UI.
- [ ] Progress: In the naming there is a high overlap. with Progress Meter (as also noted in details). Could the Progress Bar also be a Chart? Not sure, if we like the Progress as a family on top level, although there definitly is some semantic overlap with the workflow listing. Can people understand what to find in "Progress"? Also, the bar mostly is a visualisation (a simple text "7%" or something would do the same...), hence
Chart seems to be a good match.BarandProgresscould then become siblings in aProgress` family? - [x] Float: Try not to use them (in general =)), they are full of surprises and ill behaviour. Try to use rationals ifpossible, either with fixed or variable denominator. For this usecase here: Wo we really want to know sub-percent process? If not: a simple
intbetween 0 and 100 would do just fine. If we want sub-percent process, maybe 0...1000 gives enough room? If we want to have other scales (see last question below), we could allow users to pick the denominator. - [x] Text-Smithing: The
in a single step, would benefit from ain a single step **without further user interaction**, if that is really meant here. Something similar goes for the description of theWorkflowrival.
Please answer the following question:
- [ ] Instruction: Is it a UI Component? From the description, this all looks much more like technical detail to keep internal.
- [ ] Percent scale: How sure are you that we really only want to have a progress bar showing percents? There are use cases like "copy object" where "x of y subobjects" seems to be a semantic (instead of "X% of copy process") where users would understand the actual scale of the whole process better. Could we easily incorporate this now? How would we incorporate it later?
thx a lot @amstutz and @klees
Hi @Amstutz and @klees,
Thx for your feedback! Let me answer your questions right away:
-
Progress(family): I was doing some research, and I found out "the meter element should not be used to indicate progress (as in a progress bar)" (https://html.spec.whatwg.org/#the-meter-element). Therefore I suggest to rename theProgressMetertoMeter, so we can get rid of this overlap. With this in mind it also makes more sense thatMeteris aChart. The progress bar does IMO not fit into this category for one reason: It knows an indeterminate state, which does not represent any raw data on purpose, and is simply used to indicate progress. Since this component has actually some overlap with theListing\Workflowcomponent, it made sense to me to introduce their own family (Workflowstill needs to be moved). I think consumers can expect these kind of components to be simple indicators of progress within a process or task, be that a percentage, timeline, steps or simple text. This task could e.g. also be loading, where we could introduce components to improve user waiting experience (which actually becomes important with more asynchronous rendering). I also believe that this entire component family should be strictly internal someday. - Percent scale: You are right. There will probably be the need for more flexibility in regards of scales. However, the
Progress\Baris represented as a percentage by design, so I think the different scales would only ever affect the wording around it. This could also lead to very basic representations like1 out of 9in certain contexts, but maybe these should not be consideredProgress\Bars anymore. IMO, the allowance of different scales would only be sugar for our consumers at this point, because the component ultimately breaks it down to a percentage. Nonetheless, maybe in the next round this component or component family can benefit from someILIAS\Datatype, which can be used to configure your own scale. But maybe these should also be other components altogether. - Instruction(s): You are right again :). These "components" are definitely meant to be kept internal and should not be exposed on the factory like they are right now. However, we are limited by the technology of our time, so we need to expose these components for the time being. Otherwise consumers will not be able to use them properly inside their endpoints. Our goal is to ultimately shift the request handling closer to the UI framework, which is made possible by the new component revision. This will allow us to only ever expose this factory to some kind of
InstructionRetrieval, which will be managed by the UI framework during asynchronous requests. @klees and I have already discussed the concept of "HTML over the wire" for some time now, and this (and the proposed prompts) are the first implementation(s) of it. "HTML over the wire" refers to the asynchronous rendering of components, where a client-side component requests HTML from an endpoint, which will be used to update the current HTML in some way. The idea is that instructions are shaped into sections, each of which conveys specific HTML for specific parts of the existing HTML structure. While talking about this in a short meeting with @klees today, we have realised that we were focusing too much on "ordering the client to do something", while we should have rather focused on the thing at hand. This is why we have decided to rename this (again) toState. Now it should be more visible as to why this thing is a component.
The rest of your review is incorporated. I especially agree with your remarks about the floating point numbers. I also renamed to argument to a more appropriate $visual_progress_value, and phrased the factory description accordingly.
Let me know if this is ready for JF then.
Kind regards, @thibsy
Jour Fixe, 14 OCT 2024: We highly appreciate this suggestion and accept the PR for ILIAS 10.