Closed garrett closed 1 year ago
cc @mcarrano @mmenestr
@garrett I can see the desire for this but is this a continuous process from start to end or does each step represent a stop along the way. i.e. to progress stop when I get to the end of a step and the user needs to intervene?
You can use the current PF design with PF icons and combine the sub-steps for additional indications such as we use in OCM:
Firstly, reminder: This mockup was made as a response to a user study. PatternFly currently does not solve the issue in the study, so the installer team will either have to do something custom or rely on PatternFly to address the need of having a widget that communicates a long running, multi-step progress.
@garrett I can see the desire for this but is this a continuous process from start to end or does each step represent a stop along the way. i.e. to progress stop when I get to the end of a step and the user needs to intervene?
It's for Anaconda. It installs Linux to a computer.
Just like any other operating system installer (just like when installing Windows, macOS), it can take a very long time (such as half an hour; sometimes more, sometimes less) to install, depending on several different factors (especially disk speed; but sometimes network speed too, when it's downloading packages from a remote site).
Each step is along the way where the installer is doing something different. There's (usually) no user intervention in this long-running process, but each step can take different amounts of time to complete. (Some might take a minute or less, whereas others might be the bulk of the time, such as 10 - 30 minutes or even longer.) There is always user intervention at the end of the process, when the installation has either succeeded or failed (in which it still would show which step it has failed). There might need to be user intervention in a mid-step too (example: such as if the network went down while it was downloading packages during a network install; one could try again or the process could fail, depending). The final screen shows the status (success/fail), along with the step in the stepper, and that the user needs to reboot the system.
Knowing each step is important, as someone who has installed Linux before will know that some steps are longer (installing especially). The steps of the installer are, basically:
These are done in order and one step has to wait on the next.
If someone walks away form an installation to get coffee and they return and it's still installing software packages, they'll know it'll take a while longer. If it's finalizing installation, it might just be a minute or two before they have to tell the computer to reboot. If it fails in a step, it's important to know which step failed, as the resolution might be different (try again vs. replacing faulty hardware).
Right now, using the PF stepper component, it can sit there with absolutely no user feedback of progress, so the system looks like it has hung. (An indeterminate spinner doesn't help, either; one was used in the current PF-based Anaconda during the user study.)
Basically: Someone installing an OS on a computer needs feedback that it's still happening and that there is forward progression. The PF progress bar does not have steps (or even tickmarks) and the stepper does not show progress, and every single person in the user study commented on this problem... so this is why I'm suggesting this hybrid to solve the issue.
The normal component could even have the progression indicated in the line and circle part, to reinforce progress, even if it doesn't have partial lines between the items. (Especially because it's a little confusing where you are in the screenshots that @shirimordechay posted. But I guess the context of actually doing the process might help there?)
You can use the current PF design with PF icons and combine the sub-steps for additional indications such as we use in OCM:
That's not the same thing at all. There's no progress between long-running steps in these screenshots, which is what this issue is about. I know the icons can be changed; the icons are basically placeholders in my mockup above... I didn't want to distract from the actual issue and solution, so I just used the default incomplete, current, & complete icons.
@garrett thanks for posting this detailed explanation. Having done many OS installs myself over the years, I get what the problem is, and think your proposed solution is a reasonable one. Before putting this on our feature roadmap, I think this would be a good topic to present in an upcoming design share meeting just to see if others have also encountered this and if there are other potential solutions we are not considering here. Those meetings are every third Wednesday at 11am EDT. Is it possible for you to be available to present this at that time? If not, I can present this on your behalf for feedback on your proposal. Let me know.
I am also going to move this issue over to Design for further consideration.
I've implemented the mockup in basically 5 lines of CSS (mainly to set colors and a width for percentage), where the percentage is exposed as a number (representing a percentage), which React can modify.
Demo: https://codesandbox.io/s/unruffled-benji-cx657r?file=/progress-demo.scss
Screenshot:
Most of the content below are pulled directly from PatternFly's basic demo for the stepper, in JSX. We'd probably want to set the progress colors to the same color, like a progress color variable (unless we want past, active, and future to be the same). In the mockup, I merged the colors of past and current and leave future the default color. In the demo, I used green and red for past and current, respectively. I do not suggest using green and red in the actual implementation; they're for demonstration purposes only.
When progress isn't set, the width between steps is 0%, so it works by default to indicate past and current step, but not current progress.
Additionally, the ::after
could have a CSS transition set for width so for smooth animation can be handled by CSS (therefore GPU accelerated), so when something jumps from 25% to 63% (or whatever), it won't just jump, but smoothly move.
Current progress is relative to the step, not the overall progress.
SCSS:
// Example CSS
.pf-m-success {
// Demo colors
--pf-c-progress-stepper__step-icon--BorderColor: green;
--pf-c-progress-stepper__step-connector--before--BorderBottomColor: green;
}
.pf-m-current {
// Another demo color (could be the same as the success colors)
--pf-c-progress-stepper__step-icon--BorderColor: red;
}
.pf-c-progress-stepper__step:not(:last-of-type) > .pf-c-progress-stepper__step-connector::after {
// Unique to ::after
--pf-c-progress-stepper__step-connector--before--BorderBottomColor: red;
width: calc(var(--pf-c-progress-stepper__step-percent) * 1%);
// /////////////////////////////////////////////////////////////
// Shared in common with ::before (from PF)
position: absolute;
top: var(--pf-c-progress-stepper__step-connector--before--Top);
left: var(--pf-c-progress-stepper__step-connector--before--Left);
height: var(--pf-c-progress-stepper__step-connector--before--Height);
content: "";
border-right: var(--pf-c-progress-stepper__step-connector--before--BorderRightWidth) solid var(--pf-c-progress-stepper__step-connector--before--BorderRightColor);
border-bottom: var(--pf-c-progress-stepper__step-connector--before--BorderBottomWidth) solid var(--pf-c-progress-stepper__step-connector--before--BorderBottomColor);
transform: var(--pf-c-progress-stepper__step-connector--before--Transform);
}
JSX:
import ReactDOM from "react-dom";
import "@patternfly/react-core/dist/styles/base.css";
import "./fonts.css";
import "./progress-demo.scss";
import React from "react";
import { ProgressStepper, ProgressStep } from "@patternfly/react-core";
const Basic = () => (
<ProgressStepper>
<ProgressStep
variant="success"
id="basic-step1"
titleId="basic-step1-title"
aria-label="completed step, step with success"
>
First step
</ProgressStep>
<ProgressStep
variant="info"
isCurrent
id="basic-step2"
titleId="basic-step2-title"
aria-label="step with info"
// Implemented here as a style, so I didn't have to change any PF JS;
// ideally, it would be exposed as a property
style={{ "--pf-c-progress-stepper__step-percent": 50 }}
>
Second step
</ProgressStep>
<ProgressStep
variant="pending"
id="basic-step3"
titleId="basic-step3-title"
aria-label="pending step"
>
Third step
</ProgressStep>
</ProgressStepper>
);
const rootElement = document.getElementById("root");
ReactDOM.render(<Basic />, rootElement);
I've made a modified second demo which has closer-to-ready SCSS (tying it to the widget), adding it as a pf-m- variant, uses success and current colors, and adds a transition:
https://codesandbox.io/s/staging-dream-6wrzt8?file=/progress-demo.scss
It adds a className to the topmost widget and changes the SCSS to:
.pf-c-progress-stepper.pf-m-show-progress {
--pf-c-progress--SuccessColor: green;
--pf-c-progress--CurrentColor: red;
.pf-c-progress-stepper__step {
&.pf-m-success {
// Demo colors
--pf-c-progress-stepper__step-icon--BorderColor: var(--pf-c-progress--SuccessColor);
--pf-c-progress-stepper__step-connector--before--BorderRightColor: var(--pf-c-progress--SuccessColor);
--pf-c-progress-stepper__step-connector--before--BorderBottomColor: var(--pf-c-progress--SuccessColor);
}
&.pf-m-current {
// Another demo color (could be the same as the success colors)
--pf-c-progress-stepper__step-icon--BorderColor: var(--pf-c-progress--CurrentColor);
}
}
.pf-c-progress-stepper__step:not(:last-of-type) > .pf-c-progress-stepper__step-connector::after {
// Unique to ::after
--pf-c-progress-stepper__step-connector--before--BorderBottomColor: var(--pf-c-progress--CurrentColor);
--pf-c-progress-stepper__step-connector--before--BorderRightColor: var(--pf-c-progress--CurrentColor);
width: calc(var(--pf-c-progress-stepper__step-percent, 0) * 1%);
transition: width 500ms ease-out;
// /////////////////////////////////////////////////////////////
// Shared in common with ::before (from PF); PF CSS should be modified to share this with ::before
position: absolute;
top: var(--pf-c-progress-stepper__step-connector--before--Top);
left: var(--pf-c-progress-stepper__step-connector--before--Left);
height: var(--pf-c-progress-stepper__step-connector--before--Height);
content: "";
border-right: var(--pf-c-progress-stepper__step-connector--before--BorderRightWidth) solid var(--pf-c-progress-stepper__step-connector--before--BorderRightColor);
border-bottom: var(--pf-c-progress-stepper__step-connector--before--BorderBottomWidth) solid var(--pf-c-progress-stepper__step-connector--before--BorderBottomColor);
transform: var(--pf-c-progress-stepper__step-connector--before--Transform);
}
}
@garrett , thanks for your brainstorming around this! In your proposed design above (afaik) the bar is calculating progress between steps 1-2, 2-3, rather than overall progress. If so it requires the availability of realtime, detailed intra-step progress (%, or other calculations) between all of the steps. That might impose a functional limitation.
To make the design solution more feasible if that data were not available, wdyt of using an indeterminate progress bar between steps instead? I don’t believe that PF has one of these bar types, so I have to make one up for the mockup that I posted. If this worked we would obviously need help from a visual designer. ;) Note: I believe that that if a particular milestone step (dot) is in progress, then it’s the preceding segment of bar that would be highlighted.
The solution that @shirimordechay is workable for sure. But I wanted to add this to the brainstorming effort, for ongoing design explorations.
cc @mkolman@redhat.com ^^
In your proposed design above (afaik) the bar is calculating progress between steps 1-2, 2-3, rather than overall progress.
No, I am actually talking about the current progress for the step, which is usually known during the install process (especially for the longer steps).
During the package installation step (the longest step in the overall installation), an example would be that the installer would know that it's on package 320 out of 2200 or something like that, so it could easily compute the progress of that specific step (in this example, 14.5%) during the package installation.
Some earlier or later steps, such as formatting partitions or setting up the bootloader, might be indeterminate, but finish within several seconds at the latest, whereas the longer steps might be up to several dozens of minutes (like somewhere between 5 to 45 minutes, depending on the speed of the installation media, the storage location, and network speed).
Having an indeterminate bar could be an enhancement after showing the general progress, although it might be misleading to label it blue in this case if it's not done (whereas, like a progress bar, the progress stepper indicating actual progress is using blue in the mockup above — and has green/red in the demo instead just for debugging purposes). But it's a good idea to add later, certainly! Thanks for suggesting it.
Please also note that I changed the outline of the circle around the icons too, to reinforce the progress.
@garrett - By "between" I meant Step x has been completed, now Step next is in progress. We might be talking about the same thing?
By "between" I meant Step x has been completed, now Step next is in progress. We might be talking about the same thing?
Yeah, in the demo I made, the current progress is in red. (I did use the green and red for demo purposes to show that they're not the same, but could be.) If we do know the progress and want to show that it's continuing, we could use animation like you're suggesting in the places where that's red.
I've revised the demo to make it use the same color for previous and current. I've also added an alternating line with a secondary color (which was initially transparent, but I made it use a similar color instead) and I've animated it. It's also using a pf-m-animated to opt-in to the animation (so the default non-animated version of the progress mockup would still work too).
https://codesandbox.io/s/modern-cdn-ebhubp?file=/progress-demo.scss
Screenshot:
(Visit the link above for the animation.)
Thanks @garrett , personal opinion, I really like the addition of the blue outline and coloring the completed segment. If coloring the step circle and segment line is already possible with the current component, maybe that's something to consider? Wdyt @mcarrano? I guess it would need a visual design/accessibility assessment. I'm not sure if the completed step-segments would be blue or green... Here's a quick mockup to illustrate a potential combo, minus the partially completed segment.
If coloring the step circle and segment line is already possible with the current component, maybe that's something that might be feasible to consider in the short term?
It is! The demo I posted is some additional CSS that you can adapt to override the component a little if you'd like it without having to wait for an official implementation. (That's what the demo is doing, of course.)
Of course, an official implementation would be better. :wink:
I really like the addition of the blue outline and coloring the completed segment. My hesitation is the partial segments, at least for the installer use case that I'm working with.
Thanks!
The current segment also defaults to 0%, which means that a line isn't shown. The HTML+CSS is exactly the same. I left the green/red in the earlier demo (the most recent one that's not animated) to show that the finished and current colors can be separate too. (The animation has this in the CSS as well, but they're both set to a standard PF blue.)
By the way:
We do this kind of thing often enough with Cockpit, where we either find issues with PatternFly components or need to adjust them a little for ourselves. (Whenever possible, when we find actual bugs, we report them upstream and have a comment on our overrides. And then, when it's fixed in PatternFly and when we upgrade to the fixed version of PF, we drop our override. We do this for enhancements too, so we can use a custom version while we wait on a variant to be made.)
Our current list of overrides is @ https://github.com/cockpit-project/cockpit/blob/main/pkg/lib/patternfly/patternfly-4-overrides.scss (if you'd like to see it as an example). We even used to override PF3 to look like PF4 during our transition from PF3 to PF4 (hence this file specifically mentioning 4).
@garrett @lclay2 I like the addition of the blue outline and coloring of the completed segment, also, and would be in favor of making that enhancement. I'm not completely sold on the progress indicator, however. From the mockups you are showing, it's a bit unclear to me whether we have completed step 2 and are progressing to set three or if step 2 is still in progress. We don't currently have an indeterminate progress bar, and while we could add one, I wonder if it would make more sense to use the animated spinner to just indicate the step in progress.
From the mockups you are showing, it's a bit unclear to me whether we have completed step 2 and are progressing to set three or if step 2 is still in progress.
Step 2 is the current step, in progress. It's probably more obvious when using it interactively, as it would get to step 2; that would change, and then the progress would start crawling to the next step. Having different colors (the green/red above, but not green/red, but perhaps different shades of blue) could make this more obvious too, but I think the changing of the circle and the text is probably enough when this would be in action.
Similarly, Title 2 is in the current step here. However, you don't know how far along you might be between Title 2 and Finalizing.
We don't currently have an indeterminate progress bar, and while we could add one, I wonder if it would make more sense to use the animated spinner to just indicate the step in progress.
Yeah, I didn't include an animated bar (it's determinate still, not indeterminate) earlier as I assumed there was already a spinner within Anaconda at the moment. It's redundant to have both. However, with a moving and animated progress bar, it could make sense to show that the computer hasn't frozen (which is really the point of all indeterminate progress indicators, including spinners) in the same place that indicates progress.
I know Mac OS X and macOS have famously had animated progress bars for this reason.
Indeterminate bar:
Animated bar:
Animated, in context:
Windows has done this too over the years, for the same reason (to show that something's still happening even if the bar isn't currently moving forward at a detectable pace):
But Windows 10 and up sometimes gets a bit complex :wink::
Anyway, adding the ability to have an animated progress bar (instead of a spinner + progress bar) makes it super-simple to re-use the same animation (perhaps with color customization) for the indeterminate progress bar too. (It's just set to 100%, usually with different colors.)
Moving this here for further discussion: https://github.com/orgs/patternfly/discussions/categories/feature-requests
Is this a new component or an extension of an existing one? Progress Stepper component
Describe the feature Display in-between progress for steps that take a while.
For the new Anaconda (OS installation for Fedora, RHEL, CentOS, Alma, Rocky, etc.) implementation using PatternFly, during a usability test, there wasn't enough granular feedback for the process. The stepper component was used, but each step could take some time between several seconds to several minutes.
Are there visuals for this feature? If applicable, please include examples for each state and for varying widths
Here's a quick idea that would blend the progress bar experience into the progress stepper, so the stepper works as it does currently, but in-between progress shows up as a progress-bar-like line.
Source SVG: Progress stepper.svg
An additional idea is that we could even have a spinner on the current step. But that's probably overkill. :wink: