diff --git a/Provision/assets/deploy.ps1 b/Provision/assets/deploy.ps1 index a157bd3..4cde1a7 100644 --- a/Provision/assets/deploy.ps1 +++ b/Provision/assets/deploy.ps1 @@ -14,9 +14,6 @@ .PARAMETER resourceGroupLocation Optional, a resource group location. If specified, will try to create a new resource group in this location. If not specified, assumes resource group is existing. - .PARAMETER deploymentName - The deployment name. - .PARAMETER templateFilePath Optional, path to the template file. Defaults to template.json. @@ -36,10 +33,6 @@ param( [string] $resourceGroupLocation, - [Parameter(Mandatory=$True)] - [string] - $deploymentName, - [string] $templateFilePath = "template.json", @@ -57,7 +50,7 @@ Function RegisterRP { ) Write-Host "Registering resource provider '$ResourceProviderNamespace'"; - Register-AzureRmResourceProvider -ProviderNamespace $ResourceProviderNamespace; + Register-AzResourceProvider -ProviderNamespace $ResourceProviderNamespace; } #****************************************************************************** @@ -68,11 +61,11 @@ $ErrorActionPreference = "Stop" # sign in Write-Host "Logging in..."; -Login-AzureRmAccount; +Login-AzAccount; # select subscription Write-Host "Selecting subscription '$subscriptionId'"; -Select-AzureRmSubscription -SubscriptionID $subscriptionId; +Select-AzSubscription -SubscriptionID $subscriptionId; # Register RPs $resourceProviders = @("microsoft.cognitiveservices","microsoft.documentdb","microsoft.insights","microsoft.storage","microsoft.web"); @@ -84,7 +77,7 @@ if($resourceProviders.length) { } #Create or check for existing resource group -$resourceGroup = Get-AzureRmResourceGroup -Name $resourceGroupName -ErrorAction SilentlyContinue +$resourceGroup = Get-AzResourceGroup -Name $resourceGroupName -ErrorAction SilentlyContinue if(!$resourceGroup) { Write-Host "Resource group '$resourceGroupName' does not exist. To create a new resource group, please enter a location."; @@ -92,7 +85,7 @@ if(!$resourceGroup) $resourceGroupLocation = Read-Host "resourceGroupLocation"; } Write-Host "Creating resource group '$resourceGroupName' in location '$resourceGroupLocation'"; - New-AzureRmResourceGroup -Name $resourceGroupName -Location $resourceGroupLocation + New-AzResourceGroup -Name $resourceGroupName -Location $resourceGroupLocation } else{ Write-Host "Using existing resource group '$resourceGroupName'"; @@ -101,7 +94,7 @@ else{ # Start the deployment Write-Host "Starting deployment..."; if(Test-Path $parametersFilePath) { - New-AzureRmResourceGroupDeployment -ResourceGroupName $resourceGroupName -TemplateFile $templateFilePath -TemplateParameterFile $parametersFilePath; + New-AzResourceGroupDeployment -ResourceGroupName $resourceGroupName -TemplateFile $templateFilePath -TemplateParameterFile $parametersFilePath; } else { - New-AzureRmResourceGroupDeployment -ResourceGroupName $resourceGroupName -TemplateFile $templateFilePath; + New-AzResourceGroupDeployment -ResourceGroupName $resourceGroupName -TemplateFile $templateFilePath; } \ No newline at end of file diff --git a/Provision/assets/template.json b/Provision/assets/template.json index 8036dd6..b87b60f 100644 --- a/Provision/assets/template.json +++ b/Provision/assets/template.json @@ -1,373 +1,370 @@ { - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "unique_name": { - "type": "string" - } + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "unique_name": { + "type": "string" + } + }, + "variables": { + "WebSiteName": "[concat(parameters('unique_name'),'site')]", + "DocumentDBName": "[concat(parameters('unique_name'),'docdb')]", + "StorageAccountName": "[concat(parameters('unique_name'),'stor')]", + "AppInsightsInstanceName": "[concat(parameters('unique_name'),'insights')]" + }, + "resources": [ + { + "type": "Microsoft.CognitiveServices/accounts", + "sku": { + "name": "F0" + }, + "kind": "ComputerVision", + "name": "[concat(parameters('unique_name'),'computervision')]", + "apiVersion": "2017-04-18", + "location": "[resourceGroup().location]", + "properties": {}, + "dependsOn": [] }, - "variables": { - "WebSiteName": "[concat(parameters('unique_name'),'site')]", - "DocumentDBName": "[concat(parameters('unique_name'),'docdb')]", - "StorageAccountName": "[concat(parameters('unique_name'),'stor')]", - "AppInsightsInstanceName": "[concat(parameters('unique_name'),'insights')]" + { + "type": "Microsoft.CognitiveServices/accounts", + "sku": { + "name": "F0" + }, + "kind": "ContentModerator", + "name": "[concat(parameters('unique_name'),'contentmoderator')]", + "apiVersion": "2017-04-18", + "location": "[resourceGroup().location]", + "properties": {}, + "dependsOn": [] }, - "resources": [ - { - "type": "Microsoft.CognitiveServices/accounts", - "sku": { - "name": "S1" - }, - "kind": "ComputerVision", - "name": "[concat(parameters('unique_name'),'computervision')]", - "apiVersion": "2016-02-01-preview", - "location": "westus", - "properties": {}, - "dependsOn": [] - }, - { - "type": "Microsoft.CognitiveServices/accounts", - "sku": { - "name": "S0" - }, - "kind": "ContentModerator", - "name": "[concat(parameters('unique_name'),'contentmoderator')]", - "apiVersion": "2016-02-01-preview", - "location": "westus", - "properties": {}, - "dependsOn": [] + { + "type": "Microsoft.DocumentDB/databaseAccounts", + "kind": "GlobalDocumentDB", + "name": "[variables('DocumentDBName')]", + "apiVersion": "2019-08-01", + "location": "[resourceGroup().location]", + "tags": {}, + "properties": { + "databaseAccountOfferType": "Standard", + "consistencyPolicy": { + "defaultConsistencyLevel": "Session", + "maxIntervalInSeconds": 5, + "maxStalenessPrefix": 100 }, + "name": "[concat(parameters('unique_name'),'docdb')]" + }, + "dependsOn": [] + }, + { + "type": "Microsoft.Storage/storageAccounts", + "sku": { + "name": "Standard_LRS", + "tier": "Standard" + }, + "kind": "StorageV2", + "name": "[variables('StorageAccountName')]", + "apiVersion": "2018-07-01", + "location": "[resourceGroup().location]", + "tags": {}, + "properties": {}, + "dependsOn": [] + }, + { + "type": "Microsoft.Web/serverfarms", + "sku": { + "name": "S1", + "tier": "Standard" + }, + "kind": "app", + "name": "[concat(parameters('unique_name'),'farm')]", + "apiVersion": "2018-02-01", + "location": "[resourceGroup().location]", + "properties": { + "numberOfWorkers": 1 + }, + "dependsOn": [] + }, + { + "type": "microsoft.insights/components", + "kind": "other", + "name": "[variables('AppInsightsInstanceName')]", + "apiVersion": "2014-04-01", + "location": "[resourceGroup().location]", + "properties": { + "ApplicationId": "[variables('AppInsightsInstanceName')]" + }, + "dependsOn": [] + }, + { + "type": "Microsoft.Web/sites", + "kind": "app", + "name": "[variables('WebSiteName')]", + "apiVersion": "2015-08-01", + "location": "[resourceGroup().location]", + "properties": { + "name": "[concat(parameters('unique_name'),'site')]", + "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', concat(parameters('unique_name'),'farm'))]" + }, + "dependsOn": [ + "[resourceId('Microsoft.Web/serverfarms', concat(parameters('unique_name'),'farm'))]", + "[resourceId('Microsoft.Storage/storageAccounts', concat(parameters('unique_name'),'stor'))]", + "[resourceId('Microsoft.DocumentDB/databaseAccounts', variables('DocumentDBName'))]" + ], + "resources": [ { - "type": "Microsoft.DocumentDB/databaseAccounts", - "kind": "GlobalDocumentDB", - "name": "[variables('DocumentDBName')]", - "apiVersion": "2015-04-08", - "location": "West US", - "tags": {}, - "properties": { - "databaseAccountOfferType": "Standard", - "consistencyPolicy": { - "defaultConsistencyLevel": "Session", - "maxIntervalInSeconds": 5, - "maxStalenessPrefix": 100 + "name": "appsettings", + "type": "config", + "apiVersion": "2015-08-01", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites', variables('WebSiteName'))]" + ], + "properties": { + "documentDbEndpoint": "[reference(concat('Microsoft.DocumentDb/databaseAccounts/', variables('DocumentDBName'))).documentEndpoint]", + "documentDbKey": "[listKeys(resourceId('Microsoft.DocumentDb/databaseAccounts', variables('DocumentDBName')), '2015-04-08').primaryMasterKey]", + "documentDbName": "customerReviewData", + "documentDbColl": "reviews", + "storageAccountConnectionString": "[concat('DefaultEndpointsProtocol=https;AccountName=',variables('StorageAccountName'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('StorageAccountName')), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value)]", + "containerName": "input-images", + "queueName": "review-queue", + "APPINSIGHTS_INSTRUMENTATIONKEY": "[reference(resourceId('Microsoft.Insights/components', variables('AppInsightsInstanceName')), '2014-04-01').InstrumentationKey]" + } + } + ] + }, + { + "name": "ReviewsDashboard", + "type": "Microsoft.Portal/dashboards", + "location": "centralus", + "apiVersion": "2015-08-01-preview", + "tags": { + "hidden-title": "Reviews Insights" + }, + "properties": { + "lenses": { + "0": { + "order": 0, + "parts": { + "0": { + "position": { + "x": 0, + "y": 0, + "rowSpan": 4, + "colSpan": 6 }, - "name": "[concat(parameters('unique_name'),'docdb')]" - }, - "dependsOn": [] - }, - { - "type": "Microsoft.Storage/storageAccounts", - "sku": { - "name": "Standard_RAGRS", - "tier": "Standard" - }, - "kind": "Storage", - "name": "[variables('StorageAccountName')]", - "apiVersion": "2016-01-01", - "location": "westus", - "tags": {}, - "properties": {}, - "dependsOn": [] - }, - { - "type": "Microsoft.Web/serverfarms", - "sku": { - "name": "S1", - "tier": "Standard", - "size": "S1", - "family": "S", - "capacity": 1 - }, - "kind": "app", - "name": "[concat(parameters('unique_name'),'farm')]", - "apiVersion": "2015-08-01", - "location": "West US", - "properties": { - "name": "[concat(parameters('unique_name'),'farm')]", - "numberOfWorkers": 1 - }, - "dependsOn": [] - }, - { - "type": "microsoft.insights/components", - "kind": "other", - "name": "[variables('AppInsightsInstanceName')]", - "apiVersion": "2014-04-01", - "location": "southcentralus", - "properties": { - "ApplicationId": "[variables('AppInsightsInstanceName')]" - }, - "dependsOn": [] - }, - { - "type": "Microsoft.Web/sites", - "kind": "app", - "name": "[concat(parameters('unique_name'),'site')]", - "apiVersion": "2015-08-01", - "location": "West US", - "properties": { - "name": "[concat(parameters('unique_name'),'site')]", - "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', concat(parameters('unique_name'),'farm'))]" - }, - "dependsOn": [ - "[resourceId('Microsoft.Web/serverfarms', concat(parameters('unique_name'),'farm'))]", - "[resourceId('Microsoft.Storage/storageAccounts', concat(parameters('unique_name'),'stor'))]", - "[resourceId('Microsoft.DocumentDB/databaseAccounts', variables('DocumentDBName'))]" - ], - "resources": [ - { - "name": "appsettings", - "type": "config", - "apiVersion": "2015-08-01", - "dependsOn": [ - "[resourceId('Microsoft.Web/sites', variables('WebSiteName'))]" - ], - "properties": { - "documentDbEndpoint": "[reference(concat('Microsoft.DocumentDb/databaseAccounts/', variables('DocumentDBName'))).documentEndpoint]", - "documentDbKey": "[listKeys(resourceId('Microsoft.DocumentDb/databaseAccounts', variables('DocumentDBName')), '2015-04-08').primaryMasterKey]", - "documentDbName": "customerReviewData", - "documentDbColl": "reviews","storageAccountConnectionString": "[concat('DefaultEndpointsProtocol=https;AccountName=',variables('StorageAccountName'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('StorageAccountName')), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value)]", - "containerName": "input-images", - "queueName": "review-queue", - "iKey": "[reference(resourceId('Microsoft.Insights/components', variables('AppInsightsInstanceName')), '2014-04-01').InstrumentationKey]" - } - } - ] - }, - { - "name": "ReviewsDashboard", - "type": "Microsoft.Portal/dashboards", - "location": "centralus", - "apiVersion": "2015-08-01-preview", - "tags": { - "hidden-title": "Reviews Insights" - }, - "properties": { - "lenses": { - "0": { - "order": 0, - "parts": { - "0": { - "position": { - "x": 0, - "y": 0, - "rowSpan": 4, - "colSpan": 6 - }, - "metadata": { - "inputs": [ - { - "name": "ComponentId", - "value": { - "SubscriptionId": "[subscription().subscriptionId]", - "ResourceGroup": "[resourceGroup().name]", - "Name": "[variables('AppInsightsInstanceName')]" - } - }, - { - "name": "Query", - "value": "set truncationmaxrecords= 1000;\ncustomMetrics\n| project name, value\n| extend ModerationResult =\n iff (name == \"ModerationResult\" and value == 0, \"Passed\",\n iff (name == \"ModerationResult\" and value == 1, \"Failed text\",\n iff (name == \"ModerationResult\" and value == 2, \"Failed image\",\n iff (name == \"ModerationResult\" and value == 3, \"Failed text and image\", \"Unknown\"))))\n| where ModerationResult != \"Unknown\"\n| summarize count() by ModerationResult\n| render columnchart\n| project ModerationResult, count_\n| order by ModerationResult desc" - }, - { - "name": "TimeRange", - "value": "P7D" - }, - { - "name": "Dimensions", - "value": { - "xAxis": { - "name": "ModerationResult", - "type": "String" - }, - "yAxis": [ - { - "name": "count_", - "type": "Int64" - } - ], - "splitBy": [], - "aggregation": "Sum" - } - }, - { - "name": "Version", - "value": "1.0" - }, - { - "name": "DashboardId", - "value": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Portal/dashboards/ReviewsDashboard')]" - }, - { - "name": "PartId", - "value": "a71f7336-8ac0-4c3b-90b5-e3af23306482" - }, - { - "name": "PartTitle", - "value": "Analytics" - }, - { - "name": "PartSubTitle", - "value": "Reviews" - }, - { - "name": "resourceTypeMode", - "value": "components" - } - ], - "type": "Extension/AppInsightsExtension/PartType/AnalyticsDonutPart", - "settings": {}, - "asset": { - "idInputName": "ComponentId", - "type": "ApplicationInsights" - } - } + "metadata": { + "inputs": [ + { + "name": "ComponentId", + "value": { + "SubscriptionId": "[subscription().subscriptionId]", + "ResourceGroup": "[resourceGroup().name]", + "Name": "[variables('AppInsightsInstanceName')]" + } }, - "1": { - "position": { - "x": 6, - "y": 0, - "rowSpan": 4, - "colSpan": 6 - }, - "metadata": { - "inputs": [ - { - "name": "ComponentId", - "value": { - "SubscriptionId": "[subscription().subscriptionId]", - "ResourceGroup": "[resourceGroup().name]", - "Name": "[variables('AppInsightsInstanceName')]" - } - }, - { - "name": "MetricsExplorerJsonDefinitionId", - "value": "InsightsTimelineMetrics" - }, - { - "name": "TimeContext", - "value": { - "durationMs": 86400000, - "endTime": null, - "createdTime": "2017-04-26T20:55:14.198Z", - "isInitialTime": true, - "grain": 1, - "useDashboardTimeRange": false - } - }, - { - "name": "Version", - "value": "1.0" - } - ], - "type": "Extension/AppInsightsExtension/Blade/GeneralAppOverview/Lens/ApplicationHealthLens/PartInstance/InsightsTimeline_MetricsExplorerPartReferenceOveriew", - "asset": { - "idInputName": "ComponentId", - "type": "ApplicationInsights" - } - } + { + "name": "Query", + "value": "set truncationmaxrecords= 1000;\ncustomMetrics\n| project name, value\n| extend ModerationResult =\n iff (name == \"ModerationResult\" and value == 0, \"Passed\",\n iff (name == \"ModerationResult\" and value == 1, \"Failed text\",\n iff (name == \"ModerationResult\" and value == 2, \"Failed image\",\n iff (name == \"ModerationResult\" and value == 3, \"Failed text and image\", \"Unknown\"))))\n| where ModerationResult != \"Unknown\"\n| summarize count() by ModerationResult\n| render columnchart\n| project ModerationResult, count_\n| order by ModerationResult desc" }, - "2": { - "position": { - "x": 12, - "y": 0, - "rowSpan": 4, - "colSpan": 2 - }, - "metadata": { - "inputs": [ - { - "name": "resourceGroup", - "value": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', resourceGroup().name)]" - } - ], - "type": "Extension/HubsExtension/PartType/ResourceGroupMapPinnedPart", - "viewState": { - "content": { - "selectableData": {} - } - }, - "asset": { - "idInputName": "resourceGroup", - "type": "ResourceGroups" - }, - "defaultMenuItemId": "overview" - } + { + "name": "TimeRange", + "value": "P7D" }, - "3": { - "position": { - "x": 0, - "y": 4, - "rowSpan": 5, - "colSpan": 14 + { + "name": "Dimensions", + "value": { + "xAxis": { + "name": "ModerationResult", + "type": "String" }, - "metadata": { - "inputs": [ - { - "name": "ComponentId", - "value": { - "SubscriptionId": "[subscription().subscriptionId]", - "ResourceGroup": "[resourceGroup().name]", - "Name": "[variables('AppInsightsInstanceName')]" - } - }, - { - "name": "DashboardTimeRange", - "binding": "timeRange", - "isOptional": true - }, - { - "name": "DataModel", - "isOptional": true - }, - { - "name": "TimeContext", - "value": { - "durationMs": 86400000, - "endTime": null, - "createdTime": "2017-04-26T20:23:45.99Z", - "isInitialTime": true, - "grain": 1, - "useDashboardTimeRange": false - }, - "isOptional": true - }, - { - "name": "ConfigurationId", - "value": "34f36974-2e50-41c2-8add-c97de8ae1129", - "isOptional": true - } + "yAxis": [ + { + "name": "count_", + "type": "Int64" + } ], - "type": "Extension/AppInsightsExtension/PartType/TopologyV2AdaptedPart", - "settings": { - "content": { - "DataModelJSON": "{\"sortMetric\":\"Telemetry count\",\"sortOrder\":2,\"filters\":[],\"warningThreshold\":5,\"criticalThreshold\":20,\"nodeConfigurations\":[],\"timeContext\":{\"durationMs\":604800000,\"endTime\":null,\"createdTime\":\"2017-04-27T17:20:44.864Z\",\"isInitialTime\":false,\"grain\":1,\"useDashboardTimeRange\":false},\"userSelectedActiveOnlySetting\":true,\"hasActiveNodes\":false,\"hasNotConfiguredNodes\":false,\"showActiveNodesOnly\":true}" - } - }, - "isAdapter": true, - "asset": { - "idInputName": "ComponentId", - "type": "ApplicationInsights" - }, - "defaultMenuItemId": "applicationMap" - } + "splitBy": [], + "aggregation": "Sum" + } + }, + { + "name": "Version", + "value": "1.0" + }, + { + "name": "DashboardId", + "value": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Portal/dashboards/ReviewsDashboard')]" + }, + { + "name": "PartId", + "value": "a71f7336-8ac0-4c3b-90b5-e3af23306482" + }, + { + "name": "PartTitle", + "value": "Analytics" + }, + { + "name": "PartSubTitle", + "value": "Reviews" + }, + { + "name": "resourceTypeMode", + "value": "components" } + ], + "type": "Extension/AppInsightsExtension/PartType/AnalyticsDonutPart", + "settings": {}, + "asset": { + "idInputName": "ComponentId", + "type": "ApplicationInsights" + } + } + }, + "1": { + "position": { + "x": 6, + "y": 0, + "rowSpan": 4, + "colSpan": 6 + }, + "metadata": { + "inputs": [ + { + "name": "ComponentId", + "value": { + "SubscriptionId": "[subscription().subscriptionId]", + "ResourceGroup": "[resourceGroup().name]", + "Name": "[variables('AppInsightsInstanceName')]" + } + }, + { + "name": "MetricsExplorerJsonDefinitionId", + "value": "InsightsTimelineMetrics" + }, + { + "name": "TimeContext", + "value": { + "durationMs": 86400000, + "endTime": null, + "createdTime": "2017-04-26T20:55:14.198Z", + "isInitialTime": true, + "grain": 1, + "useDashboardTimeRange": false + } + }, + { + "name": "Version", + "value": "1.0" } + ], + "type": "Extension/AppInsightsExtension/Blade/GeneralAppOverview/Lens/ApplicationHealthLens/PartInstance/InsightsTimeline_MetricsExplorerPartReferenceOveriew", + "asset": { + "idInputName": "ComponentId", + "type": "ApplicationInsights" + } } + }, + "2": { + "position": { + "x": 12, + "y": 0, + "rowSpan": 4, + "colSpan": 2 }, "metadata": { - "model": { - "timeRange": { - "value": { - "relative": { - "duration": 24, - "timeUnit": 1 - } - }, - "type": "MsPortalFx.Composition.Configuration.ValueTypes.TimeRange" - } + "inputs": [ + { + "name": "resourceGroup", + "value": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', resourceGroup().name)]" + } + ], + "type": "Extension/HubsExtension/PartType/ResourceGroupMapPinnedPart", + "viewState": { + "content": { + "selectableData": {} + } + }, + "asset": { + "idInputName": "resourceGroup", + "type": "ResourceGroups" + }, + "defaultMenuItemId": "overview" + } + }, + "3": { + "position": { + "x": 0, + "y": 4, + "rowSpan": 5, + "colSpan": 14 + }, + "metadata": { + "inputs": [ + { + "name": "ComponentId", + "value": { + "SubscriptionId": "[subscription().subscriptionId]", + "ResourceGroup": "[resourceGroup().name]", + "Name": "[variables('AppInsightsInstanceName')]" + } + }, + { + "name": "DashboardTimeRange", + "binding": "timeRange", + "isOptional": true + }, + { + "name": "DataModel", + "isOptional": true + }, + { + "name": "TimeContext", + "value": { + "durationMs": 86400000, + "endTime": null, + "createdTime": "2017-04-26T20:23:45.99Z", + "isInitialTime": true, + "grain": 1, + "useDashboardTimeRange": false + }, + "isOptional": true + }, + { + "name": "ConfigurationId", + "value": "34f36974-2e50-41c2-8add-c97de8ae1129", + "isOptional": true + } + ], + "type": "Extension/AppInsightsExtension/PartType/TopologyV2AdaptedPart", + "settings": { + "content": { + "DataModelJSON": "{\"sortMetric\":\"Telemetry count\",\"sortOrder\":2,\"filters\":[],\"warningThreshold\":5,\"criticalThreshold\":20,\"nodeConfigurations\":[],\"timeContext\":{\"durationMs\":604800000,\"endTime\":null,\"createdTime\":\"2017-04-27T17:20:44.864Z\",\"isInitialTime\":false,\"grain\":1,\"useDashboardTimeRange\":false},\"userSelectedActiveOnlySetting\":true,\"hasActiveNodes\":false,\"hasNotConfiguredNodes\":false,\"showActiveNodesOnly\":true}" } + }, + "isAdapter": true, + "asset": { + "idInputName": "ComponentId", + "type": "ApplicationInsights" + }, + "defaultMenuItemId": "applicationMap" + } + } + } + } + }, + "metadata": { + "model": { + "timeRange": { + "value": { + "relative": { + "duration": 24, + "timeUnit": 1 } + }, + "type": "MsPortalFx.Composition.Configuration.ValueTypes.TimeRange" } + } } - ] + } + } + ] } \ No newline at end of file diff --git a/SETUP.md b/SETUP.md index 2f97dff..fb1278a 100644 --- a/SETUP.md +++ b/SETUP.md @@ -3,31 +3,33 @@ SAMPLE SETUP - Azure Functions tools for Visual Studio 2017 This covers the pre-requisites and set up for the Azure Functions tools for Visual Studio 2017 sample. ## Setup ## -Below are set up instructions for your computer, Azure, and Visual Studio Team Services. +Below are set up instructions for your computer, Azure, and Azure DevOps. ## Machine Pre-requisites ## Install the following on your machine: -- [Visual Studio 2017 Enterprise Update 3 Preview](https://www.visualstudio.com/vs/preview/) (Enterprise is used for the Live Unit Tests) with the following selected: +- [Visual Studio Enterprise 2017 Update 3 or 2019](https://visualstudio.microsoft.com/downloads) (Enterprise is used for the Live Unit Tests) with the following selected: - ASP.NET and Web development - Azure development - .NET Core cross-platform development -- [Latest Azure Functions tools for Visual Studio 2017](https://marketplace.visualstudio.com/vsgallery/e3705d94-7cc3-4b79-ba7b-f43f30774d28). When you first use this it will also install the Azure Functions CLI tools. -- [Microsoft .NET Framework 4.6.2 Developer Pack](http://getdotnet.azurewebsites.net/target-dotnet-platforms.html) -- [Azure PowerShell](https://azure.microsoft.com/en-us/downloads/) or the [Azure CLI 2.0](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli) (for the ARM template deployment) +- [Azure PowerShell](https://docs.microsoft.com/en-us/powershell/azure/install-az-ps) or the [Azure CLI 2.0](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli) (for the ARM template deployment) - [Git tools for Windows](https://git-scm.com/download/win) + +Only for Visual Studio 2017: + +- [Latest Azure Functions tools for Visual Studio 2017](https://marketplace.visualstudio.com/vsgallery/e3705d94-7cc3-4b79-ba7b-f43f30774d28). When you first use this it will also install the Azure Functions CLI tools. - Optional: [Continuous Delivery Tools for Visual Studio](https://marketplace.visualstudio.com/items?itemName=VSIDEDevOpsMSFT.ContinuousDeliveryToolsforVisualStudio) --- Notes: -- You can still use the sample with other editions of `Visual Studio 2017 Update 3 Preview` (like Community), but Live Unit Tests feature won't be available. -- `Continuous Delivery Tools for Visual Studio` is needed to show the status of automated builds for your function, and is optional if you won't set up Visual Studio Team Services. +- You can still use the sample with other editions of `Visual Studio' (like Community), but Live Unit Tests feature won't be available. +- `Continuous Delivery Tools for Visual Studio` is needed to show the status of automated builds for your function, and is optional if you won't set up Azure DevOps. --- ## Fork the Repo and Clone it ## - Fork this repo to your own GitHub account -- Clone your fork to a folder of your preferenceon your machine. Or, if you downloded a zip file of the sample, expand the zip file to your preferred folder. +- Clone your fork to a folder of your preference on your machine. Or, if you downloded a zip file of the sample, expand the zip file to your preferred folder. - Windows may block Powershell and Batch script execution if the OS determines the scripts originated from an untrusted source. To bypass this, run ``Get-ChildItem -Recurse -Path 'c:\Code' | Unblock-File`` (*replacing the path value with your target code root*). - In order to run non-digitally signed Powershell scripts you will need to run ``Set-ExecutionPolicy -ExecutionPolicy Unrestricted``. @@ -81,7 +83,7 @@ Note: ## Deploy the Website Code ## Now let's deploy the Reviews site code to the Web App: -- Open Visual Studio 2017 Update 3 +- Open Visual Studio - Open the ``CatsReviewApp.sln`` solution from the ``\Source\CatsReviewApp`` folder - Right click and build the web app in Visual Studio to ensure it is building working correctly - Right click the ``CatReviewsApp `` project and select ``Publish``. Follow the publish web app wizard to publish to an **existing App Service**, then choose the web app in the Reviews resource group in your Azure Subscription. @@ -89,12 +91,12 @@ Now let's deploy the Reviews site code to the Web App: ![](Media/Setup4.png) -## Optional: Visual Studio Team Services ## +## Optional: Azure DevOps ## -You can also create a VSTS build definition to trigger from a code commit. To get it set up, follow these instructions: -- Use an existing VSTS account or [create a new one](https://www.visualstudio.com/en-us/docs/setup-admin/team-services/sign-up-for-visual-studio-team-services) +You can also create an Azure DevOps build definition to trigger from a code commit. To get it set up, follow these instructions: +- Use an existing Azure DevOps account or [create a new one](https://docs.microsoft.com/fr-fr/azure/devops/organizations/accounts/create-organization) - [Make sure you have Colin's ALM Corner Build & Release Tools installed on your VSTS account](https://marketplace.visualstudio.com/items?itemName=colinsalmcorner.colinsalmcorner-buildtasks) -- [Create a Personal Access Token (PAT)](https://www.visualstudio.com/en-us/docs/setup-admin/team-services/use-personal-access-tokens-to-authenticate) and save the value. +- [Create a Personal Access Token (PAT)](https://docs.microsoft.com/fr-fr/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate) and save the value. - Create a new Build Definition as documented in [this blog post](https://blogs.msdn.microsoft.com/appserviceteam/2017/06/01/deploying-visual-studio-2017-function-projects-with-vsts/) using your GitHub fork as the source - Create the following variables for your new build definitions: - AzureWebJobsStorage @@ -147,6 +149,6 @@ You can also create a VSTS build definition to trigger from a code commit. To ge If you want to clean up the sample: - Delete the 'Reviews' resource group from your Azure subscription -- Delete the 'Reviews' project from your Visual Studio Team Services account +- Delete the 'Reviews' project from your Azure DevOps account - Delete the folder on your machine where you cloned the repo(s) - Delete the fork of the code from your GitHub account \ No newline at end of file diff --git a/Source/CatsReviewApp/CatsReviewApp.sln b/Source/CatsReviewApp/CatsReviewApp.sln index 38b0148..beef205 100644 --- a/Source/CatsReviewApp/CatsReviewApp.sln +++ b/Source/CatsReviewApp/CatsReviewApp.sln @@ -1,9 +1,9 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26403.3 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29609.76 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CatsReviewApp", "CatsReviewApp\CatsReviewApp.csproj", "{270BD635-CAD8-458B-BFFB-B40E62A36E49}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CatsReviewApp", "CatsReviewApp\CatsReviewApp.csproj", "{31C4FF77-19AF-4379-AAC9-944BE01142A6}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -11,12 +11,15 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {270BD635-CAD8-458B-BFFB-B40E62A36E49}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {270BD635-CAD8-458B-BFFB-B40E62A36E49}.Debug|Any CPU.Build.0 = Debug|Any CPU - {270BD635-CAD8-458B-BFFB-B40E62A36E49}.Release|Any CPU.ActiveCfg = Release|Any CPU - {270BD635-CAD8-458B-BFFB-B40E62A36E49}.Release|Any CPU.Build.0 = Release|Any CPU + {31C4FF77-19AF-4379-AAC9-944BE01142A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {31C4FF77-19AF-4379-AAC9-944BE01142A6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {31C4FF77-19AF-4379-AAC9-944BE01142A6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {31C4FF77-19AF-4379-AAC9-944BE01142A6}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {2D8DC9B9-7584-4499-BD91-648AE2DD8B02} + EndGlobalSection EndGlobal diff --git a/Source/CatsReviewApp/CatsReviewApp/App_Data/img-01.jpg b/Source/CatsReviewApp/CatsReviewApp/App_Data/img-01.jpg deleted file mode 100644 index d150f5d..0000000 Binary files a/Source/CatsReviewApp/CatsReviewApp/App_Data/img-01.jpg and /dev/null differ diff --git a/Source/CatsReviewApp/CatsReviewApp/App_Data/img-02.jpg b/Source/CatsReviewApp/CatsReviewApp/App_Data/img-02.jpg deleted file mode 100644 index eddc186..0000000 Binary files a/Source/CatsReviewApp/CatsReviewApp/App_Data/img-02.jpg and /dev/null differ diff --git a/Source/CatsReviewApp/CatsReviewApp/App_Data/img-03.jpg b/Source/CatsReviewApp/CatsReviewApp/App_Data/img-03.jpg deleted file mode 100644 index 9b649df..0000000 Binary files a/Source/CatsReviewApp/CatsReviewApp/App_Data/img-03.jpg and /dev/null differ diff --git a/Source/CatsReviewApp/CatsReviewApp/App_Start/BundleConfig.cs b/Source/CatsReviewApp/CatsReviewApp/App_Start/BundleConfig.cs deleted file mode 100644 index 3b38995..0000000 --- a/Source/CatsReviewApp/CatsReviewApp/App_Start/BundleConfig.cs +++ /dev/null @@ -1,30 +0,0 @@ -namespace CatsReviewApp -{ - using System.Web.Optimization; - - public class BundleConfig - { - // For more information on bundling, visit https://go.microsoft.com/fwlink/?LinkId=301862 - public static void RegisterBundles(BundleCollection bundles) - { - bundles.Add(new ScriptBundle("~/bundles/jquery").Include( - "~/Scripts/jquery-{version}.js")); - - bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include( - "~/Scripts/jquery.validate*")); - - // Use the development version of Modernizr to develop with and learn from. Then, when you're - // ready for production, use the build tool at https://modernizr.com to pick only the tests you need. - bundles.Add(new ScriptBundle("~/bundles/modernizr").Include( - "~/Scripts/modernizr-*")); - - bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include( - "~/Scripts/bootstrap.js", - "~/Scripts/respond.js")); - - bundles.Add(new StyleBundle("~/Content/css").Include( - "~/Content/bootstrap.css", - "~/Content/site.css")); - } - } -} diff --git a/Source/CatsReviewApp/CatsReviewApp/App_Start/FilterConfig.cs b/Source/CatsReviewApp/CatsReviewApp/App_Start/FilterConfig.cs deleted file mode 100644 index b6b68e1..0000000 --- a/Source/CatsReviewApp/CatsReviewApp/App_Start/FilterConfig.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace CatsReviewApp -{ - using System.Web.Mvc; - - public class FilterConfig - { - public static void RegisterGlobalFilters(GlobalFilterCollection filters) - { - filters.Add(new ErrorHandler.AiHandleErrorAttribute()); - } - } -} diff --git a/Source/CatsReviewApp/CatsReviewApp/App_Start/RouteConfig.cs b/Source/CatsReviewApp/CatsReviewApp/App_Start/RouteConfig.cs deleted file mode 100644 index f6caba9..0000000 --- a/Source/CatsReviewApp/CatsReviewApp/App_Start/RouteConfig.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace CatsReviewApp -{ - using System.Web.Mvc; - using System.Web.Routing; - - public class RouteConfig - { - public static void RegisterRoutes(RouteCollection routes) - { - routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); - - routes.MapRoute( - name: "Default", - url: "{controller}/{action}/{id}", - defaults: new { controller = "Review", action = "Index", id = UrlParameter.Optional }); - } - } -} diff --git a/Source/CatsReviewApp/CatsReviewApp/ApplicationInsights.config b/Source/CatsReviewApp/CatsReviewApp/ApplicationInsights.config deleted file mode 100644 index 7022293..0000000 --- a/Source/CatsReviewApp/CatsReviewApp/ApplicationInsights.config +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - - - - - - search|spider|crawl|Bot|Monitor|AlwaysOn - - - - - - - - - - - - - - - - - - - - - - System.Web.Handlers.TransferRequestHandler - Microsoft.VisualStudio.Web.PageInspector.Runtime.Tracing.RequestDataHttpHandler - System.Web.StaticFileHandler - System.Web.Handlers.AssemblyResourceLoader - System.Web.Optimization.BundleHandler - System.Web.Script.Services.ScriptHandlerFactory - System.Web.Handlers.TraceHandler - System.Web.Services.Discovery.DiscoveryRequestHandler - System.Web.HttpDebugHandler - - - - - - - - 5 - - - - - - \ No newline at end of file diff --git a/Source/CatsReviewApp/CatsReviewApp/CatsReviewApp.csproj b/Source/CatsReviewApp/CatsReviewApp/CatsReviewApp.csproj index f805ceb..0ef3ef0 100644 --- a/Source/CatsReviewApp/CatsReviewApp/CatsReviewApp.csproj +++ b/Source/CatsReviewApp/CatsReviewApp/CatsReviewApp.csproj @@ -1,298 +1,22 @@ - - - - - + + - Debug - AnyCPU - - - 2.0 - {270BD635-CAD8-458B-BFFB-B40E62A36E49} - {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} - Library - Properties - CatsReviewApp - CatsReviewApp - v4.5.2 - false - true - - - - - - - - /subscriptions/e7e4debd-456e-45a8-8bec-ccb824b1f34c/resourcegroups/Reviews/providers/microsoft.insights/components/ImageReview - /subscriptions/e7e4debd-456e-45a8-8bec-ccb824b1f34c/resourcegroups/Reviews/providers/microsoft.insights/components/ImageReview + netcoreapp3.1 - - true - full - false - bin\ - DEBUG;TRACE - prompt - 4 - - - true - pdbonly - true - bin\ - TRACE - prompt - 4 - - - - ..\packages\Microsoft.ApplicationInsights.TraceListener.2.2.0\lib\net45\Microsoft.ApplicationInsights.TraceListener.dll - - - ..\packages\Microsoft.Azure.DocumentDB.1.13.2\lib\net45\Microsoft.Azure.Documents.Client.dll - - - ..\packages\Microsoft.Azure.KeyVault.Core.1.0.0\lib\net40\Microsoft.Azure.KeyVault.Core.dll - - - ..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.3\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll - - - - ..\packages\Microsoft.Data.Edm.5.8.2\lib\net40\Microsoft.Data.Edm.dll - - - ..\packages\Microsoft.Data.OData.5.8.2\lib\net40\Microsoft.Data.OData.dll - - - ..\packages\Microsoft.Data.Services.Client.5.8.2\lib\net40\Microsoft.Data.Services.Client.dll - - - ..\packages\Microsoft.WindowsAzure.ConfigurationManager.3.2.3\lib\net40\Microsoft.WindowsAzure.Configuration.dll - - - ..\packages\WindowsAzure.Storage.8.1.1\lib\net45\Microsoft.WindowsAzure.Storage.dll - - - ..\packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll - True - - - - - - ..\packages\System.Spatial.5.8.2\lib\net40\System.Spatial.dll - - - - - - - - - - - - - - - - - - True - ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll - - - - - - - True - ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.Helpers.dll - - - True - ..\packages\Microsoft.AspNet.Mvc.5.2.3\lib\net45\System.Web.Mvc.dll - - - ..\packages\Microsoft.AspNet.Web.Optimization.1.1.3\lib\net40\System.Web.Optimization.dll - - - True - ..\packages\Microsoft.AspNet.Razor.3.2.3\lib\net45\System.Web.Razor.dll - - - True - ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.dll - - - True - ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Deployment.dll - - - True - ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Razor.dll - - - True - ..\packages\WebGrease.1.5.2\lib\WebGrease.dll - - - True - ..\packages\Antlr.3.4.1.9004\lib\Antlr3.Runtime.dll - - - - - ..\packages\Microsoft.ApplicationInsights.2.2.0\lib\net45\Microsoft.ApplicationInsights.dll - - - ..\packages\Microsoft.ApplicationInsights.Agent.Intercept.2.0.6\lib\net45\Microsoft.AI.Agent.Intercept.dll - - - ..\packages\Microsoft.ApplicationInsights.DependencyCollector.2.2.0\lib\net45\Microsoft.AI.DependencyCollector.dll - - - ..\packages\Microsoft.ApplicationInsights.PerfCounterCollector.2.2.0\lib\net45\Microsoft.AI.PerfCounterCollector.dll - - - ..\packages\Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.2.2.0\lib\net45\Microsoft.AI.ServerTelemetryChannel.dll - - - ..\packages\Microsoft.ApplicationInsights.WindowsServer.2.2.0\lib\net45\Microsoft.AI.WindowsServer.dll - - - ..\packages\Microsoft.ApplicationInsights.Web.2.2.0\lib\net45\Microsoft.AI.Web.dll - - - - - - - - - - - Global.asax - - - - - - - - - - - - - - - - - - - - - PreserveNewest - Designer - - - - - - - - - - - - - - - - - - Designer - - - Web.config - - - Web.config - - - - - - - - - - + - + + + + + - + + + + + - - - - - - - - - Designer - - - - - - - 10.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - - - - - - - - - False - True - 31625 - / - http://localhost:31625/ - False - False - - - False - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - - \ No newline at end of file + + diff --git a/Source/CatsReviewApp/CatsReviewApp/Components/StatusLabelViewComponent.cs b/Source/CatsReviewApp/CatsReviewApp/Components/StatusLabelViewComponent.cs new file mode 100644 index 0000000..b183fed --- /dev/null +++ b/Source/CatsReviewApp/CatsReviewApp/Components/StatusLabelViewComponent.cs @@ -0,0 +1,12 @@ +using Microsoft.AspNetCore.Mvc; + +namespace CatsReviewApp.Components +{ + public class StatusLabelViewComponent : ViewComponent + { + public IViewComponentResult Invoke(bool? isApproved) + { + return View(isApproved); + } + } +} diff --git a/Source/CatsReviewApp/CatsReviewApp/Connected Services/Application Insights/ConnectedService.json b/Source/CatsReviewApp/CatsReviewApp/Connected Services/Application Insights/ConnectedService.json deleted file mode 100644 index cb82c19..0000000 --- a/Source/CatsReviewApp/CatsReviewApp/Connected Services/Application Insights/ConnectedService.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "ProviderId": "Microsoft.ApplicationInsights.ConnectedService.ConnectedServiceProvider", - "Version": "8.6.209.10", - "GettingStartedDocument": { - "Uri": "https://go.microsoft.com/fwlink/?LinkID=613413" - } -} \ No newline at end of file diff --git a/Source/CatsReviewApp/CatsReviewApp/Controllers/HomeController.cs b/Source/CatsReviewApp/CatsReviewApp/Controllers/HomeController.cs index 15d182b..f66dbdd 100644 --- a/Source/CatsReviewApp/CatsReviewApp/Controllers/HomeController.cs +++ b/Source/CatsReviewApp/CatsReviewApp/Controllers/HomeController.cs @@ -1,6 +1,6 @@ namespace CatsReviewApp.Controllers { - using System.Web.Mvc; + using Microsoft.AspNetCore.Mvc; public class HomeController : Controller { diff --git a/Source/CatsReviewApp/CatsReviewApp/Controllers/ReviewController.cs b/Source/CatsReviewApp/CatsReviewApp/Controllers/ReviewController.cs index 5a9ce3b..30bd407 100644 --- a/Source/CatsReviewApp/CatsReviewApp/Controllers/ReviewController.cs +++ b/Source/CatsReviewApp/CatsReviewApp/Controllers/ReviewController.cs @@ -1,31 +1,31 @@ namespace CatsReviewApp.Controllers { - using System; - using System.Threading.Tasks; - using System.Web.Mvc; using CatsReviewApp.Models; - using System.Linq; using CatsReviewApp.Services; + using Microsoft.AspNetCore.Mvc; + using System; + using System.Linq; + using System.Threading.Tasks; public class ReviewController : Controller { - private readonly ReviewProvider provider; + private readonly ReviewProvider reviewProvider; - public ReviewController() + public ReviewController(ReviewProvider reviewProvider) { - this.provider = new ReviewProvider(); + this.reviewProvider = reviewProvider; } // GET: Review public async Task Index() { - return this.View((await this.provider.GetReviewsAsync()).OrderByDescending(r => r.Created)); + return this.View((await this.reviewProvider.GetReviewsAsync()).OrderByDescending(r => r.Created)); } // GET: Review/Details/5 public async Task Details(Guid id) { - return this.View(await this.provider.GetReviewAsync(id)); + return this.View(await this.reviewProvider.GetReviewAsync(id)); } // GET: Review/Create @@ -40,7 +40,7 @@ public async Task Create(CreateCatReview newCatReview) { try { - var id = await this.provider.CreateReviewAsync(newCatReview.Image.InputStream, newCatReview.ReviewText); + var id = await this.reviewProvider.CreateReviewAsync(newCatReview.Image.OpenReadStream(), newCatReview.ReviewText); return this.RedirectToAction("Details", new { Id = id }); } diff --git a/Source/CatsReviewApp/CatsReviewApp/ErrorHandler/AiHandleErrorAttribute.cs b/Source/CatsReviewApp/CatsReviewApp/ErrorHandler/AiHandleErrorAttribute.cs deleted file mode 100644 index be43088..0000000 --- a/Source/CatsReviewApp/CatsReviewApp/ErrorHandler/AiHandleErrorAttribute.cs +++ /dev/null @@ -1 +0,0 @@ -using System; using System.Web.Mvc; using Microsoft.ApplicationInsights; namespace CatsReviewApp.ErrorHandler { [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)] public class AiHandleErrorAttribute : HandleErrorAttribute { public override void OnException(ExceptionContext filterContext) { if (filterContext != null && filterContext.HttpContext != null && filterContext.Exception != null) { //If customError is Off, then AI HTTPModule will report the exception if (filterContext.HttpContext.IsCustomErrorEnabled) { var ai = new TelemetryClient(); ai.TrackException(filterContext.Exception); } } base.OnException(filterContext); } } } \ No newline at end of file diff --git a/Source/CatsReviewApp/CatsReviewApp/Global.asax b/Source/CatsReviewApp/CatsReviewApp/Global.asax deleted file mode 100644 index 048f05b..0000000 --- a/Source/CatsReviewApp/CatsReviewApp/Global.asax +++ /dev/null @@ -1 +0,0 @@ -<%@ Application Codebehind="Global.asax.cs" Inherits="CatsReviewApp.MvcApplication" Language="C#" %> diff --git a/Source/CatsReviewApp/CatsReviewApp/Global.asax.cs b/Source/CatsReviewApp/CatsReviewApp/Global.asax.cs deleted file mode 100644 index dd875e1..0000000 --- a/Source/CatsReviewApp/CatsReviewApp/Global.asax.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace CatsReviewApp -{ - using Microsoft.ApplicationInsights.Extensibility; - using System.Web.Mvc; - using System.Web.Optimization; - using System.Web.Routing; - - public class MvcApplication : System.Web.HttpApplication - { - protected void Application_Start() - { - AreaRegistration.RegisterAllAreas(); - FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); - RouteConfig.RegisterRoutes(RouteTable.Routes); - BundleConfig.RegisterBundles(BundleTable.Bundles); - - var iKey = System.Web.Configuration.WebConfigurationManager.AppSettings["iKey"]; - if (string.IsNullOrEmpty(iKey)) { throw new System.Exception("Missing instrumentation key in Web.config"); }; - - TelemetryConfiguration.Active.InstrumentationKey = iKey; - } - } -} diff --git a/Source/CatsReviewApp/CatsReviewApp/Models/CreateCatReview.cs b/Source/CatsReviewApp/CatsReviewApp/Models/CreateCatReview.cs index 0e91181..c452103 100644 --- a/Source/CatsReviewApp/CatsReviewApp/Models/CreateCatReview.cs +++ b/Source/CatsReviewApp/CatsReviewApp/Models/CreateCatReview.cs @@ -1,11 +1,11 @@ -using System.ComponentModel.DataAnnotations; -using System.Web; +using Microsoft.AspNetCore.Http; +using System.ComponentModel.DataAnnotations; namespace CatsReviewApp.Models { public class CreateCatReview : CatReview { [Display(Name = "Image File")] - public HttpPostedFileBase Image { get; set; } + public IFormFile Image { get; set; } } } \ No newline at end of file diff --git a/Source/CatsReviewApp/CatsReviewApp/Program.cs b/Source/CatsReviewApp/CatsReviewApp/Program.cs new file mode 100644 index 0000000..dc4270a --- /dev/null +++ b/Source/CatsReviewApp/CatsReviewApp/Program.cs @@ -0,0 +1,25 @@ +using Microsoft.AspNetCore; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Hosting; + +namespace CatsReviewApp +{ + public class Program + { + public static void Main(string[] args) + { + CreateHostBuilder(args).Build().Run(); + } + + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.ConfigureKestrel(serverOptions => + { + // Set properties and call methods on options + }) + .UseStartup(); + }); + } +} diff --git a/Source/CatsReviewApp/CatsReviewApp/Properties/AssemblyInfo.cs b/Source/CatsReviewApp/CatsReviewApp/Properties/AssemblyInfo.cs deleted file mode 100644 index b4aa4c4..0000000 --- a/Source/CatsReviewApp/CatsReviewApp/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("CatsReviewApp")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("CatsReviewApp")] -[assembly: AssemblyCopyright("Copyright © 2017")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("a2bce1a3-8f65-4a22-a9fb-37b9d73b220d")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Revision and Build Numbers -// by using the '*' as shown below: -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Source/CatsReviewApp/CatsReviewApp/Properties/launchSettings.json b/Source/CatsReviewApp/CatsReviewApp/Properties/launchSettings.json new file mode 100644 index 0000000..82ca6a2 --- /dev/null +++ b/Source/CatsReviewApp/CatsReviewApp/Properties/launchSettings.json @@ -0,0 +1,27 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:59884", + "sslPort": 44353 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "CatsReviewApp": { + "commandName": "Project", + "launchBrowser": true, + "applicationUrl": "https://localhost:5001;http://localhost:5000", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/Source/CatsReviewApp/CatsReviewApp/Scripts/bootstrap.js b/Source/CatsReviewApp/CatsReviewApp/Scripts/bootstrap.js deleted file mode 100644 index 5aa9982..0000000 --- a/Source/CatsReviewApp/CatsReviewApp/Scripts/bootstrap.js +++ /dev/null @@ -1,2014 +0,0 @@ -/* NUGET: BEGIN LICENSE TEXT - * - * Microsoft grants you the right to use these script files for the sole - * purpose of either: (i) interacting through your browser with the Microsoft - * website or online service, subject to the applicable licensing or use - * terms; or (ii) using the files as included with a Microsoft product subject - * to that product's license terms. Microsoft reserves all other rights to the - * files not expressly granted by Microsoft, whether by implication, estoppel - * or otherwise. Insofar as a script file is dual licensed under GPL, - * Microsoft neither took the code under GPL nor distributes it thereunder but - * under the terms set out in this paragraph. All notices and licenses - * below are for informational purposes only. - * - * NUGET: END LICENSE TEXT */ - -/** -* bootstrap.js v3.0.0 by @fat and @mdo -* Copyright 2013 Twitter Inc. -* http://www.apache.org/licenses/LICENSE-2.0 -*/ -if (!jQuery) { throw new Error("Bootstrap requires jQuery") } - -/* ======================================================================== - * Bootstrap: transition.js v3.0.0 - * http://twbs.github.com/bootstrap/javascript.html#transitions - * ======================================================================== - * Copyright 2013 Twitter, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ======================================================================== */ - - -+function ($) { "use strict"; - - // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) - // ============================================================ - - function transitionEnd() { - var el = document.createElement('bootstrap') - - var transEndEventNames = { - 'WebkitTransition' : 'webkitTransitionEnd' - , 'MozTransition' : 'transitionend' - , 'OTransition' : 'oTransitionEnd otransitionend' - , 'transition' : 'transitionend' - } - - for (var name in transEndEventNames) { - if (el.style[name] !== undefined) { - return { end: transEndEventNames[name] } - } - } - } - - // http://blog.alexmaccaw.com/css-transitions - $.fn.emulateTransitionEnd = function (duration) { - var called = false, $el = this - $(this).one($.support.transition.end, function () { called = true }) - var callback = function () { if (!called) $($el).trigger($.support.transition.end) } - setTimeout(callback, duration) - return this - } - - $(function () { - $.support.transition = transitionEnd() - }) - -}(window.jQuery); - -/* ======================================================================== - * Bootstrap: alert.js v3.0.0 - * http://twbs.github.com/bootstrap/javascript.html#alerts - * ======================================================================== - * Copyright 2013 Twitter, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ======================================================================== */ - - -+function ($) { "use strict"; - - // ALERT CLASS DEFINITION - // ====================== - - var dismiss = '[data-dismiss="alert"]' - var Alert = function (el) { - $(el).on('click', dismiss, this.close) - } - - Alert.prototype.close = function (e) { - var $this = $(this) - var selector = $this.attr('data-target') - - if (!selector) { - selector = $this.attr('href') - selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 - } - - var $parent = $(selector) - - if (e) e.preventDefault() - - if (!$parent.length) { - $parent = $this.hasClass('alert') ? $this : $this.parent() - } - - $parent.trigger(e = $.Event('close.bs.alert')) - - if (e.isDefaultPrevented()) return - - $parent.removeClass('in') - - function removeElement() { - $parent.trigger('closed.bs.alert').remove() - } - - $.support.transition && $parent.hasClass('fade') ? - $parent - .one($.support.transition.end, removeElement) - .emulateTransitionEnd(150) : - removeElement() - } - - - // ALERT PLUGIN DEFINITION - // ======================= - - var old = $.fn.alert - - $.fn.alert = function (option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.alert') - - if (!data) $this.data('bs.alert', (data = new Alert(this))) - if (typeof option == 'string') data[option].call($this) - }) - } - - $.fn.alert.Constructor = Alert - - - // ALERT NO CONFLICT - // ================= - - $.fn.alert.noConflict = function () { - $.fn.alert = old - return this - } - - - // ALERT DATA-API - // ============== - - $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close) - -}(window.jQuery); - -/* ======================================================================== - * Bootstrap: button.js v3.0.0 - * http://twbs.github.com/bootstrap/javascript.html#buttons - * ======================================================================== - * Copyright 2013 Twitter, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ======================================================================== */ - - -+function ($) { "use strict"; - - // BUTTON PUBLIC CLASS DEFINITION - // ============================== - - var Button = function (element, options) { - this.$element = $(element) - this.options = $.extend({}, Button.DEFAULTS, options) - } - - Button.DEFAULTS = { - loadingText: 'loading...' - } - - Button.prototype.setState = function (state) { - var d = 'disabled' - var $el = this.$element - var val = $el.is('input') ? 'val' : 'html' - var data = $el.data() - - state = state + 'Text' - - if (!data.resetText) $el.data('resetText', $el[val]()) - - $el[val](data[state] || this.options[state]) - - // push to event loop to allow forms to submit - setTimeout(function () { - state == 'loadingText' ? - $el.addClass(d).attr(d, d) : - $el.removeClass(d).removeAttr(d); - }, 0) - } - - Button.prototype.toggle = function () { - var $parent = this.$element.closest('[data-toggle="buttons"]') - - if ($parent.length) { - var $input = this.$element.find('input') - .prop('checked', !this.$element.hasClass('active')) - .trigger('change') - if ($input.prop('type') === 'radio') $parent.find('.active').removeClass('active') - } - - this.$element.toggleClass('active') - } - - - // BUTTON PLUGIN DEFINITION - // ======================== - - var old = $.fn.button - - $.fn.button = function (option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.button') - var options = typeof option == 'object' && option - - if (!data) $this.data('bs.button', (data = new Button(this, options))) - - if (option == 'toggle') data.toggle() - else if (option) data.setState(option) - }) - } - - $.fn.button.Constructor = Button - - - // BUTTON NO CONFLICT - // ================== - - $.fn.button.noConflict = function () { - $.fn.button = old - return this - } - - - // BUTTON DATA-API - // =============== - - $(document).on('click.bs.button.data-api', '[data-toggle^=button]', function (e) { - var $btn = $(e.target) - if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') - $btn.button('toggle') - e.preventDefault() - }) - -}(window.jQuery); - -/* ======================================================================== - * Bootstrap: carousel.js v3.0.0 - * http://twbs.github.com/bootstrap/javascript.html#carousel - * ======================================================================== - * Copyright 2012 Twitter, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ======================================================================== */ - - -+function ($) { "use strict"; - - // CAROUSEL CLASS DEFINITION - // ========================= - - var Carousel = function (element, options) { - this.$element = $(element) - this.$indicators = this.$element.find('.carousel-indicators') - this.options = options - this.paused = - this.sliding = - this.interval = - this.$active = - this.$items = null - - this.options.pause == 'hover' && this.$element - .on('mouseenter', $.proxy(this.pause, this)) - .on('mouseleave', $.proxy(this.cycle, this)) - } - - Carousel.DEFAULTS = { - interval: 5000 - , pause: 'hover' - , wrap: true - } - - Carousel.prototype.cycle = function (e) { - e || (this.paused = false) - - this.interval && clearInterval(this.interval) - - this.options.interval - && !this.paused - && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) - - return this - } - - Carousel.prototype.getActiveIndex = function () { - this.$active = this.$element.find('.item.active') - this.$items = this.$active.parent().children() - - return this.$items.index(this.$active) - } - - Carousel.prototype.to = function (pos) { - var that = this - var activeIndex = this.getActiveIndex() - - if (pos > (this.$items.length - 1) || pos < 0) return - - if (this.sliding) return this.$element.one('slid', function () { that.to(pos) }) - if (activeIndex == pos) return this.pause().cycle() - - return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos])) - } - - Carousel.prototype.pause = function (e) { - e || (this.paused = true) - - if (this.$element.find('.next, .prev').length && $.support.transition.end) { - this.$element.trigger($.support.transition.end) - this.cycle(true) - } - - this.interval = clearInterval(this.interval) - - return this - } - - Carousel.prototype.next = function () { - if (this.sliding) return - return this.slide('next') - } - - Carousel.prototype.prev = function () { - if (this.sliding) return - return this.slide('prev') - } - - Carousel.prototype.slide = function (type, next) { - var $active = this.$element.find('.item.active') - var $next = next || $active[type]() - var isCycling = this.interval - var direction = type == 'next' ? 'left' : 'right' - var fallback = type == 'next' ? 'first' : 'last' - var that = this - - if (!$next.length) { - if (!this.options.wrap) return - $next = this.$element.find('.item')[fallback]() - } - - this.sliding = true - - isCycling && this.pause() - - var e = $.Event('slide.bs.carousel', { relatedTarget: $next[0], direction: direction }) - - if ($next.hasClass('active')) return - - if (this.$indicators.length) { - this.$indicators.find('.active').removeClass('active') - this.$element.one('slid', function () { - var $nextIndicator = $(that.$indicators.children()[that.getActiveIndex()]) - $nextIndicator && $nextIndicator.addClass('active') - }) - } - - if ($.support.transition && this.$element.hasClass('slide')) { - this.$element.trigger(e) - if (e.isDefaultPrevented()) return - $next.addClass(type) - $next[0].offsetWidth // force reflow - $active.addClass(direction) - $next.addClass(direction) - $active - .one($.support.transition.end, function () { - $next.removeClass([type, direction].join(' ')).addClass('active') - $active.removeClass(['active', direction].join(' ')) - that.sliding = false - setTimeout(function () { that.$element.trigger('slid') }, 0) - }) - .emulateTransitionEnd(600) - } else { - this.$element.trigger(e) - if (e.isDefaultPrevented()) return - $active.removeClass('active') - $next.addClass('active') - this.sliding = false - this.$element.trigger('slid') - } - - isCycling && this.cycle() - - return this - } - - - // CAROUSEL PLUGIN DEFINITION - // ========================== - - var old = $.fn.carousel - - $.fn.carousel = function (option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.carousel') - var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option) - var action = typeof option == 'string' ? option : options.slide - - if (!data) $this.data('bs.carousel', (data = new Carousel(this, options))) - if (typeof option == 'number') data.to(option) - else if (action) data[action]() - else if (options.interval) data.pause().cycle() - }) - } - - $.fn.carousel.Constructor = Carousel - - - // CAROUSEL NO CONFLICT - // ==================== - - $.fn.carousel.noConflict = function () { - $.fn.carousel = old - return this - } - - - // CAROUSEL DATA-API - // ================= - - $(document).on('click.bs.carousel.data-api', '[data-slide], [data-slide-to]', function (e) { - var $this = $(this), href - var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7 - var options = $.extend({}, $target.data(), $this.data()) - var slideIndex = $this.attr('data-slide-to') - if (slideIndex) options.interval = false - - $target.carousel(options) - - if (slideIndex = $this.attr('data-slide-to')) { - $target.data('bs.carousel').to(slideIndex) - } - - e.preventDefault() - }) - - $(window).on('load', function () { - $('[data-ride="carousel"]').each(function () { - var $carousel = $(this) - $carousel.carousel($carousel.data()) - }) - }) - -}(window.jQuery); - -/* ======================================================================== - * Bootstrap: collapse.js v3.0.0 - * http://twbs.github.com/bootstrap/javascript.html#collapse - * ======================================================================== - * Copyright 2012 Twitter, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ======================================================================== */ - - -+function ($) { "use strict"; - - // COLLAPSE PUBLIC CLASS DEFINITION - // ================================ - - var Collapse = function (element, options) { - this.$element = $(element) - this.options = $.extend({}, Collapse.DEFAULTS, options) - this.transitioning = null - - if (this.options.parent) this.$parent = $(this.options.parent) - if (this.options.toggle) this.toggle() - } - - Collapse.DEFAULTS = { - toggle: true - } - - Collapse.prototype.dimension = function () { - var hasWidth = this.$element.hasClass('width') - return hasWidth ? 'width' : 'height' - } - - Collapse.prototype.show = function () { - if (this.transitioning || this.$element.hasClass('in')) return - - var startEvent = $.Event('show.bs.collapse') - this.$element.trigger(startEvent) - if (startEvent.isDefaultPrevented()) return - - var actives = this.$parent && this.$parent.find('> .panel > .in') - - if (actives && actives.length) { - var hasData = actives.data('bs.collapse') - if (hasData && hasData.transitioning) return - actives.collapse('hide') - hasData || actives.data('bs.collapse', null) - } - - var dimension = this.dimension() - - this.$element - .removeClass('collapse') - .addClass('collapsing') - [dimension](0) - - this.transitioning = 1 - - var complete = function () { - this.$element - .removeClass('collapsing') - .addClass('in') - [dimension]('auto') - this.transitioning = 0 - this.$element.trigger('shown.bs.collapse') - } - - if (!$.support.transition) return complete.call(this) - - var scrollSize = $.camelCase(['scroll', dimension].join('-')) - - this.$element - .one($.support.transition.end, $.proxy(complete, this)) - .emulateTransitionEnd(350) - [dimension](this.$element[0][scrollSize]) - } - - Collapse.prototype.hide = function () { - if (this.transitioning || !this.$element.hasClass('in')) return - - var startEvent = $.Event('hide.bs.collapse') - this.$element.trigger(startEvent) - if (startEvent.isDefaultPrevented()) return - - var dimension = this.dimension() - - this.$element - [dimension](this.$element[dimension]()) - [0].offsetHeight - - this.$element - .addClass('collapsing') - .removeClass('collapse') - .removeClass('in') - - this.transitioning = 1 - - var complete = function () { - this.transitioning = 0 - this.$element - .trigger('hidden.bs.collapse') - .removeClass('collapsing') - .addClass('collapse') - } - - if (!$.support.transition) return complete.call(this) - - this.$element - [dimension](0) - .one($.support.transition.end, $.proxy(complete, this)) - .emulateTransitionEnd(350) - } - - Collapse.prototype.toggle = function () { - this[this.$element.hasClass('in') ? 'hide' : 'show']() - } - - - // COLLAPSE PLUGIN DEFINITION - // ========================== - - var old = $.fn.collapse - - $.fn.collapse = function (option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.collapse') - var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) - - if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) - if (typeof option == 'string') data[option]() - }) - } - - $.fn.collapse.Constructor = Collapse - - - // COLLAPSE NO CONFLICT - // ==================== - - $.fn.collapse.noConflict = function () { - $.fn.collapse = old - return this - } - - - // COLLAPSE DATA-API - // ================= - - $(document).on('click.bs.collapse.data-api', '[data-toggle=collapse]', function (e) { - var $this = $(this), href - var target = $this.attr('data-target') - || e.preventDefault() - || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7 - var $target = $(target) - var data = $target.data('bs.collapse') - var option = data ? 'toggle' : $this.data() - var parent = $this.attr('data-parent') - var $parent = parent && $(parent) - - if (!data || !data.transitioning) { - if ($parent) $parent.find('[data-toggle=collapse][data-parent="' + parent + '"]').not($this).addClass('collapsed') - $this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed') - } - - $target.collapse(option) - }) - -}(window.jQuery); - -/* ======================================================================== - * Bootstrap: dropdown.js v3.0.0 - * http://twbs.github.com/bootstrap/javascript.html#dropdowns - * ======================================================================== - * Copyright 2012 Twitter, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ======================================================================== */ - - -+function ($) { "use strict"; - - // DROPDOWN CLASS DEFINITION - // ========================= - - var backdrop = '.dropdown-backdrop' - var toggle = '[data-toggle=dropdown]' - var Dropdown = function (element) { - var $el = $(element).on('click.bs.dropdown', this.toggle) - } - - Dropdown.prototype.toggle = function (e) { - var $this = $(this) - - if ($this.is('.disabled, :disabled')) return - - var $parent = getParent($this) - var isActive = $parent.hasClass('open') - - clearMenus() - - if (!isActive) { - if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) { - // if mobile we we use a backdrop because click events don't delegate - $('