ProgressBar is a process status indicator that can either work on client side or integrate with server side via ajax.
<script>
    //<![CDATA[
    function start() {
        PF('startButton1').disable();
        window['progress'] = setInterval(function () {
            var pbClient = PF('pbClient'),
                oldValue = pbClient.getValue(),
                newValue = oldValue + 10;
            pbClient.setValue(pbClient.getValue() + 10);
            if (newValue === 100) {
                clearInterval(window['progress']);
            }
        }, 1000);
    }
    function cancel() {
        clearInterval(window['progress']);
        PF('pbClient').setValue(0);
        PF('startButton1').enable();
    }
    //]]>
</script>
<div class="card">
    <h:form>
        <p:growl id="growl"/>
        <h5 class="mt-0">Client ProgressBar</h5>
        <p:commandButton value="Start" id="start" type="button" onclick="start()" widgetVar="startButton1" styleClass="mr-2" />
        <p:commandButton value="Cancel" id="cancel" type="button" onclick="cancel()" styleClass="ui-button-outlined" />
        <p:progressBar id="progressBarClient" widgetVar="pbClient" style="width:300px" styleClass="mt-3"/>
        <h5>Ajax ProgressBar</h5>
        <p:commandButton value="Start" type="button"
                         onclick="PF('pbAjax').start();PF('startButton2').disable()" widgetVar="startButton2" styleClass="mr-2"/>
        <p:commandButton value="Cancel" action="#{progressBarView.cancel}"
                         oncomplete="PF('pbAjax').cancel();PF('startButton2').enable()" styleClass="ui-button-outlined"/>
        <p:progressBar widgetVar="pbAjax" ajax="true" value="#{progressBarView.progress1}"
                       labelTemplate="{value}%" styleClass="mt-3" global="false">
            <p:ajax event="complete" listener="#{progressBarView.onComplete}" update="growl"
                    oncomplete="PF('startButton2').enable()" />
            <p:ajax event="start" listener="#{progressBarView.onStart}" update="growl" />
            <p:ajax event="progress" listener="#{progressBarView.onProgress}" update="growl" />
        </p:progressBar>
        <h5>Ajax ProgressBar (with long running method)</h5>
        <p:commandButton value="Start"
                         onclick="PF('pbAjaxLong').start();PF('startButton3').disable()"
                         widgetVar="startButton3" actionListener="#{progressBarView.longRunning}" styleClass="mr-2"/>
        <p:commandButton value="Cancel" action="#{progressBarView.cancel}" onclick="PF('pbAjaxLong').cancel();"
                         oncomplete="PF('startButton3').enable()" styleClass="ui-button-outlined"/>
        <p:progressBar widgetVar="pbAjaxLong" ajax="true" value="#{progressBarView.progress2}"
                       labelTemplate="{value}%" styleClass="mt-3" global="false" interval="500">
            <p:ajax event="complete" listener="#{progressBarView.onComplete}" update="growl"
                    oncomplete="PF('startButton3').enable()" />
        </p:progressBar>
        <h5>Static Display</h5>
        <p:progressBar value="50" labelTemplate="{value}%" displayOnly="true"/>
        <h5>Indeterminate</h5>
        <p:progressBar id="progressBarIndeterminate" style="height:6px" mode="indeterminate"/>
        <h5>Severities</h5>
        <p:progressBar id="progressBarDanger" value="25" severity="danger" displayOnly="true"/>
        <p:progressBar id="progressBarWarning" value="50" severity="warning" displayOnly="true" styleClass="mt-3"/>
        <p:progressBar id="progressBarInfo" value="75" severity="info" displayOnly="true" styleClass="mt-3"/>
        <p:progressBar id="progressBarSuccess" value="100" severity="success" displayOnly="true" styleClass="mt-3"/>
    </h:form>
</div>
package org.primefaces.showcase.view.misc;
import java.io.Serializable;
import jakarta.faces.application.FacesMessage;
import jakarta.faces.context.FacesContext;
import jakarta.faces.view.ViewScoped;
import jakarta.inject.Named;
@Named
@ViewScoped
public class ProgressBarView implements Serializable {
    private Integer progress1;
    private Integer progress2;
    public void longRunning() throws InterruptedException {
        setProgress2(0);
        Integer k = getProgress2();
        while (k == null || k < 100) {
            k = updateProgress(k);
            setProgress2(k);
            Thread.sleep(500);
        }
    }
    private static Integer updateProgress(Integer progress) {
        if (progress == null) {
            progress = 0;
        }
        else {
            progress = progress + (int) (Math.random() * 35);
            if (progress > 100) {
                progress = 100;
            }
        }
        return progress;
    }
    public void onComplete() {
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Progress Completed"));
    }
    public void onStart() {
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Progress Started"));
    }
    public void onProgress() {
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Progress Updated " + progress1));
    }
    public void cancel() {
        progress1 = null;
        progress2 = null;
    }
    public Integer getProgress1() {
        progress1 = updateProgress(progress1);
        return progress1;
    }
    public Integer getProgress2() {
        return progress2;
    }
    public void setProgress1(Integer progress1) {
        this.progress1 = progress1;
    }
    public void setProgress2(Integer progress2) {
        this.progress2 = progress2;
    }
}