Exemplo n.º 1
0
        /// <summary>
        /// Update the first trail card with user details.
        /// </summary>
        /// <param name="scrumSummary">Scrum summary information to be shown on card.</param>
        /// <param name="scrum">Scrum details.</param>
        /// <param name="scrumMaster">Scrum master details.</param>
        /// <param name="membersActivityIdMap">Members id who are part of the scrum.</param>
        /// <param name="timeZone">Used to convert scrum start time as per specified time zone.</param>
        /// <param name="turnContext">Context object containing information cached for a single turn of conversation with a user.</param>
        /// <param name="cancellationToken">Propagates notification that operations should be canceled.</param>
        /// <returns>A task of type bool where true represents summary card updated successfully while false indicates failure in updating the summary card.</returns>
        public async Task <bool> UpdateSummaryCardWithEndScrumAsync(ScrumSummary scrumSummary, Scrum scrum, ScrumMaster scrumMaster, Dictionary <string, string> membersActivityIdMap, string timeZone, ITurnContext turnContext, CancellationToken cancellationToken)
        {
            if (scrumSummary != null)
            {
                var activitySummary  = MessageFactory.Attachment(ScrumCard.GetScrumStartCard(scrumSummary, membersActivityIdMap, scrumMaster?.ScrumMasterId, scrum?.ScrumStartActivityId, this.localizer, timeZone));
                var teamsChannelInfo = await TeamsInfo.GetTeamChannelsAsync(turnContext, scrumMaster.TeamId, CancellationToken.None);

                var channelInfo = teamsChannelInfo.Where(channel => channel.Id.Equals(scrumMaster.ChannelId, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();

                if (channelInfo != null)
                {
                    activitySummary.Id           = scrum.ScrumStartCardResponseId;
                    activitySummary.Conversation = new ConversationAccount
                    {
                        Id = $"{scrumMaster.ChannelId};messageid={scrum.ScrumStartCardResponseId}",
                    };
                    this.logger.LogInformation($"Trail card updated for: {scrum.ThreadConversationId} summaryCardActivityId: {scrum.ScrumStartCardResponseId}");
                    await turnContext?.UpdateActivityAsync(activitySummary, cancellationToken);
                }

                return(true);
            }
            else
            {
                this.logger.LogInformation($"No data obtained from storage to update summary card for summaryCardActivityId : {scrum?.ScrumStartCardResponseId}");
                return(false);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Update the scrum summary card with updated details.
        /// </summary>
        /// <param name="scrumSummary">Scrum summary information to be shown on card.</param>
        /// <param name="summaryCardActivityId">Summary card activity id.</param>
        /// <param name="scrumTeamConfigId">Unique identifier for scrum team configuration details.</param>
        /// <param name="scrumStartActivityId">Scrum start card activity id</param>
        /// <param name="membersActivityIdMap">Members id who are part of the scrum.</param>
        /// <param name="timeZone">Used to convert scrum start time as per specified time zone.</param>
        /// <param name="turnContext">Context object containing information cached for a single turn of conversation with a user.</param>
        /// <param name="cancellationToken">Propagates notification that operations should be canceled.</param>
        /// <returns>A task of type boolean where true represents summary card updated successfully while false indicates failure in updating the summary card.</returns>
        public async Task <bool> UpdateSummaryCardAsync(ScrumSummary scrumSummary, string summaryCardActivityId, string scrumTeamConfigId, string scrumStartActivityId, Dictionary <string, string> membersActivityIdMap, string timeZone, ITurnContext turnContext, CancellationToken cancellationToken)
        {
            var activitySummary = MessageFactory.Attachment(ScrumCard.GetScrumStartCard(scrumSummary, membersActivityIdMap, scrumTeamConfigId, scrumStartActivityId, this.localizer, timeZone));

            activitySummary.Id           = summaryCardActivityId;
            activitySummary.Conversation = turnContext?.Activity.Conversation;
            this.logger.LogInformation($"Trail card updated for: {turnContext.Activity.Conversation.Id} summaryCardActivityId: {summaryCardActivityId}");
            await turnContext.UpdateActivityAsync(activitySummary, cancellationToken);

            return(true);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Get scrum summary from table storage.
        /// </summary>
        /// <param name="scrumTeamConfigId">Scrum team configuration details describing scrum team name and channel id.</param>
        /// <param name="aadGroupId">Azure Active Directory group Id.</param>
        /// <param name="scrumCardResponseId">Scrum card response id.</param>
        /// <param name="membersActivityIdMap">Members id who are part of the scrum.</param>
        /// <returns>A task that represents the scrum summary data needs to be returned.</returns>
        public async Task <ScrumSummary> GetScrumSummaryAsync(string scrumTeamConfigId, string aadGroupId, string scrumCardResponseId = null, Dictionary <string, string> membersActivityIdMap = null)
        {
            var scrumSummary = new ScrumSummary();

            var scrumConfiguration = await this.scrumConfigurationStorageProvider.GetScrumConfigurationDetailByScrumTeamConfigIdAsync(scrumTeamConfigId, aadGroupId);

            if (scrumConfiguration == null)
            {
                this.logger.LogInformation("scrum configuration details obtained from ScrumConfiguration table is null");
                return(null);
            }

            if (string.IsNullOrEmpty(scrumCardResponseId))
            {
                scrumSummary.ScrumName          = string.IsNullOrEmpty(scrumConfiguration.ScrumTeamName) ? Strings.GeneralChannel : scrumConfiguration.ScrumTeamName;
                scrumSummary.ScrumStartTime     = string.Format(CultureInfo.CurrentCulture, $"{{0:{ScrumStartDateTimeFormat}}}", DateTime.UtcNow);
                scrumSummary.TotalUserCount     = scrumConfiguration.UserPrincipalNames.Split(',').Where(email => !string.IsNullOrEmpty(email)).Count();
                scrumSummary.RespondedUserCount = 0;
                scrumSummary.BlockedUsersCount  = 0;
                scrumSummary.ScrumRunningStatus = ScrumRunningStatus.Active;
                return(scrumSummary);
            }

            var scrum = (await this.scrumStorageProvider.GetScrumsBySummaryCardActivityIdAsync(scrumCardResponseId, scrumConfiguration.AadGroupId)).FirstOrDefault();

            if (scrum == null)
            {
                this.logger.LogInformation("Scrum details obtained from Scrum table is null");
                return(null);
            }

            var scrumStatus = (await this.scrumStatusStorageProvider.GetScrumStatusBySummaryCardIdAsync(scrumCardResponseId, scrumConfiguration.AadGroupId))?.ToList();

            if (scrumStatus != null && scrumStatus.Count > 0)
            {
                scrumSummary.RespondedUserCount = scrumStatus.Count;
                scrumSummary.BlockedUsersCount  = scrumStatus.Where(scrumDetails => !string.IsNullOrEmpty(scrumDetails.BlockerDescription) && !string.IsNullOrWhiteSpace(scrumDetails.BlockerDescription)).ToList().Count;
            }
            else
            {
                scrumSummary.RespondedUserCount = 0;
                scrumSummary.BlockedUsersCount  = 0;
            }

            scrumSummary.ScrumName          = string.IsNullOrEmpty(scrumConfiguration.ScrumTeamName) ? Strings.GeneralChannel : scrumConfiguration.ScrumTeamName;
            scrumSummary.ScrumStartTime     = DateTimeOffset.Parse(scrum.CreatedOn, CultureInfo.InvariantCulture).ToString(ScrumStartDateTimeFormat, CultureInfo.InvariantCulture);
            scrumSummary.TotalUserCount     = membersActivityIdMap == null ? 0 : membersActivityIdMap.Count;
            scrumSummary.ScrumRunningStatus = scrum.IsCompleted ? ScrumRunningStatus.Closed : ScrumRunningStatus.Active;
            return(scrumSummary);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Get scrum start card when user clicks on update status button, end scrum button or scrum is started by background service.
        /// </summary>
        /// <param name="scrumSummary">Instance containing scrum related details.</param>
        /// <param name="membersActivityIdMap">Members id who are part of the scrum.</param>
        /// <param name="scrumMasterId">Unique identifier for scrum master details.</param>
        /// <param name="scrumStartActivityId">Scrum start card activity id. This will be used to refresh card if needed.</param>
        /// <param name="localizer">The current cultures' string localizer.</param>
        /// <param name="timeZone">Used to convert scrum start time as per specified time zone.</param>
        /// <returns>Scrum status update card attachment.</returns>
        public static Attachment GetScrumStartCard(ScrumSummary scrumSummary, Dictionary <string, string> membersActivityIdMap, string scrumMasterId, string scrumStartActivityId, IStringLocalizer <Strings> localizer, string timeZone)
        {
            string       userSpecifiedDateTime = FormatDateStringToAdaptiveCardDateFormat(scrumSummary?.ScrumStartTime, timeZone);
            string       scrumMembers          = JsonConvert.SerializeObject(membersActivityIdMap);
            string       isAnyUserResponded    = scrumSummary.RespondedUserCount == 0 ? localizer.GetString("StartScrumCardWelcomeText") : string.Format(CultureInfo.CurrentCulture, localizer.GetString("StartScrumCardBlockedText"), scrumSummary.BlockedUsersCount);
            AdaptiveCard getScrumStartCard     = new AdaptiveCard(Constants.AdaptiveCardVersion)
            {
                Body = new List <AdaptiveElement>
                {
                    new AdaptiveColumnSet
                    {
                        Columns = new List <AdaptiveColumn>
                        {
                            new AdaptiveColumn
                            {
                                VerticalContentAlignment = AdaptiveVerticalContentAlignment.Center,
                                Width = AdaptiveColumnWidth.Auto,
                                Items = new List <AdaptiveElement>
                                {
                                    new AdaptiveTextBlock
                                    {
                                        HorizontalAlignment = AdaptiveHorizontalAlignment.Left,
                                        Text   = scrumSummary.ScrumName,
                                        Weight = AdaptiveTextWeight.Bolder,
                                        Wrap   = true,
                                    },
                                },
                            },
                            new AdaptiveColumn
                            {
                                VerticalContentAlignment = AdaptiveVerticalContentAlignment.Center,
                                Width = AdaptiveColumnWidth.Stretch,
                                Items = new List <AdaptiveElement>
                                {
                                    new AdaptiveTextBlock
                                    {
                                        HorizontalAlignment = AdaptiveHorizontalAlignment.Right,
                                        Wrap  = true,
                                        Text  = scrumSummary.ScrumRunningStatus == ScrumRunningStatus.Active ? localizer.GetString("ScrumRunningStatusActive") : localizer.GetString("ScrumRunningStatusClosed"),
                                        Color = scrumSummary.ScrumRunningStatus == ScrumRunningStatus.Active ? AdaptiveTextColor.Good : AdaptiveTextColor.Default,
                                    },
                                },
                            },
                        },
                    },
                    new AdaptiveColumnSet
                    {
                        Columns = new List <AdaptiveColumn>
                        {
                            new AdaptiveColumn
                            {
                                VerticalContentAlignment = AdaptiveVerticalContentAlignment.Center,
                                Width = AdaptiveColumnWidth.Auto,
                                Items = new List <AdaptiveElement>
                                {
                                    new AdaptiveTextBlock
                                    {
                                        HorizontalAlignment = AdaptiveHorizontalAlignment.Left,
                                        Wrap = true,
                                        Text = string.Format(CultureInfo.CurrentCulture, localizer.GetString("ScrumDetailsRespondedVsTotalUserStatus"), scrumSummary.RespondedUserCount, scrumSummary.TotalUserCount),
                                    },
                                },
                            },
                            new AdaptiveColumn
                            {
                                VerticalContentAlignment = AdaptiveVerticalContentAlignment.Center,
                                Width = AdaptiveColumnWidth.Stretch,
                                Items = new List <AdaptiveElement>
                                {
                                    new AdaptiveTextBlock
                                    {
                                        HorizontalAlignment = AdaptiveHorizontalAlignment.Right,
                                        Text = userSpecifiedDateTime,
                                        Wrap = true,
                                    },
                                },
                            },
                        },
                    },
                    new AdaptiveColumnSet
                    {
                        Columns = new List <AdaptiveColumn>
                        {
                            new AdaptiveColumn
                            {
                                Width = AdaptiveColumnWidth.Stretch,
                                Items = new List <AdaptiveElement>
                                { // Represents empty column required for alignment.
                                },
                            },
                        },
                    },
                    new AdaptiveColumnSet
                    {
                        Columns = new List <AdaptiveColumn>
                        {
                            new AdaptiveColumn
                            {
                                Width = AdaptiveColumnWidth.Stretch,
                                Items = new List <AdaptiveElement>
                                { // Represents empty column required for alignment.
                                },
                            },
                        },
                    },
                    new AdaptiveColumnSet
                    {
                        Columns = new List <AdaptiveColumn>
                        {
                            new AdaptiveColumn
                            {
                                Items = new List <AdaptiveElement>
                                {
                                    new AdaptiveTextBlock
                                    {
                                        Size = AdaptiveTextSize.Medium,
                                        Wrap = true,
                                        Text = isAnyUserResponded,
                                        HorizontalAlignment = AdaptiveHorizontalAlignment.Left,
                                        Color     = scrumSummary.RespondedUserCount == 0 ? AdaptiveTextColor.Default : AdaptiveTextColor.Attention,
                                        Height    = AdaptiveHeight.Stretch,
                                        Separator = true,
                                    },
                                },
                                Spacing = AdaptiveSpacing.Medium,
                            },
                        },
                    },
                    new AdaptiveColumnSet
                    {
                        Columns = new List <AdaptiveColumn>
                        {
                            new AdaptiveColumn
                            {
                                Width = AdaptiveColumnWidth.Stretch,
                                Items = new List <AdaptiveElement>
                                { // Represents empty column required for alignment.
                                },
                            },
                        },
                    },
                    new AdaptiveColumnSet
                    {
                        Columns = new List <AdaptiveColumn>
                        {
                            new AdaptiveColumn
                            {
                                Width = AdaptiveColumnWidth.Stretch,
                                Items = new List <AdaptiveElement>
                                { // Represents empty column required for alignment.
                                },
                            },
                        },
                    },
                },
            };

            var scrumDetailsAdaptiveSubmitAction = new AdaptiveSubmitAction()
            {
                Title = localizer.GetString("ScrumDetailsButtonText"),
                Data  = new AdaptiveSubmitActionData
                {
                    MsTeams = new CardAction
                    {
                        Type = Constants.TaskModuleFetchType,
                    },
                    AdaptiveActionType   = Constants.ScrumDetailsTaskModuleCommand,
                    ScrumMasterId        = scrumMasterId,
                    ScrumStartActivityId = scrumStartActivityId,
                    ScrumMembers         = scrumMembers,
                },
            };

            if (scrumSummary.ScrumRunningStatus == ScrumRunningStatus.Active)
            {
                getScrumStartCard.Actions = new List <AdaptiveAction>
                {
                    new AdaptiveSubmitAction()
                    {
                        Title = localizer.GetString("UpdateStatusButtonText"),
                        Data  = new AdaptiveSubmitActionData
                        {
                            MsTeams = new CardAction
                            {
                                Type = Constants.TaskModuleFetchType,
                            },
                            AdaptiveActionType   = Constants.UpdateStatusTaskModuleCommand,
                            ScrumMasterId        = scrumMasterId,
                            ScrumStartActivityId = scrumStartActivityId,
                            ScrumMembers         = scrumMembers,
                        },
                    },
                    scrumDetailsAdaptiveSubmitAction,
                    new AdaptiveSubmitAction()
                    {
                        Title = localizer.GetString("EndScrumButtonText"),
                        Data  = new AdaptiveSubmitActionData
                        {
                            MsTeams = new CardAction
                            {
                                Type = ActionTypes.MessageBack,
                            },
                            AdaptiveActionType   = Constants.EndScrum,
                            ScrumMasterId        = scrumMasterId,
                            ScrumStartActivityId = scrumStartActivityId,
                            ScrumMembers         = scrumMembers,
                        },
                    },
                };
            }
            else
            {
                getScrumStartCard.Actions = new List <AdaptiveAction>
                {
                    scrumDetailsAdaptiveSubmitAction,
                };
            }

            var adaptiveCardAttachment = new Attachment()
            {
                ContentType = AdaptiveCard.ContentType,
                Content     = getScrumStartCard,
            };

            return(adaptiveCardAttachment);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Get scrum details card for viewing all user status details.
        /// </summary>
        /// <param name="scrumStatuses">Scrum statuses details filled by members.</param>
        /// <param name="scrumSummary">Scrum related summary.</param>
        /// <param name="teamsChannels">Team channel information from which team roaster information to fetch.</param>
        /// <param name="applicationBasePath">Application base URL.</param>
        /// <param name="localizer">The current cultures' string localizer.</param>
        /// <param name="timeZone">Used to convert scrum start time as per specified time zone.</param>
        /// <returns>Returns scrum details card attachment.</returns>
        public static Attachment GetScrumDetailsCard(IEnumerable <ScrumStatus> scrumStatuses, ScrumSummary scrumSummary, IEnumerable <TeamsChannelAccount> teamsChannels, string applicationBasePath, IStringLocalizer <Strings> localizer, string timeZone)
        {
            string       userSpecifiedDateTime = FormatDateStringToAdaptiveCardDateFormat(scrumSummary?.ScrumStartTime, timeZone);
            AdaptiveCard scrumDetailsCard      = new AdaptiveCard(Constants.AdaptiveCardVersion)
            {
                Body = new List <AdaptiveElement>
                {
                    new AdaptiveColumnSet
                    {
                        Columns = new List <AdaptiveColumn>
                        {
                            new AdaptiveColumn
                            {
                                VerticalContentAlignment = AdaptiveVerticalContentAlignment.Center,
                                Width = AdaptiveColumnWidth.Auto,
                                Items = new List <AdaptiveElement>
                                {
                                    new AdaptiveTextBlock
                                    {
                                        HorizontalAlignment = AdaptiveHorizontalAlignment.Left,
                                        Text   = scrumSummary.ScrumName,
                                        Weight = AdaptiveTextWeight.Bolder,
                                        Wrap   = true,
                                    },
                                },
                            },
                            new AdaptiveColumn
                            {
                                VerticalContentAlignment = AdaptiveVerticalContentAlignment.Center,
                                Width = AdaptiveColumnWidth.Stretch,
                                Items = new List <AdaptiveElement>
                                {
                                    new AdaptiveTextBlock
                                    {
                                        Color = scrumSummary.ScrumRunningStatus == ScrumRunningStatus.Active ? AdaptiveTextColor.Good : AdaptiveTextColor.Default,
                                        HorizontalAlignment = AdaptiveHorizontalAlignment.Right,
                                        Text = scrumSummary.ScrumRunningStatus == ScrumRunningStatus.Active ? localizer.GetString("ScrumRunningStatusActive") : localizer.GetString("ScrumRunningStatusClosed"),
                                        Wrap = true,
                                    },
                                },
                            },
                        },
                    },
                    new AdaptiveColumnSet
                    {
                        Columns = new List <AdaptiveColumn>
                        {
                            new AdaptiveColumn
                            {
                                VerticalContentAlignment = AdaptiveVerticalContentAlignment.Center,
                                Width = AdaptiveColumnWidth.Auto,
                                Items = new List <AdaptiveElement>
                                {
                                    new AdaptiveTextBlock
                                    {
                                        HorizontalAlignment = AdaptiveHorizontalAlignment.Left,
                                        Text = string.Format(CultureInfo.CurrentCulture, localizer.GetString("ScrumDetailsRespondedVsTotalUserStatus"), scrumSummary.RespondedUserCount, scrumSummary.TotalUserCount),
                                        Wrap = true,
                                    },
                                },
                            },
                            new AdaptiveColumn
                            {
                                VerticalContentAlignment = AdaptiveVerticalContentAlignment.Center,
                                Width = AdaptiveColumnWidth.Stretch,
                                Items = new List <AdaptiveElement>
                                {
                                    new AdaptiveTextBlock
                                    {
                                        HorizontalAlignment = AdaptiveHorizontalAlignment.Right,
                                        Text = userSpecifiedDateTime,
                                        Wrap = true,
                                    },
                                },
                            },
                        },
                    },
                    new AdaptiveColumnSet
                    {
                        Columns = new List <AdaptiveColumn>
                        {
                            new AdaptiveColumn
                            {
                                Width = AdaptiveColumnWidth.Stretch,
                                Items = new List <AdaptiveElement>
                                { // Represents empty column required for alignment.
                                },
                            },
                        },
                    },
                    new AdaptiveColumnSet
                    {
                        Columns = new List <AdaptiveColumn>
                        {
                            new AdaptiveColumn
                            {
                                Width = AdaptiveColumnWidth.Stretch,
                                Items = new List <AdaptiveElement>
                                { // Represents empty column required for alignment.
                                },
                            },
                        },
                    },
                },
            };

            List <AdaptiveElement> userScrumStatusList = GetAllUserScrumStatusCard(scrumStatuses, teamsChannels, applicationBasePath, localizer);

            scrumDetailsCard.Body.AddRange(userScrumStatusList);

            var scrumDetailsCardAttachment = new Attachment()
            {
                ContentType = AdaptiveCard.ContentType,
                Content     = scrumDetailsCard,
            };

            return(scrumDetailsCardAttachment);
        }