Skip to content
This repository has been archived by the owner on Oct 17, 2024. It is now read-only.

Commit

Permalink
ARM deployment and code updates (#4)
Browse files Browse the repository at this point in the history
- /Deployment: ARM deployment file updated to provide config UPN list setting 
- /Source: code refactoring in Bot and common libraries 
            - removed additional check for \\ during card template parsing from storage 
            - added new constant class for cards and cleaned up common Constants class 
            - modify input-form.tsx to use resource string for button
  • Loading branch information
abbodh authored Apr 15, 2020
1 parent 88b476b commit ae9b772
Show file tree
Hide file tree
Showing 13 changed files with 74 additions and 89 deletions.
15 changes: 15 additions & 0 deletions Deployment/azuredeploy.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,21 @@
"description": "The client secret of the bot Azure AD app."
}
},
"configAppClientId": {
"type": "string",
"minLength": 36,
"maxLength": 36,
"metadata": {
"description": "The client ID of the of the configuration Azure AD app, e.g., 123e4567-e89b-12d3-a456-426655440000."
}
},
"configAdminUPNList": {
"type": "string",
"minLength": 1,
"metadata": {
"description": "Semicolon-delimited list of the user principal names (UPNs) allowed to access the configuration app."
}
},
"appDisplayName": {
"type": "string",
"minLength": 1,
Expand Down
13 changes: 0 additions & 13 deletions Source/Microsoft.Teams.Apps.RemoteSupport.Common/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,14 +104,6 @@ public static class Constants
/// </summary>
public const string UrgentString = "Urgent";

/// <summary>
/// Date time format to support adaptive card text feature.
/// </summary>
/// <remarks>
/// refer adaptive card text feature https://docs.microsoft.com/en-us/adaptive-cards/authoring-cards/text-features#datetime-formatting-and-localization.
/// </remarks>
public const string Rfc3339DateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'";

/// <summary>
/// Cancel command.
/// </summary>
Expand Down Expand Up @@ -146,10 +138,5 @@ public static class Constants
/// Closed requests command id in the manifest file.
/// </summary>
public const string ClosedCommandId = "closedrequests";

/// <summary>
/// Text block card id for first observed on text in remote support request card
/// </summary>
public const string IssueOccurredOnId = "IssueOccurredOn";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,7 @@ public async Task<CardConfigurationEntity> GetConfigurationAsync()
}
while (continuationToken != null);

var cardConfigurationEntity = configurations.OrderByDescending(configuration => configuration.CreatedOn).FirstOrDefault();
if (cardConfigurationEntity == null)
{
return null;
}
else
{
cardConfigurationEntity.CardTemplate = cardConfigurationEntity.CardTemplate.Replace("\\", string.Empty);
return cardConfigurationEntity;
}
return configurations.OrderByDescending(configuration => configuration.CreatedOn).FirstOrDefault();
}

/// <summary>
Expand All @@ -87,16 +78,7 @@ public async Task<CardConfigurationEntity> GetConfigurationsByCardIdAsync(string
}
while (continuationToken != null);

var cardConfigurationEntity = configurations.OrderByDescending(configuration => configuration.CreatedOn).FirstOrDefault();
if (cardConfigurationEntity == null)
{
return null;
}
else
{
cardConfigurationEntity.CardTemplate = cardConfigurationEntity.CardTemplate.Replace("\\", string.Empty);
return cardConfigurationEntity;
}
return configurations.OrderByDescending(configuration => configuration.CreatedOn).FirstOrDefault();
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const InputTextForm: React.FunctionComponent<IPropertiesProps> = (props) => {
<Input fluid placeholder={props.resourceStrings.placeholderText} value={properties.placeholder} onChange={(e: any) => { setProperties({ ...properties, placeholder: e.target.value }) }} />
</>
</Flex.Item>
<Button content="Add Component" onClick={onAddComponent} />
<Button content={props.resourceStrings.common.btnAddComponent} onClick={onAddComponent} />
</>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ protected override async Task<TaskModuleResponse> OnTeamsTaskModuleSubmitAsync(I
{
case Constants.UpdateRequestAction:
var ticketDetail = await this.ticketDetailStorageProvider.GetTicketAsync(valuesforTaskModule.TicketId);
if (TicketHelper.ValidateRequestDetail(editTicketDetail, turnContext, ticketDetail))
if (TicketHelper.ValidateRequestDetail(editTicketDetail))
{
ticketDetail.AdditionalProperties = CardHelper.ValidateAdditionalTicketDetails(((JObject)activity.Value).GetValue("data", StringComparison.OrdinalIgnoreCase)?.ToString(), turnContext.Activity.LocalTimestamp.Value.Offset);

Expand Down
30 changes: 30 additions & 0 deletions Source/Microsoft.Teams.Apps.RemoteSupport/Cards/CardConstants.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// <copyright file="CardConstants.cs" company="Microsoft">
// Copyright (c) Microsoft. All rights reserved.
// </copyright>

namespace Microsoft.Teams.Apps.RemoteSupport.Cards
{
/// <summary>
/// Constants used in bot and task module cards
/// </summary>
public static class CardConstants
{
/// <summary>
/// Text block card id for first observed on text in remote support request card
/// </summary>
public const string IssueOccurredOnId = "IssueOccurredOn";

/// <summary>
/// Text block card id for date time validation message in remote support request card
/// </summary>
public const string DateValidationMessageId = "DateValidationMessage";

/// <summary>
/// Date time format to support adaptive card text feature.
/// </summary>
/// <remarks>
/// refer adaptive card text feature https://docs.microsoft.com/en-us/adaptive-cards/authoring-cards/text-features#datetime-formatting-and-localization.
/// </remarks>
public const string Rfc3339DateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ namespace Microsoft.Teams.Apps.RemoteSupport.Cards
{
using System;
using System.Collections.Generic;
using System.Globalization;
using AdaptiveCards;
using Microsoft.Bot.Schema;
using Microsoft.Extensions.Localization;
Expand Down Expand Up @@ -60,15 +59,6 @@ public static Attachment GetEditRequestCard(TicketDetail ticketDetail, CardConfi
issueDescription = ticketDetail.Description;
}

if (ticketDetail.IssueOccurredOn == null || DateTimeOffset.Compare(ticketDetail.IssueOccurredOn, DateTime.Today) > 0 || string.IsNullOrEmpty(ticketDetail.IssueOccurredOn.ToString(CultureInfo.InvariantCulture)))
{
showDateValidation = true;
}
else if (existingTicketDetail != null && DateTimeOffset.Compare(ticketDetail.IssueOccurredOn, existingTicketDetail.IssueOccurredOn) > 0)
{
showDateValidation = true;
}

var ticketAdditionalDetails = JsonConvert.DeserializeObject<Dictionary<string, string>>(ticketDetail.AdditionalProperties);
ticketAdditionalFields = CardHelper.ConvertToAdaptiveCard(localizer, cardConfiguration.CardTemplate, showDateValidation, ticketAdditionalDetails);

Expand Down Expand Up @@ -204,4 +194,4 @@ public static Attachment GetClosedErrorCard(IStringLocalizer<Strings> localizer)
};
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,18 @@ public Attachment GetTicketDetailsForSMEChatCard(Dictionary<string, string> card
var dynamicElements = new List<AdaptiveElement>();
var ticketAdditionalFields = new List<AdaptiveElement>();

foreach (KeyValuePair<string, string> ticket in ticketAdditionalDetail)
foreach (KeyValuePair<string, string> ticketField in ticketAdditionalDetail)
{
string key = ticket.Key;
string key = ticketField.Key;

// Issue occured on text block name needs to be fetched from card templates
// here IssueOccurredOn is the id of text block
if (ticket.Key.Equals(Constants.IssueOccurredOnId, StringComparison.OrdinalIgnoreCase))
if (ticketField.Key.Equals(CardConstants.IssueOccurredOnId, StringComparison.OrdinalIgnoreCase))
{
key = localizer.GetString("FirstObservedText");
}

ticketAdditionalFields.Add(CardHelper.GetAdaptiveCardColumnSet(cardElementMapping.ContainsKey(key) ? cardElementMapping[key] : key, ticket.Value));
ticketAdditionalFields.Add(CardHelper.GetAdaptiveCardColumnSet(cardElementMapping.ContainsKey(key) ? cardElementMapping[key] : key, ticketField.Value));
}

dynamicElements.AddRange(new List<AdaptiveElement>
Expand Down
16 changes: 5 additions & 11 deletions Source/Microsoft.Teams.Apps.RemoteSupport/Cards/TicketCard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ namespace Microsoft.Teams.Apps.RemoteSupport.Cards
{
using System;
using System.Collections.Generic;
using System.Globalization;
using AdaptiveCards;
using Microsoft.Bot.Schema;
using Microsoft.Extensions.Localization;
Expand Down Expand Up @@ -62,11 +61,6 @@ public static Attachment GetNewTicketCard(CardConfigurationEntity cardConfigurat
{
issueDescription = ticketDetail.Description;
}

if (ticketDetail.IssueOccurredOn == null || DateTimeOffset.Compare(ticketDetail.IssueOccurredOn, DateTime.Today) > 0 || string.IsNullOrEmpty(ticketDetail.IssueOccurredOn.ToString(CultureInfo.InvariantCulture)))
{
showDateValidation = true;
}
}

ticketAdditionalFields = CardHelper.ConvertToAdaptiveCard(localizer, cardConfiguration.CardTemplate, showDateValidation);
Expand Down Expand Up @@ -199,15 +193,15 @@ public static Attachment GetTicketDetailsForPersonalChatCard(Dictionary<string,
var dynamicElements = new List<AdaptiveElement>();
var ticketAdditionalFields = new List<AdaptiveElement>();

foreach (KeyValuePair<string, string> item in ticketAdditionalDetail)
foreach (KeyValuePair<string, string> ticketField in ticketAdditionalDetail)
{
string key = item.Key;
if (item.Key.Equals(Constants.IssueOccurredOnId, StringComparison.OrdinalIgnoreCase))
string key = ticketField.Key;
if (ticketField.Key.Equals(CardConstants.IssueOccurredOnId, StringComparison.OrdinalIgnoreCase))
{
key = localizer.GetString("FirstObservedText");
}

ticketAdditionalFields.Add(CardHelper.GetAdaptiveCardColumnSet(cardElementMapping.ContainsKey(key) ? cardElementMapping[key] : key, item.Value));
ticketAdditionalFields.Add(CardHelper.GetAdaptiveCardColumnSet(cardElementMapping.ContainsKey(key) ? cardElementMapping[key] : key, ticketField.Value));
}

dynamicElements.AddRange(new List<AdaptiveElement>
Expand Down Expand Up @@ -275,4 +269,4 @@ public static Attachment GetTicketDetailsForPersonalChatCard(Dictionary<string,
};
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ internal static async Task OnAdaptiveCardSubmitInPersonalChatAsync(
{
case Constants.SendRequestAction:
TicketDetail newTicketDetail = JsonConvert.DeserializeObject<TicketDetail>(message.Value?.ToString());
if (TicketHelper.ValidateRequestDetail(newTicketDetail, turnContext))
if (TicketHelper.ValidateRequestDetail(newTicketDetail))
{
AdaptiveCardAction cardDetail = ((JObject)message.Value).ToObject<AdaptiveCardAction>();
logger.LogInformation("Adding new request with additional details.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ namespace Microsoft.Teams.Apps.RemoteSupport.Helpers
{
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using AdaptiveCards;
using Microsoft.Teams.Apps.RemoteSupport.Cards;
using Microsoft.Teams.Apps.RemoteSupport.Models;
using Newtonsoft.Json;

Expand All @@ -33,7 +33,7 @@ public static AdaptiveTextBlock ConvertToAdaptiveTextBlock(string cardElementTem

string color = CardHelper.TryParseTicketDetailsKeyValuePair(result, "color");
AdaptiveTextColor textColor;
if (CardHelper.TryParseTicketDetailsKeyValuePair(result, "id") == "DateValidationMessage")
if (CardHelper.TryParseTicketDetailsKeyValuePair(result, "id") == CardConstants.DateValidationMessageId)
{
textColor = AdaptiveTextColor.Attention;
}
Expand Down Expand Up @@ -83,7 +83,7 @@ public static AdaptiveDateInput ConvertToAdaptiveDateInput(string cardElementTem
{
Id = CardHelper.TryParseTicketDetailsKeyValuePair(result, "id"),
Placeholder = CardHelper.TryParseTicketDetailsKeyValuePair(result, "placeholder"),
Value = string.IsNullOrEmpty(CardHelper.TryParseTicketDetailsKeyValuePair(result, "value")) ? DateTime.Now.ToString(CultureInfo.InvariantCulture) : CardHelper.TryParseTicketDetailsKeyValuePair(result, "value"),
Value = CardHelper.TryParseTicketDetailsKeyValuePair(result, "value"),
Max = CardHelper.TryParseTicketDetailsKeyValuePair(result, "max"),
Min = CardHelper.TryParseTicketDetailsKeyValuePair(result, "min"),
};
Expand Down Expand Up @@ -115,4 +115,4 @@ public static AdaptiveChoiceSetInput ConvertToAdaptiveChoiceSetInput(string card
};
}
}
}
}
11 changes: 5 additions & 6 deletions Source/Microsoft.Teams.Apps.RemoteSupport/Helpers/CardHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ namespace Microsoft.Teams.Apps.RemoteSupport.Helpers
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using Microsoft.Teams.Apps.RemoteSupport.Cards;
using Microsoft.Teams.Apps.RemoteSupport.Common;
using Microsoft.Teams.Apps.RemoteSupport.Common.Models;
using Microsoft.Teams.Apps.RemoteSupport.Common.Providers;
using Microsoft.Teams.Apps.RemoteSupport.Models;
Expand Down Expand Up @@ -466,7 +465,7 @@ public static List<AdaptiveElement> ConvertToAdaptiveCard(IStringLocalizer<Strin
if (templateMapping.InputType != "TextBlock")
{
// get first observed display text if parsed from appSettings; rest all values will be set up directly in JSON payload.
if (templateMapping.Id == Constants.IssueOccurredOnId)
if (templateMapping.Id == CardConstants.IssueOccurredOnId)
{
templateMapping.DisplayName = localizer.GetString("FirstObservedText");
}
Expand All @@ -491,17 +490,17 @@ public static List<AdaptiveElement> ConvertToAdaptiveCard(IStringLocalizer<Strin
else
{
// Enabling validation message for First observed on date time field.
if (templateMapping.Id == "DateValidationMessage")
if (templateMapping.Id == CardConstants.DateValidationMessageId)
{
if (showDateValidation)
{
cardTemplateElements.Add(JObject.FromObject(new AdaptiveTextBlock
{
Type = AdaptiveTextBlock.TypeName,
Id = "DateValidationMessage",
Id = CardConstants.DateValidationMessageId,
Spacing = AdaptiveSpacing.None,
Color = AdaptiveTextColor.Attention,
IsVisible = true,
IsVisible = showDateValidation,
Text = localizer.GetString("DateValidationText"),
}));
}
Expand All @@ -526,7 +525,7 @@ public static string AdaptiveTextParseWithDateTime(string inputText)
{
if (DateTime.TryParse(inputText, out DateTime inputDateTime))
{
return "{{DATE(" + inputDateTime.ToUniversalTime().ToString(Constants.Rfc3339DateTimeFormat, CultureInfo.InvariantCulture) + ", SHORT)}}";
return "{{DATE(" + inputDateTime.ToUniversalTime().ToString(CardConstants.Rfc3339DateTimeFormat, CultureInfo.InvariantCulture) + ", SHORT)}}";
}

return inputText;
Expand Down
22 changes: 5 additions & 17 deletions Source/Microsoft.Teams.Apps.RemoteSupport/Helpers/TicketHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
namespace Microsoft.Teams.Apps.RemoteSupport.Helpers
{
using System;
using System.Globalization;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Schema;
using Microsoft.Bot.Schema.Teams;
Expand All @@ -19,23 +18,12 @@ public static class TicketHelper
/// Validates user entered ticket details.
/// </summary>
/// <param name="updatedTicketDetail">Ticket details entered by the user.</param>
/// <param name="turnContext">Context object containing information cached for a single turn of conversation with a user.</param>
/// <param name="existingTicketDetail">Ticket details which are existing in table.</param>
/// <returns>Returns success/failure depending on whether validation succeeds.</returns>
public static bool ValidateRequestDetail(TicketDetail updatedTicketDetail, ITurnContext turnContext, TicketDetail existingTicketDetail = null)
public static bool ValidateRequestDetail(TicketDetail updatedTicketDetail)
{
turnContext = turnContext ?? throw new ArgumentNullException(nameof(turnContext));
if (updatedTicketDetail == null || string.IsNullOrWhiteSpace(updatedTicketDetail.Title) || string.IsNullOrWhiteSpace(updatedTicketDetail.Description) ||
updatedTicketDetail.IssueOccurredOn == null || (DateTimeOffset.Compare(updatedTicketDetail.IssueOccurredOn, DateTime.Today) > 0 || string.IsNullOrEmpty(updatedTicketDetail.IssueOccurredOn.ToString(CultureInfo.InvariantCulture))))
{
return false;
}
else if (existingTicketDetail != null && DateTimeOffset.Compare(existingTicketDetail.IssueOccurredOn, ConvertToDateTimeoffset(updatedTicketDetail.IssueOccurredOn, turnContext.Activity.LocalTimestamp.Value.Offset)) < 0)
{
return false;
}

return true;
return updatedTicketDetail != null
&& !string.IsNullOrWhiteSpace(updatedTicketDetail.Title)
&& !string.IsNullOrWhiteSpace(updatedTicketDetail.Description);
}

/// <summary>
Expand Down Expand Up @@ -134,4 +122,4 @@ public static DateTimeOffset ConvertToDateTimeoffset(DateTimeOffset datetime, Ti
}
}
}
}
}

0 comments on commit ae9b772

Please sign in to comment.