/// <summary> /// Store or update new hire introduction detail in Azure Table Storage. /// </summary> /// <param name="introductionEntity">Represents new hire introduction entity used for storage and retrieval.</param> /// <returns><see cref="Task"/> that represents new hire introduction entity is saved or updated.</returns> public async Task <bool> StoreOrUpdateIntroductionDetailAsync(IntroductionEntity introductionEntity) { introductionEntity = introductionEntity ?? throw new ArgumentNullException(nameof(introductionEntity)); if (string.IsNullOrWhiteSpace(introductionEntity.NewHireAadObjectId) || string.IsNullOrWhiteSpace(introductionEntity.ManagerAadObjectId) || string.IsNullOrWhiteSpace(introductionEntity.NewHireConversationId) || string.IsNullOrWhiteSpace(introductionEntity.ManagerConversationId) || string.IsNullOrWhiteSpace(introductionEntity.NewHireQuestionnaire) || string.IsNullOrWhiteSpace(introductionEntity.NewHireUserPrincipalName)) { return(false); } var result = await this.InsertOrReplaceIntroductionAsync(introductionEntity); if (result == null) { return(false); } else { return(result.HttpStatusCode == (int)HttpStatusCode.NoContent); } }
/// <summary> /// Stores or update new hire introduction data in Azure Table Storage. /// </summary> /// <param name="introductionEntity">Holds new hire introduction detail entity data.</param> /// <returns>A task that represents introduction entity data is saved or updated.</returns> private async Task <TableResult> InsertOrReplaceIntroductionAsync(IntroductionEntity introductionEntity) { await this.EnsureInitializedAsync(); TableOperation addOrUpdateOperation = TableOperation.InsertOrReplace(introductionEntity); return(await this.CloudTable.ExecuteAsync(addOrUpdateOperation)); }
public IntroductionEntity Create(EmployeeEntity EmployeeEntity, IntroductionEntity IntroductionEntity) { if (IntroductionEntity == null) { throw new NotFoundException(); } Introduction Introduction = new Introduction(IntroductionEntity); UnitOfWork.IntroductionRepository.AddOrUpdate(Introduction); UnitOfWork.Complete(); return(Get(EmployeeEntity, Introduction.Id)); }
/// <summary> /// To generate the introduction entity. /// </summary> /// <param name="turnContext">Context object containing information cached for a single turn of conversation with a user.</param> /// <param name="taskModuleRequest">Task module invoke request value payload.</param> /// <param name="userDetails">Get user details.</param> /// <returns>Introduction entity.</returns> private async Task <IntroductionEntity> GenerateIntroductionEntityAsync(ITurnContext <IInvokeActivity> turnContext, TaskModuleRequest taskModuleRequest, TeamsChannelAccount userDetails) { var objects = (JObject)taskModuleRequest.Data; var count = 0; List <IntroductionDetail> questionList; // Get Microsoft Graph token response. var response = await this.graphUtility.ObtainApplicationTokenAsync( this.botOptions.Value.TenantId, this.botOptions.Value.MicrosoftAppId, this.botOptions.Value.MicrosoftAppPassword); // Check if Microsoft Graph token is null. if (response == null) { this.logger.LogInformation("Response obtained from Microsoft Graph for access taken is null."); return(null); } questionList = (List <IntroductionDetail>) await this.sharePointHelper.GetIntroductionQuestionsAsync(response.AccessToken); var aboutMe = objects.Properties().Where(row => row.Name.Equals(CardConstants.NewHireProfileNoteInputId, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault()?.Value.ToString(); // Mapping question and answer based on question's unique id. foreach (var question in questionList) { question.Answer = objects.Properties().Where(row => row.Name == $"{CardConstants.QuestionId}{count}").FirstOrDefault()?.Value.ToString(); count++; } IntroductionEntity introductionEntity = new IntroductionEntity { NewHireAadObjectId = userDetails.AadObjectId, ManagerAadObjectId = string.Empty, NewHireQuestionnaire = JsonConvert.SerializeObject(questionList), ApprovalStatus = (int)IntroductionStatus.PendingForApproval, Comments = null, NewHireName = userDetails.Name, ManagerConversationId = string.Empty, NewHireUserPrincipalName = userDetails.Email, NewHireConversationId = turnContext.Activity.Conversation.Id, ApprovedOn = null, NewHireProfileNote = aboutMe, }; return(introductionEntity); }
/// <summary> /// Get introduction adaptive card. /// </summary> /// <param name="introductionEntity">New hire introduction details.</param> /// <param name="isAllQuestionAnswered">false if any of the question is not answered.</param> /// <returns>Envelope for Task Module Response.</returns> public TaskModuleResponse GetNewHireIntroductionCard(IntroductionEntity introductionEntity, bool isAllQuestionAnswered = true) { return(new TaskModuleResponse { Task = new TaskModuleContinueResponse { Value = new TaskModuleTaskInfo() { Card = NewHireIntroductionCard.GetNewHireIntroductionCardAttachment(introductionEntity, this.localizer, this.botOptions.Value.AppBaseUri, isAllQuestionAnswered), Height = isAllQuestionAnswered ? IntroductionTaskModuleHeight : ValidateIntroductionTaskModuleHeight, Width = IntroductionTaskModuleWidth, Title = this.localizer.GetString("AppTitle"), }, }, }); }
/// <summary> /// Get introduction detail adaptive card for hiring manager's team. /// </summary> /// <param name="introductionEntity">New hire introduction details.</param> /// <returns>Envelope for Task Module Response.</returns> public TaskModuleResponse GetIntroductionDetailCardForTeam(IntroductionEntity introductionEntity) { return(new TaskModuleResponse { Task = new TaskModuleContinueResponse { Value = new TaskModuleTaskInfo() { Card = IntroductionDetailCard.GetCard(this.botOptions.Value.AppBaseUri, this.localizer, introductionEntity), Height = IntroductionTaskModuleHeight, Width = IntroductionDetailTaskModuleWidth, Title = this.localizer.GetString("AppTitle"), }, }, }); }
/// <summary> /// Gets introduction validation card to show in task module. /// </summary> /// <param name="introductionEntity">New hire introduction details.</param> /// <returns>Envelope for Task Module Response.</returns> public TaskModuleResponse GetIntroductionValidationCard(IntroductionEntity introductionEntity) { return(new TaskModuleResponse { Task = new TaskModuleContinueResponse { Value = new TaskModuleTaskInfo() { Card = TellMeMoreCard.GetValidationMessageCard(introductionEntity, this.localizer), Height = ValidationMessageTaskModuleHeight, Width = ValidationMessageTaskModuleWidth, Title = this.localizer.GetString("AppTitle"), }, }, }); }
/// <summary> /// This method will construct the introduction detail card for hiring manager's team. /// </summary> /// <param name="applicationBasePath">Application base path to get the logo of the application.</param> /// <param name="localizer">The current culture's string localizer.</param> /// <param name="introductionEntity">Introduction entity.</param> /// <returns>Introduction detail card attachment.</returns> public static Attachment GetCard( string applicationBasePath, IStringLocalizer <Strings> localizer, IntroductionEntity introductionEntity) { introductionEntity = introductionEntity ?? throw new ArgumentNullException(nameof(introductionEntity)); var questionAnswerList = JsonConvert.DeserializeObject <List <IntroductionDetail> >(introductionEntity.NewHireQuestionnaire); AdaptiveCard card = new AdaptiveCard(new AdaptiveSchemaVersion(CardConstants.AdaptiveCardVersion)) { Body = new List <AdaptiveElement> { new AdaptiveImage { Url = new Uri($"{applicationBasePath}/Artifacts/hiringManagerNotification.png"), AltText = localizer.GetString("AlternativeText"), }, }, }; foreach (var questionAnswer in questionAnswerList) { card.Body.Add( new AdaptiveTextBlock { Weight = AdaptiveTextWeight.Bolder, Spacing = AdaptiveSpacing.Medium, Text = questionAnswer.Question, Wrap = true, }); card.Body.Add( new AdaptiveTextBlock { Spacing = AdaptiveSpacing.Small, Text = questionAnswer.Answer, Wrap = true, }); } return(new Attachment { ContentType = AdaptiveCard.ContentType, Content = card, }); }
/// <summary> /// Construct validation message card to show on task module. /// </summary> /// <param name="introductionEntity">New hire introduction details.</param> /// <param name="localizer">The current culture's string localizer.</param> /// <returns>Validation message card attachment.</returns> public static Attachment GetValidationMessageCard(IntroductionEntity introductionEntity, IStringLocalizer <Strings> localizer) { introductionEntity = introductionEntity ?? throw new ArgumentNullException(nameof(introductionEntity)); AdaptiveCard validationCard = new AdaptiveCard(new AdaptiveSchemaVersion(CardConstants.AdaptiveCardVersion)) { Body = new List <AdaptiveElement> { new AdaptiveTextBlock { Text = introductionEntity.ApprovalStatus == (int)IntroductionStatus.PendingForApproval ? localizer.GetString("PendingMessageText") : localizer.GetString("ApprovedMessageText"), Wrap = true, }, }, }; return(new Attachment { ContentType = AdaptiveCard.ContentType, Content = validationCard, }); }
/// <summary> /// Get confirmation card attachment to post a card to particular team. /// </summary> /// <param name="teamChannelMapping">Teams/Channel mappings.</param> /// <param name="localizer">The current culture's string localizer.</param> /// <param name="introductionEntity">New hire introduction details.</param> /// <param name="isTeamSelected">True if team selected.</param> /// <returns>Introduction confirmation card attachment.</returns> public static Attachment GetTeamConfirmationCard(List <Models.TeamDetail> teamChannelMapping, IStringLocalizer <Strings> localizer, IntroductionEntity introductionEntity, bool isTeamSelected = true) { introductionEntity = introductionEntity ?? throw new ArgumentNullException(nameof(introductionEntity)); teamChannelMapping = teamChannelMapping ?? throw new ArgumentNullException(nameof(teamChannelMapping)); var teamsChoices = new List <AdaptiveChoice>(); foreach (var team in teamChannelMapping) { if (team.Channels != null) { foreach (var channel in team.Channels) { teamsChoices.Add(new AdaptiveChoice() { Title = HttpUtility.HtmlEncode($"{team.TeamName} | {channel.ChannelName}"), // binding team id and Channel id by ';' (semicolon) Value = $"{team.TeamId};{channel.ChannelId}", }); } } } AdaptiveCard card = new AdaptiveCard(CardConstants.AdaptiveCardVersion) { Body = new List <AdaptiveElement> { new AdaptiveContainer() { PixelMinHeight = ContainerPixelHeight, Items = new List <AdaptiveElement>() { new AdaptiveTextBlock { Weight = AdaptiveTextWeight.Bolder, Spacing = AdaptiveSpacing.Medium, Text = localizer.GetString("TeamConfirmHeaderText"), Wrap = true, }, new AdaptiveChoiceSetInput { Spacing = AdaptiveSpacing.Small, Id = TeamInputId, Choices = teamsChoices, }, new AdaptiveTextBlock { Size = AdaptiveTextSize.Small, Text = localizer.GetString("RequiredFieldText"), IsVisible = !isTeamSelected, HorizontalAlignment = AdaptiveHorizontalAlignment.Right, Color = AdaptiveTextColor.Attention, }, }, }, }, Actions = new List <AdaptiveAction> { new AdaptiveSubmitAction { Title = localizer.GetString("PostInTeamButtonText"), Data = new AdaptiveSubmitActionData { Command = BotCommandConstants.PostTeamNotificationAction, IntroductionEntity = introductionEntity, }, }, }, }; return(new Attachment { ContentType = AdaptiveCard.ContentType, Content = card, }); }
public IntroductionEntity Update(EmployeeEntity EmployeeEntity, Guid IntroductionId, IntroductionEntity IntroductionEntity) { IntroductionEntity.Id = IntroductionId; Introduction Introduction = new Introduction(IntroductionEntity); UnitOfWork.IntroductionRepository.AddOrUpdate(Introduction); UnitOfWork.Complete(); return(Get(EmployeeEntity, Introduction.Id)); }
/// <summary> /// Get notification card after approved introduction from hiring manager. /// </summary> /// <param name="applicationBasePath">Application base path to get the logo of the application.</param> /// <param name="localizer">The current culture's string localizer.</param> /// <param name="introductionEntity">New hire introduction details.</param> /// <returns>Team introduction card attachment.</returns> public static Attachment GetCard( string applicationBasePath, IStringLocalizer <Strings> localizer, IntroductionEntity introductionEntity) { introductionEntity = introductionEntity ?? throw new ArgumentNullException(nameof(introductionEntity)); AdaptiveCard card = new AdaptiveCard(new AdaptiveSchemaVersion(CardConstants.AdaptiveCardVersion)) { Body = new List <AdaptiveElement> { new AdaptiveTextBlock { Text = localizer.GetString("TeamNotificationHeaderText", introductionEntity.NewHireName), Spacing = AdaptiveSpacing.Small, Color = AdaptiveTextColor.Accent, }, new AdaptiveTextBlock { Weight = AdaptiveTextWeight.Bolder, Size = AdaptiveTextSize.Large, Spacing = AdaptiveSpacing.None, Text = introductionEntity.NewHireName, }, new AdaptiveImage { Url = new Uri(!string.IsNullOrEmpty(introductionEntity.UserProfileImageUrl) ? introductionEntity.UserProfileImageUrl : $"{applicationBasePath}/Artifacts/peopleAvatar.png"), Spacing = AdaptiveSpacing.ExtraLarge, PixelHeight = IntroductionImageHeightInPixel, PixelWidth = IntroductionImageWidthInPixel, HorizontalAlignment = AdaptiveHorizontalAlignment.Center, Style = AdaptiveImageStyle.Person, AltText = localizer.GetString("AlternativeText"), }, new AdaptiveTextBlock { Text = !string.IsNullOrEmpty(introductionEntity.NewHireProfileNote) ? introductionEntity.NewHireProfileNote : localizer.GetString("IntroductionGreetText", introductionEntity.NewHireName), Spacing = AdaptiveSpacing.Small, Wrap = true, }, }, Actions = new List <AdaptiveAction> { new AdaptiveOpenUrlAction { Title = localizer.GetString("ChatButtonText", introductionEntity.NewHireName), Url = new Uri($"{DeepLinkConstants.ChatInitiateURL}?users={Uri.EscapeDataString(introductionEntity.NewHireUserPrincipalName)}"), }, new AdaptiveSubmitAction { Title = localizer.GetString("SeeMoreDetailsButtonText"), Data = new AdaptiveSubmitActionData { Msteams = new CardAction { Type = CardConstants.FetchActionType, Text = BotCommandConstants.SeeIntroductionDetailAction, }, IntroductionEntity = introductionEntity, Command = BotCommandConstants.SeeIntroductionDetailAction, }, }, }, }; return(new Attachment { ContentType = AdaptiveCard.ContentType, Content = card, }); }
/// <summary> /// This method will construct the edit introduction card for new hire employee. /// </summary> /// <param name="applicationBasePath">Application base path to get the logo of the application.</param> /// <param name="localizer">The current culture's string localizer.</param> /// <param name="introductionEntity">New hire introduction details.</param> /// <returns>Tell me more card attachment.</returns> public static Attachment GetCard( string applicationBasePath, IStringLocalizer <Strings> localizer, IntroductionEntity introductionEntity) { introductionEntity = introductionEntity ?? throw new ArgumentNullException(nameof(introductionEntity)); AdaptiveCard card = new AdaptiveCard(new AdaptiveSchemaVersion(CardConstants.AdaptiveCardVersion)) { Body = new List <AdaptiveElement> { new AdaptiveColumnSet { Columns = new List <AdaptiveColumn> { new AdaptiveColumn { Items = new List <AdaptiveElement> { new AdaptiveTextBlock { Weight = AdaptiveTextWeight.Bolder, Size = AdaptiveTextSize.Large, Text = localizer.GetString("EditIntroCardHeaderText"), Spacing = AdaptiveSpacing.Small, Wrap = true, }, new AdaptiveTextBlock { Spacing = AdaptiveSpacing.Small, Text = localizer.GetString("EditIntroCardSubHeaderText"), Wrap = true, }, new AdaptiveTextBlock { Weight = AdaptiveTextWeight.Bolder, Size = AdaptiveTextSize.Medium, Spacing = AdaptiveSpacing.Small, Text = localizer.GetString("ManagerCommentsTitleText"), Wrap = true, }, new AdaptiveTextBlock { Spacing = AdaptiveSpacing.Small, Text = introductionEntity.Comments, Wrap = true, }, }, }, new AdaptiveColumn { Items = new List <AdaptiveElement> { new AdaptiveImage { Url = new Uri($"{applicationBasePath}/Artifacts/moreInformationImage.png"), Size = AdaptiveImageSize.Large, HorizontalAlignment = AdaptiveHorizontalAlignment.Right, AltText = localizer.GetString("AlternativeText"), }, }, }, }, }, }, Actions = new List <AdaptiveAction> { new AdaptiveSubmitAction { Title = localizer.GetString("EditIntroButtonText"), Data = new AdaptiveSubmitActionData { Msteams = new CardAction { Type = CardConstants.FetchActionType, Text = BotCommandConstants.IntroductionAction, }, Command = BotCommandConstants.IntroductionAction, }, }, }, }; return(new Attachment { ContentType = AdaptiveCard.ContentType, Content = card, }); }
/// <summary> /// Submit introduction card action. /// </summary> /// <param name="userGraphAccessToken">User access token.</param> /// <param name="turnContext">Provides context for a step in a bot dialog.</param> /// <param name="taskModuleRequest">Task module invoke request value payload.</param> /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param> /// <returns>A task that returns submitted introduction card attachment as task module response.</returns> public async Task <TaskModuleResponse> SubmitIntroductionActionAsync( string userGraphAccessToken, ITurnContext <IInvokeActivity> turnContext, TaskModuleRequest taskModuleRequest, CancellationToken cancellationToken) { turnContext = turnContext ?? throw new ArgumentNullException(nameof(turnContext)); taskModuleRequest = taskModuleRequest ?? throw new ArgumentNullException(nameof(taskModuleRequest)); var userDetails = await this.GetUserDetailAsync(turnContext, cancellationToken); IntroductionEntity introductionEntity = await this.GenerateIntroductionEntityAsync( turnContext, taskModuleRequest, userDetails); var questionnaire = JsonConvert.DeserializeObject <List <IntroductionDetail> >(introductionEntity.NewHireQuestionnaire); if (!questionnaire.Where(row => string.IsNullOrEmpty(row.Answer)).ToList().Any() && !string.IsNullOrWhiteSpace(introductionEntity.NewHireProfileNote)) { // Get Manager details from Microsoft Graph API. var myManager = await this.userProfileGraphApiHelper.GetMyManagerAsync(userGraphAccessToken); if (myManager == null) { this.logger.LogWarning($"Error in getting manager details from Microsoft Graph API for user {turnContext.Activity.From.Id}."); await turnContext.SendActivityAsync(this.localizer.GetString("UserNotMappedWithManagerMessageText")); return(null); } // Get Manager's conversation id from storage. var userConversationDetails = await this.userStorageProvider.GetUserDetailAsync(myManager.Id); if (userConversationDetails == null) { this.logger.LogWarning($"Error in getting user conversation details from storage for user {myManager.Id}."); await turnContext.SendActivityAsync(this.localizer.GetString("ManagerUnavailableText")); return(null); } introductionEntity.ManagerAadObjectId = myManager.Id; introductionEntity.ManagerConversationId = userConversationDetails.ConversationId; await this.introductionStorageProvider.StoreOrUpdateIntroductionDetailAsync(introductionEntity); await turnContext.SendActivityAsync(this.localizer.GetString("IntroSubmittedMessage")); this.logger.LogInformation($"Introduction submitted by: {turnContext.Activity.From.Id}."); var hiringMangerNotification = MessageFactory.Attachment(HiringManagerNotificationCard.GetNewEmployeeIntroductionCard(this.botOptions.Value.AppBaseUri, this.localizer, introductionEntity)); hiringMangerNotification.Conversation = new ConversationAccount { Id = introductionEntity.ManagerConversationId }; await turnContext.Adapter.SendActivitiesAsync(turnContext, new Activity[] { (Activity)hiringMangerNotification }, cancellationToken); return(null); } else { // send back introduction card with corresponding validation message. return(this.introductionCardHelper.GetNewHireIntroductionCard(introductionEntity, isAllQuestionAnswered: false)); } }
/// <summary> /// Get new hire introduction card. /// </summary> /// <param name="userGraphAccessToken">User access token.</param> /// <param name="turnContext">Provides context for a step in a bot dialog.</param> /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param> /// <returns>A task that returns introduction card attachment as task module response.</returns> public async Task <TaskModuleResponse> GetIntroductionAsync( string userGraphAccessToken, ITurnContext turnContext, CancellationToken cancellationToken) { turnContext = turnContext ?? throw new ArgumentNullException(nameof(turnContext)); var userDetails = await this.GetUserDetailAsync(turnContext, cancellationToken); // Get Manager details from Microsoft Graph API. var myManager = await this.userProfileGraphApiHelper.GetMyManagerAsync(userGraphAccessToken); if (myManager == null) { this.logger.LogWarning($"Error in getting manager details from Microsoft Graph API for user {turnContext.Activity.From.Id}."); await turnContext.SendActivityAsync(this.localizer.GetString("GenericErrorMessageText")); return(null); } var introductionEntity = await this.introductionStorageProvider.GetIntroductionDetailAsync(userDetails.AadObjectId, myManager.Id); if (introductionEntity == null) { // Get Microsoft Graph token response. var response = await this.graphUtility.ObtainApplicationTokenAsync( this.botOptions.Value.TenantId, this.botOptions.Value.MicrosoftAppId, this.botOptions.Value.MicrosoftAppPassword); // Check if Microsoft Graph token is null. if (response == null) { this.logger.LogInformation("Response obtained from Microsoft Graph for access taken is null."); return(null); } var introductionQuestions = await this.sharePointHelper.GetIntroductionQuestionsAsync(response.AccessToken); if (introductionQuestions == null) { return(null); } var profileNote = await this.userProfileGraphApiHelper.GetUserProfileNoteAsync(userGraphAccessToken, userDetails.AadObjectId); introductionEntity = new IntroductionEntity { NewHireAadObjectId = userDetails.AadObjectId, ManagerAadObjectId = myManager.Id, NewHireQuestionnaire = JsonConvert.SerializeObject(introductionQuestions), ApprovalStatus = (int)IntroductionStatus.PendingForApproval, Comments = null, NewHireName = userDetails.Name, ManagerConversationId = string.Empty, NewHireUserPrincipalName = userDetails.Email, NewHireConversationId = userDetails.Id, ApprovedOn = null, NewHireProfileNote = profileNote, }; return(this.introductionCardHelper.GetNewHireIntroductionCard(introductionEntity)); } else if (introductionEntity != null && introductionEntity.ApprovalStatus != (int)IntroductionStatus.TellMeMore) { return(this.introductionCardHelper.GetIntroductionValidationCard(introductionEntity)); } else { return(this.introductionCardHelper.GetNewHireIntroductionCard(introductionEntity)); } }
/// <summary> /// Get new employee introduction card attachment for hiring manager to show on Microsoft Teams personal scope. /// </summary> /// <param name="applicationBasePath">Application base path to get the logo of the application.</param> /// <param name="localizer">The current culture's string localizer.</param> /// <param name="introductionEntity">Introduction entity.</param> /// <returns>New employee introduction card attachment.</returns> public static Attachment GetNewEmployeeIntroductionCard( string applicationBasePath, IStringLocalizer <Strings> localizer, IntroductionEntity introductionEntity) { introductionEntity = introductionEntity ?? throw new ArgumentNullException(nameof(introductionEntity)); var questionAnswerList = JsonConvert.DeserializeObject <List <IntroductionDetail> >(introductionEntity.NewHireQuestionnaire); AdaptiveCard card = new AdaptiveCard(new AdaptiveSchemaVersion(CardConstants.AdaptiveCardVersion)) { Body = new List <AdaptiveElement> { new AdaptiveImage { Url = new Uri($"{applicationBasePath}/Artifacts/hiringManagerNotification.png"), AltText = localizer.GetString("AlternativeText"), }, new AdaptiveTextBlock { Weight = AdaptiveTextWeight.Bolder, Size = AdaptiveTextSize.Large, Spacing = AdaptiveSpacing.Medium, Text = introductionEntity.NewHireName, }, new AdaptiveTextBlock { Spacing = AdaptiveSpacing.Small, Text = !string.IsNullOrWhiteSpace(introductionEntity.NewHireProfileNote) ? introductionEntity.NewHireProfileNote : localizer.GetString("IntroductionGreetText", introductionEntity.NewHireName), Wrap = true, }, }, Actions = new List <AdaptiveAction>(), }; foreach (var questionAnswer in questionAnswerList) { card.Body.Add( new AdaptiveTextBlock { Weight = AdaptiveTextWeight.Bolder, Spacing = AdaptiveSpacing.Medium, Text = questionAnswer.Question, Wrap = true, }); card.Body.Add( new AdaptiveTextBlock { Spacing = AdaptiveSpacing.Small, Text = questionAnswer.Answer, Wrap = true, }); } card.Actions.Add( new AdaptiveSubmitAction { Title = localizer.GetString("ApproveButtonText"), Data = new AdaptiveSubmitActionData { Msteams = new CardAction { Type = CardConstants.FetchActionType, Text = BotCommandConstants.ApproveIntroductionAction, }, Command = BotCommandConstants.ApproveIntroductionAction, IntroductionEntity = introductionEntity, }, }); card.Actions.Add( new AdaptiveShowCardAction() { Title = localizer.GetString("TellMeMoreButtonText"), Card = GetMoreInfoCard(localizer, introductionEntity), }); return(new Attachment { ContentType = AdaptiveCard.ContentType, Content = card, }); }
public IntroductionEntity Create([FromBody] IntroductionEntity IntroductionEntity) { return(IntroductionService.Create(EmployeeEntity, IntroductionEntity)); }
/// <summary> /// Get team confirmation adaptive card. /// </summary> /// <param name="teamChannelMapping">Teams/Channel mappings.</param> /// <param name="introductionEntity">New hire introduction details.</param> /// <param name="isTeamSelected">false if not team has selected.</param> /// <returns>Envelope for Task Module Response.</returns> public TaskModuleResponse GetApproveDetailCard(List <Models.TeamDetail> teamChannelMapping, IntroductionEntity introductionEntity, bool isTeamSelected = true) { return(new TaskModuleResponse { Task = new TaskModuleContinueResponse { Value = new TaskModuleTaskInfo() { Card = HiringManagerNotificationCard.GetTeamConfirmationCard(teamChannelMapping, this.localizer, introductionEntity, isTeamSelected), Height = ApproveDetailTaskModuleHeight, Width = ApproveDetailTaskModuleWidth, Title = this.localizer.GetString("AppTitle"), }, }, }); }
/// <summary> /// Get new hire introduction card attachment to show on Microsoft Teams personal scope. /// </summary> /// <param name="introductionEntity">New hire introduction details.</param> /// <param name="localizer">The current culture's string localizer.</param> /// <param name="applicationBasePath">Application base path to get the logo of the application.</param> /// <param name="isAllQuestionsAnswered">False when any of the question is not answered.</param> /// <returns>New Hire Introduction Card attachment.</returns> public static Attachment GetNewHireIntroductionCardAttachment(IntroductionEntity introductionEntity, IStringLocalizer <Strings> localizer, string applicationBasePath, bool isAllQuestionsAnswered = true) { introductionEntity = introductionEntity ?? throw new ArgumentNullException(nameof(introductionEntity)); List <IntroductionDetail> questionAnswerList = JsonConvert.DeserializeObject <List <IntroductionDetail> >(introductionEntity.NewHireQuestionnaire); AdaptiveCard card = new AdaptiveCard(new AdaptiveSchemaVersion(CardConstants.AdaptiveCardVersion)) { Body = new List <AdaptiveElement> { new AdaptiveImage { Url = new Uri($"{applicationBasePath}/Artifacts/introductionImage.png"), AltText = localizer.GetString("AlternativeText"), }, new AdaptiveTextBlock { Spacing = AdaptiveSpacing.Medium, Text = localizer.GetString("IntroductionText"), Wrap = true, }, new AdaptiveTextBlock { Size = AdaptiveTextSize.Small, Spacing = AdaptiveSpacing.Small, Text = localizer.GetString("IntroductionHeaderText"), Wrap = true, }, new AdaptiveTextInput { Spacing = AdaptiveSpacing.Small, Value = !string.IsNullOrWhiteSpace(introductionEntity.NewHireProfileNote) ? introductionEntity.NewHireProfileNote : localizer.GetString("IntroductionGreetText", introductionEntity.NewHireName), Id = CardConstants.NewHireProfileNoteInputId, MaxLength = 500, }, }, Actions = new List <AdaptiveAction> { new AdaptiveSubmitAction { Title = localizer.GetString("IntroductionSubmitButtonText"), Data = new AdaptiveSubmitActionData { Command = BotCommandConstants.SubmitIntroductionAction, }, }, }, }; foreach (var questionAnswer in questionAnswerList) { card.Body.Add( new AdaptiveTextBlock { Size = AdaptiveTextSize.Medium, Text = questionAnswer.Question, Wrap = true, Spacing = AdaptiveSpacing.Medium, }); card.Body.Add( new AdaptiveTextInput { Id = $"{CardConstants.QuestionId}{questionAnswerList.IndexOf(questionAnswer)}", Spacing = AdaptiveSpacing.Small, Value = !string.IsNullOrWhiteSpace(questionAnswer.Answer) ? questionAnswer.Answer : string.Empty, MaxLength = 500, Placeholder = localizer.GetString("IntroductionInputPlaceholderText"), }); } card.Body.Add( new AdaptiveTextBlock { Text = localizer.GetString("ValidationMessageText"), Spacing = AdaptiveSpacing.Medium, IsVisible = !isAllQuestionsAnswered, Color = AdaptiveTextColor.Attention, Size = AdaptiveTextSize.Small, }); return(new Attachment { ContentType = AdaptiveCard.ContentType, Content = card, }); }
public IntroductionEntity Update(Guid IntroductionId, [FromBody] IntroductionEntity IntroductionEntity) { return(IntroductionService.Update(EmployeeEntity, IntroductionId, IntroductionEntity)); }
/// <summary> /// Get more information card attachment to get more information about new hire employee. /// </summary> /// <param name="localizer">The current culture's string localizer.</param> /// <param name="introductionEntity">Introduction entity</param> /// <returns>Tell me more information card attachment.</returns> public static AdaptiveCard GetMoreInfoCard(IStringLocalizer <Strings> localizer, IntroductionEntity introductionEntity) { introductionEntity = introductionEntity ?? throw new ArgumentNullException(nameof(introductionEntity)); AdaptiveCard card = new AdaptiveCard(CardConstants.AdaptiveCardVersion) { Body = new List <AdaptiveElement> { new AdaptiveTextBlock { Weight = AdaptiveTextWeight.Bolder, Spacing = AdaptiveSpacing.Small, Text = localizer.GetString("MoreInfoCardSubHeaderText", introductionEntity.NewHireName), Wrap = true, }, new AdaptiveTextInput { Id = CommentsInputId, Placeholder = localizer.GetString("CommentsPlaceHolderText"), IsMultiline = true, Height = AdaptiveHeight.Stretch, MaxLength = 200, }, }, Actions = new List <AdaptiveAction> { new AdaptiveSubmitAction { Title = localizer.GetString("SendButtonText"), Data = new AdaptiveSubmitActionData { Msteams = new CardAction { Type = ActionTypes.MessageBack, Text = BotCommandConstants.RequestMoreInfoAction, }, IntroductionEntity = introductionEntity, }, }, }, }; return(card); }
public Introduction(IntroductionEntity IntroductionEntity) : base(IntroductionEntity) { }