Search code examples
c#.netblazordevexpressxaf

How can I implement status bar for state transition in xaf blazor .net 6 application


enter image description here

I need a status bar like this. I have no idea how to do this. Is any reference available?


Solution

  • To give you a base to Work on you could use a Component like this:

    <div class="status-bar">
        <div class="bar filled" style="width: @GetFilledPercentage()%"></div>
        <div class="bar empty" style="width: @GetEmptyPercentage()%"></div>
        <div class="status-bar-checkpoints">
            @foreach (var checkpoint in Checkpoints) {
                <div class="checkpoint">
                    <div class="checkpoint-cirlce @GetCirlceClass(checkpoint)">
                    </div>
                    <p class="checkpoint-text">
                        @checkpoint.Name
                    </p>
                </div>
            }
        </div>
    </div>
    
    @code {
        [Parameter]
        public ICollection<Checkpoint> Checkpoints { get; set; } = new List<Checkpoint>();
    
        private string GetCirlceClass(Checkpoint checkpoint) {
            return checkpoint.Status switch {
                CheckpointStatus.Checked => "checked",
                CheckpointStatus.Current => "current",
                CheckpointStatus.Unchecked => "unchecked",
                _ => ""
            };
        }
    
        private int GetFilledPercentage() {
            return Checkpoints.Count(x => x.Status == CheckpointStatus.Checked ) * 100 / (Checkpoints.Count - 1);
        }
        private int GetEmptyPercentage() {
            return 100 - GetFilledPercentage();
        }
    }
    
    

    This creates the base for all html elements that you need including the text. To style it in a way that it shows a status bar. The css I created looks like that:

    .status-bar{
        position: relative;
    }
    
    .status-bar-checkpoints {
        display: flex;
        justify-content: space-between;
    }
    
    .checkpoint {
        display: inline-block;
        z-index: 10;
    }
    
    .checkpoint-cirlce {
        border-radius: 50%;
        border: 5px #CCC solid;
        height: 30px;
        width: 30px;
        margin-left: auto;
        margin-right: auto;
        background: white;
    }
    
        .checkpoint-cirlce.current {
            border: 5px #c43535 solid;
        }
    
        .checkpoint-cirlce.checked {
            background: #c43535;
            border: 5px #c43535 solid;
        }
    
    .bar {
        position: absolute;
        top: 10px;
        height: 10px;
    }
        .bar.filled {
            background: #c43535;
            padding-left: 10px;
            left: 10px;
        }
        .bar.empty {
            background: #CCC;
            right: 10px;
            padding-right: 10px;
        }
    

    To make the status bar reusable in different locations I use a class saves the data of the checkpoints (Name and status). That is used in the component to create the status bar. I use a record class for that.

    public record Checkpoint(string Name, CheckpointStatus Status);
    
    public enum CheckpointStatus {
        Unchecked,
        Current,
        Checked
    }
    

    The enum represents the Status of the Checkpoint.

    To use the Component you have to create a ICollection<Checkpoint> (for example Array or List) and hand it to the Component, a simple example to use the component looks like that:

    <StatusBar Checkpoints="_checkpoints"/>
    
    @code{
        private Checkpoint[] _checkpoints = new Checkpoint[] {
            new Checkpoint("Open", CheckpointStatus.Checked),
            new Checkpoint("Qualified", CheckpointStatus.Checked),
            new Checkpoint("Develop", CheckpointStatus.Current),
            new Checkpoint("Propose", CheckpointStatus.Unchecked),
            new Checkpoint("Closed", CheckpointStatus.Unchecked),
        };
    }