Skip to content

Commit

Permalink
CB-33 Add Interaction Image Ports
Browse files Browse the repository at this point in the history
  • Loading branch information
izzat5233 committed Jan 13, 2025
1 parent 88ae748 commit 53d9fee
Show file tree
Hide file tree
Showing 9 changed files with 64 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public sealed record InteractionNodeDto(
InfoMeta Info,
VisualMeta Visual,
InputPortDto? TextInputPort,
IReadOnlyList<InputPortDto> ImageInputPorts,
OutputPortDto? TextOutputPort,
int? OutputEnumIdentifier,
OutputPortDto? OptionOutputPort,
Expand All @@ -20,9 +21,14 @@ public sealed record InteractionNodeDto(
{
public IEnumerable<int> GetInputPortIds()
{
if (TextOutputPort is not null)
if (TextInputPort is not null)
{
yield return TextOutputPort.Info.Identifier;
yield return TextInputPort.Info.Identifier;
}

foreach (var imageInputPort in ImageInputPorts)
{
yield return imageInputPort.Info.Identifier;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@ public static InteractionNode ToDomain(this InteractionNodeDto dto, Enum? output
dto.Info,
dto.Visual,
textInputPort,
dto.ImageInputPorts
.Select(i => InputPort<ImageData>.Create(
new InputPortId(Guid.NewGuid()),
i.Info,
i.Visual,
nodeId))
.ToHashSet(),
textOutputPort,
outputEnum,
optionOutputPort,
Expand Down Expand Up @@ -82,6 +89,13 @@ public static InteractionNodeDto ToDto(this InteractionNode domain)
domain.Info,
domain.Visual,
textInputPort,
domain.ImageInputPorts
.Select(i => new InputPortDto(
i.Info,
i.Visual,
domain.Info.Identifier,
DataType.Image))
.ToList(),
textOutputPort,
domain.OutputEnum?.Info.Identifier,
optionOutputPort,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using ChatbotBuilderApi.Application.Graphs.Ports.InputPorts;
using ChatbotBuilderApi.Application.Core.Extensions;
using ChatbotBuilderApi.Application.Graphs.Ports.InputPorts;
using ChatbotBuilderApi.Application.Graphs.Ports.OutputPorts;
using ChatbotBuilderApi.Application.Graphs.Shared.Data;
using ChatbotBuilderApi.Application.Graphs.Shared.Interactions;
Expand All @@ -24,6 +25,16 @@ public InteractionNodeValidator()
.WithMessage("TextInputPort node identifier must match node identifier.");
});

RuleForEach(x => x.ImageInputPorts)
.SetValidator(new InputPortValidator(DataType.Image));

RuleFor(x => x.ImageInputPorts)
.MustBeUnique();

RuleFor(x => x)
.Must(x => x.ImageInputPorts.Count < 20)
.WithMessage("ImageInputPorts count must be less than 20.");

When(x => x.TextOutputPort is not null, () =>
{
RuleFor(x => x.TextOutputPort)
Expand Down
12 changes: 11 additions & 1 deletion ChatbotBuilderApi.Domain/Graphs/Nodes/InteractionNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ public sealed class InteractionNode : Node,
IInputNode, IEnumNode, IOutputNode
{
public InputPort<TextData>? TextInputPort { get; }
public IReadOnlySet<InputPort<ImageData>> ImageInputPorts { get; } = null!;
public OutputPort<TextData>? TextOutputPort { get; }

public Enum? OutputEnum { get; }
public OutputPort<OptionData>? OptionOutputPort { get; }
public IReadOnlyDictionary<OptionData, InteractionOptionMeta>? OutputOptionMetas { get; }
Expand All @@ -25,13 +25,15 @@ private InteractionNode(
InfoMeta info,
VisualMeta visual,
InputPort<TextData>? textInputPort,
IReadOnlySet<InputPort<ImageData>> imageInputPorts,
OutputPort<TextData>? textOutputPort,
Enum? outputEnum,
OutputPort<OptionData>? optionOutputPort,
IReadOnlyDictionary<OptionData, InteractionOptionMeta>? outputOptionMetas)
: base(id, info, visual)
{
TextInputPort = textInputPort;
ImageInputPorts = imageInputPorts;
TextOutputPort = textOutputPort;
OutputEnum = outputEnum;
OptionOutputPort = optionOutputPort;
Expand All @@ -48,6 +50,7 @@ public static InteractionNode Create(
InfoMeta info,
VisualMeta visual,
InputPort<TextData>? textInputPort,
IReadOnlySet<InputPort<ImageData>> imageInputPorts,
OutputPort<TextData>? textOutputPort,
Enum? outputEnum,
OutputPort<OptionData>? optionOutputPort,
Expand Down Expand Up @@ -98,6 +101,7 @@ public static InteractionNode Create(
info,
visual,
textInputPort,
imageInputPorts,
textOutputPort,
outputEnum,
optionOutputPort,
Expand All @@ -108,6 +112,7 @@ public InteractionOutput GetInteractionOutput()
{
return InteractionOutput.Create(
TextInputPort?.GetData(),
ImageInputPorts.Select(i => i.GetData()).ToList(),
TextOutputPort is not null,
OptionOutputPort is not null,
OutputOptionMetas);
Expand Down Expand Up @@ -144,6 +149,11 @@ public IEnumerable<Port<InputPortId>> GetInputPorts()
{
yield return TextInputPort;
}

foreach (var imageInputPort in ImageInputPorts)
{
yield return imageInputPort;
}
}

public IEnumerable<Port<OutputPortId>> GetOutputPorts()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,20 @@ namespace ChatbotBuilderApi.Domain.Graphs.ValueObjects.Interactions;
public sealed class InteractionOutput : ValueObject
{
public TextData? TextOutput { get; }
public IReadOnlyList<ImageData> ImageOutputs { get; } = null!;
public bool TextExpected { get; }
public bool OptionExpected { get; }
public IReadOnlyDictionary<OptionData, InteractionOptionMeta>? ExpectedOptionMetas { get; }

private InteractionOutput(
TextData? textOutput,
IReadOnlyList<ImageData> imageOutputs,
bool textExpected,
bool optionExpected,
IReadOnlyDictionary<OptionData, InteractionOptionMeta>? expectedOptionMetas)
{
TextOutput = textOutput;
ImageOutputs = imageOutputs;
TextExpected = textExpected;
OptionExpected = optionExpected;
ExpectedOptionMetas = expectedOptionMetas;
Expand All @@ -33,16 +36,23 @@ private InteractionOutput()

public static InteractionOutput Create(
TextData? textOutput,
IReadOnlyList<ImageData> imageOutputs,
bool textExpected,
bool optionExpected,
IReadOnlyDictionary<OptionData, InteractionOptionMeta>? expectedOptionsMetas)
{
return new InteractionOutput(textOutput, textExpected, optionExpected, expectedOptionsMetas);
return new InteractionOutput(textOutput, imageOutputs, textExpected, optionExpected, expectedOptionsMetas);
}

protected override IEnumerable<object> GetAtomicValues()
{
yield return (object?)TextOutput ?? false;

foreach (var imageOutput in ImageOutputs)
{
yield return imageOutput;
}

yield return TextExpected;
yield return OptionExpected;
yield return (object?)ExpectedOptionMetas ?? false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ public sealed record InputMessageViewModel(
/// </summary>
/// <param name="CreatedAt">Date and time the message was created.</param>
/// <param name="TextOutput">Text output data. If any.</param>
/// <param name="ImageOutputs">A list of image output data. If any.</param>
/// <param name="TextExpected">Whether a text input is expected on the next user message.</param>
/// <param name="OptionExpected">Whether an option input is expected on the next user message.</param>
/// <param name="ExpectedOptionMetas">If an option input is expected,
/// use these option metas to display the options to the user.</param>
public sealed record OutputMessageViewModel(
DateTime CreatedAt,
TextDataModel? TextOutput,
IReadOnlyList<ImageDataModel> ImageOutputs,
bool TextExpected,
bool OptionExpected,
IReadOnlyDictionary<string, InteractionOptionMeta>? ExpectedOptionMetas);
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public static OutputMessageViewModel ToViewModel(this OutputMessage message)
return new OutputMessageViewModel(
message.CreatedAt,
message.Output.TextOutput?.ToModel(),
message.Output.ImageOutputs.Select(i => i.ToModel()).ToList(),
message.Output.TextExpected,
message.Output.OptionExpected,
message.Output.ExpectedOptionMetas?.ToDictionary(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public static InteractionNodeModel ToModel(this InteractionNodeDto dto)
dto.Info.ToModel(),
dto.Visual.ToModel(),
dto.TextInputPort?.ToModel(),
dto.ImageInputPorts.Select(i => i.ToModel()).ToList(),
dto.TextOutputPort?.ToModel(),
dto.OutputEnumIdentifier,
dto.OptionOutputPort?.ToModel(),
Expand All @@ -30,6 +31,7 @@ public static InteractionNodeDto ToDto(this InteractionNodeModel model)
model.Info.ToDomain(),
model.Visual.ToDomain(),
model.TextInputPort?.ToDto(),
model.ImageInputPorts.Select(i => i.ToDto()).ToList(),
model.TextOutputPort?.ToDto(),
model.OutputEnumId,
model.OptionOutputPort?.ToDto(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ namespace ChatbotBuilderApi.Presentation.Graphs.Nodes.Interaction;
/// <param name="Info">Generic information for the node.</param>
/// <param name="Visual">Visual information for the node.</param>
/// <param name="TextInputPort">Add this port if you want to display a text to the user.</param>
/// <param name="ImageInputPorts">(Max of 20) Add an Image port for each image you want to display to the user.
/// They will all be displayed to the user at once.</param>
/// <param name="TextOutputPort">Add this port if you want the user to input a text.</param>
/// <param name="OutputEnumId">Which enum to use for the OptionOutputPort.</param>
/// <param name="OptionOutputPort">Add this port if you want the user to select an option.</param>
Expand All @@ -26,6 +28,7 @@ public sealed record InteractionNodeModel(
InfoMetaModel Info,
VisualMetaModel Visual,
InputPortModel? TextInputPort,
IReadOnlyList<InputPortModel> ImageInputPorts,
OutputPortModel? TextOutputPort,
int? OutputEnumId,
OutputPortModel? OptionOutputPort,
Expand Down

0 comments on commit 53d9fee

Please sign in to comment.