//Confirm Change Charttype
        private async Task <DialogTurnResult> FinalStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            ConsoleWriter.WriteLineInfo("ResultTypeString: " + stepContext.Result.GetType().ToString());
            ConsoleWriter.WriteLineInfo("Result: " + stepContext.Result.ToString());
            var changeChartTypeDetails = (ChangeChartTypeDetails)stepContext.Options;

            //We are comming from a ChoicePromt/Ambiguity Dialog ==> Convert result to FoundCHoice
            if (stepContext.Result.GetType().ToString().Equals("Microsoft.Bot.Builder.Dialogs.Choices.FoundChoice"))
            {
                //Extract the picked result from the step-context
                var pickedChoice = (FoundChoice)stepContext.Result;
                var choiceText   = pickedChoice.Value;

                //Set the result to the ChangeCharttypeDetails-Object
                changeChartTypeDetails.ToChartType         = choiceText;
                changeChartTypeDetails.AmbiguousChartTypes = new string[] { choiceText };
            }
            //Now the Object is set right and we can print, what we want to change our charttype to
            ConsoleWriter.WriteLineInfo("Change Charttype to: " + changeChartTypeDetails.AmbiguousChartTypes[0]);

            //Send Request to API
            await BOT_Api.SendChangeChartTypeAsync(stepContext, changeChartTypeDetails.AmbiguousChartTypes[0]);

            return(await stepContext.EndDialogAsync(changeChartTypeDetails, cancellationToken));
        }
        private async Task <DialogTurnResult> FinalStepAsync(
            WaterfallStepContext stepContext,
            CancellationToken cancellationToken)
        {
            // Retrieve their selection list, the choice they made, and whether they chose to finish.
            var list   = stepContext.Values[CountriesSelected] as List <string>;
            var choice = (FoundChoice)stepContext.Result;
            var done   = choice.Value == DoneOption;

            if (!done)
            {
                // If they chose a company, add it to the list.
                list.Add(choice.Value);
            }

            if (done)
            {
                // If they're done, exit and return their list.
                ConsoleWriter.WriteLineInfo("Filter for: " + string.Join(", ", list));
                FilterForWordDetails filterForWordDetails = new FilterForWordDetails();
                filterForWordDetails.columnName = list.ToArray();


                ConsoleWriter.WriteLineInfo("ColumnName: " + filterForWordDetails.columnName[0]);
                await BOT_Api.SendFilterForWord(stepContext, usedColumn, list.ToArray());

                return(await stepContext.EndDialogAsync(list, cancellationToken));
            }
            else
            {
                // Otherwise, repeat this dialog, passing in the list from this iteration.
                return(await stepContext.ReplaceDialogAsync(nameof(FilterForWordDialog), list, cancellationToken));
            }
        }
        //Summarize results (e.g. by extracting information from the ambiguity dialog)
        private async Task <DialogTurnResult> FinalStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            var nl4dvQueryDetails = (Nl4dvQueryDetails)stepContext.Options;

            //We are comming from a ChoicePromt ==> Convert result to FoundCHoice (in this case we come from an ambiguity dialog. Otherwise there would have been no ChoicePromt)
            if (stepContext.Result.GetType().ToString().Equals("Microsoft.Bot.Builder.Dialogs.Choices.FoundChoice"))
            {
                //Extract the picked result from the step-context
                var pickedChoice = (FoundChoice)stepContext.Result;
                var choiceText   = pickedChoice.Value;
                ConsoleWriter.WriteLineInfo("Replacing Chart by " + choiceText);
                if (choiceText.Equals("I am not sure"))
                {
                    nl4dvQueryDetails.queryText = nl4dvQueryDetails.queryText.Replace("chart", "");
                }
                else
                {
                    nl4dvQueryDetails.queryText = nl4dvQueryDetails.queryText.Replace("chart", choiceText);
                    if (!nl4dvQueryDetails.queryText.Contains(choiceText))
                    {
                        nl4dvQueryDetails.queryText = nl4dvQueryDetails.queryText + " in a " + choiceText;
                    }
                }
            }
            //Now the Object is set right and we can print, what we want to change our charttype to

            await BOT_Api.SendNL4DV(stepContext, nl4dvQueryDetails.queryText);

            return(await stepContext.EndDialogAsync(nl4dvQueryDetails, cancellationToken));
        }
