Visual Studio templating - conditionally hide parameter - visual-studio

I am attempting to create a custom Visual Studio project template and I have a template.json. What I am trying to achieve is to hide / disable the DoStuff parameter from the Visual Studio create project wizard if another parameter (in my case, ProjectType) was equal to something specific. It would essentially be something like the Docker OS parameter from the default Visual Studio API template.
As you can see, by default the dropdown (in my case, it would be a checkbox) is hidden / disabled, but if I check Enable Docker, it can be selected.
Below is my current template.json file which I can't seem to get right to have this feature.
{
"$schema": "http://json.schemastore.org/template",
"symbols": {
"ProjectType": {
"type": "parameter",
"datatype": "choice",
"choices": [
{
"choice": "Console"
},
{
"choice": "API"
}
],
"defaultValue": "API",
"description": "The type of the project you are building."
},
"DoStuff": {
"type": "parameter",
"datatype": "bool",
"defaultValue": "false",
// hide if ProjectType == API
}
}
}
I tried to combine it with ide.host.json to achieve this, but it's not working at all.
{
"$schema": "https://json.schemastore.org/ide.host.json",
"defaultSymbolVisibility": true,
"order": 2,
"icon": "icon.png",
"symbolInfo": [
{
"id": "DoStuff",
"isVisible": "(ProjectType == \"API\")"
}
]
}

After some more investigation and contacting Sayed Ibrahim Hashimi (sayedihashimi) on Twitter, it turns out this is currently not supported and there's likely no way to achieve it right now in .NET 6 and prior releases.
However, as per Chet Husk's (#ChetHusk) template engine upgrades comment (which redirects you to Github:dotnet/templating/docs/Conditions.md), templating conditions will be a feature added to .NET 7. The dotnet new cli already supports it, but the Visual Studio support has not yet been started on.

Related

How to use "Go to action" in the MS Bot Composer?

Trying to manage a conversation flow by "Go to action" action (sorry for tautology). All tests to call all types of actions by ID from *.dialog return error.
ClassName:"System.ArgumentException" Message:"GotoAction: could not find an action of "cW0raQ"."
How reference looks
I didn't find any mention in the documentation how to work with this action, therefore it must be pretty simple, but I can't catch the correct way.
As usually, answer myself.
Had a look at MS tests in their repo https://github.com/microsoft/botbuilder-dotnet/ and found out that it requires creating ID for action manually. Automatic $designer.id doesn't work.
{
"$kind": "Microsoft.GotoAction",
"$designer": {
"id": "uFOn5P"
},
"actionId": "targetID"
},
...
{
"id": "targetID",
"$kind": "Microsoft.SendActivity",
"$designer": {
"id": "oWxpDh",
"comment": "",
"name": "GoTo test"
},
"activity": "${SendActivity_oWxpDh()}"
}
Moreover, this action works in scope of trigger only, not dialog.

How to get team id when the bot is installed in personal scope(MS Teams)?

I have a use case where I need to show following information in my personal application.
List of channels in teams where bot is installed.
List of users in teams where bot is installed.
I was exploring connector client for the same and came up with following code:-
const credentials = new MicrosoftAppCredentials(appId, appPassword);
const connectorClient = new ConnectorClient(credentials, {
baseUri: serviceUrl
});
const token = await credentials.getToken();
axios.defaults.headers.common.Authorization = `Bearer ${ token }`;
# To get channels
const response = await axios.get(
'https://smba.trafficmanager.net/in/v3/teams/{teamId}/conversations'
);
# To get members
const users = await connectorClient.conversations.getConversationPagedMembers(teamId);
This works perfect as long as I have the teamId.
But the issue I am facing here is with respect to finding teamId in personal scope. I install my bot application as follows by choosing the Add option.
As far as I understand, the above installs the bot in the personal scope of the user. Now, in this scenario the team id information is not present in conversationUpdate event at all. Please note that this is the first time I am installing the bot in the team, so the data should be available as per Microsoft documentation, but the only information available in channel object is tenant.
{
"membersAdded": [
{
"id": "28:f5d48856-5b42-41a0-8c3a-c5f944b679b0"
}
],
"type": "conversationUpdate",
"timestamp": "2017-02-23T19:38:35.312Z",
"localTimestamp": "2017-02-23T12:38:35.312-07:00",
"id": "f:5f85c2ad",
"channelId": "msteams",
"serviceUrl": "https://smba.trafficmanager.net/amer-client-ss.msg/",
"from": {
"id": "29:1I9Is_Sx0OIy2rQ7Xz1lcaPKlO9eqmBRTBuW6XzkFtcjqxTjPaCMij8BVMdBcL9L_RwWNJyAHFQb0TRzXgyQvA"
},
"conversation": {
"isGroup": true,
"conversationType": "channel",
"id": "19:efa9296d959346209fea44151c742e73#thread.skype"
},
"recipient": {
"id": "28:f5d48856-5b42-41a0-8c3a-c5f944b679b0",
"name": "SongsuggesterBot"
},
"channelData": {
// for me this object is empty
"team": {
"id": "19:efa9296d959346209fea44151c742e73#thread.skype"
},
"eventType": "teamMemberAdded",
"tenant": {
"id": "72f988bf-86f1-41af-91ab-2d7cd011db47"
}
}
}
Next, I also tried to install the bot in the team scope by using Add To Teams option. In this case it prompts me to select a channel to install, in which I choose general.
Now, I do get the team object inside channelData in onConversationUpdate and this flow works perfectly fine.
{
"membersAdded": [
{
"id": "28:64564f44-dd7c-441a-b427-efcd662f21b5"
}
],
"type": "conversationUpdate",
"timestamp": "2021-10-14T13:22:01.6072361Z",
"id": "f:4ebc9a41-5140-7621-33f5-31d97275ce00",
"channelId": "msteams",
"serviceUrl": "https://smba.trafficmanager.net/in/",
"from": {
"id": "29:17ZGff4Pvqz_zSNqEexg-86uBFcB6vnOBZzCwu4_puGdDsrYWCW_DdlB15PrcjC--nLlqD5CwtLMJyzXPY5OSsg",
"aadObjectId": "eac26e98-104a-4785-87aa-bcf77ea1d7c1"
},
"conversation": {
"isGroup": true,
"conversationType": "channel",
"tenantId": "c8fef0de-e240-4456-b523-3285ecc62087",
"id": "19:y7qDBfGH2jE_Ze6G8mJS_CiWiqCaRFfH77jFZvJ1xgU1#thread.tacv2"
},
"recipient": {
"id": "28:64564f44-dd7c-441a-b427-efcd662f21b5",
"name": "Trick"
},
"channelData": {
"team": {
"aadGroupId": "5bc77aa9-9487-49ae-958f-b37b2191e64d",
"name": "test 5",
"id": "19:y7qDBfGH2jE_Ze6G8mJS_CiWiqCaRFfH77jFZvJ1xgU1#thread.tacv2"
},
"eventType": "teamMemberAdded",
"tenant": {
"id": "c8fef0de-e240-4456-b523-3285ecc62087"
}
}
}
So what I am trying to understand here is that, why is the information not coming in case the bot is installed in personal scope?
I am asking this mainly because without personal scope added for bot(i.e if I keep scope only as team), the application does not show for user, inside Apps. But if I allow the scope to be extended to personal the user might select that while installing the application and my teamId information will not be available to fetch the data, that I need.
This brings to my next question, which is, is there any way in which the default add button on the add app screen installs the bot in such a way that I get team object inside channelData, in conversationUpdate in every scenario, i.e whether I choose add or add to team?
Is this how it is supposed to behave or am I missing something. Would love to hear some thoughts on this. Thanks in advance.
It might be that you're over thinking this - here's a more simple view:
if you install a bot into a Team, you'll get a Team Id (and any related channel where it is installed).
if you have "personal" scope set up for the bot, then the user also has the option to install the bot into "personal" scope. As this implies, they are NOT installing the bot INTO an actual Team - that's why you're not receiving a Team Id. It's not broken - it's entirely correct.
If you don't WANT your bot to be able to be installed in personal scope, simply remove that option in your manifest (the "personal" scope) - you have the ability to choose because it depends what you're wanting the user to be able to do with your bot. Some bots only make sense inside a Team, others only in Personal Scope, others only in Group Chat or in a Meeting - you can allow your bot to installed in any/all of these are relevant.

Why I can't save my connector on Microsoft Teams?

I made a custom connector for teams that display notifications on channels and add Tab on teams.
For the tab parts -> Everything is working well
But I have a problem for the connector parts, I get an error when I try to save my settings in the developer console:
Received error from connectors {"seq":1585127802210,"timestamp":1585127814174,"flightSettings":{"Name":"ConnectorFrontEndSettings","AriaSDKT....
-> registerOnSaveHandler is called
-> setSettings is correctly set with entityId, contentUrl (same configurationUrl as the connector configuration) and the configName.
getSettings -> is called to save to my app the webhook url -> it works
-> notifySuccess is then called and
I checked on the connector dashboard everything seems fine, on the App Studio everything is green also!
I don't know what is happening..
My manifest
{
"$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.5/MicrosoftTeams.schema.json",
"manifestVersion": "1.5",
"version": "1.0.0",
"id": "ca153ede-92f2-46e7-8695-3726b5343bf4",
"packageName": "com.kagilum.icescrum",
"developer": {
"name": "Kagilum SAS",
"websiteUrl": "https://www.icescrum.com",
"privacyUrl": "https://www.icescrum.com/privacy",
"termsOfUseUrl": "https://www.icescrum.com/termsofuser"
},
"icons": {
"color": "color.png",
"outline": "outline.png"
},
"name": {
"short": "iceScrum",
"full": "Connect with iceScrum"
},
"description": {
"short": "A true Agile project management tool",
"full": "iceScrum is a web application for using Scrum while keeping the spirit of a collaborative workspace. It also offers virtual boards with post-its for sprint backlog, product backlog and others."
},
"accentColor": "#FFFFFF",
"configurableTabs": [
{
"configurationUrl": "https://preview.icescrum.com/msTeams/setupTab/",
"canUpdateConfiguration": true,
"scopes": [
"team",
"groupchat"
],
"supportedSharePointHosts": [
"sharePointFullPage",
"sharePointWebPart"
]
}
],
"connectors": [
{
"connectorId": "f00d8890-daa8-4c87-89f5-83cbab0bccd4",
"configurationUrl": "https://preview.icescrum.com/msTeams/setup/",
"scopes": [
"team"
]
}
],
"permissions": [
"identity",
"messageTeamMembers"
],
"validDomains": [
"preview.icescrum.com"
]
}
Piece of code related to
microsoftTeams.settings.registerOnSaveHandler(function(saveEvent) {
microsoftTeams.settings.setSettings({
entityId: 'icescrum-pkey-' + $scope.settings.project.pkey,
contentUrl: isSettings.serverUrl + '/msTeams/setup/',
configName: $scope.settings.project.name
});
microsoftTeams.settings.getSettings(function(settings) {
$scope.settings.webhookUrl = settings.webhookUrl;
return FormService.httpPost('msTeams/save', $scope.settings, true).then(function() {
saveEvent.notifySuccess(); //wait that the settings are really saved on iceScrum side
});
});
});
microsoftTeams.settings.getSettings(function(settings) {
$scope.setup = !settings.configName;
var tokenData = JSON.parse(localStorage.getItem("msTeams-oauth"));
var userData = JSON.parse(localStorage.getItem("msTeams-user"));
if (tokenData) {
FormService.httpGet('ws/project/user/' + userData.id + '?light=true', {headers: {'Authorization': 'Bearer ' + tokenData['accessToken']}}, true).then(function(projects) {
$scope.projects = projects;
if (settings.entityId) {
$scope.settings.project = _.find($scope.projects, {pkey: settings.entityId.split('icescrum-pkey-')[1]});
}
$scope.ready = true;
});
}
});
Full error:
angular.min.js:113 2020-03-25T20:35:25.953Z Received error from connectors {"seq":1585168484680,"timestamp":1585168525943,"flightSettings":{"Name":"ConnectorFrontEndSettings","AriaSDKToken":"d127f72a3abd41c9b9dd94faca947689-d58285e6-3a68-4cab-a458-37b9d9761d35-7033","SPAEnabled":true,"ClassificationFilterEnabled":true,"ClientRoutingEnabled":true,"EnableYammerGroupOption":true,"EnableFadeMessage":false,"EnableDomainBasedOwaConnectorList":false,"EnableDomainBasedTeamsConnectorList":false,"DevPortalSPAEnabled":true,"ShowHomeNavigationButtonOnConfigurationPage":false,"DisableConnectToO365InlineDeleteFeedbackPage":true},"status":500,"clientType":"SkypeSpaces","connectorType":"f00d8890-daa8-4c87-89f5-83cbab0bccd4","name":"handleMessageError"}
In case this helps anyone else, I spent ages today trying to get to the bottom of this and couldn't find a solution. Until...as a last gasp show of desperation I decide to use App Studio to recreate the entire connector manifest from scratch, including creating a new connector in the portal.
For some reason, this then worked fine - even though I can see that the two manifest files are identical with the exception of the ID (and I already tried regenerating the ID for the original one).
Bit late to the story, but having followed multiple github issues like this and stack overflow posts, I'm pretty convinced that its the problem with Connectors dashboard. If you made any change to settings, they are not really propageted/saved correctly.
So for example, if you changed validDomains or configurationPage URL, they won't actually do anything. You can verify that with your devtools. For me, after changing the configurationPage the Teams is still making request to old URL as well as the new one, but the old request produces error that's listed in question.
The only workaround I was able to find is to recreate connector in dashboard. Reported problem to MS Teams dev team, waiting to hear back.
Also late here, but I ran into this problem and the below was the solution after 3 days of frustration.
Despite everything mentioned in the documentation, the following is required otherwise you'll get this error. This fixed things for me.
microsoftTeams.settings.registerOnSaveHandler(saveEvent => {
microsoftTeams.settings.setSettings({
contentUrl: "https://xxxxxx.ngrok.io/teams/connector"
});
saveEvent.notifySuccess();
});
The documentation states that registering a save handler is optional and Teams will handle notify success if it's not declared. WRONG. You must register a save handler.
The documentation does not state that setSettings is required. WRONG. You must set settings or else you will receive this error.
The documentation does not state that you must save a contentURL. WRONG. You must set content URL in the setSettings. You can apparently omit other things when setting your settings, but not content URL.
The documentation does not specifically mention it, but the contentURL must comply with your validURLs in your manifest. If it does not, you'll also see this error.
So in your case, you must ensure that isSettings.serverUrl (setSettings() contentURL) does match preview.icescrum.com (manifest validURLs). If they do not, you'll see this error.

How to Get Visual Studio to Publish an Application to Service Fabric Cluster Secured by Certificate Common Name Instead of Thumbprint?

I followed the steps documented here to convert my existing ARM template to use the commonname setting instead of thumbprint. The deployment was successful and I was able to connect to the Service Fabric Explorer using my browser after the typical certificate selection popup. Next, I tried to deploy an application to the cluster just like I had been previously. Even though I can see the cluster connection endpoint URI in the VS public service fabric application dialog, VS fails to connect to the cluster. Before, I would get a prompt to permit VS to access the local certificate. Does anyone know how to get VS to deploy an application to a service fabric cluster setup using the certificate common name?
Extracts from the MS link above:
"virtualMachineProfile": {
"extensionProfile": {
"extensions": [`enter code here`
{
"name": "[concat('ServiceFabricNodeVmExt','_vmNodeType0Name')]",
"properties": {
"type": "ServiceFabricNode",
"autoUpgradeMinorVersion": true,
"protectedSettings": {
"StorageAccountKey1": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('supportLogStorageAccountName')),'2015-05-01-preview').key1]",
"StorageAccountKey2": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('supportLogStorageAccountName')),'2015-05-01-preview').key2]"
},
"publisher": "Microsoft.Azure.ServiceFabric",
"settings": {
"clusterEndpoint": "[reference(parameters('clusterName')).clusterEndpoint]",
"nodeTypeRef": "[variables('vmNodeType0Name')]",
"dataPath": "D:\\SvcFab",
"durabilityLevel": "Bronze",
"enableParallelJobs": true,
"nicPrefixOverride": "[variables('subnet0Prefix')]",
"certificate": {
"commonNames": [
"[parameters('certificateCommonName')]"
],
"x509StoreName": "[parameters('certificateStoreValue')]"
}
},
"typeHandlerVersion": "1.0"
}
},
and
{
"apiVersion": "2018-02-01",
"type": "Microsoft.ServiceFabric/clusters",
"name": "[parameters('clusterName')]",
"location": "[parameters('clusterLocation')]",
"dependsOn": [
"[concat('Microsoft.Storage/storageAccounts/', variables('supportLogStorageAccountName'))]"
],
"properties": {
"addonFeatures": [
"DnsService",
"RepairManager"
],
"certificateCommonNames": {
"commonNames": [
{
"certificateCommonName": "[parameters('certificateCommonName')]",
"certificateIssuerThumbprint": ""
}
],
"x509StoreName": "[parameters('certificateStoreValue')]"
},
...
I found the solution for Visual Studio. I needed to add/update to the PublishProfiles/Cloud.xml file. I replaced ServerCertThumbprint with ServerCommonName, and then used the certificate CN for the new property and the existing FindValue property. Additionally, I changed the property for FindType to FindBySubjectName. I am now able to successfully connect and publish my application to the cluster.
<ClusterConnectionParameters
ConnectionEndpoint="sf-commonnametest-scus.southcentralus.cloudapp.azure.com:19000"
X509Credential="true"
ServerCommonName="sfrpe2eetest.southcentralus.cloudapp.azure.com"
FindType="FindBySubjectName"
FindValue="sfrpe2eetest.southcentralus.cloudapp.azure.com"
StoreLocation="CurrentUser"
StoreName="My" />

A way to colorize the #regions in VS Code C#

I'm trying to get as comfortable as possible with this new IDE (coming from Visual Studio Community for Windows).
I used a very specific color theme that allowed me to understand the parts of the code at a glance. With VS Code though, it's more complicated for me as there aren't many options in the:
Settings > editor.tokenColorCustomizations.
Is there a way to colorize the #region pre-processor directives with a specific color?
Thanks.
Yes, it seems it has a distinct scope name (keyword.preprocessor.region), allowing you to target it with the setting, as the Developer: Show TM Scopes command shows:
"editor.tokenColorCustomizations": {
"textMateRules": [
{
"scope": "keyword.preprocessor.region.cs",
"settings": {
"foreground": "#FF0000"
}
},
{
"scope": "keyword.preprocessor.endregion.cs",
"settings": {
"foreground": "#FF0000"
}
}
]
}
It seems the scope includes neither the # nor the string though:

Resources