- Additional Q&A about breaking changes can be found here
- To ask a question about breaking changes use this
| 2316884 | Upgrade to the latest Microsoft.WindowsAzure.ConfigurationManager package The Microsoft.WindowsAzure.ConfigurationManager dependency of the Azure Portal SDK has been upgraded from 2.0.1.0 to 3.2.3. |
| 2275444 | Set a default value for TypeScriptForceConsistentCasingInFileNames in tools targets RequireJS config is case sensitive. If an import statement module name differs from the actual filename by case, then the lookup to get the bundle URI from the RequireJS paths config will fail. RequireJS falls back to using baseUrl to construct the URI to the unbundled file. The backend URI handling is not case sensitive. We are enabling TypeScriptForceConsistentCasingInFileNames by default to catch these violations. Fixing these issues will increase performance and reliability. |
| 2236339 | Add placeholder texts to the datetime controls The placeholderText properties have been replaced with more specific placeholderTextForDate & placeholderTextForTime properties. |
| 2236338 | Remove the use of timezoneOffset from the dateTime related controls The DateTime controls have been fixed/updated to better handle timezones and offsets.
|
| 2210440 | Change resource/asset part pinning to use Asset PartName/Asset Kind PartName instead of Asset BladeName/Asset Kind BladeName Previously when the portal pinned a part to the dashboard from the browse blade it would use the blade name (Kind.BladeName) to try to resolve which part should be pinned. This approach has led to bugs as sometimes it cannot determine correctly which part to pin. This change adds a new required property called PartName to Kind which is used when the user right clicks and selects Pin to dashboard in the browse blade. This property is required for Kinds which specify BladeName. So taking a example in samples extension. The "Container" asset type has a Kind called "coreos". Previously this kind only specified blade name but now it provides both a blade name and a part name. <Kind Name="coreos" CompositeDisplayName="{Resource AssetTypeNames.CoreOSContainer, Module=ClientResources}" Icon="{Resource ContainerImages.coreOSLogo, Module=V1/ResourceTypes/Container/ContainerLogos}" BladeName="CoreOSContainerBlade" PartName="CoreOSContainerPart" MarketplaceItemId="Microsoft/maccontainer"> |
| 2185284 | Deprecate JSON camel case serialization APIs In the previous versions of the Azure Portal SDK, the fx.environment object was serialized using JSON.NET CamelCasePropertyNamesContractResolver. Due to quirks in serializing as camel case, fx.environment will now be serialized with the default ContractResolver that preserves casing. The SDK will raise an error at runtime if it detects a property that will serialized differently depending on which ContractResolver is used. You can use a JsonProperty attribute to explicitly specify how a property is to be serialized. |
| 2184815 | Allow resource to be updated after creation for Essential control The Essentials control has gone some interface changes to make development easier:
|
| 2147875 | [DashboardFilters] Resolve remaining TODOs |
| 2140129 | Modify context.dashboard.filtering.updateFilters to use a strongly typed model When using a No-PDL part that supports filtering, calls to `context.dashboard.filtering.updateFilters(dashboardFilters)` took an array of `{ filterId: string; filterModel: FxFilters.AnyFilterModel; }` This was updated to use the strongly typed user-defined `TFilterModels` interface that was used as the generic argument to `XXXPart.Filterable.Context<TFilterModels>`, providing a better strongly typed experience. |
| 2139965 | [BREAKING] [TestFramework] C# Test framework now requires selenium.webdriver 3.9.1 and newtonsoft.json 10.0.3 The C# test framework now requires Selenium Webdriver 3.8 and NewtonSoft.Json 10.0.3. This is a breaking change due to a change in the webdriver interface. Builds may fail to compile and tests may fail with an error around the webdriver interfaces to run if mismatched versions are used. Specifically the following packages have been updated to the corresponding versions: <package id="Newtonsoft.Json" version="10.0.3" targetFramework="net45" /> <package id="Selenium.Support" version="3.9.1" targetFramework="net40" /> <package id="Selenium.WebDriver" version="3.9.1" targetFramework="net40" /> |
| 2122345 | Update Newtonsoft.Json to version 10.0.3 The version of Newtonsoft.Json has been updated from 8.0.3 to 10.0.3 |
| 1975832 | PDL: Blades with Pinnable="true" now require a pinned part to be specified Currently in the Ibiza Portal SDK there is a feature that exists in which if a PDL blade author indicates that a blade is pinnable but does not provide a dashboard part then the portal dynamically creates a part for that blade. We call this dynamically created part a inferred pinned part. The inferred pinned part loads the blade view model to populate its title, subtitle and icon. When this feature was developed blade view models were very simple and in many if not most cases just consisted of code to populate the blade title, subtitle and icon. Since then we have added menu blades, template blades and no PDL as well. It is now costly to load blade view models to populate these inferred pinned parts on the dashboard. As well as we are finding a growing number of bugs. We are now retiring pinned inferred parts for blades. This means that any pinnable PDL blade must specify a pinned part to use on the dashboard when it is pinned. This does NOT affect noPDL blades as they already require a pinnable part to be specified.
For example –
<TemplateBlade Name="RPStatusBlade" ViewModel="{ViewModel Name=RPStatusBlade, Module=./ViewModels/RPStatusBlade}" Template="{Html Source='./Templates/RPStatusBlade.html'}" Width="Medium" InitialDisplayState="Maximized" Pinnable="true" PartSize="FullWidthFitHeight"> </TemplateBlade>
Lacking a pinned part will produce this error when compiling the extension –
PDL1245: The blade 'RPStatusBlade' has Pinnable enabled but is missing PinnedPart. Either set Pinnable to false or provide a pinned part.
To resolve this error you can very quickly and easily add a new noPDL part to that can be used when pinning your blade. Here is a sample of what this looks like for the example blade shared in this email below.
import * as ButtonPart from "Fx/Composition/ButtonPart";
export interface RPStatusBladePinnedPartParameters { subscriptionId: string; }
@ButtonPart.Decorator() export class RPStatusBladePinnedPart { public title = strings.title; public shortTitle: string; public subtitle: string; public description: string; public icon: MsPortalFx.Base.Image;
public context: ButtonPart.Context<RPStatusBladePinnedPartParameters, DataContext>;
public onInitialize() { const { parameters } = this.context;
.. implementation details omitted but here is where you can assign title, subtitle and icon .. }
public onClick() { const { container, parameters } = this.context; container.openBlade(new RPStatusBladeReference(parameters)); } }
And once you have this new part you can specify it as the pinned part for your PDL blade –
<TemplateBlade Name="RPStatusBlade" ViewModel="{ViewModel Name=RPStatusBlade, Module=./ViewModels/RPStatusBlade}" Template="{Html Source='./Templates/RPStatusBlade.html'}" Width="Medium" InitialDisplayState="Maximized" Pinnable="true" PartSize="FullWidthFitHeight">
….
<PinnedPart PartType="RPStatusBladePinnedPart" /> </TemplateBlade>
It maybe very likely that your customers already have inferred pinned parts for your blade on their dashboards. For these customers now is a good time also to specify a redirect in for these older pinned parts. If this is a new blade you can skip this step. If you are unsure if customers have pinned the inferred part you can use the extension analyzer to determine this. The extension analyzer report is here. Simply change the extension name in the URL to be your extension name. Parts that have the prefix [InferredBladePinPart] in their name are parts that need redirects.
https://extensionanalyzer.azurewebsites.net/extensions/Microsoft_Azure_Classic_Compute#parttelemetry
So returning back to the example above our redirect looks like this –
<RedirectInferredPinnedPart Blade= |
| 1577996 | [DropDown] Items property and options should be typed for observable array
|
| 2316884 | Upgrade to the latest Microsoft.WindowsAzure.ConfigurationManager package The Microsoft.WindowsAzure.ConfigurationManager dependency of the Azure Portal SDK has been upgraded from 2.0.1.0 to 3.2.3. |
| 2184815 | Allow resource to be updated after creation for Essential control The Essentials control has gone some interface changes to make development easier:
|
| 2275444 | Set a default value for TypeScriptForceConsistentCasingInFileNames in tools targets RequireJS config is case sensitive. If an import statement module name differs from the actual filename by case, then the lookup to get the bundle URI from the RequireJS paths config will fail. RequireJS falls back to using baseUrl to construct the URI to the unbundled file. The backend URI handling is not case sensitive. We are enabling TypeScriptForceConsistentCasingInFileNames by default to catch these violations. Fixing these issues will increase performance and reliability. |
| 1892721 | Accessibility: TabList control should move between individual tabs using the arrow keys
|
| 1975832 | PDL: Blades with Pinnable="true" now require a pinned part to be specified Currently in the Ibiza Portal SDK there is a feature that exists in which if a PDL blade author indicates that a blade is pinnable but does not provide a dashboard part then the portal dynamically creates a part for that blade. We call this dynamically created part a inferred pinned part. The inferred pinned part loads the blade view model to populate its title, subtitle and icon. When this feature was developed blade view models were very simple and in many if not most cases just consisted of code to populate the blade title, subtitle and icon. Since then we have added menu blades, template blades and no PDL as well. It is now costly to load blade view models to populate these inferred pinned parts on the dashboard. As well as we are finding a growing number of bugs. We are now retiring pinned inferred parts for blades. This means that any pinnable PDL blade must specify a pinned part to use on the dashboard when it is pinned. This does NOT affect noPDL blades as they already require a pinnable part to be specified.
For example –
<TemplateBlade Name="RPStatusBlade" ViewModel="{ViewModel Name=RPStatusBlade, Module=./ViewModels/RPStatusBlade}" Template="{Html Source='./Templates/RPStatusBlade.html'}" Width="Medium" InitialDisplayState="Maximized" Pinnable="true" PartSize="FullWidthFitHeight"> </TemplateBlade>
Lacking a pinned part will produce this error when compiling the extension –
PDL1245: The blade 'RPStatusBlade' has Pinnable enabled but is missing PinnedPart. Either set Pinnable to false or provide a pinned part.
To resolve this error you can very quickly and easily add a new noPDL part to that can be used when pinning your blade. Here is a sample of what this looks like for the example blade shared in this email below.
import * as ButtonPart from "Fx/Composition/ButtonPart";
export interface RPStatusBladePinnedPartParameters { subscriptionId: string; }
@ButtonPart.Decorator() export class RPStatusBladePinnedPart { public title = strings.title; public shortTitle: string; public subtitle: string; public description: string; public icon: MsPortalFx.Base.Image;
public context: ButtonPart.Context<RPStatusBladePinnedPartParameters, DataContext>;
public onInitialize() { const { parameters } = this.context;
.. implementation details omitted but here is where you can assign title, subtitle and icon .. }
public onClick() { const { container, parameters } = this.context; container.openBlade(new RPStatusBladeReference(parameters)); } }
And once you have this new part you can specify it as the pinned part for your PDL blade –
<TemplateBlade Name="RPStatusBlade" ViewModel="{ViewModel Name=RPStatusBlade, Module=./ViewModels/RPStatusBlade}" Template="{Html Source='./Templates/RPStatusBlade.html'}" Width="Medium" InitialDisplayState="Maximized" Pinnable="true" PartSize="FullWidthFitHeight">
….
<PinnedPart PartType="RPStatusBladePinnedPart" /> </TemplateBlade>
It maybe very likely that your customers already have inferred pinned parts for your blade on their dashboards. For these customers now is a good time also to specify a redirect in for these older pinned parts. If this is a new blade you can skip this step. If you are unsure if customers have pinned the inferred part you can use the extension analyzer to determine this. The extension analyzer report is here. Simply change the extension name in the URL to be your extension name. Parts that have the prefix [InferredBladePinPart] in their name are parts that need redirects.
https://extensionanalyzer.azurewebsites.net/extensions/Microsoft_Azure_Classic_Compute#parttelemetry
So returning back to the example above our redirect looks like this –
<RedirectInferredPinnedPart Blade=The C# test framework now requires Selenium Webdriver 3.8 and NewtonSoft.Json 10.0.3. This is a breaking change due to a change in the webdriver interface. Builds may fail to compile and tests may fail with an error around the webdriver interfaces to run if mismatched versions are used. Specifically the following packages have been updated to the corresponding versions: <package id="Newtonsoft.Json" version="10.0.3" targetFramework="net45" /> <package id="Selenium.Support" version="3.9.1" targetFramework="net40" /> <package id="Selenium.WebDriver" version="3.9.1" targetFramework="net40" /> |
| 2122345 | Update Newtonsoft.Json to version 10.0.3 The version of Newtonsoft.Json has been updated from 8.0.3 to 10.0.3 |
| 2020334 | Add support for bypass health check with SDP when deploying with extensions with EV2 If you have customized or made a copy of the ContentUnbundler/Ev2 deployment templates then you need to make sure to copy/merge the latest versions of the deployment templates or you may see failures during deployment template generation that look similar to below. Unhandled Exception: System.AggregateException: One or more errors occurred. ---> System.AggregateException: One or more errors occurred. ---> System.Not
SupportedException: Some replacements are not been used, please remove it from file. unusedReplacements: PortalExtensionNameForHealthCheck, file: D:\git\
Rep\out\debug-i386\MyExtension\\bin\ServiceGroupRootReplacements.json
at ContentUnbundler.Ev2.ServiceGroupRootGenerator.ValidateUnusedReplacements(Dictionary`2 replacementsUsage, String serviceGroupRootReplacementsFilePa
th)
|
| 1874809 | Upgrade Azure Portal TypeScript compiler to version 2.3
For new features, check out the What's new in TypeScript 2.3: https://github.com/Microsoft/TypeScript/wiki/What's-new-in-TypeScript#typescript-23 Note that the new TypeScript MSBuild tools depend on MSBuild 14.0 which ships with Visual Studio 2015, so this version of Visual Studio must be installed in your development and/or Build machines in order to use the framework. This is not a new prerequisite of the SDK, but it was technically possible to build some solutions with an older version of Visual Studio before. |
| 1738244 | Breaking Change: Remove C# test framework Checkbox.CheckedValue and Checkbox.IndeterminateValue
Technically this is a breaking change, but as no one is using these methods, there should be no real code changes needed by extension authors. |
| 1874809 | Upgrade Azure Portal TypeScript compiler to version 2.3
For new features, check out the What's new in TypeScript 2.3: https://github.com/Microsoft/TypeScript/wiki/What's-new-in-TypeScript#typescript-23 Note that the new TypeScript MSBuild tools depend on MSBuild 14.0 which ships with Visual Studio 2015, so this version of Visual Studio must be installed in your development and/or Build machines in order to use the framework. This is not a new prerequisite of the SDK, but it was technically possible to build some solutions with an older version of Visual Studio before. |
| 1849296 | [EditableGrid] Replace ToolbarItems interface with factory methods The ToolbarItems interface has been removed from the EditableGrid control. Consumers of this interface will need to switch to the following factory methods. grid.deletion.createDeleteRowsCommand(toolbarLifetime, grid.selection) grid.insertion.createInsertRowCommand(toolbarLifetime, grid.selection) grid.reordering.createMoveRowsUpCommand(toolbarLifetime, grid.selection) grid.reordering.createMoveRowsDownCommand(toolbarLifetime, grid.selection) grid.reordering.createMoveRowsTopCommand(toolbarLifetime, grid.selection) grid.reordering.createMoveRowsBottomCommand(toolbarLifetime, grid.selection) |
| 1784649 | Expand SVG JSON To increase compression of SVGs content, the contents of the SVG bundle has been changed. It is no longer possible to import the contents using something like " import Svg from "../Svg". Instead you will need to change the code to: import Svg = require("./Svg") |
| 1743316 | Remove msportalfx dependencies from fx Button IconPosition enum in Fx Button was moved into the Button AMD module. import * as Button from "Fx/Controls/Button"; const myButton = Button.create(ltm, { position: MsPortalFx.ViewModels.Controls.SimpleButton.IconPosition.Left }); becomes import * as Button from "Fx/Controls/Button"; const myButton = Button.create(ltm, { position: Button.IconPosition.Left }); |
| 1737169 | Remove dependencies on MsPortalFx from Fx/Controls There are some types and enums that have been moved to further isolate Fx code from MsPortalFx. Tristate checkbox value If you are using the new create pattern, the return type is now defined in the Fx/Controls/TriStateCheckBox module. import * as TriStateCheckBox from "Fx/Controls/TriStateCheckBox"; const myCheckBox = TristateCheckBox.create(lifetime); myCheckBox.value(TriStateCheckBox.Value.Checked); // was MsPortalFx.ViewModels.Forms.TriStateCheckBox.Value.Checked. DateTimeRange properties If you are using the new create pattern, the DateTimeRange class now exists in the module you loaded the control from. import * as DateTimeRangePicker from "Fx/Controls/DateTimeRangePicker"; const myDateTimeRangePicker = DateTimeRangePicker.create(lifetime, { startDateTimeEnabledRange: new DateTimeRangePicker.DateTimeRange(...) }); // was new MsPortalFx.DateUtil.DateTimeRange(...) |
| 1726692 | Scrub video control api in fx namespace We're updating controls in the "Fx/Controls" module path to follow consistent create patterns. If you have the following code: import * as Video from "Fx/Controls/Video"; var myVideo: Video.ViewModel = new Video.ViewModel(container, options); You need to change your code to: import * as Video from "Fx/Controls/Video"; var myVideo: Video.Contract = Video.create(container, options); |
| 1724972 | GroupNavigator, ArrayListNavigator, ArrayBaseNavigator is leaking, it should take the first argument as LifetimeManager to avoid leak To avoid further memory leaking from EditScope object since the EditScope<TData> have the dispose method. we now require the first argument to be lifetimeManager to allow the return object to be disposed. MsPortalFx.Data.createEditScope change from function createEditScope<TData>(data: TData, options?: EditScopeOptions<TData>): EditScope<TData>; To function createEditScope<TData>(lifetimeManager: MsPortalFx.Base.LifetimeManager, data: TData, options?: EditScopeOptions<TData>): EditScope<TData>; |
| 1711235 | [EV2] Add configurable bake time The Content Unbundler EV2 template files that are shipped are now formatted to accept customized monitor durations (the time to wait between each stage of a deployment, also known as bake time). To accommodate this, the files have been renamed from: Blackforest.RolloutParameters.PT6H.json to: Blackforest.RolloutParameters.{MonitorDuration}.json You can specify the monitor duration by updating your ServiceGroupRootReplacements.json file to include a new array called "MonitorDuration". EG:
If no monitor durations are specified then the content unbundler ev2 generation will default to 6 hours (PT6H) and 1 day (P1D) |
| 1667478 | [Hosting Service] Add support for creating removeFriendlyName templates in ContentUnbundler The Content Unbundler/Express V2 Deployment Template Generator has been updated to support generating templates to remove friendly names from Hosting Service deployments. In order to support this feature, the friendlyname template file names were renamed to specify the action they were performing (SetFriendlyName vs RemoveFriendlyName). EG: Old friendlyname template file name: Test.RolloutSpec.friendlyname1.json New friendlyname template file name(s): Test.RolloutSpec.RemoveFriendlyName.friendlyname1.json Test.RolloutSpec.SetFriendlyName.friendlyname1.json |
| 1578000 | Breaking Change: Normalize all properties from fxClient form controls to use KnockoutObservableBase type
Technically this is a breaking change, but there should be no real code changes needed by extension authors. The types are very similar. |
| 1711235 | [EV2] Add configurable bake time The Content Unbundler EV2 template files that are shipped are now formatted to accept customized monitor durations (the time to wait between each stage of a deployment, also known as bake time). To accommodate this, the files have been renamed from: Blackforest.RolloutParameters.PT6H.json to: Blackforest.RolloutParameters.{MonitorDuration}.json You can specify the monitor duration by updating your ServiceGroupRootReplacements.json file to include a new array called "MonitorDuration". EG:
If no monitor durations are specified then the content unbundler ev2 generation will default to 6 hours (PT6H) and 1 day (P1D) |