Initial data storage sample
This commit is contained in:
Родитель
1d80d48b89
Коммит
34fd5df560
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"name": "data-storage",
|
||||
"homepage": "https://github.com/Microsoft/vsts-extension-samples",
|
||||
"description": "",
|
||||
"main": "",
|
||||
"moduleType": [],
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests"
|
||||
],
|
||||
"dependencies": {
|
||||
"vss-web-extension-sdk": "^1.95.2"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
.form-inline {
|
||||
display: table;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.form-inline .form-pair {
|
||||
display: table-row;
|
||||
}
|
||||
|
||||
.form-inline .form-key {
|
||||
display: table-cell;
|
||||
vertical-align: top;
|
||||
padding: 6px 16px 0px 10px;
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
.form-inline .form-value {
|
||||
display: table-cell;
|
||||
padding-top: 6px;
|
||||
}
|
||||
|
||||
.note-content {
|
||||
position: absolute;
|
||||
top: 185px;
|
||||
left: 15px;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.notes-grid-container {
|
||||
position: absolute;
|
||||
top: 30px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.notes-grid {
|
||||
height: 100%;
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Data storage service sample</title>
|
||||
<script src="bower_components/vss-web-extension-sdk/lib/VSS.SDK.min.js"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
// Initialize the VSS SDK
|
||||
VSS.init({
|
||||
usePlatformScripts: true,
|
||||
});
|
||||
|
||||
// Wait for the SDK to be initialized
|
||||
VSS.ready(function () {
|
||||
require(["scripts/extensionData"], function (extensionData) { });
|
||||
VSS.notifyLoadSucceeded();
|
||||
});
|
||||
</script>
|
||||
<div id="vss-extension">
|
||||
<div class="user">
|
||||
<div class="bool">
|
||||
<label>Boolean Value</label>
|
||||
<input class="booleanValue" type="checkbox" />
|
||||
</div>
|
||||
<div class="number">
|
||||
<label>Integer Value</label>
|
||||
<input class="numberValue" />
|
||||
</div>
|
||||
<div class="obj">
|
||||
<label>Object Value 1</label>
|
||||
<input class="objectValue1" />
|
||||
|
||||
<label>Object Value 2</label>
|
||||
<input class="objectValue2" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="default">
|
||||
<div class="bool">
|
||||
<label>Boolean Value</label>
|
||||
<input class="booleanValue" type="checkbox" />
|
||||
</div>
|
||||
<div class="number">
|
||||
<label>Integer Value</label>
|
||||
<input class="numberValue" />
|
||||
</div>
|
||||
<div class="obj">
|
||||
<label>Object Value 1</label>
|
||||
<input class="objectValue1" />
|
||||
|
||||
<label>Object Value 2</label>
|
||||
<input class="objectValue2" />
|
||||
|
||||
<button class="deleteButton">Delete</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
<button class="saveButton">Save Settings</button>
|
||||
|
||||
<div class="note-content">
|
||||
<div class="notes-toolbar-container"></div>
|
||||
<div class="notes-grid-container"></div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,59 @@
|
|||
/// <reference path='../typings/main.d.ts' />
|
||||
|
||||
define(["require", "exports", "VSS/SDK/Services/ExtensionData", "q" ], function (require, exports, ExtensionData, Q) {
|
||||
|
||||
$(function () {
|
||||
$('.saveButton').on('click', function (eventObject) {
|
||||
saveSettings("User", ".user");
|
||||
saveSettings("Default", ".default");
|
||||
});
|
||||
|
||||
$('.deleteButton').on('click', function (eventObject) {
|
||||
VSS.getService(VSS.ServiceIds.ExtensionData).then(function(dataService) {
|
||||
var deletePromise = dataService.deleteDocument("$settings", "objectValue");
|
||||
deletePromise.then( function() {
|
||||
getSettings("Default", ".default");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
getSettings("User", ".user");
|
||||
getSettings("Default", ".default");
|
||||
|
||||
NotesView.NotesView.enhance(NotesView.NotesView, $("#ess-extension"), {
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
function saveSettings(scope, selector) {
|
||||
var boolValue = $(selector + " .booleanValue").prop("checked");
|
||||
var numValue = parseInt($(selector + " .numberValue").val());
|
||||
var objValue = {
|
||||
val1: $(selector + " .objectValue1").val(),
|
||||
val2: $(selector + " .objectValue2").val()
|
||||
};
|
||||
VSS.getService(VSS.ServiceIds.ExtensionData).then(function (dataService) {
|
||||
dataService.setValue("booleanValue", boolValue, {scopeType: scope}).then(function (value) {
|
||||
});
|
||||
dataService.setValue("numberValue", numValue, {scopeType: scope}).then(function (value) {
|
||||
});
|
||||
dataService.setValue("objectValue", objValue, {scopeType: scope}).then(function (value) {
|
||||
});
|
||||
});
|
||||
}
|
||||
function getSettings(scope, selector) {
|
||||
VSS.getService(VSS.ServiceIds.ExtensionData).then(function (dataService) {
|
||||
var boolPromise = dataService.getValue("booleanValue", {scopeType: scope});
|
||||
var numPromise = dataService.getValue("numberValue", {scopeType: scope});
|
||||
var objPromise = dataService.getValue("objectValue", {scopeType: scope});
|
||||
Q.all([boolPromise, numPromise, objPromise]).spread(function (boolValue, numValue, objValue) {
|
||||
$(selector + " .booleanValue").prop("checked", boolValue);
|
||||
$(selector + " .numberValue").val(numValue ? numValue.toString() : "");
|
||||
$(selector + " .objectValue1").val(objValue ? objValue.val1 : "");
|
||||
$(selector + " .objectValue2").val(objValue ? objValue.val2 : "");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
//# sourceMappingURL=extension.js.map
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"ambientDependencies": {
|
||||
"Q": "github:DefinitelyTyped/DefinitelyTyped/q/Q.d.ts#4de74cb527395c13ba20b438c3a7a419ad931f1c",
|
||||
"jquery": "github:DefinitelyTyped/DefinitelyTyped/jquery/jquery.d.ts#470954c4f427e0805a2d633636a7c6aa7170def8",
|
||||
"knockout": "github:DefinitelyTyped/DefinitelyTyped/knockout/knockout.d.ts#4de74cb527395c13ba20b438c3a7a419ad931f1c",
|
||||
"vss": "github:microsoft/vss-web-extension-sdk/typings/vss.d.ts"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
{
|
||||
"manifestVersion": 1.0,
|
||||
"id": "samples-data-storage",
|
||||
"version": "0.1.0",
|
||||
"name": "Data Storage Sample",
|
||||
"description": "Explore how to store settings and documents using the provided data storage service.",
|
||||
"publisher": "fabrikam",
|
||||
"icons": {
|
||||
"default": "images/fabrikam-logo.png"
|
||||
},
|
||||
"categories": [
|
||||
"Developer samples"
|
||||
],
|
||||
"targets": [
|
||||
{
|
||||
"id": "Microsoft.VisualStudio.Services"
|
||||
}
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "css",
|
||||
"addressable": true
|
||||
},
|
||||
{
|
||||
"path": "images",
|
||||
"addressable": true
|
||||
},
|
||||
{
|
||||
"path": "extensionData.html",
|
||||
"addressable": true
|
||||
},
|
||||
{
|
||||
"path": "scripts",
|
||||
"addressable": true
|
||||
},
|
||||
{
|
||||
"path": "bower_components/vss-web-extension-sdk/lib/VSS.SDK.min.js",
|
||||
"addressable": true
|
||||
}
|
||||
],
|
||||
"contributions": [
|
||||
{
|
||||
"id": "data-storage-hub",
|
||||
"type": "ms.vss-web.hub",
|
||||
"description": "Adds an 'Extension Data Sample' hub to the Home hub group which shows how to use the extension data service apis.",
|
||||
"targets": [
|
||||
"ms.vss-web.home-hub-group"
|
||||
],
|
||||
"properties": {
|
||||
"name": "Data Storage",
|
||||
"order": 22,
|
||||
"uri": "extensionData.html"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Delete Branch</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script src="/lib/VSS.SDK.js"></script>
|
||||
<script>
|
||||
VSS.init({ usePlatformScripts: true });
|
||||
VSS.ready(function() {
|
||||
var activeWorkItemServiceSample = (function () {
|
||||
"use strict";
|
||||
|
||||
return {
|
||||
execute: function (ctx) {
|
||||
console.log(JSON.stringify(ctx));
|
||||
}
|
||||
};
|
||||
}());
|
||||
|
||||
VSS.register("activeWorkItemServiceSample", activeWorkItemServiceSample);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,77 +0,0 @@
|
|||
/// <reference path='ref/VSS/VSS.d.ts' />
|
||||
define(["require", "exports", "VSS/SDK/Services/ExtensionData", "q", "Scripts/NotesView"], function (require, exports, ExtensionData, Q, NotesView) {
|
||||
$(function () {
|
||||
$('.saveButton').on('click', function (eventObject) {
|
||||
saveSettings("User", ".user");
|
||||
saveSettings("Default", ".default");
|
||||
});
|
||||
|
||||
$('.deleteButton').on('click', function (eventObject) {
|
||||
VSS.getService("ms.vss-web.data-service").then(function (extensionSettingsService) {
|
||||
var deletePromise = extensionSettingsService.deleteDocument("$settings", "objectValue");
|
||||
deletePromise.then( function() {
|
||||
getSettings("Default", ".default");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
getSettings("User", ".user");
|
||||
getSettings("Default", ".default");
|
||||
|
||||
NotesView.NotesView.enhance(NotesView.NotesView, $("#ess-extension"), {
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
function saveSettings(scope, selector) {
|
||||
var boolValue = $(selector + " .booleanValue").prop("checked");
|
||||
var numValue = parseInt($(selector + " .numberValue").val());
|
||||
var objValue = {
|
||||
val1: $(selector + " .objectValue1").val(),
|
||||
val2: $(selector + " .objectValue2").val()
|
||||
};
|
||||
VSS.getService("ms.vss-web.data-service").then(function (extensionSettingsService) {
|
||||
extensionSettingsService.setValue("booleanValue", boolValue, {scopeType: scope}).then(function (value) {
|
||||
});
|
||||
extensionSettingsService.setValue("numberValue", numValue, {scopeType: scope}).then(function (value) {
|
||||
});
|
||||
extensionSettingsService.setValue("objectValue", objValue, {scopeType: scope}).then(function (value) {
|
||||
});
|
||||
});
|
||||
}
|
||||
function getSettings(scope, selector) {
|
||||
VSS.getService("ms.vss-web.data-service").then(function (extensionSettingsService) {
|
||||
var boolPromise = extensionSettingsService.getValue("booleanValue", {scopeType: scope});
|
||||
var numPromise = extensionSettingsService.getValue("numberValue", {scopeType: scope});
|
||||
var objPromise = extensionSettingsService.getValue("objectValue", {scopeType: scope});
|
||||
Q.all([boolPromise, numPromise, objPromise]).spread(function (boolValue, numValue, objValue) {
|
||||
$(selector + " .booleanValue").prop("checked", boolValue);
|
||||
$(selector + " .numberValue").val(numValue ? numValue.toString() : "");
|
||||
$(selector + " .objectValue1").val(objValue ? objValue.val1 : "");
|
||||
$(selector + " .objectValue2").val(objValue ? objValue.val2 : "");
|
||||
});
|
||||
});
|
||||
}
|
||||
// function addNote(id, title desc) {
|
||||
// VSS.getService("settings-service", VSS.getExtensionContext().id).then(function (extensionSettingsService) {
|
||||
// var note = {'id': id, 'title': title, 'description': desc};
|
||||
// extensionSettingsService.createDocument(note, "notes", {"ScopeType": "User"});
|
||||
// }
|
||||
// }
|
||||
// function editNote(note) {
|
||||
// VSS.getService("settings-service", VSS.getExtensionContext().id).then(function (extensionSettingsService) {
|
||||
// extensionSettingsService.createDocument(note, "notes", {"ScopeType": "User"});
|
||||
// }
|
||||
// }
|
||||
// function deleteNote(noteId) {
|
||||
// VSS.getService("settings-service", VSS.getExtensionContext().id).then(function (extensionSettingsService) {
|
||||
// extensionSettingsService.createDocument("notes", {"ScopeType": "User"}, noteId);
|
||||
// }
|
||||
// }
|
||||
// function getNotes() {
|
||||
// VSS.getService("settings-service", VSS.getExtensionContext().id).then(function (extensionSettingsService) {
|
||||
// extensionSettingsService.getDocuments("notes", {"ScopeType": "User"});
|
||||
// }
|
||||
// }
|
||||
});
|
||||
//# sourceMappingURL=extension.js.map
|
|
@ -1,155 +0,0 @@
|
|||
/// <reference path='ref/VSS/VSS.d.ts' />
|
||||
var __extends = this.__extends || function (d, b) {
|
||||
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||
function __() { this.constructor = d; }
|
||||
__.prototype = b.prototype;
|
||||
d.prototype = new __();
|
||||
};
|
||||
define(["require",
|
||||
"exports",
|
||||
"VSS/Utils/String",
|
||||
"VSS/Service",
|
||||
"VSS/Utils/UI",
|
||||
"VSS/Controls",
|
||||
"VSS/Controls/Notifications",
|
||||
"VSS/Controls/Dialogs"], function (require, exports, Utils_String, Service, Utils_UI, Controls, ControlsNotifications, ControlsDialogs) {
|
||||
var domElem = Utils_UI.domElem;
|
||||
/**
|
||||
* A dialog for creating or editing a note
|
||||
*/
|
||||
var NotesDialog = (function (_super) {
|
||||
__extends(NotesDialog, _super);
|
||||
function NotesDialog() {
|
||||
_super.apply(this, arguments);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param options
|
||||
*/
|
||||
NotesDialog.prototype.initializeOptions = function (options) {
|
||||
_super.prototype.initializeOptions.call(this, $.extend({}, options));
|
||||
};
|
||||
/**
|
||||
* Adds input elements to the dialog
|
||||
*/
|
||||
NotesDialog.prototype.initialize = function () {
|
||||
var _this = this;
|
||||
_super.prototype.initialize.call(this);
|
||||
this._$container = $(domElem('div')).addClass('.edit-note-container').appendTo(this._element);
|
||||
this._noteValidationError = Controls.BaseControl.createIn(ControlsNotifications.MessageAreaControl, this._$container, { closeable: false });
|
||||
var inputId = "noteId" + Controls.getId();
|
||||
$(domElem("label"))
|
||||
.attr("for", inputId)
|
||||
.text("ID")
|
||||
.appendTo(this._$container);
|
||||
var idDiv = $(domElem('div')).appendTo(this._$container);
|
||||
this._$inputId = $(domElem("input", "note-id"))
|
||||
.addClass('requiredInfoLight')
|
||||
.addClass('textbox')
|
||||
.attr("type", "text")
|
||||
.attr("id", inputId)
|
||||
.appendTo(idDiv)
|
||||
.bind("input keyup", function (e) {
|
||||
if (e.keyCode !== Utils_UI.KeyCode.ENTER) {
|
||||
var isValid = _this._validateId();
|
||||
_this.updateOkButton(isValid && $.trim(_this._$inputId.val()).length > 0);
|
||||
if (isValid) {
|
||||
_this._clearError();
|
||||
}
|
||||
}
|
||||
});
|
||||
inputId = "noteTitle" + Controls.getId();
|
||||
$(domElem("label"))
|
||||
.attr("for", inputId)
|
||||
.text("Title")
|
||||
.appendTo(this._$container);
|
||||
var titleDiv = $(domElem('div')).appendTo(this._$container);
|
||||
this._$inputTitle = $(domElem("textarea", "note-title"))
|
||||
.addClass('requiredInfoLight')
|
||||
.addClass('textbox')
|
||||
.attr("type", "text")
|
||||
.attr("id", inputId)
|
||||
.appendTo(titleDiv)
|
||||
.bind("input keyup", function (e) {
|
||||
if (e.keyCode !== Utils_UI.KeyCode.ENTER) {
|
||||
if (_this._options.note) {
|
||||
_this.updateOkButton($.trim(_this._$inputTitle.val()) !== _this._options.note.title);
|
||||
}
|
||||
}
|
||||
});
|
||||
this._$inputId.select();
|
||||
|
||||
inputId = "noteUserOnly" + Controls.getId();
|
||||
$(domElem("label"))
|
||||
.attr("for", inputId)
|
||||
.text("User-Only")
|
||||
.appendTo(this._$container);
|
||||
var userOnlyDiv = $(domElem('div')).appendTo(this._$container);
|
||||
this._$inputUserOnly = $(domElem("input", "note-user-only"))
|
||||
.attr("type", "checkbox")
|
||||
.attr("id", inputId)
|
||||
.appendTo(userOnlyDiv);
|
||||
|
||||
if (this._options.note) {
|
||||
this._$inputTitle.val(this._options.note.title);
|
||||
this._$inputId.val(this._options.note.noteId);
|
||||
this._$inputUserOnly.prop('checked', this._options.note.userOnly);
|
||||
this._$inputId.attr('disabled', 'disabled');
|
||||
this._$inputId.removeClass('requiredInfoLight');
|
||||
this._$inputTitle.select();
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Returns the title of the dialog
|
||||
*/
|
||||
NotesDialog.prototype.getTitle = function () {
|
||||
return this._options.title;
|
||||
};
|
||||
/**
|
||||
* Processes the data that the user has entered and either
|
||||
* shows an error message, or returns the edited note.
|
||||
*/
|
||||
NotesDialog.prototype.onOkClick = function () {
|
||||
var _this = this;
|
||||
var noteId = parseInt($.trim(this._$inputId.val()));
|
||||
var title = $.trim(this._$inputTitle.val());
|
||||
var userOnly = this._$inputUserOnly.prop('checked');
|
||||
this._note = { noteId: noteId, title: title, userOnly: userOnly};
|
||||
if (this._options.note) {
|
||||
this._note.__etag = this._options.note.__etag;
|
||||
this._note.id = this._options.note.id;
|
||||
}
|
||||
// if (!this._options.note) {
|
||||
// var notesClient = Service.getClient(VSS_VssfSdkSample_WebApi.VssfSdkSampleHttpClient);
|
||||
// notesClient.getNote(this._note.noteId).then(function (note) {
|
||||
// _this._setError(Utils_String.format(VSS_Resources_VssfSdkSample.NoteExistsMessage, _this._note.noteId));
|
||||
// }, function (e) {
|
||||
// _this.processResult(_this._note);
|
||||
// });
|
||||
// }
|
||||
// else {
|
||||
this.processResult(this._note);
|
||||
//}
|
||||
};
|
||||
NotesDialog.prototype._validateId = function () {
|
||||
var id = $.trim(this._$inputId.val());
|
||||
var idNum = parseInt(id, 10);
|
||||
var isValid = !isNaN(idNum) && 0 < idNum && idNum < 2147483648; // 0 < idNum < int32.MaxValue + 1
|
||||
if (id.length === 0 || isValid) {
|
||||
this._clearError();
|
||||
}
|
||||
else if (id.length > 0) {
|
||||
this._setError(Utils_String.format("ID {0} is invalid.", id));
|
||||
}
|
||||
return isValid;
|
||||
};
|
||||
NotesDialog.prototype._setError = function (errorMessage) {
|
||||
this._noteValidationError.setError($("<span />").html(errorMessage));
|
||||
};
|
||||
NotesDialog.prototype._clearError = function () {
|
||||
this._noteValidationError.clear();
|
||||
};
|
||||
return NotesDialog;
|
||||
})(ControlsDialogs.ModalDialog);
|
||||
exports.NotesDialog = NotesDialog;
|
||||
});
|
|
@ -1,180 +0,0 @@
|
|||
/// <reference path='ref/VSS/VSS.d.ts' />
|
||||
var __extends = this.__extends || function (d, b) {
|
||||
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||
function __() { this.constructor = d; }
|
||||
__.prototype = b.prototype;
|
||||
d.prototype = new __();
|
||||
};
|
||||
define(["require", "exports", "VSS/Utils/Core", "VSS/Controls/Grids"], function (require, exports, Utils_Core, Grids) {
|
||||
var delegate = Utils_Core.delegate;
|
||||
/**
|
||||
* Represents a grid of note objects.
|
||||
* Displays notes, as well as handles context menu for editing and deleting.
|
||||
*/
|
||||
var NotesGrid = (function (_super) {
|
||||
__extends(NotesGrid, _super);
|
||||
function NotesGrid() {
|
||||
_super.apply(this, arguments);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param options
|
||||
*/
|
||||
NotesGrid.prototype.initializeOptions = function (options) {
|
||||
_super.prototype.initializeOptions.call(this, $.extend({
|
||||
sharedMeasurements: false,
|
||||
allowMoveColumns: false,
|
||||
allowMultiSelect: true,
|
||||
gutter: {
|
||||
contextMenu: true
|
||||
},
|
||||
contextMenu: {
|
||||
items: delegate(this, this._getContextMenuItems),
|
||||
updateCommandStates: delegate(this, this._updateCommandStates),
|
||||
executeAction: delegate(this, this._onMenuItemClick)
|
||||
},
|
||||
cssClass: "notes-grid",
|
||||
columns: this._getColumns(),
|
||||
sortOrder: this._getSortOrder(),
|
||||
initialSelection: false
|
||||
}, options));
|
||||
};
|
||||
/**
|
||||
* Populates the grid with a collection of note objects.
|
||||
* Also attempts to maintain note selection.
|
||||
* @param rawSource The collection of notes to populate in the grid.
|
||||
*/
|
||||
NotesGrid.prototype.setSource = function (rawSource) {
|
||||
var options = this._options;
|
||||
var prevSelection = this.getSelectedNote();
|
||||
options.source = rawSource;
|
||||
options.columns = this._columns;
|
||||
options.sortOrder = this._sortOrder;
|
||||
this.initializeDataSource();
|
||||
this.onSort(options.sortOrder);
|
||||
if (rawSource && rawSource.length > 0) {
|
||||
var indexToSelect = 0;
|
||||
if (prevSelection) {
|
||||
for (var i = 0, l = rawSource.length; i < l; i++) {
|
||||
if (rawSource[i] && prevSelection.noteId === rawSource[i].noteId) {
|
||||
indexToSelect = this._getRowIndex(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
this._selectRow(indexToSelect);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Row double-click handler
|
||||
* @param eventArgs
|
||||
*/
|
||||
NotesGrid.prototype.onRowDoubleClick = function (eventArgs) {
|
||||
var note = this.getSelectedNote();
|
||||
if (note) {
|
||||
this._fire(NotesGrid.Events.NOTE_DOUBLE_CLICK, note);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Returns a list of selected notes in the grid
|
||||
*/
|
||||
NotesGrid.prototype.getSelectedNotes = function () {
|
||||
var selectedItems = [];
|
||||
for (var rowIndex in this._selectedRows) {
|
||||
if (this._selectedRows.hasOwnProperty(rowIndex)) {
|
||||
selectedItems.push(this._dataSource[this._selectedRows[rowIndex]]);
|
||||
}
|
||||
}
|
||||
return selectedItems;
|
||||
};
|
||||
/**
|
||||
* Returns a single, selected note in the grid
|
||||
*/
|
||||
NotesGrid.prototype.getSelectedNote = function () {
|
||||
var selectedDataIndex = this._selectedRows[this._selectedIndex];
|
||||
return (typeof (selectedDataIndex) === "number") ? this._dataSource[selectedDataIndex] : null;
|
||||
};
|
||||
/**
|
||||
* Updates the selected row index and fires an event
|
||||
* indicating the selected note has changed.
|
||||
*/
|
||||
NotesGrid.prototype.selectedIndexChanged = function (selectedRowIndex, selectedDataIndex) {
|
||||
_super.prototype.selectedIndexChanged.call(this, selectedRowIndex, selectedDataIndex);
|
||||
this._fire(NotesGrid.Events.SELECTED_NOTE_CHANGED, this._dataSource[selectedDataIndex]);
|
||||
};
|
||||
NotesGrid.prototype._getContextMenuItems = function () {
|
||||
var that = this;
|
||||
function getActionArgs() {
|
||||
return {
|
||||
selectedNote: that.getSelectedNotes(),
|
||||
selectedNotes: that.getSelectedNote()
|
||||
};
|
||||
}
|
||||
var commands = [];
|
||||
commands.push({ rank: 5, id: NotesGrid.MenuCommands.EDIT_NOTE, text: "Edit Note", icon: "icon-edit", 'arguments': getActionArgs });
|
||||
commands.push({ rank: 10, id: NotesGrid.MenuCommands.DELETE_SELECTED_NOTE, text: "Delete Note", icon: "icon-delete", 'arguments': getActionArgs });
|
||||
return commands;
|
||||
};
|
||||
NotesGrid.prototype._updateCommandStates = function (menu) {
|
||||
var items = this.getSelectedNotes();
|
||||
var exactlyOneItem = items && items.length == 1;
|
||||
var states = [];
|
||||
states.push({ id: NotesGrid.MenuCommands.EDIT_NOTE, disabled: !exactlyOneItem });
|
||||
states.push({ id: NotesGrid.MenuCommands.DELETE_SELECTED_NOTE, disabled: !items || items.length < 1 });
|
||||
menu.updateCommandStates(states);
|
||||
};
|
||||
NotesGrid.prototype._onMenuItemClick = function (e) {
|
||||
this._fire(NotesGrid.Events.NOTE_MENU_ITEM_CLICKED, e);
|
||||
};
|
||||
NotesGrid.prototype._getColumns = function () {
|
||||
var columns = [];
|
||||
columns.push({
|
||||
index: "noteId",
|
||||
text: "Note Id",
|
||||
width: 150,
|
||||
getColumnValue: function (dataIndex, columnIndex, columnOrder) {
|
||||
var note = this._dataSource[dataIndex];
|
||||
return note.noteId;
|
||||
},
|
||||
comparer: function (column, order, item1, item2) {
|
||||
return item1.noteId - item2.noteId;
|
||||
}
|
||||
});
|
||||
columns.push({
|
||||
index: "title",
|
||||
text: "Title",
|
||||
width: 150,
|
||||
getColumnValue: function (dataIndex, columnIndex, columnOrder) {
|
||||
var note = this._dataSource[dataIndex];
|
||||
return note.title;
|
||||
}
|
||||
});
|
||||
columns.push({
|
||||
index: "userOnly",
|
||||
text: "User Only",
|
||||
width: 150,
|
||||
getColumnValue: function (dataIndex, columnIndex, columnOrder) {
|
||||
var note = this._dataSource[dataIndex];
|
||||
return note.userOnly;
|
||||
}
|
||||
});
|
||||
return columns;
|
||||
};
|
||||
NotesGrid.prototype._getSortOrder = function () {
|
||||
var sortColumns = [];
|
||||
sortColumns.push({ index: "noteId", order: "asc" });
|
||||
return sortColumns;
|
||||
};
|
||||
NotesGrid.Events = {
|
||||
NOTE_DOUBLE_CLICK: "noteDoubleClick",
|
||||
SELECTED_NOTE_CHANGED: "selectedNoteChanged",
|
||||
NOTE_MENU_ITEM_CLICKED: "noteMenuItemClicked"
|
||||
};
|
||||
NotesGrid.MenuCommands = {
|
||||
EDIT_NOTE: "edit-note",
|
||||
DELETE_SELECTED_NOTE: "delete-selected-note"
|
||||
};
|
||||
return NotesGrid;
|
||||
})(Grids.GridO);
|
||||
exports.NotesGrid = NotesGrid;
|
||||
});
|
|
@ -1,176 +0,0 @@
|
|||
/// <reference path='ref/VSS/VSS.d.ts' />
|
||||
var __extends = this.__extends || function (d, b) {
|
||||
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||
function __() { this.constructor = d; }
|
||||
__.prototype = b.prototype;
|
||||
d.prototype = new __();
|
||||
};
|
||||
define(["require", "exports", "VSS/Service"], function (require, exports, Service) {
|
||||
/**
|
||||
* Service layer for interacting with Notes Http Client
|
||||
*/
|
||||
var NotesService = (function (_super) {
|
||||
__extends(NotesService, _super);
|
||||
function NotesService() {
|
||||
_super.apply(this, arguments);
|
||||
}
|
||||
/**
|
||||
* Builds the NotesService
|
||||
* @param dataLoadedCallback function to be invoked when data has been loaded
|
||||
* @param failureCallback function to be invoked when an http request has failed
|
||||
*/
|
||||
NotesService.prototype.initService = function (dataLoadedCallback, failureCallback) {
|
||||
this._dataLoadedCallback = dataLoadedCallback;
|
||||
this._failureCallback = failureCallback;
|
||||
this._loadData();
|
||||
};
|
||||
/**
|
||||
* Issues a request to create the new note
|
||||
* @param note
|
||||
* @param successCallback function to be invoked if the request succeeds
|
||||
*/
|
||||
NotesService.prototype.createNote = function (note, successCallback) {
|
||||
var _this = this;
|
||||
VSS.getService("ms.vss-web.data-service").then(function (extensionSettingsService) {
|
||||
var scopeType = note.userOnly ? "User" : "Default";
|
||||
extensionSettingsService.createDocument("Notes", note, {scopeType: scopeType}).then(function (savedNote) {
|
||||
_this._addNote(savedNote);
|
||||
if ($.isFunction(successCallback)) {
|
||||
successCallback(savedNote);
|
||||
}
|
||||
}, function (error) {
|
||||
if ($.isFunction(_this._failureCallback)) {
|
||||
_this._failureCallback(error);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/**
|
||||
* Issues a request to delete note
|
||||
* @param note
|
||||
* @param successCallback function to be invoked if the request succeeds
|
||||
*/
|
||||
NotesService.prototype.deleteNote = function (note, successCallback) {
|
||||
var _this = this;
|
||||
VSS.getService("ms.vss-web.data-service").then(function (extensionSettingsService) {
|
||||
var scopeType = note.userOnly ? "User" : "Default";
|
||||
extensionSettingsService.deleteDocument("Notes", note.id, {scopeType: scopeType}).then(function () {
|
||||
_this._removeNote(note);
|
||||
if ($.isFunction(successCallback)) {
|
||||
successCallback();
|
||||
}
|
||||
}, function (error) {
|
||||
if ($.isFunction(_this._failureCallback)) {
|
||||
_this._failureCallback(error);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/**
|
||||
* Issues a request to update the note
|
||||
* @param note
|
||||
* @param successCallback function to be invoked if the request succeeds
|
||||
*/
|
||||
NotesService.prototype.updateNote = function (originalNote, editedNote, successCallback) {
|
||||
var _this = this;
|
||||
VSS.getService("ms.vss-web.data-service").then(function (extensionSettingsService) {
|
||||
if (originalNote.userOnly !== editedNote.userOnly) {
|
||||
var oldScopeType = originalNote.userOnly ? "User" : "Default";
|
||||
extensionSettingsService.deleteDocument("Notes", originalNote.id, {scopeType: oldScopeType}).then(function () {
|
||||
var newScopeType = editedNote.userOnly ? "User" : "Default";
|
||||
|
||||
extensionSettingsService.createDocument("Notes", editedNote, {scopeType: newScopeType}).then(function (savedNote) {
|
||||
_this._replaceNote(editedNote, savedNote);
|
||||
if ($.isFunction(successCallback)) {
|
||||
successCallback();
|
||||
}
|
||||
}, function (error) {
|
||||
if ($.isFunction(_this._failureCallback)) {
|
||||
_this._failureCallback(error);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
else {
|
||||
var scopeType = editedNote.userOnly ? "User" : "Default";
|
||||
extensionSettingsService.updateDocument("Notes", editedNote, {scopeType: scopeType}).then(function (savedNote) {
|
||||
_this._replaceNote(editedNote, savedNote);
|
||||
if ($.isFunction(successCallback)) {
|
||||
successCallback();
|
||||
}
|
||||
}, function (error) {
|
||||
if ($.isFunction(_this._failureCallback)) {
|
||||
_this._failureCallback(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
/**
|
||||
* Refreshes the cached notes from the server
|
||||
*/
|
||||
NotesService.prototype.refresh = function () {
|
||||
this._loadData();
|
||||
};
|
||||
NotesService.prototype._loadData = function () {
|
||||
var _this = this;
|
||||
VSS.getService("ms.vss-web.data-service").then(function (extensionSettingsService) {
|
||||
_this.notes = [];
|
||||
extensionSettingsService.getDocuments("Notes")
|
||||
.then(function (notes) {
|
||||
_this._processData(notes);
|
||||
if ($.isFunction(_this._dataLoadedCallback)) {
|
||||
_this._dataLoadedCallback.call(_this);
|
||||
}
|
||||
}, function (error) {
|
||||
if ($.isFunction(_this._failureCallback)) {
|
||||
//_this._failureCallback(error);
|
||||
}
|
||||
});
|
||||
extensionSettingsService.getDocuments("Notes", {"scopeType": "User"})
|
||||
.then(function (notes) {
|
||||
_this._processData(notes);
|
||||
if ($.isFunction(_this._dataLoadedCallback)) {
|
||||
_this._dataLoadedCallback.call(_this);
|
||||
}
|
||||
}, function (error) {
|
||||
if ($.isFunction(_this._failureCallback)) {
|
||||
//_this._failureCallback(error);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
NotesService.prototype._processData = function (notes) {
|
||||
var _this = this;
|
||||
$.each(notes, function (i, note) {
|
||||
_this.notes.push(note);
|
||||
});
|
||||
};
|
||||
NotesService.prototype._addNote = function (note) {
|
||||
this.notes.push(note);
|
||||
};
|
||||
NotesService.prototype._replaceNote = function (oldNote, newNote) {
|
||||
var newNotes = [];
|
||||
$.each(this.notes, function (i, note) {
|
||||
if (note.id == oldNote.id) {
|
||||
newNotes.push(newNote);
|
||||
}
|
||||
else {
|
||||
newNotes.push(note);
|
||||
}
|
||||
});
|
||||
this.notes = newNotes;
|
||||
};
|
||||
NotesService.prototype._removeNote = function (noteToRemove) {
|
||||
var newNotes = [];
|
||||
$.each(this.notes, function (i, note) {
|
||||
if (noteToRemove.id != note.id) {
|
||||
newNotes.push(note);
|
||||
}
|
||||
});
|
||||
this.notes = newNotes;
|
||||
};
|
||||
return NotesService;
|
||||
})(Service.VssService);
|
||||
exports.NotesService = NotesService;
|
||||
});
|
|
@ -1,174 +0,0 @@
|
|||
/// <reference path='ref/VSS.d.ts' />
|
||||
var __extends = this.__extends || function (d, b) {
|
||||
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||
function __() { this.constructor = d; }
|
||||
__.prototype = b.prototype;
|
||||
d.prototype = new __();
|
||||
};
|
||||
define([
|
||||
"require",
|
||||
"exports",
|
||||
"VSS/Utils/Core",
|
||||
"Scripts/notesDialog",
|
||||
"Scripts/notesGrid",
|
||||
"Scripts/notesService",
|
||||
"VSS/Service",
|
||||
"VSS/Controls",
|
||||
"VSS/Controls/Menus",
|
||||
"VSS/Controls/Navigation",
|
||||
"VSS/Controls/Notifications"], function (require, exports, Utils_Core, NotesDialog, NotesGrid, NotesService, Service, Controls, Menus, Navigation, Notifications) {
|
||||
var delegate = Utils_Core.delegate;
|
||||
/**
|
||||
* Creates a high-level view object the notes UI.
|
||||
* Contains a grid and toolbar for viewing, adding, deleting and editing notes.
|
||||
*/
|
||||
var NotesView = (function (_super) {
|
||||
__extends(NotesView, _super);
|
||||
function NotesView() {
|
||||
_super.apply(this, arguments);
|
||||
}
|
||||
/**
|
||||
* Initializes the view to populate data and wire up other controls
|
||||
*/
|
||||
NotesView.prototype.initialize = function () {
|
||||
var _this = this;
|
||||
this._notesService = Service.getService(NotesService.NotesService);
|
||||
this._notesService.initService(function () { _this._onDataLoaded(); }, function (e) { _this._setError(e.message); });
|
||||
this._noteValidationError = Controls.BaseControl.createIn(Notifications.MessageAreaControl, this._element, { closeable: true });
|
||||
var $toolbarContainer = this._element.find(".notes-toolbar-container");
|
||||
this._toolbar = this._createMenuBar($toolbarContainer);
|
||||
var $gridContainer = this._element.find(".notes-grid-container");
|
||||
this._grid = Controls.BaseControl.createIn(NotesGrid.NotesGrid, $gridContainer, {
|
||||
viewModel: this._notesService
|
||||
});
|
||||
this._updateMenubarItems();
|
||||
this._bind(NotesGrid.NotesGrid.Events.NOTE_MENU_ITEM_CLICKED, delegate(this, this._onContextMenuItemClick));
|
||||
this._bind(NotesGrid.NotesGrid.Events.SELECTED_NOTE_CHANGED, delegate(this, this._onSelectedNoteChanged));
|
||||
this._bind(NotesGrid.NotesGrid.Events.NOTE_DOUBLE_CLICK, delegate(this, this._onNoteDoubleClick));
|
||||
|
||||
};
|
||||
NotesView.prototype._setError = function (message) {
|
||||
this._noteValidationError.setError(message);
|
||||
};
|
||||
NotesView.prototype._clearError = function () {
|
||||
this._noteValidationError.clear();
|
||||
};
|
||||
NotesView.prototype._createMenuBar = function ($container) {
|
||||
return Controls.BaseControl.createIn(Menus.MenuBar, $container, {
|
||||
items: this._createMenubarItems(),
|
||||
executeAction: Utils_Core.delegate(this, this._onMenuItemClick)
|
||||
});
|
||||
};
|
||||
NotesView.prototype._createMenubarItems = function () {
|
||||
var items = [];
|
||||
items.push({ id: NotesView.MenuCommands.NEW_NOTE, text: "New", title: "New Note", showText: false, icon: "icon-add-small" });
|
||||
items.push({ separator: true });
|
||||
items.push({ id: NotesView.MenuCommands.EDIT_NOTE, text: "Edit", title: "Edit Note", showText: false, icon: "icon-edit" });
|
||||
items.push({ id: NotesView.MenuCommands.REFRESH_NOTES, text: "Refresh", title: "Refresh Notes", showText: false, icon: "icon-refresh" });
|
||||
items.push({ id: NotesView.MenuCommands.DELETE_SELECTED_NOTE, text: "Delete", title: "Delete Note", showText: false, icon: "icon-delete" });
|
||||
return items;
|
||||
};
|
||||
NotesView.prototype._onContextMenuItemClick = function (e, args) {
|
||||
this._onMenuItemClick(args);
|
||||
};
|
||||
NotesView.prototype._onMenuItemClick = function (e) {
|
||||
var command = e.get_commandName();
|
||||
switch (command) {
|
||||
case NotesView.MenuCommands.NEW_NOTE:
|
||||
this._createNewNote();
|
||||
break;
|
||||
case NotesView.MenuCommands.EDIT_NOTE:
|
||||
this._editNote(this._grid.getSelectedNote());
|
||||
break;
|
||||
case NotesView.MenuCommands.REFRESH_NOTES:
|
||||
this._refreshNotes();
|
||||
break;
|
||||
case NotesView.MenuCommands.DELETE_SELECTED_NOTE:
|
||||
this._deleteNotes(this._grid.getSelectedNotes());
|
||||
break;
|
||||
}
|
||||
};
|
||||
NotesView.prototype._updateGrid = function (notes) {
|
||||
this._clearError();
|
||||
this._grid.setSource(notes);
|
||||
var noteExists = notes.length > 0;
|
||||
$(".no-notes").toggleClass("vssf-sdk-sample-hide", noteExists);
|
||||
$(".add-first-note-link").toggleClass("vssf-sdk-sample-hide", noteExists);
|
||||
$(".notes-content").toggleClass("vssf-sdk-sample-hide", !noteExists);
|
||||
};
|
||||
NotesView.prototype._setSelectedNote = function (noteToSelect) {
|
||||
var _this = this;
|
||||
$.each(this._notesService.notes, function (i, note) {
|
||||
if (note.noteId == noteToSelect.noteId) {
|
||||
_this._grid.setSelectedDataIndex(i);
|
||||
return false; // break
|
||||
}
|
||||
});
|
||||
};
|
||||
NotesView.prototype._onSelectedNoteChanged = function (e, selectedNote) {
|
||||
this.delayExecute("updateMenuItems", 250, true, this._updateMenubarItems);
|
||||
};
|
||||
NotesView.prototype._onNoteDoubleClick = function (e, note) {
|
||||
if (note) {
|
||||
this._editNote(note);
|
||||
}
|
||||
};
|
||||
NotesView.prototype._showNoteDialog = function (title, note, okCallback) {
|
||||
ControlsCommon.Dialog.show(NotesDialog.NotesDialog, {
|
||||
height: 600,
|
||||
width: 600,
|
||||
resizable: true,
|
||||
okCallback: okCallback,
|
||||
title: title,
|
||||
note: note
|
||||
});
|
||||
};
|
||||
NotesView.prototype._updateMenubarItems = function () {
|
||||
var selectedNotes = this._grid.getSelectedNotes();
|
||||
this._toolbar.updateCommandStates([{ id: NotesView.MenuCommands.EDIT_NOTE, disabled: selectedNotes.length !== 1 }]);
|
||||
this._toolbar.updateCommandStates([{ id: NotesView.MenuCommands.DELETE_SELECTED_NOTE, disabled: selectedNotes.length === 0 }]);
|
||||
};
|
||||
NotesView.prototype._onDataLoaded = function () {
|
||||
this._updateGrid(this._notesService.notes);
|
||||
};
|
||||
NotesView.prototype._createNewNote = function () {
|
||||
var _this = this;
|
||||
this._showNoteDialog("Create Note", null, function (newNote) {
|
||||
_this._notesService.createNote(newNote, function () {
|
||||
_this._updateGrid(_this._notesService.notes);
|
||||
_this._setSelectedNote(newNote);
|
||||
});
|
||||
});
|
||||
};
|
||||
NotesView.prototype._deleteNotes = function (notes) {
|
||||
var _this = this;
|
||||
if (confirm("Are you sure you want to delete this note?")) {
|
||||
$.each(notes, function (i, note) {
|
||||
_this._notesService.deleteNote(note, function () {
|
||||
_this._updateGrid(_this._notesService.notes);
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
NotesView.prototype._editNote = function (note) {
|
||||
var _this = this;
|
||||
this._showNoteDialog("Edit Note", note, function (editedNote) {
|
||||
_this._notesService.updateNote(note, editedNote, function () {
|
||||
_this._updateGrid(_this._notesService.notes);
|
||||
_this._setSelectedNote(editedNote);
|
||||
});
|
||||
});
|
||||
};
|
||||
NotesView.prototype._refreshNotes = function () {
|
||||
this._notesService.refresh();
|
||||
};
|
||||
NotesView.MenuCommands = {
|
||||
DELETE_SELECTED_NOTE: "delete-selected-note",
|
||||
EDIT_NOTE: "edit-note",
|
||||
NEW_NOTE: "new-note",
|
||||
REFRESH_NOTES: "refresh-notes"
|
||||
};
|
||||
return NotesView;
|
||||
})(Navigation.NavigationView);
|
||||
exports.NotesView = NotesView;
|
||||
});
|
|
@ -1,89 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Work item extension page sample</title>
|
||||
</head>
|
||||
|
||||
<body style="overflow:auto;">
|
||||
<script src="sdk/scripts/VSS.SDK.js"></script>
|
||||
|
||||
<script>
|
||||
|
||||
VSS.init({
|
||||
explicitNotifyLoaded: true,
|
||||
usePlatformScripts: true
|
||||
});
|
||||
|
||||
VSS.require(["TFS/WorkItemTracking/Services"], function (_WorkItemServices) {
|
||||
|
||||
// Get the WorkItemFormService. This service allows you to get/set fields/links on the 'active' work item (the work item
|
||||
// that currently is displayed in the UI).
|
||||
function getWorkItemFormService()
|
||||
{
|
||||
return _WorkItemServices.WorkItemFormService.getService();
|
||||
}
|
||||
|
||||
// Register a listener for the work item group contribution.
|
||||
VSS.register("sample-work-item-form-group", function () {
|
||||
return {
|
||||
// Called when the active work item is modified
|
||||
onFieldChanged: function(args) {
|
||||
$(".events").append($("<div/>").text("onFieldChanged - " + JSON.stringify(args)));
|
||||
},
|
||||
|
||||
// Called when a new work item is being loaded in the UI
|
||||
onLoaded: function (args) {
|
||||
|
||||
getWorkItemFormService().then(function(service) {
|
||||
// Get the current values for a few of the common fields
|
||||
service.getFieldValues(["System.Id", "System.Title", "System.State", "System.CreatedDate"]).then(
|
||||
function (value) {
|
||||
$(".events").append($("<div/>").text("onLoaded - " + JSON.stringify(value)));
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
// Called when the active work item is being unloaded in the UI
|
||||
onUnloaded: function (args) {
|
||||
$(".events").empty();
|
||||
$(".events").append($("<div/>").text("onUnloaded - " + JSON.stringify(args)));
|
||||
},
|
||||
|
||||
// Called after the work item has been saved
|
||||
onSaved: function (args) {
|
||||
$(".events").append($("<div/>").text("onSaved - " + JSON.stringify(args)));
|
||||
},
|
||||
|
||||
// Called when the work item is reset to its unmodified state (undo)
|
||||
onReset: function (args) {
|
||||
$(".events").append($("<div/>").text("onReset - " + JSON.stringify(args)));
|
||||
},
|
||||
|
||||
// Called when the work item has been refreshed from the server
|
||||
onRefreshed: function (args) {
|
||||
$(".events").append($("<div/>").text("onRefreshed - " + JSON.stringify(args)));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
VSS.notifyLoadSucceeded();
|
||||
|
||||
// register a handler for the 'Click me!' button.
|
||||
$("#clickme").click(function() {
|
||||
getWorkItemFormService().then(function(service) {
|
||||
service.setFieldValue("System.Title", "Title set from your group extension!")
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<p> Hello, your work item group contribution is now active! </p>
|
||||
<button type="button" id="clickme">Click me!</button>
|
||||
<div class='events'> </div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,91 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Work item extension page sample</title>
|
||||
</head>
|
||||
|
||||
<body style="overflow:auto;">
|
||||
<script src="sdk/scripts/VSS.SDK.js"></script>
|
||||
|
||||
<script>
|
||||
|
||||
VSS.init({
|
||||
explicitNotifyLoaded: true,
|
||||
usePlatformScripts: true
|
||||
});
|
||||
|
||||
VSS.require(["TFS/WorkItemTracking/Services"], function (_WorkItemServices) {
|
||||
|
||||
// Get the WorkItemFormService. This service allows you to get/set fields/links on the 'active' work item (the work item
|
||||
// that currently is displayed in the UI).
|
||||
function getWorkItemFormService()
|
||||
{
|
||||
return _WorkItemServices.WorkItemFormService.getService();
|
||||
}
|
||||
|
||||
// Register a listener for the work item page contribution
|
||||
VSS.register("sample-work-item-form-page", function () {
|
||||
return {
|
||||
// Called when the active work item is modified
|
||||
onFieldChanged: function(args) {
|
||||
$(".events").append($("<div/>").text("onFieldChanged - " + JSON.stringify(args)));
|
||||
},
|
||||
|
||||
// Called when a new work item is being loaded in the UI
|
||||
onLoaded: function (args) {
|
||||
|
||||
getWorkItemFormService().then(function(service) {
|
||||
// Get the current values for a few of the common fields
|
||||
service.getFieldValues(["System.Id", "System.Title", "System.State", "System.CreatedDate"]).then(
|
||||
function (value) {
|
||||
$(".events").append($("<div/>").text("onLoaded - " + JSON.stringify(value)));
|
||||
},
|
||||
function(error) {
|
||||
window.alert(error.message);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
// Called when the active work item is being unloaded in the UI
|
||||
onUnloaded: function (args) {
|
||||
$(".events").empty();
|
||||
$(".events").append($("<div/>").text("onUnloaded - " + JSON.stringify(args)));
|
||||
},
|
||||
|
||||
// Called after the work item has been saved
|
||||
onSaved: function (args) {
|
||||
$(".events").append($("<div/>").text("onSaved - " + JSON.stringify(args)));
|
||||
},
|
||||
|
||||
// Called when the work item is reset to its unmodified state (undo)
|
||||
onReset: function (args) {
|
||||
$(".events").append($("<div/>").text("onReset - " + JSON.stringify(args)));
|
||||
},
|
||||
|
||||
// Called when the work item has been refreshed from the server
|
||||
onRefreshed: function (args) {
|
||||
$(".events").append($("<div/>").text("onRefreshed - " + JSON.stringify(args)));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
VSS.notifyLoadSucceeded();
|
||||
|
||||
$("#clickme").click(function() {
|
||||
getWorkItemFormService().then(function(service) {
|
||||
service.setFieldValue("System.Title", "Title set from extension!")
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<p> Hello, your work item tab page contribution is now active! </p>
|
||||
<button type="button" id="clickme">Click me!</button>
|
||||
<div class='events'> </div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,82 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Work Item Form Service Example</title>
|
||||
<script src="/lib/VSS.SDK.js"></script>
|
||||
<style>
|
||||
.open-existing-work-item, .open-existing-work-item {
|
||||
margin: 20px;
|
||||
}
|
||||
.work-item-types {
|
||||
width: 200px;
|
||||
display: inline-block;
|
||||
margin-left: 5px;
|
||||
margin-right: 5px;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
#existing-wit-id {
|
||||
border: 1px solid #DDD;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="open-existing-work-item">
|
||||
<label for="existing-wit-id">Existing work item id:</label>
|
||||
<input id="existing-wit-id" value="1" />
|
||||
<input type="button" id="existing-wit-button" value="Open..." />
|
||||
</div>
|
||||
|
||||
<div class="open-existing-work-item">
|
||||
<label for="new-work-item-type">New work item type:</label>
|
||||
<div class="work-item-types"></div>
|
||||
<input type="button" id="new-wit-button" value="New..." />
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
VSS.init({ usePlatformScripts: true, explicitNotifyLoaded: true });
|
||||
VSS.require([
|
||||
"TFS/WorkItemTracking/Services",
|
||||
"TFS/WorkItemTracking/RestClient",
|
||||
"VSS/Controls",
|
||||
"VSS/Controls/Combos"], function(_WorkItemServices, _WorkItemRestClient, _Controls, _Combos) {
|
||||
|
||||
VSS.notifyLoadSucceeded();
|
||||
|
||||
var workItemTypesCombo;
|
||||
|
||||
var witClient = _WorkItemRestClient.getClient();
|
||||
witClient.getWorkItemTypes(VSS.getWebContext().project.name).then(function(workItemTypes) {
|
||||
workItemTypesCombo = _Controls.create(_Combos.Combo, $(".work-item-types"), {
|
||||
source: $.map(workItemTypes, function(wiType) { return wiType.name })
|
||||
});
|
||||
if (workItemTypes.length > 0) {
|
||||
workItemTypesCombo.setText(workItemTypes[0].name);
|
||||
}
|
||||
});
|
||||
|
||||
$("#existing-wit-button").click(function() {
|
||||
var workItemId = parseInt($("#existing-wit-id").val());
|
||||
if (workItemId > 0) {
|
||||
_WorkItemServices.WorkItemFormNavigationService.getService().then(function (workItemNavSvc) {
|
||||
workItemNavSvc.openWorkItem(workItemId);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$("#new-wit-button").click(function() {
|
||||
var workItemType = workItemTypesCombo ? workItemTypesCombo.getText() : "";
|
||||
if (workItemType) {
|
||||
_WorkItemServices.WorkItemFormNavigationService.getService().then(function (workItemNavSvc) {
|
||||
workItemNavSvc.openNewWorkItem(workItemType, {
|
||||
"Title": "Opened a work item from the Work Item Nav Service",
|
||||
"Tags": "extension;wit-service",
|
||||
"System.AssignedTo": VSS.getWebContext().user.name,
|
||||
"priority": 1
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Загрузка…
Ссылка в новой задаче