Users/aazhou/cleanup (#5)
* 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:
Родитель
608e7953fc
Коммит
666e26547c
|
@ -1,4 +1,5 @@
|
|||
node_modules
|
||||
scripts/*.js
|
||||
typings
|
||||
dist
|
||||
dist
|
||||
*.vsix
|
|
@ -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
|
||||
|
|
11
gruntfile.js
11
gruntfile.js
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче