Skip to content

Latest commit

 

History

History
474 lines (305 loc) · 110 KB

File metadata and controls

474 lines (305 loc) · 110 KB

Breaking Changes since 12/26/2017

  • Additional Q&A about breaking changes can be found here
  • To ask a question about breaking changes use this

5.0.302.1101

2316884Upgrade 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.

2275444Set 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.

2236339Add placeholder texts to the datetime controls


The placeholderText properties have been replaced with more specific placeholderTextForDate & placeholderTextForTime properties.

2236338Remove the use of timezoneOffset from the dateTime related controls


The DateTime controls have been fixed/updated to better handle timezones and offsets.
  1. To avoid confusion of use, the timezoneOffset properties have been removed from all the controls and also from the DateTimeRange class.
  2. The values of all the DateTime controls are now always in the local time. Even the range validators expect the values to be in local time.
  3. There is a new property timezoneDropDownValue which has been introduced in the DateTimePicker and the DateTimeRangePicker which can be used to select the timezone. Even if this set to something other than current timezone, the value of the control will still always be in local time with the control doing the logic of applying the offsets to the user input before setting the local time on the value of the control.
  4. Also the validation errors have been updated to show the error in the selected timezone. instead of defaulting to GMT always.

2210440Change 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">


2185284Deprecate 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.

2184815Allow resource to be updated after creation for Essential control


The Essentials control has gone some interface changes to make development easier:
  1. The Essentials ViewModel is no longer existing. You need to use the 'create' method to create an instance of the Essentials contract.
  2. The option types and contracts have been renamed ("Default" to "DefaultResourceLayout", "CustomLayout" to "CustomResourceLayout", "NonResource" to "NonResourceLayout"). 
  3. Some of the unused interfaces (like BladeOpenOptions, etc) have been removed.

2147875[DashboardFilters] Resolve remaining TODOs

2140129Modify 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" />

2122345Update Newtonsoft.Json to version 10.0.3

The version of Newtonsoft.Json has been updated from 8.0.3 to 10.0.3

1975832PDL: 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.


What is changing

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.

 

Adding a PinnedPart

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>

 

Redirecting existing pinned parts on customer dashboards

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

  • import FxDropDown = require("Fx/Controls/DropDown");
    • FxDropDown.items is now of type KnockoutObservableArray<Item<TValue> | Group<TValue>>;
    • i.e. transitioned to observable array from base observable of regular arrays.
    • Note: older drop-down implementations do not benefit from this change, as it only applies to the latest one.

5.0.302.1056

2316884Upgrade 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.

5.0.302.1051

2184815Allow resource to be updated after creation for Essential control


The Essentials control has gone some interface changes to make development easier:
  1. The Essentials ViewModel is no longer existing. You need to use the 'create' method to create an instance of the Essentials contract.
  2. The option types and contracts have been renamed ("Default" to "DefaultResourceLayout", "CustomLayout" to "CustomResourceLayout", "NonResource" to "NonResourceLayout"). 
  3. Some of the unused interfaces (like BladeOpenOptions, etc) have been removed.

5.0.302.1046

2275444Set 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.

1892721Accessibility: TabList control should move between individual tabs using the arrow keys

  • ViewModel MsPortalFx.ViewModels.Forms.Section now has a new tabs navigation experience for both Tabs and Blocks: please use 'ArrowRight'/'ArrowLeft' instead of the obsolete 'tab'/SHIFT + 'tab' navigation respectively.
  • TabStopSequenceTest in DirectoryPaneTests.cs was affected too: it is now adapted to succeed on the new navigation experience, and will thus fail when run against the old 'tab' key based implementation.

5.0.302.1036

1975832PDL: 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.


What is changing

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.

 

Adding a PinnedPart

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>

 

Redirecting existing pinned parts on customer dashboards

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" />

5.0.302.1032

2122345Update Newtonsoft.Json to version 10.0.3

The version of Newtonsoft.Json has been updated from 8.0.3 to 10.0.3

5.0.302.1019

2020334Add 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)

1874809Upgrade Azure Portal TypeScript compiler to version 2.3


There are some small breaking changes as you can see in the TypeScript official page: https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#typescript-23 (see breaking changes for 2.1, 2.2 and 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.

1738244Breaking Change: Remove C# test framework Checkbox.CheckedValue and Checkbox.IndeterminateValue

  • Removing the following methods which out of date and throwing System.InvalidOperationException all the time
    • Checkbox.CheckedValue
    • 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. 

5.0.302.1011

1874809Upgrade Azure Portal TypeScript compiler to version 2.3


There are some small breaking changes as you can see in the TypeScript official page: https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#typescript-23 (see breaking changes for 2.1, 2.2 and 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)

1784649Expand 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")

1743316Remove 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 });

1737169Remove 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(...)

1726692Scrub 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);

1724972GroupNavigator, 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:

"Test": {
    "AzureSubscriptionId": "0531c8c8-df32-4254-a717-b6e983273e5f",
    "TargetContainerName": "hostingservicedf",
    "ContactEmail": "rowong@microsoft.com",
    "PortalExtensionName": "Microsoft_Azure_Resources",
    "FriendlyNames": [
      "friendlyname1"
    ],
    "MonitorDuration": [
        "PT1H",
        "PT30M"
    ]

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

1578000Breaking Change: Normalize all properties from fxClient form controls to use KnockoutObservableBase type

  • "Fx/Controls"
    • Updated all properties with type KnockoutObservable to KnockoutObservableBase
Technically this is a breaking change, but there should be no real code changes needed by extension authors.  The types are very similar.

5.0.302.958

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:

"Test": {
    "AzureSubscriptionId": "0531c8c8-df32-4254-a717-b6e983273e5f",
    "TargetContainerName": "hostingservicedf",
    "ContactEmail": "rowong@microsoft.com",
    "PortalExtensionName": "Microsoft_Azure_Resources",
    "FriendlyNames": [
      "friendlyname1"
    ],
    "MonitorDuration": [
        "PT1H",
        "PT30M"
    ]

If no monitor durations are specified then the content unbundler ev2 generation will default to 6 hours (PT6H) and 1 day (P1D)