Beispiel #4
0
        //Confirm task
        private async Task <DialogTurnResult> FinalStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            var changeAggregateDetails = (ChangeAggregateDetails)stepContext.Options;

            //Now the Object is set right and we can print, what we want to change our charttype to
            ConsoleWriter.WriteLineInfo("Change aggregate of " + changeAggregateDetails.visualizationPart + " to: " + changeAggregateDetails.toAggregate);

            await BOT_Api.SendChangeAggregate(stepContext, changeAggregateDetails.visualizationPart, changeAggregateDetails.toAggregate);

            return(await stepContext.EndDialogAsync(changeAggregateDetails, cancellationToken));
        }
        //Summarize results (e.g. by extracting information from the ambiguity dialog)
        private async Task <DialogTurnResult> FinalStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            var filterForNumberDetails = (FilterForNumberDetails)stepContext.Options;

            //We are comming from a ChoicePromt ==> Convert result to FoundCHoice (in this case we come from an ambiguity dialog. Otherwise there would have been no ChoicePromt)
            if (stepContext.Result.GetType().ToString().Equals("Microsoft.Bot.Builder.Dialogs.Choices.FoundChoice"))
            {
                //Extract the picked result from the step-context
                var pickedChoice = (FoundChoice)stepContext.Result;
                var choiceText   = pickedChoice.Value;

                //Set the result to the ChangeCharttypeDetails-Object
                filterForNumberDetails.columnName = new string[] { choiceText };
            }
            //Now the Object is set right and we can print, what we want to change our charttype to
            ConsoleWriter.WriteLineInfo("Filtering " + filterForNumberDetails.columnName[0] + " " + filterForNumberDetails.comparisonOperator + " " + filterForNumberDetails.filterNumber);

            await BOT_Api.SendFilterForNumber(stepContext, filterForNumberDetails.columnName[0], filterForNumberDetails.comparisonOperator, filterForNumberDetails.filterNumber);

            return(await stepContext.EndDialogAsync(filterForNumberDetails, cancellationToken));
        }
        //Confirm task
        private async Task <DialogTurnResult> FinalStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            var changeVisualizationPartDetails = (ChangeVisualizationPartDetails)stepContext.Options;

            //We are comming from a ChoicePromt ==> Convert result to FoundCHoice
            if (stepContext.Result.GetType().ToString().Equals("Microsoft.Bot.Builder.Dialogs.Choices.FoundChoice"))
            {
                //Extract the picked result from the step-context
                var pickedChoice = (FoundChoice)stepContext.Result;
                var choiceText   = pickedChoice.Value;

                //Set the result to the ChangeCharttypeDetails-Object
                changeVisualizationPartDetails.toValue = new string[] { choiceText };
            }
            //Now the Object is set right and we can print, what we want to change our charttype to
            ConsoleWriter.WriteLineInfo("Change " + changeVisualizationPartDetails.visualizationPart + " to (first Value): " + changeVisualizationPartDetails.toValue[0]);

            await BOT_Api.SendChangeVisualizationPart(stepContext, changeVisualizationPartDetails.visualizationPart, changeVisualizationPartDetails.toValue[0]);

            return(await stepContext.EndDialogAsync(changeVisualizationPartDetails, cancellationToken));
        }
Beispiel #7
0
        //This function is called every time the user enters an input. The intent is determined in the switch case block. From there we call the needed Dialogs
        private async Task <DialogTurnResult> ActStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            var luisResult = await _luisRecognizer.RecognizeAsync <VisualizationInteraction>(stepContext.Context, cancellationToken);


            switch (luisResult.TopIntent().intent)
            {
            //The user wants to change the charttype
            case VisualizationInteraction.Intent.ChangeChartType:

                string[] chartTypeResults = luisResult.ToChartTypeEntity;

                var changeChartTypeDetails = new ChangeChartTypeDetails()
                {
                    AmbiguousChartTypes = chartTypeResults,
                    ToChartType         = chartTypeResults?[0],
                };

                //Check if changechartTypeDetails is null (in the Dialog) and ask for information if it is null
                return(await stepContext.BeginDialogAsync(nameof(ChangeChartTypeDialog), changeChartTypeDetails, cancellationToken));

            // user wants to filter for country, product or segment (nominal Rows)
            case VisualizationInteraction.Intent.Filter:

                (string[] columnnameLuis, string[] filterAttributeLuis, string[] countryLuis, string[] segmentLuis, string[] productLuis) = luisResult.FilterForWordEntities;

                string usedColumn;

                if (countryLuis != null)
                {
                    usedColumn = "Country";
                }
                else if (segmentLuis != null)
                {
                    usedColumn = "Segment";
                }
                else if (productLuis != null)
                {
                    usedColumn = "Product";
                }
                else
                {
                    usedColumn = "Country";
                }

                ConsoleWriter.WriteLineInfo("Column: " + usedColumn);

                var filterForWordDetails = new FilterForWordDetails
                {
                    columnName      = columnnameLuis,
                    filterAttribute = filterAttributeLuis,
                    country         = countryLuis,
                    segment         = segmentLuis,
                    product         = productLuis,
                    usedColumn      = usedColumn
                };
                return(await stepContext.BeginDialogAsync(nameof(FilterForWordDialog), filterForWordDetails, cancellationToken));


            //user wants to filter for number (cardinal rows)
            case VisualizationInteraction.Intent.FilterForNumber:

                (string[] columnNameLuis, string comparisonOperatorLuis, string filterNumberLuis) = luisResult.FilterForNumberEntities;

                var filterForNumberDetails = new FilterForNumberDetails
                {
                    columnName         = columnNameLuis,
                    comparisonOperator = comparisonOperatorLuis,
                    filterNumber       = filterNumberLuis
                };

                return(await stepContext.BeginDialogAsync(nameof(FilterForNumberDialog), filterForNumberDetails, cancellationToken));

            //user input is a complete query to be visualized -> send query to nl4dv
            case VisualizationInteraction.Intent.Nl4dv:
                //Gets the whole message from the User to the bot out of the luis result
                string nl4dvQuery = luisResult.Text;

                (string queryText, string[] chartType, string[] axis1, string[] axis2) = luisResult.Nl4dvEntities;

                var nl4dvQueryDetails = new Nl4dvQueryDetails
                {
                    queryText = queryText,
                    chartType = chartType,
                    axis1     = axis1,
                    axis2     = axis2
                };

                ConsoleWriter.WriteLineInfo("nl4dvQuery: " + nl4dvQuery);

                return(await stepContext.BeginDialogAsync(nameof(Nl4dvDialog), nl4dvQueryDetails, cancellationToken));


                //Here we would have to call the NL4DV function in the event handler (in the Python project)
                //BOT_Api.SendNL4DV(nl4dvQuery);
                break;

            // user wants to change e.g. legend or y-axis
            case VisualizationInteraction.Intent.ChangeVisualizationPart:

                (string visualizationPartLuis, string[] toValueLuis) = luisResult.ChangeVisualizationPartEntities;


                var changeVisualizationPartDetails = new ChangeVisualizationPartDetails
                {
                    visualizationPart = visualizationPartLuis,
                    toValue           = toValueLuis
                };

                return(await stepContext.BeginDialogAsync(nameof(ChangeVisualizationPartDialog), changeVisualizationPartDetails, cancellationToken));

            // user wants to change the aggregate of an axis
            case VisualizationInteraction.Intent.ChangeAggregate:

                (string toVisPartLuis, string toAggregateLuis) = luisResult.ChangeAggregateEntities;


                var changeAggregateDetails = new ChangeAggregateDetails
                {
                    visualizationPart = toVisPartLuis,
                    toAggregate       = toAggregateLuis
                };

                return(await stepContext.BeginDialogAsync(nameof(ChangeAggregateDialog), changeAggregateDetails, cancellationToken));

            case VisualizationInteraction.Intent.ClearFilter:
                await BOT_Api.SendClearFilter(stepContext);

                break;

            case VisualizationInteraction.Intent.Help:
                var helpMessageText = "Here is a quick guide for you: say \"show me sales by country\" to create a new visualization || \"change yaxis to profit\" to change the label of y-axis to profit || \"change aggregate of yaxis to sum\" changes the data aggregation of yaxis to sum (you can say sum, count, average) || \"change charttype to piechart\" changes the visualization to a piechart || \"filter for sales >= 200\" filters the dataset for all rows containing sales >= 200 || \"clear filter\" to clear all added filters";
                var helpMessage     = MessageFactory.Text(helpMessageText, helpMessageText, InputHints.IgnoringInput);
                await stepContext.Context.SendActivityAsync(helpMessage, cancellationToken);

                break;


            //intent not recognized
            default:
                // Catch all for unhandled intents
                var didntUnderstandMessageText = $"Sorry, I didn't get that. Please try asking in a different way (intent was {luisResult.TopIntent().intent})";
                var didntUnderstandMessage     = MessageFactory.Text(didntUnderstandMessageText, didntUnderstandMessageText, InputHints.IgnoringInput);
                await stepContext.Context.SendActivityAsync(didntUnderstandMessage, cancellationToken);

                break;
            }

            return(await stepContext.NextAsync(null, cancellationToken));
        }
        //Check if input is empty or additionally it is asked to filter for countries, then add country option list
        private async Task <DialogTurnResult> SelectionStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            // Continue using the same selection list, if any, from the previous iteration of this dialog.
            var list = stepContext.Options as List <string> ?? new List <string>();

            bool filterForCountry = false;

            if (stepContext.Options.GetType().ToString().Equals("Microsoft.BotBuilderSamples.FilterForWordDetails"))
            {
                FilterForWordDetails filterForWordDetails = (FilterForWordDetails)stepContext.Options;
                usedColumn = filterForWordDetails.usedColumn;
                // Check if filter for Word Dialog input is empty
                if (filterForWordDetails.columnName == null)
                {
                    string messageNull   = "I could not recognize what column you want to apply that filter to. Please say something like \"Filter for Germany and Canada\"";
                    var    cancelMessage = MessageFactory.Text(messageNull, CancelMsgText, InputHints.IgnoringInput);
                    await stepContext.Context.SendActivityAsync(cancelMessage, cancellationToken);

                    return(await stepContext.CancelAllDialogsAsync(cancellationToken));
                }

                //Filter for country
                for (int i = 0; i < filterForWordDetails.columnName.Length; i++)
                {
                    string s = UppercaseFirst(filterForWordDetails.columnName[i]);
                    list.Add(s);

                    //becomes true when you enter "filter for country"
                    if (string.Equals(s, "Country") || string.Equals(s, "Countries"))
                    {
                        filterForCountry = true;
                    }
                }

                if ((filterForWordDetails.country == null) && (filterForWordDetails.segment == null) && (filterForWordDetails.product == null) && !filterForCountry)
                {
                    string messageNull = "I could not recognize what column you want to apply that filter to. Please say something like \"Filter for Germany and Canada\"";

                    var cancelMessage = MessageFactory.Text(messageNull, CancelMsgText, InputHints.IgnoringInput);
                    await stepContext.Context.SendActivityAsync(cancelMessage, cancellationToken);

                    return(await stepContext.CancelAllDialogsAsync(cancellationToken));
                }


                //Breaks if we did not recognize any countries
                if (!filterForCountry)
                {
                    filterForWordDetails.columnName = list.ToArray();
                    ConsoleWriter.WriteLineInfo("Filter for: " + string.Join(", ", list));
                    ConsoleWriter.WriteLineInfo("ColumnName: " + filterForWordDetails.columnName[0]);
                    await BOT_Api.SendFilterForWord(stepContext, usedColumn, list.ToArray());

                    return(await stepContext.EndDialogAsync(filterForWordDetails.columnName));
                }
            }


            //if user entered "FILTER FOR COUNTRY" OR "COUNTRIES":

            stepContext.Values[CountriesSelected] = list;
            //Create a prompt message
            string message;

            if (list[0] == "Country")
            {
                message = $"Please choose a country to filter to finish.";
                list.Remove("Country");
            }
            else if (list[0] == "Countries")
            {
                message = $"Please choose a country to filter to finish.";
                list.Remove("Countries");
            }
            else
            {
                message = $"You have selected **{String.Join(", ", list)}**. You can filter for an additional country, " +
                          $"or choose `{DoneOption}` to finish.";
            }

            // Create the list of options to choose from.
            var options = _countryOptions.ToList();

            if (list.Count > 0)
            {
                options.Add(DoneOption);
                options = options.Except(list).ToList();
            }

            var promptOptions = new PromptOptions
            {
                Prompt      = MessageFactory.Text(message),
                RetryPrompt = MessageFactory.Text("Please choose an option from the list."),
                Choices     = ChoiceFactory.ToChoices(options),
            };

            // Prompt the user for a choice.
            return(await stepContext.PromptAsync(nameof(ChoicePrompt), promptOptions, cancellationToken));
        }