Flow

When you use Flow Components to build something that involves use of a multiple components, your implementation may become a bit cluttered. To ease these use cases, we added a ComponentFlow that can hook multiple component executions together as a “flow”.

The following listings show examples of flows and their output in a shell:

static class FlowSampleComplex {

	@Autowired
	private ComponentFlow.Builder componentFlowBuilder;

	public void runFlow() {
		List<SelectItem> single1SelectItems = Arrays.asList(SelectItem.of("key1", "value1"),
				SelectItem.of("key2", "value2"));
		List<SelectItem> multi1SelectItems = Arrays.asList(SelectItem.of("key1", "value1"),
				SelectItem.of("key2", "value2"), SelectItem.of("key3", "value3"));
		ComponentFlow flow = componentFlowBuilder.clone()
			.reset()
			.withStringInput("field1")
			.name("Field1")
			.defaultValue("defaultField1Value")
			.and()
			.withStringInput("field2")
			.name("Field2")
			.and()
			.withNumberInput("number1")
			.name("Number1")
			.and()
			.withNumberInput("number2")
			.name("Number2")
			.defaultValue(20.5)
			.numberClass(Double.class)
			.and()
			.withConfirmationInput("confirmation1")
			.name("Confirmation1")
			.and()
			.withPathInput("path1")
			.name("Path1")
			.and()
			.withSingleItemSelector("single1")
			.name("Single1")
			.selectItems(single1SelectItems)
			.and()
			.withMultiItemSelector("multi1")
			.name("Multi1")
			.selectItems(multi1SelectItems)
			.and()
			.build();
		flow.run();
	}

}
Normal execution order of a components is same as defined with a builder.

It’s possible to conditionally choose where to jump in a flow by using a next function and returning target component id. If this returned id is either null or doesn’t exist flow is essentially stopped right there.

static class FlowSampleConditional {

	@Autowired
	private ComponentFlow.Builder componentFlowBuilder;

	public void runFlow() {
		Map<String, String> single1SelectItems = new HashMap<>();
		single1SelectItems.put("Field1", "field1");
		single1SelectItems.put("Field2", "field2");
		ComponentFlow flow = componentFlowBuilder.clone()
			.reset()
			.withSingleItemSelector("single1")
			.name("Single1")
			.selectItems(single1SelectItems)
			.next(ctx -> ctx.getResultItem().get().getItem())
			.and()
			.withStringInput("field1")
			.name("Field1")
			.defaultValue("defaultField1Value")
			.next(ctx -> null)
			.and()
			.withStringInput("field2")
			.name("Field2")
			.defaultValue("defaultField2Value")
			.next(ctx -> null)
			.and()
			.build();
		flow.run();
	}

}
The result from running a flow returns ComponentFlowResult, which you can use to do further actions.