With the toolbar you have the possibility to design your command with the use of labels in the right down corner.
A specific requirement is also that the labels with the values shall have certain colors, not just any default colors. This is how the PowerCommandAttribute look like, to help the user consume this command.
The look is that one showing in the image above with the fruits, notice that the command name is toolbar
.
For this case we will use the attribute PowerCommandsToolbar
attribute like this:
You can also see the PowerCommandDesign
attribute, where the suggestions also are added with valid values, if the PowerCommandsToolbar
is omitted the suggestions will be uses as labels instead.
But in this case I want to show the values surrounded by []
and with a describing label [Pick a valid fruit]
to really guide the user right.
If I had added that as suggestions, the user could not us tab to cycle trough valid values.
For this to work we need to inherit the CommandWithToolbarBase
base class instead of the regular base class CommandBase
class.
But other than that is is just the PowerCommandsToolbar
attribute that you need to add and the rest will just work.
Notice that the Run function starts with calling the base.Run() function, that is to automatically clear the toolbar. If the user input is wrong the toolbar is programmatically called to show the toolbar again.
[PowerCommandsToolbar( labels: "[ Pick a valid fruit ->]|[Apple]|[Orange]|[Banana]",
colors: new [] { ConsoleColor.DarkBlue,ConsoleColor.DarkGreen ,ConsoleColor.Red,ConsoleColor.DarkYellow})]
[PowerCommandDesign( description: "Demonstration of the usage of a command with a toolbar",
suggestions: "Apple|Orange|Banana",
example: "toolbar")]
public class ToolbarCommand : CommandWithToolbarBase<PowerCommandsConfiguration>
{
public ToolbarCommand(string identifier, PowerCommandsConfiguration configuration) : base(identifier, configuration) { }
public override RunResult Run()
{
base.Run();
var fruits = new[] { "Apple", "Orange", "Banana" };
var fruit = Input.SingleArgument;
if(fruits.Any(f => f == fruit))WriteSuccessLine($"You picked {fruit}\nWell done");
else
{
WriteFailureLine($"{fruit} is not a valid fruit!");
DrawToolbar();
}
return Ok();
}
}
This use case is a bit more tricky, the command openapi
has this requirements:
- Needs to first set the working directory to a specific folder that contains a couple of *.yaml files.
- If the
openapi
is typed a check will performed to see if the current working directory is a valid one.- if not a label will be displayed to the user with instructions.
- If it is a valid directory a couple of labels will be shown what to do next.
We inherit the same base class CommandWithToolbarBase
base we are also been using functionality from the CdCommand
so that we could use the current WorkingDirectory.
We will not use the PowerCommandsToolbar
attribute because the labels are not static, we will instead listen on the user input from the command line and act on that if the typed in command is openapi
.
The base class already listen on this event but we override the behavior and implement a custom one.
Below is the command code, where implementation code skipped, the sample command exist in the source code if you want to use it. It´s actually is implementation code to generate WebApi using OpenAPI specification with their Docker image.
[PowerCommandDesign( description: "Generate API with OpenApi Code generator using a docker image, you create two files.\n First one with the API specification, the second one for the config, the filename should contain config so the command knows what is what...\n Navigate to the directory with the files using the cd command.",
example: "openapi --generate")]
public class OpenApiCommand : CommandWithToolbarBase<PowerCommandsConfiguration>
{
public OpenApiCommand(string identifier, PowerCommandsConfiguration configuration) : base(identifier, configuration, autoShowToolbar: false) { }
protected override void ReadLineService_CmdLineTextChanged(object? sender, CmdLineTextChangedArgs e)
{
if (e.CmdText.StartsWith(Identifier))
{
if (e.CmdText == Identifier)
{
Labels.Clear();
if (ValidFilesExists())
{
Labels.Add("Valid files found! ->");
Labels.Add("--generate");
DrawToolbar();
return;
}
Labels.Add("Navigate to a directory with the yaml files, using cd command");
DrawToolbar();
}
}
else
{
ClearToolbar();
Labels.Clear();
}
}
public override RunResult Run()
{
if(HasOption("generate")) GenerateCode();
return Ok();
}
public void GenerateCode()
{
//Implementation code excluded
}
public bool ValidFilesExists()
{
//Implementation code excluded
}
}
If the user navigates with CdCommand
to a directory with two *.yaml files this toolbar will be shown.
You could also use DialogService
direct in your command without inherit functionality from the CommandWithToolbarBase
base class.
DialogService.DrawToolbar(labels, colors)
Read more about: