* Fix build

* Fix tests

* Allow less colors than values and clear up texts

* Update urls

* Remove whitespace

* Use different container class for error view

* Change errorview to not use table

* Correct version

* Three basic grunt tasks => five basic grunt tasks
This commit is contained in:
Aaron Zhou 2016-10-12 17:07:20 -07:00 коммит произвёл GitHub
Родитель 608e7953fc
Коммит 666e26547c
11 изменённых файлов: 85 добавлений и 85 удалений

3
.gitignore поставляемый
Просмотреть файл

@ -1,4 +1,5 @@
node_modules
scripts/*.js
typings
dist
dist
*.vsix

10
.vscode/settings.json поставляемый Normal file
Просмотреть файл

@ -0,0 +1,10 @@
// Place your settings in this file to overwrite default and user settings.
{
"files.exclude": {
"**/*.js": {
"when": "$(basename).ts"
},
"**/*.vsix": true,
"*.gitignore": true
}
}

Просмотреть файл

@ -177,7 +177,7 @@ vss-extension.json - Extension manifest
#### Grunt ####
Three basic `grunt` tasks are defined:
Five basic `grunt` tasks are defined:
* `build` - Compiles TS files in `scripts` folder
* `package-dev` - Builds the development version of the vsix package

Просмотреть файл

@ -2,8 +2,7 @@
grunt.initConfig({
ts: {
build: {
tsconfig: true,
"outDir": "./dist"
tsconfig: true
},
buildTest: {
tsconfig: true,
@ -16,22 +15,22 @@
},
exec: {
package_dev: {
command: "tfx extension create --root dist --manifest-globs vss-extension.json --overrides-file configs/dev.json",
command: "tfx extension create --manifest-globs vss-extension.json --overrides-file configs/dev.json",
stdout: true,
stderr: true
},
package_release: {
command: "tfx extension create --root dist --manifest-globs vss-extension.json --overrides-file configs/release.json",
command: "tfx extension create --manifest-globs vss-extension.json --overrides-file configs/release.json",
stdout: true,
stderr: true
},
publish_dev: {
command: "tfx extension publish --service-url https://marketplace.visualstudio.com --root dist --manifest-globs vss-extension.json --overrides-file configs/dev.json",
command: "tfx extension publish --service-url https://marketplace.visualstudio.com --manifest-globs vss-extension.json --overrides-file configs/dev.json",
stdout: true,
stderr: true
},
publish_release: {
command: "tfx extension publish --service-url https://marketplace.visualstudio.com --root dist --manifest-globs vss-extension.json --overrides-file configs/release.json",
command: "tfx extension publish --service-url https://marketplace.visualstudio.com --manifest-globs vss-extension.json --overrides-file configs/release.json",
stdout: true,
stderr: true
}

Просмотреть файл

@ -18,7 +18,7 @@
});
// Load main entry point for extension
VSS.require(["dist/app"], function () {
VSS.require(["scripts/app"], function () {
// loading succeeded
VSS.notifyLoadSucceeded();
});

Просмотреть файл

@ -31,19 +31,6 @@ describe("InputParser", () => {
{ value: "4", color: "blue", label: "Low" }]);
});
it("returns options with empty strings in label key when no labels are provided", () => {
expect(InputParser.getOptions({
"FieldName": "Priority",
"Colors": "red;orange;yellow;blue",
"Values": "1;2;3;4",
"Labels": ""
}, bestCaseValues)).to.be.deep.equal([
{ value: "1", color: "red", label: "" },
{ value: "2", color: "orange", label: "" },
{ value: "3", color: "yellow", label: "" },
{ value: "4", color: "blue", label: "" }]);
});
it("returns 1 default color when 1 value and no colors are provided", () => {
expect(InputParser.getOptions({
"FieldName": "Priority",
@ -56,18 +43,15 @@ describe("InputParser", () => {
it("returns options with default colors and NO labels when NO colors and NO labels provided.", () => {
expect(InputParser.getOptions({
"FieldName": "Priority",
"Colors": "",
"Values": "1;2;3;4",
"Labels": ""
}, ["1", "2", "3", "4"])).to.be.deep.equal([
{ value: "1", color: "red", label: "" },
{ value: "2", color: "orange", label: "" },
{ value: "3", color: "yellow", label: "" },
{ value: "4", color: "blue", label: "" }]);
});
it("throws when allowed values are not specified", () => {
@ -76,29 +60,34 @@ describe("InputParser", () => {
"Colors": "red;orange;yellow;blue",
"Values": "",
"Labels": "Critical;High;Medium"
}, [])).throw("Allowed values not specified.");
}, [])).throw("The backing field does not have allowed values.");
});
it("Returns options with some empty labels if less labels than values provided", () => {
it("returns options with empty strings as labels if less labels than values are provided", ()=>{
expect(InputParser.getOptions({
"FieldName": "Priority",
"Colors": "red;orange;yellow;blue",
"Values": "1;2;3;4",
"Labels": "Critical;High;Medium"
"Labels": "High;Medium;Low"
}, ["1", "2", "3", "4"])).to.be.deep.equal([
{ value: "1", color: "red", label: "Critical" },
{ value: "2", color: "orange", label: "High" },
{ value: "3", color: "yellow", label: "Medium" },
{ value: "1", color: "red", label: "High" },
{ value: "2", color: "orange", label: "Medium" },
{ value: "3", color: "yellow", label: "Low" },
{ value: "4", color: "blue", label: "" }]);
});
it("throws when less colors than values are provided", () => {
expect(() => InputParser.getOptions({
it("returns options with default colors if less colors than values are provided", () => {
expect(InputParser.getOptions({
"FieldName": "Priority",
"Colors": "red;orange",
"Values": "1;2;3;4",
"Labels": "Critical;High;Medium;Low"
}, ["1", "2", "3", "4"])).throw("Not enough colors provided in admin XML file.");
}, ["1", "2", "3", "4"])).to.be.deep.equal([
{ value: "1", color: "red", label: "Critical" },
{ value: "2", color: "orange", label: "High" },
{ value: "3", color: "yellow", label: "Medium" },
{ value: "4", color: "blue", label: "Low" }
]);
});
it("gives one label to every value, and truncates unused labels when MORE Labels THAN values are provided", () => {
@ -138,7 +127,7 @@ describe("InputParser", () => {
{ value: "2", color: "orange", label: "" },
{ value: "3", color: "yellow", label: "" },
{ value: "4", color: "blue", label: "Low" }]);
}); //
});
it("returns custom positions of colors when no color is placed between semicolons.", () => {
expect(InputParser.getOptions({
@ -153,7 +142,7 @@ describe("InputParser", () => {
{ value: "4", color: "blue", label: "Low" }]);
});
it("Returns one option when one value,one label, and one are color provided", () => {
it("returns one option when one value,one label, and one are color provided", () => {
expect(InputParser.getOptions({
"FieldName": "Priority",
"Colors": "red",

Просмотреть файл

@ -29,12 +29,9 @@ export class InputParser {
* label: labels[i]
* }
* @throws Will throw an {string} error if allowedValues are not specified.
* @throws Will throw an {string} error if Not enough colors provided in admin XML file.
*/
public static getOptions(inputs: IDictionaryStringTo<string>, allowedValues: string[]): IOption[] {
if (allowedValues && allowedValues.length) {
let colors: string[] = [];
let inputColors: string[] = [];
let labels: string[] = [];
@ -47,10 +44,8 @@ export class InputParser {
labels = InputParser._getLabels(inputLabels, allowedValues);
return InputParser._buildOptions(allowedValues, colors, labels);
} else {
throw ("The backing field does not have allowed values. Verify that the field used by this control is a picklist");
throw ("The backing field does not have allowed values.");
}
}
/**
@ -72,23 +67,15 @@ export class InputParser {
* to every value. Also, it checks if the colors were correctly inputed.
* @return {string[]} newColors - An array of {string} colors that match
* the number of values.
* @throws {string} "Not enough colors provided in admin XML file."
* @static
* @private
*/
private static _getColors(inputColors: string[], values: string[]): string[] {
// Values length can never be 0, colors length can be 0 or more
if (values.length > inputColors.length && inputColors.length !== 0) {
// If values array length is greater, an error will appear
throw ("Not enough colors provided in admin XML file.");
}
if (inputColors.length === 0) {
//DefaultColors is a static class wich does the processing of colors.
return Colors.getColors(values.length);
if(inputColors.length < values.length) {
//append default colors if we are given less colors than values
return inputColors.concat(Colors.getColors(values.length).slice(inputColors.length));
} else {
return values.map((v, idx) => inputColors[idx] || "");
return inputColors.slice(0, values.length);
}
}
/**
@ -102,7 +89,7 @@ export class InputParser {
*/
private static _getLabels(inputLabels: string[], values: string[]): string[] {
// Values length can never be 0, labels length can be 0 or more
// There will be no default labels, just whitespace ""
// Defaults to empty string if less labels than values are provided
return values.map((v, idx) => inputLabels[idx] || "");
}
/**
@ -113,7 +100,6 @@ export class InputParser {
* @private
*/
private static _buildOptions(values: string[], colors: string[], labels: string[]): IOption[] {
let options: IOption[] = [];
let valuesLength: number = values.length;

Просмотреть файл

@ -29,12 +29,12 @@ describe("Colors", () => {
// Tests for eight values, exceeds maximum and should repeat last one
it("outputs color array for 8 values", () => {
expect(Colors.getColors(8)).to.be.deep.equal((["dark red", "red", "orange", "yellow", "blue", "dark blue", "purple", "purple"]));
expect(Colors.getColors(8)).to.be.deep.equal((["darkred", "red", "orange", "yellow", "blue", "darkblue", "purple", "purple"]));
});
// Tests for twenty values, extreme case, exceeds maximum as well
it("outputs color array for 15 values", () => {
expect(Colors.getColors(15)).to.be.deep.equal((["dark red", "red", "orange", "yellow", "blue", "dark blue", "purple", "purple", "purple", "purple", "purple", "purple", "purple", "purple", "purple"]));
expect(Colors.getColors(15)).to.be.deep.equal((["darkred", "red", "orange", "yellow", "blue", "darkblue", "purple", "purple", "purple", "purple", "purple", "purple", "purple", "purple", "purple"]));
});
// Tests for invalid input of negative

Просмотреть файл

@ -4,34 +4,36 @@ Purpose: This class is being used to get errors from an input parser and
order to be sent to a view to display them.
***************************************************************************/
// shows the errors in the control container rather than the control.
export class ErrorView {
constructor(error: string) {
// container div
var container = $("<div />");
container.addClass("container");
var errorContainer = $("<div />");
errorContainer.addClass("errorContainer");
// create an icon and text for the error
var warning = $("<p />");
warning.text(error);
warning.attr("title", error);
container.append(warning);
var rdiv = $("<div/>").addClass("rightDiv");
var ldiv = $("<div/>");
var icon = $("<span class='bowtie-icon bowtie-status-error'></span>");
rdiv.append(icon);
// include documentation link for help.
var help = $("<p />");
help.text("See ");
var warning = $("<span></span>").text(error).attr("title", error);
var help = $("<span></span>").text("For more information click ");
var a = $("<a> </a>");
a.attr("href", "https://www.visualstudio.com/en-us/products/visual-studio-team-services-vs.aspx");
a.attr("href", "https://www.visualstudio.com/en-us/docs/work/customize/customize-work");
a.attr("target", "_blank");
a.text("Documentation.");
a.text("here.");
help.append(a);
container.append(help);
$('body').empty().append(container);
ldiv.append(warning);
ldiv.append($("<br/>"));
ldiv.append(help);
errorContainer.append(rdiv);
errorContainer.append(ldiv);
$('body').empty().append(errorContainer);
}
}

Просмотреть файл

@ -6,6 +6,11 @@ div {
text-overflow: ellipsis;
}
.rightDiv {
margin-right: 3px;
margin-left: 3px;
}
.container:focus {
outline: solid lightgray 1px;
}
@ -18,6 +23,12 @@ div {
background-color:#E3F2FD
}
.errorContainer {
display: flex;
height:100%;
border: 1px solid #E6E6E6;
}
.container {
height:100%;
border: 1px solid transparent;

Просмотреть файл

@ -1,7 +1,7 @@
{
"manifestVersion": 1,
"id": "color-form-control",
"version": "0.1.1",
"version": "0.1.2",
"name": "Color Form Control",
"description": "The example we built adds color to picklists and allows user customization through labels.",
"publisher": "ms-devlabs",
@ -26,16 +26,16 @@
},
"links": {
"learn": {
"uri": "https://github.com/Microsoft/vsts-sample-wit-custom-control/blob/master/README.md"
"uri": "https://github.com/Microsoft/vsts-extension-color-control/blob/master/README.md"
},
"support": {
"uri": "https://github.com/Microsoft/vsts-sample-wit-custom-control"
"uri": "https://github.com/Microsoft/vsts-extension-color-control"
},
"repository": {
"uri": "https://github.com/Microsoft/vsts-sample-wit-custom-control"
"uri": "https://github.com/Microsoft/vsts-extension-color-control"
},
"issues": {
"uri": "https://github.com/Microsoft/vsts-sample-wit-custom-control/issues"
"uri": "https://github.com/Microsoft/vsts-extension-color-control/issues"
}
},
"branding": {
@ -51,6 +51,10 @@
"path": "dist",
"addressable": true
},
{
"path": "scripts",
"addressable": true
},
{
"path": "styles",
"addressable": true
@ -78,8 +82,8 @@
"inputs": [
{
"id": "FieldName",
"name": "Backing string field, must have allowed values.",
"description": "The field associated with the control.",
"name": "Select the field for this control. Example: Priority",
"description": "The field must have allowed values.",
"type": "WorkItemField",
"properties": {
"workItemFieldTypes": ["String", "Integer"]
@ -91,8 +95,7 @@
},
{
"id": "Labels",
"name": "Labels, ';' seperated. Example: a;b;c",
"description": "The list of values to select from.",
"name": "Define labels for each value. Example: a;b;c",
"validation": {
"dataType": "String",
"isRequired": false
@ -100,8 +103,7 @@
},
{
"id": "Colors",
"name": "Colors, ';' seperated. Example red;blue;green",
"description": "The field associated with the control.",
"name": "Define colors for each value. Example: red;blue;green",
"validation": {
"dataType": "String",
"isRequired": false