28 | The selected repository is not hosted on a supported platform. Currently only GitHub and GitLab are
29 | supported.
30 | If the repository is actually hosted on one of the supported platforms, please check the configuration and
31 | make sure that the URL is correct.
32 |
33 |
34 |
35 |
36 |
37 | An error occurred and the access token could not be retrieved from the server. Please refresh the page and
38 | try again.
39 | This may be caused by the token service being unavailable or incorrectly configured.
40 | If this error persists, please contact the Jazz Administrator and inform them of the problem.
41 |
42 |
43 |
44 |
45 |
46 | Unable to connect to the repository.
47 | Check that the repository URL is correct and that you are connected to the same network where the repository
48 | is hosted.
49 | For example, if the repository is hosted on an internal company network, make sure that you are connected to
50 | that network directly or with a VPN.
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 | Please wait while your changes are being saved
69 |
70 |
71 |
72 |
73 |
79 |
80 | Please enter your GitHub access token below.
81 | You can create a new access token here:
82 | GitHub Access Token
83 | Please grant the token access to the "repo" and "user" scopes in order to ensure that it has enough
84 | permissions.
85 | If you already saved an access token for GitHub, you are seeing it again because your access token has
86 | expired or has been revoked.
87 | Please follow the instructions above to create a new access token to continue.
88 |
89 |
90 | Please enter your GitLab access token below.
91 | Instructions on creating an access token for GitLab can be found here:
92 | GitLab Access Token
95 | Please grant the token access to the "api" and "read_user" scopes in order to ensure that it has enough
96 | permissions.
97 | If you already saved an access token for this GitLab host, you are seeing it again because your access token
98 | has expired or has been revoked.
99 | Please follow the instructions above to create a new access token to continue.
100 |
Please review and save the following new work items:
3 |
4 |
5 |
--------------------------------------------------------------------------------
/resources/ui/widget/components/NewWorkItemList/NewWorkItemList.js:
--------------------------------------------------------------------------------
1 | define([
2 | "dojo/_base/declare",
3 | "dojo/_base/array",
4 | "dojo/dom-construct",
5 | "dojo/on",
6 | "dijit/_WidgetBase",
7 | "dijit/_TemplatedMixin",
8 | "dijit/registry",
9 | "dojo/text!./NewWorkItemList.html",
10 | "jazz/css!./NewWorkItemList.css",
11 | "com.ibm.team.workitem.web.cache.internal.Cache",
12 | "com.ibm.team.workitem.web.cache.internal.QueryProxy",
13 | "com.ibm.team.workitem.web.client.internal.query.AttributeExpression",
14 | "com.ibm.team.workitem.web.client.internal.query.Operator",
15 | "com.ibm.team.workitem.web.client.internal.query.QueryDescriptor",
16 | "com.ibm.team.workitem.web.client.internal.query.Term",
17 | "com.ibm.team.workitem.web.client.internal.query.UIItem",
18 | "com.ibm.team.workitem.web.client.internal.query.Variable",
19 | "com.ibm.team.workitem.web.client.util"
20 | ], function (declare, array, domConstruct, on, _WidgetBase, _TemplatedMixin, registry, template) {
21 | var Cache = com.ibm.team.workitem.web.cache.internal.Cache;
22 | var QueryProxy = com.ibm.team.workitem.web.cache.internal.QueryProxy;
23 | var AttributeExpression = com.ibm.team.workitem.web.client.internal.query.AttributeExpression;
24 | var Operator = com.ibm.team.workitem.web.client.internal.query.Operator;
25 | var QueryDescriptor = com.ibm.team.workitem.web.client.internal.query.QueryDescriptor;
26 | var Term = com.ibm.team.workitem.web.client.internal.query.Term;
27 | var UIItem = com.ibm.team.workitem.web.client.internal.query.UIItem;
28 | var Variable = com.ibm.team.workitem.web.client.internal.query.Variable;
29 | var util = com.ibm.team.workitem.web.client.util;
30 |
31 | var NewWorkItemList = declare(
32 | "com.siemens.bt.jazz.workitemeditor.rtcGitConnector.ui.widget.newWorkItemList",
33 | [_WidgetBase, _TemplatedMixin],
34 | {
35 | templateString: template,
36 | id: "rtcGitConnectorNewWorkItemListWidget",
37 | newWorkItems: [],
38 | subscriptionHandles: [],
39 |
40 | // Add the widget above the work item editor on the work item editor page.
41 | addToPage: function () {
42 | try {
43 | jazz.app.currentApplication.workbench._pageWidgetCache[
44 | "com.ibm.team.workitem"
45 | ].domNode.lastElementChild.insertAdjacentElement("beforebegin", this.domNode);
46 | } catch (e) {
47 | console.log("Error placing NewWorkItemList on the page.");
48 | }
49 | },
50 |
51 | // Update from the current list of new work items.
52 | // If there are no more items in the list the specified handles
53 | // are unsubscribed and the widget is destroyed.
54 | updateContent: function (subscriptionHandles) {
55 | this._updateSubscriptions(subscriptionHandles);
56 | this._getNewWorkItems();
57 |
58 | if (this.newWorkItems.length) {
59 | // Set the updated list in the view
60 | this._clearContent();
61 | this._addNewWorkItemsToView();
62 | } else {
63 | // Unsubscribe from all handles before destroying
64 | this._updateSubscriptions();
65 |
66 | // Add success message with query for new work items created from git issues
67 | this._createSuccessMessage();
68 |
69 | // Destroy the widget when when the list is empty
70 | this.destroyRecursive(false);
71 | }
72 | },
73 |
74 | // Get all new work items from the work item cache
75 | _getNewWorkItems: function () {
76 | this.newWorkItems = Cache.getAllItems({
77 | filterSelectors: ["isNew"],
78 | filterAttributes: ["isWorkItem"]
79 | });
80 | },
81 |
82 | // Only keep the current subscriptions. Unsubscribe any old ones.
83 | // Unsubscribes all handles if the new list of handles is empty or not present.
84 | _updateSubscriptions: function (newSubscriptionHandles) {
85 | if (!newSubscriptionHandles) {
86 | newSubscriptionHandles = [];
87 | }
88 |
89 | if (this.subscriptionHandles.length) {
90 | this.subscriptionHandles.forEach(function (oldSubscriptionHandle) {
91 | if (
92 | !newSubscriptionHandles.some(function (newSubscriptionHandle) {
93 | return newSubscriptionHandle === oldSubscriptionHandle;
94 | })
95 | ) {
96 | dojo.unsubscribe(oldSubscriptionHandle);
97 | }
98 | });
99 | }
100 |
101 | this.subscriptionHandles = newSubscriptionHandles;
102 | },
103 |
104 | // Empty the links container so that in can be recreated
105 | _clearContent: function () {
106 | domConstruct.empty(this.linksContainer);
107 | },
108 |
109 | // Add all new work items to the view in the form of links
110 | _addNewWorkItemsToView: function () {
111 | var self = this;
112 |
113 | if (this.newWorkItems && this.newWorkItems.length) {
114 | array.forEach(this.newWorkItems, function (newWorkItem) {
115 | self._addNewWorkItemToView(newWorkItem);
116 | });
117 | }
118 | },
119 |
120 | // Add a link to a single work item to the view
121 | _addNewWorkItemToView: function (workItem) {
122 | var workItemUrl = workItem.getUrl(true);
123 | var workItemSummary = workItem.object.attributes.summary;
124 |
125 | if (typeof workItemSummary.content === "string") {
126 | workItemSummary = workItemSummary.content;
127 | }
128 |
129 | var newWorkItemRow = domConstruct.create(
130 | "a",
131 | {
132 | "class": "rtcGitConnectorNewWorkItemListRow",
133 | href: workItemUrl
134 | },
135 | this.linksContainer
136 | );
137 |
138 | if (window.location.href === workItemUrl) {
139 | var bulletSpan = domConstruct.create(
140 | "span",
141 | {
142 | "class": "rtcGitConnectorNewWorkItemListRowBullet"
143 | },
144 | newWorkItemRow
145 | );
146 | domConstruct.create(
147 | "span",
148 | {
149 | innerHTML: "•"
150 | },
151 | bulletSpan
152 | );
153 | }
154 |
155 | domConstruct.create(
156 | "img",
157 | {
158 | src: workItem.getTypeIconUrl(),
159 | alt: workItem.object.attributes.workItemType.label
160 | },
161 | newWorkItemRow
162 | );
163 | domConstruct.create(
164 | "span",
165 | {
166 | innerHTML: " * [New " + workItem.object.attributes.workItemType.label + "] " + workItemSummary
167 | },
168 | newWorkItemRow
169 | );
170 | },
171 |
172 | // Add success message with query for new work items created from git issues
173 | _createSuccessMessage: function () {
174 | var newWorkItemsQuery = this._createNewWorkItemsQuery();
175 | var successMessageDiv = domConstruct.create("div", {
176 | id: "rtcGitConnectorNewWorkItemListSuccessMessageDiv",
177 | "class": "rtcGitConnectorNewWorkItemList"
178 | });
179 | domConstruct.create(
180 | "div",
181 | {
182 | "class": "rtcGitConnectorNewWorkItemListTitle",
183 | innerHTML: "Finished creating work items from git issues"
184 | },
185 | successMessageDiv
186 | );
187 | var flexContainer = domConstruct.create(
188 | "div",
189 | {
190 | "class": "rtcGitConnectorNewWorkItemListFlex"
191 | },
192 | successMessageDiv
193 | );
194 | var queryRow = domConstruct.create(
195 | "a",
196 | {
197 | "class": "rtcGitConnectorNewWorkItemListRow",
198 | href: this._getQueryNewWorkItemsUrl(newWorkItemsQuery)
199 | },
200 | flexContainer
201 | );
202 | domConstruct.create(
203 | "img",
204 | {
205 | "class": "rtcGitConnectorNewWorkItemQueryIcon",
206 | src: this._getQueryIconUrl(newWorkItemsQuery),
207 | alt: "Query for all new work items created from git issues"
208 | },
209 | queryRow
210 | );
211 | domConstruct.create(
212 | "span",
213 | {
214 | innerHTML: "Click here to view all new work items created from git issues"
215 | },
216 | queryRow
217 | );
218 | var removeButton = domConstruct.create(
219 | "button",
220 | {
221 | "class": "rtcGitConnectorNewWorkItemListButton",
222 | type: "button",
223 | innerHTML: "Hide"
224 | },
225 | flexContainer
226 | );
227 |
228 | on(queryRow, "click", this._removeSuccessMessageFromPage);
229 | on(removeButton, "click", this._removeSuccessMessageFromPage);
230 |
231 | this.domNode.insertAdjacentElement("beforebegin", successMessageDiv);
232 | },
233 |
234 | // Remove the success message div from the page
235 | _removeSuccessMessageFromPage: function () {
236 | domConstruct.destroy("rtcGitConnectorNewWorkItemListSuccessMessageDiv");
237 | },
238 |
239 | // Get the url of the query for all new work items created from git issues
240 | _getQueryNewWorkItemsUrl: function (query) {
241 | return window.location.pathname + util.getRunNewQueryUri(query);
242 | },
243 |
244 | // Get the url of the query icon
245 | _getQueryIconUrl: function (query) {
246 | var queryProxy = new QueryProxy({
247 | query: query
248 | });
249 |
250 | return queryProxy.getMenuIconUri();
251 | },
252 |
253 | // Create a query for all work items with the tag "from-git-issue" and
254 | // created today and created by the current user.
255 | _createNewWorkItemsQuery: function () {
256 | // Create a query term with the "AND" operator
257 | var term = new Term(Operator.AND);
258 |
259 | // Create an attribute expression that matches the tag "from-git-issue"
260 | var tagsExpression = new AttributeExpression("internalTags", new Operator("is", null), [
261 | new UIItem("from-git-issue")
262 | ]);
263 | term.addAttributeExpression(tagsExpression);
264 |
265 | // Create an attribute expression that matches the creationDate and the value of "today"
266 | var creationExpression = new AttributeExpression("creationDate", new Operator("is", null));
267 | var creationVariable = new Variable("now", "0d");
268 | creationExpression.setVariables([creationVariable]);
269 | term.addAttributeExpression(creationExpression);
270 |
271 | // Create an attribute expression that matches the creator and the value "currentUser"
272 | var creatorExpression = new AttributeExpression("creator", new Operator("is", null));
273 | var creatorVariable = new Variable("currentUser", "");
274 | creatorExpression.setVariables([creatorVariable]);
275 | term.addAttributeExpression(creatorExpression);
276 |
277 | // Create a query object with a title for the UI and the created query terms
278 | var queryDto = {
279 | name: "My new work items from git issues (created today)",
280 | itemId: "",
281 | expression: term.createDTO()
282 | };
283 | var query = QueryDescriptor.createFromEditableQueryDTO(queryDto);
284 |
285 | return query;
286 | }
287 | }
288 | );
289 |
290 | // Don't expose the class directly but rather just the update function.
291 | return new (function () {
292 | // Updates the list of new work items. Creates and places the widget in the dom
293 | // if it doesn't exist. Removes and destroys the widget if the list is empty.
294 | // Also unsubscribes from the specified handles when destroying the widget.
295 | this.UpdateNewWorkItemList = function (subscriptionHandles) {
296 | // Get the existing widget by id
297 | var newWorkItemListWidget = registry.byId("rtcGitConnectorNewWorkItemListWidget");
298 |
299 | if (!newWorkItemListWidget) {
300 | // Create a new instance if the widget wasn't found
301 | newWorkItemListWidget = new NewWorkItemList();
302 |
303 | // Remove the success message if it exists before adding the new widget to the page
304 | newWorkItemListWidget._removeSuccessMessageFromPage();
305 |
306 | // Add the new widget to the page
307 | newWorkItemListWidget.addToPage();
308 | }
309 |
310 | // Create the list of new work items and add it to the view
311 | newWorkItemListWidget.updateContent(subscriptionHandles);
312 | };
313 | })();
314 | });
315 |
--------------------------------------------------------------------------------
/resources/ui/widget/components/RtcGitConnector/RtcGitConnector.css:
--------------------------------------------------------------------------------
1 | /*
2 | Don't depend on the styles being within this container style (or any container really).
3 | Dojo can and does place the elements at different places in the dom from where they were defined.
4 |
5 | If you try something like this:
6 |
7 | .rtcGitConnectorMainLayout .span {
8 | some style rule...
9 | }
10 |
11 | You would expect all spans under the element with the "rtcGitConnectorMainLayout" class
12 | to have the specified style rules. Because the spans may have been moved by dojo this might
13 | not be the case (e.g. Dialog, Select, ...).
14 |
15 | Just use long descriptive names and apply the classes to the elements directly.
16 | */
17 |
18 | /*
19 | Set the height and width of the widget in percentage of the window height / width.
20 | */
21 | #connectWithGitMainDialog {
22 | background-color: #f5f5f5;
23 | }
24 |
25 | .rtcGitConnectorMainLayout {
26 | box-sizing: border-box;
27 | width: 80vw;
28 | min-width: 800px;
29 | min-height: 60vh;
30 | position: relative;
31 | overflow: hidden;
32 | }
33 |
34 | .rtcGitConnectorSelectRegisteredGitRepository {
35 | display: flex;
36 | background-color: white;
37 | border: 1px solid #cacaca;
38 | padding-left: 10px;
39 | }
40 |
41 | .rtcGitConnectorError {
42 | color: red;
43 | }
44 |
45 | .rtcGitConnectorMessage {
46 | display: block;
47 | padding: 6px;
48 | border-radius: 4px;
49 | border-style: solid;
50 | border-width: 1px;
51 | }
52 |
53 | .rtcGitConnectorMessageInfo {
54 | background-color: #d9edf7;
55 | /* border-color: #bce8f1; */
56 | color: #31708f;
57 | }
58 |
59 | .rtcGitConnectorMessageWarning {
60 | background-color: #fcf8e3;
61 | /* border-color: #faebcc; */
62 | color: #8a6d3b;
63 | }
64 |
65 | .rtcGitConnectorMessageError {
66 | background-color: #f2dede;
67 | /* border-color: #ebccd1; */
68 | color: #a94442;
69 | }
70 |
71 | .rtcGitConnectorLabelText {
72 | display: inline-block;
73 | margin-bottom: 0.5em;
74 | font-size: 1em;
75 | font-weight: bold;
76 | color: #666666;
77 | }
78 |
79 | .rtcGitConnectorSelectRegisteredGitRepository .rtcGitConnectorLabelText {
80 | width: 200px;
81 | margin-top: auto;
82 | margin-bottom: auto;
83 | }
84 |
85 | .rtcGitConnectorSelectList {
86 | width: calc(100% - 201px);
87 | flex-grow: 1;
88 | border-top: 0px;
89 | border-bottom: 0px;
90 | border-right: 0px;
91 | }
92 |
93 | /* Limit the size of the dojo select list drop-down arrow. It looks bad when any larger. */
94 | .rtcGitConnectorSelectList .dijitArrowButton {
95 | width: 1em;
96 | }
97 |
98 | .rtcGitConnectorSelectListSpan {
99 | box-sizing: border-box;
100 | display: block;
101 | width: 100%;
102 | text-align: left;
103 | padding: 0.2em;
104 | font-size: 1em;
105 | }
106 |
107 | /* Add a light blue background to the selected option in the drop-down list. */
108 | .dijitSelectSelectedOption .rtcGitConnectorSelectListSpan {
109 | background-color: #cfe5fa;
110 | }
111 |
112 | .rtcGitConnectorSelectListSecondLine {
113 | color: gray;
114 | }
115 |
116 | #rtcGitConnectorSelectLinkTypeContainer {
117 | margin-bottom: 10px;
118 | }
119 |
120 | .rtcGitConnectorSelectLinkType {
121 | display: flex;
122 | background-color: white;
123 | border-left-width: 1px;
124 | border-bottom-width: 1px;
125 | border-top-width: 0px;
126 | border-right-width: 1px;
127 | border-style: solid;
128 | border-color: #cacaca;
129 | }
130 |
131 | .rtcGitConnectorSelectLinkType .linkTypeItem {
132 | display: inline-block;
133 | /* flex-grow: 1; */
134 | font-size: 1em;
135 | cursor: pointer;
136 | height: 2.75em;
137 | line-height: 2em;
138 | text-decoration: none;
139 | color: black;
140 | padding: 4px 20px;
141 | margin: 0px;
142 | overflow: hidden;
143 | border-bottom: 0px solid #3087b3;
144 | box-sizing: border-box;
145 | transition: all 0.1s ease-out;
146 | }
147 |
148 | .rtcGitConnectorSelectLinkType .linkTypeItem:hover {
149 | border-bottom-width: 3px;
150 | }
151 |
152 | .rtcGitConnectorSelectLinkType .linkTypeItem.selected {
153 | border-bottom-width: 3px;
154 | cursor: default;
155 | }
156 |
157 | .viewAndSelectSearchInput {
158 | flex-grow: 1;
159 | margin-right: 0.5em;
160 | margin-top: auto;
161 | margin-bottom: auto;
162 | }
163 |
164 | .viewAndSelectSearchButton {
165 | margin-right: 0.5em !important;
166 | }
167 |
168 | .viewAndSelectFilterInput {
169 | flex-grow: 1;
170 | margin-right: 0.5em;
171 | margin-top: auto;
172 | margin-bottom: auto;
173 | }
174 |
175 | .rtcGitConnectorViewAndSelectContainer {
176 | background-color: white;
177 | border: 1px solid #cacaca;
178 | padding: 10px;
179 | margin-bottom: 10px;
180 | }
181 |
182 | .rtcGitConnectorViewAndSelectWrapper {
183 | display: flex;
184 | width: 100%;
185 | }
186 |
187 | .rtcGitConnectorViewAndSelectList {
188 | box-sizing: border-box;
189 | flex-grow: 1;
190 | width: 100%;
191 | height: 300px;
192 | margin-right: 10px;
193 | border: 1px solid #cacaca;
194 | overflow-y: scroll;
195 | }
196 |
197 | .rtcGitConnectorViewAndSelectListControl {
198 | display: flex;
199 | border-bottom: 1px solid #cacaca;
200 | padding: 0.5em;
201 | }
202 |
203 | .viewAndSelectControlLabel {
204 | color: #666666;
205 | width: 75px;
206 | margin-top: auto;
207 | margin-bottom: auto;
208 | }
209 |
210 | .rtcGitConnectorViewItemsToLinkList .rtcGitConnectorViewAndSelectListItem:last-child {
211 | border-bottom-width: 0px;
212 | }
213 |
214 | .rtcGitConnectorListsToLinkContainer {
215 | display: flex;
216 | margin-right: -10px;
217 | }
218 |
219 | .rtcGitConnectorListsToLinkContainer .rtcGitConnectorListToLink {
220 | flex-grow: 1;
221 | width: 0;
222 | transition: all 0.3s ease-out;
223 | }
224 |
225 | .viewItemsToLinkContainer {
226 | background-color: white;
227 | border: 1px solid #cacaca;
228 | padding: 10px;
229 | margin-bottom: 10px;
230 | }
231 |
232 | .rtcGitConnectorViewItemsToLinkList {
233 | width: 100%;
234 | border: 1px solid #cacaca;
235 | }
236 |
237 | .rtcGitConnectorHighlightText {
238 | background-color: yellowgreen;
239 | }
240 |
241 | #rtcGitConnectorFullPageLoadingOverlay {
242 | position: absolute;
243 | top: -1em;
244 | bottom: -1em;
245 | left: -1em;
246 | right: -1em;
247 | background-color: white;
248 | z-index: 10000;
249 | text-align: center;
250 | line-height: 20vh;
251 | }
252 |
253 | #rtcGitConnectorFullPageLoadingOverlayContent {
254 | position: fixed;
255 | width: 80vw;
256 | bottom: 0;
257 | }
258 |
259 | #rtcGitConnectorFullPageLoadingOverlayContent span {
260 | display: block;
261 | }
262 |
--------------------------------------------------------------------------------
/resources/ui/widget/components/RtcGitConnector/RtcGitConnector.html:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 | Internet Explorer is not supported. Please use
11 | Google Chrome
12 | or
13 | Firefox
14 | or Edge instead.
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/resources/ui/widget/components/RtcGitConnector/RtcGitConnector.js:
--------------------------------------------------------------------------------
1 | define([
2 | "dojo/_base/declare",
3 | "dojo/dom",
4 | "dojo/dom-style",
5 | "../MainLayout/MainLayout",
6 | "../../services/MainDataStore",
7 | "../../services/JazzRestService",
8 | "../../services/GitRestService",
9 | "dijit/_WidgetBase",
10 | "dijit/_TemplatedMixin",
11 | "dijit/_WidgetsInTemplateMixin",
12 | "dijit/registry",
13 | "dijit/Dialog",
14 | "dojo/text!./RtcGitConnector.html",
15 | "dojo/domReady!",
16 | "jazz.ui.Dialog"
17 | ], function (
18 | declare,
19 | dom,
20 | domStyle,
21 | MainLayout,
22 | MainDataStore,
23 | JazzRestService,
24 | GitRestService,
25 | _WidgetBase,
26 | _TemplatedMixin,
27 | _WidgetsInTemplateMixin,
28 | registry,
29 | Dialog,
30 | template
31 | ) {
32 | return declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
33 | templateString: template,
34 | mainDataStore: null,
35 | jazzRestService: null,
36 | mainDialog: null,
37 |
38 | // Set the work item and project area properties in the
39 | // data store so that other classes can access them.
40 | // Important: wrap all constructor parameters in an object
41 | // to prevent the creation of the widget from failing at the
42 | // lifecycle event that mixes the parameters into the widget instance.
43 | constructor: function (params) {
44 | this.mainDataStore = MainDataStore.getInstance();
45 | this.jazzRestService = JazzRestService.getInstance();
46 | this.mainDataStore.newWorkItemMode = params.workItem.isNewWorkItem();
47 | this.mainDataStore.workItem = params.workItem;
48 | this.mainDataStore.projectArea = params.workItem.object.attributes.projectArea;
49 | },
50 |
51 | startup: function () {
52 | this.mainDataStore.hasHiddenChanges = this.jazzRestService.moveOldLinksToNewLinkTypes(
53 | this.mainDataStore.workItem
54 | );
55 |
56 | // Show the error dialog in Internet Explorer (better than nothing happening)
57 | if (this.isInternetExplorer()) {
58 | this.mainErrorDialog.startup();
59 | this.mainErrorDialog.show();
60 | } else {
61 | // Change the popup title in new work item mode
62 | var title = this.mainDataStore.newWorkItemMode
63 | ? "Create Work Items from Git Issues"
64 | : "Connect with Git";
65 | var mainLayout = new MainLayout();
66 | this.mainDialog = new jazz.ui.Dialog({
67 | heading: title,
68 | contentNode: mainLayout.domNode,
69 | footerNode: mainLayout.footerButtons,
70 | contentPadding: jazz.ui.Dialog.DialogContentPadding.SIDES,
71 | id: "connectWithGitMainDialog",
72 | width: "auto"
73 | });
74 | }
75 |
76 | this.setEventHandlers();
77 | },
78 |
79 | setEventHandlers: function () {
80 | var self = this;
81 |
82 | // Clean up the dom and custom class instances when the widget is closed.
83 | // This is especially important for making the widget work when opened
84 | // and closed multiple times.
85 | this.mainDialog.onClose = function () {
86 | // Destroy all dialogs and remove them from the dom
87 | self.destroyWidgetById("getAndSaveAccessTokenDialog");
88 | self.destroyWidgetById("browserIsInternetExplorerContainer");
89 | this.destroyRecursive(false);
90 |
91 | // Destroy data store and services
92 | self.destroyWidgetInstance();
93 | };
94 |
95 | // Clean up for the error dialog
96 | this.mainErrorDialog.onHide = function () {
97 | self.destroyWidgetById("getAndSaveAccessTokenDialog");
98 | self.destroyWidgetById("connectWithGitMainDialog");
99 | this.destroyRecursive(false);
100 |
101 | self.destroyWidgetInstance();
102 | };
103 | },
104 |
105 | // These custom singleton instances need to be manually destroyed.
106 | // If the widget is opened again it will then get new instances,
107 | // which is the intended behavior.
108 | destroyWidgetInstance: function () {
109 | MainDataStore.destroyInstance();
110 | JazzRestService.destroyInstance();
111 | GitRestService.destroyInstance();
112 | },
113 |
114 | // Finds a widget by it's HTML id and destroys it,
115 | // also removing it from the dom.
116 | destroyWidgetById: function (domId) {
117 | var widgetToDestroy = registry.byId(domId);
118 |
119 | if (widgetToDestroy) {
120 | widgetToDestroy.destroyRecursive(false);
121 | }
122 | },
123 |
124 | // Check if the current browser is Internet Explorer
125 | isInternetExplorer: function () {
126 | var ms_ie = false;
127 | var ua = window.navigator.userAgent;
128 | var old_ie = ua.indexOf("MSIE ");
129 | var new_ie = ua.indexOf("Trident/");
130 |
131 | if (old_ie > -1 || new_ie > -1) {
132 | ms_ie = true;
133 | }
134 |
135 | return ms_ie;
136 | }
137 | });
138 | });
139 |
--------------------------------------------------------------------------------
/resources/ui/widget/components/SelectItemMessage/SelectItemMessage.css:
--------------------------------------------------------------------------------
1 | /* See: http://www.cssarrowplease.com/ */
2 |
3 | /*
4 | Make the message div about the same width as a list item.
5 | Add extra margin top so that there is space for the arrow.
6 | */
7 | .rtcGitConnectorSelectItemMessage {
8 | position: relative;
9 | width: calc(50% - 35px);
10 | margin-top: 20px;
11 | margin-bottom: 10px;
12 | margin-left: 11px;
13 | }
14 |
15 | /*
16 | Use before and after to create and position zero size elements in the same spot.
17 | */
18 | .rtcGitConnectorSelectItemMessage::after,
19 | .rtcGitConnectorSelectItemMessage::before {
20 | position: absolute;
21 | bottom: 100%;
22 | left: 25px;
23 | height: 0;
24 | width: 0;
25 | border: solid transparent;
26 | content: " ";
27 | pointer-events: none;
28 | }
29 |
30 | /*
31 | Use the after element as the inner triangle.
32 | Looks like an extension of the div.
33 | The border width defines the height of the triangle.
34 | The triangle is created by making only the bottom border visible.
35 | Margin is used for positioning the tip of the triangle in the
36 | center (should equal border width).
37 | */
38 | .rtcGitConnectorSelectItemMessage::after {
39 | border-bottom-color: #d9edf7; /* backgroundColor */
40 | border-width: 15px; /* arrowHeight */
41 | margin-left: -15px;
42 | }
43 |
44 | /*
45 | Use the before element as the outer triangle.
46 | Looks like an extension of the border around the div.
47 | The border width should use the formula commented below.
48 | This is important when the div has a wider border, otherwise
49 | the border on the triangle part will be too small.
50 | Margin is used for positioning the tip of the triangle in the
51 | center (should equal border width).
52 | */
53 | .rtcGitConnectorSelectItemMessage::before {
54 | border-bottom-color: #31708f; /* borderColor */
55 | border-width: 17px; /* afterBorderWidth + Math.round(divBorderWidth * Math.sqrt(2)) */
56 | margin-left: -17px;
57 | }
58 |
--------------------------------------------------------------------------------
/resources/ui/widget/components/SelectItemMessage/SelectItemMessage.html:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
--------------------------------------------------------------------------------
/resources/ui/widget/components/SelectItemMessage/SelectItemMessage.js:
--------------------------------------------------------------------------------
1 | define([
2 | "dojo/_base/declare",
3 | "dojo/dom-style",
4 | "dijit/_WidgetBase",
5 | "dijit/_TemplatedMixin",
6 | "dojo/text!./SelectItemMessage.html",
7 | "jazz/css!./SelectItemMessage.css"
8 | ], function (declare, domStyle, _WidgetBase, _TemplatedMixin, template) {
9 | return declare(
10 | "com.siemens.bt.jazz.workitemeditor.rtcGitConnector.ui.widget.selectItemMessage",
11 | [_WidgetBase, _TemplatedMixin],
12 | {
13 | templateString: template,
14 |
15 | // Hide the message by default
16 | // Set to false to show the message
17 | hidden: true,
18 | _setHiddenAttr: function (hidden) {
19 | domStyle.set(this.messageNode, "display", hidden ? "none" : "block");
20 | this._set("hidden", hidden);
21 | },
22 |
23 | // Define the default message to show
24 | // Set to a different string to change the message
25 | message: "Click the colorful icon on the left to select an item to be saved.",
26 | _setMessageAttr: { node: "messageNode", type: "innerHTML" }
27 | }
28 | );
29 | });
30 |
--------------------------------------------------------------------------------
/resources/ui/widget/components/SelectLinkType/SelectLinkType.html:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/resources/ui/widget/components/SelectRegisteredGitRepository/SelectRegisteredGitRepository.js:
--------------------------------------------------------------------------------
1 | define([
2 | "dojo/_base/declare",
3 | "dojo/_base/array",
4 | "../../services/MainDataStore",
5 | "dijit/_WidgetBase",
6 | "dijit/_TemplatedMixin",
7 | "dijit/_WidgetsInTemplateMixin",
8 | "dijit/form/Select",
9 | "dojo/text!./SelectRegisteredGitRepository.html"
10 | ], function (declare, array, MainDataStore, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, Select, template) {
11 | return declare(
12 | "com.siemens.bt.jazz.workitemeditor.rtcGitConnector.ui.widget.selectRegisteredGitRepository",
13 | [_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin],
14 | {
15 | templateString: template,
16 | mainDataStore: null,
17 | selectListOptions: null,
18 |
19 | constructor: function () {
20 | this.mainDataStore = MainDataStore.getInstance();
21 |
22 | // Set the initial select list option
23 | this.selectListOptions = [
24 | {
25 | value: "",
26 | label: this.createLabelString(" ", "Loading..."),
27 | selected: true,
28 | disabled: true
29 | }
30 | ];
31 | },
32 |
33 | startup: function () {
34 | this.initializeSelectList();
35 | this.setEventHandlers();
36 | this.watchDataStore();
37 | },
38 |
39 | initializeSelectList: function () {
40 | this.setOptionsList();
41 | this.selectRegisteredGitRepository.maxHeight = -1; // Automatically adjust the height to fit the viewport
42 | },
43 |
44 | watchDataStore: function () {
45 | var self = this;
46 |
47 | // React when the list of git repositories changes
48 | this.mainDataStore.registeredGitRepositories.watchElements(function () {
49 | // Update the view list to reflect the new list of git repositories
50 | self.setRegisteredGitRepositoriesAsListOptions(self.mainDataStore.registeredGitRepositories);
51 | });
52 | },
53 |
54 | setEventHandlers: function () {
55 | var self = this;
56 |
57 | // React when the selected list option changes
58 | this.selectRegisteredGitRepository.onChange = function (value) {
59 | // Remove the first item in the list if it doesn't have a value.
60 | // This removes the placeholder option that is initially selected (Select a Git Repository...)
61 | if (this.options[0].value === "") {
62 | this.removeOption(this.options[0]);
63 | }
64 |
65 | var selectedRepository = self.mainDataStore.selectedRepositorySettings.get("repository");
66 |
67 | // Do nothing if the correct repository is already set in the store
68 | if (!selectedRepository || selectedRepository.key !== value) {
69 | // Check if there are changes
70 | if (
71 | self.mainDataStore.selectedRepositoryData.commitsToLink.length > 0 ||
72 | self.mainDataStore.selectedRepositoryData.issuesToLink.length > 0 ||
73 | self.mainDataStore.selectedRepositoryData.requestsToLink.length > 0
74 | ) {
75 | // Ask the user if they want to lose their changes
76 | if (
77 | confirm(
78 | "Changing the repository will result in losing your unsaved changes. Are you sure you want to discard your changes?"
79 | )
80 | ) {
81 | // Change the repository if the user wants to lose their changes
82 | self._setSelectedRepositoryByKey(value);
83 | } else {
84 | // Set the selected repository back to it's previous value if the user doesn't want to lose their changes
85 | self.selectRegisteredGitRepository.set("value", selectedRepository.key);
86 | }
87 | } else {
88 | // Change the repository if there are no changes
89 | self._setSelectedRepositoryByKey(value);
90 | }
91 | }
92 | };
93 | },
94 |
95 | // Need to run the startup method on the select list after setting a new options list.
96 | // This is a "bug" in dijit/form/Select (or feature?)
97 | setOptionsList: function () {
98 | this.selectRegisteredGitRepository.set("options", this.selectListOptions);
99 | this.selectRegisteredGitRepository.startup();
100 | },
101 |
102 | // Add spans and classes to the label for custom formatting
103 | createLabelString: function (firstLine, secondLine) {
104 | return (
105 | '' +
106 | firstLine +
107 | "" +
108 | '' +
109 | secondLine +
110 | ""
111 | );
112 | },
113 |
114 | // Set the view options from the list of git repositories
115 | setRegisteredGitRepositoriesAsListOptions: function (registeredGitRepositories) {
116 | if (!registeredGitRepositories.length) {
117 | // Just add a placeholder if the list doesn't contain any items
118 | this.selectListOptions = [
119 | {
120 | value: "",
121 | label: this.createLabelString(" ", "No git repositories registered..."),
122 | selected: true,
123 | disabled: true
124 | }
125 | ];
126 | } else {
127 | // Add a placeholder option (no repository should be selected by default)
128 | this.selectListOptions = [
129 | {
130 | value: "",
131 | label: this.createLabelString(" ", "Select a Git Repository..."),
132 | selected: true,
133 | disabled: true
134 | }
135 | ];
136 |
137 | // Format all items and add to the view list
138 | array.forEach(
139 | registeredGitRepositories,
140 | function (registeredGitRepository) {
141 | this.selectListOptions.push({
142 | value: registeredGitRepository.key,
143 | label: this.createLabelString(registeredGitRepository.name, registeredGitRepository.url)
144 | });
145 | },
146 | this
147 | );
148 | }
149 |
150 | // No repository should be selected right after the list has changed
151 | this.mainDataStore.selectedRepositorySettings.set("repository", null);
152 | this.setOptionsList();
153 | },
154 |
155 | // Update the data store. If the selected option is not found in the data store,
156 | // the selected repository in the data store will be set to null
157 | _setSelectedRepositoryByKey: function (key) {
158 | this.mainDataStore.selectedRepositorySettings.set(
159 | "repository",
160 | this.mainDataStore.registeredGitRepositories.find(function (element) {
161 | return element.key === key;
162 | })
163 | );
164 | }
165 | }
166 | );
167 | });
168 |
--------------------------------------------------------------------------------
/resources/ui/widget/components/SetNewWorkItemAttributes/SetNewWorkItemAttributes.css:
--------------------------------------------------------------------------------
1 | #rtcGitConnectorSetNewWorkItemAttributes .workItemEditor {
2 | padding: 0;
3 | }
4 |
--------------------------------------------------------------------------------
/resources/ui/widget/components/SetNewWorkItemAttributes/SetNewWorkItemAttributes.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/resources/ui/widget/components/SetNewWorkItemAttributes/SetNewWorkItemAttributes.js:
--------------------------------------------------------------------------------
1 | define([
2 | "dojo/_base/declare",
3 | "dojo/_base/lang",
4 | "../../services/MainDataStore",
5 | "dijit/_WidgetBase",
6 | "dijit/_TemplatedMixin",
7 | "dojo/text!./SetNewWorkItemAttributes.html",
8 | "jazz/css!./SetNewWorkItemAttributes.css",
9 | "com.ibm.team.workitem.web.ui.internal.view.editor.WorkItemOverview"
10 | ], function (declare, lang, MainDataStore, _WidgetBase, _TemplatedMixin, template) {
11 | var WorkItemOverview = com.ibm.team.workitem.web.ui.internal.view.editor.WorkItemOverview;
12 |
13 | return declare(
14 | "com.siemens.bt.jazz.workitemeditor.rtcGitConnector.ui.widget.setNewWorkItemAttributes",
15 | [_WidgetBase, _TemplatedMixin],
16 | {
17 | templateString: template,
18 | mainDataStore: null,
19 | hasOverview: false,
20 | attributesToShow: ["category", "owner", "target", "foundIn", "internalTags"],
21 |
22 | constructor: function () {
23 | this.mainDataStore = MainDataStore.getInstance();
24 | },
25 |
26 | // Only create the overview once the show method is called
27 | show: function () {
28 | if (!this.hasOverview) {
29 | this.hasOverview = true;
30 | this.createOverview();
31 | }
32 | },
33 |
34 | // Create a work item editor with only the specified attributes.
35 | // ["category", "owner", "target", "foundIn", "internalTags"]
36 | // If the attribute is not available for the current work item presentation
37 | // it will just be left out.
38 | createOverview: function () {
39 | var workItem = this.mainDataStore.workItem;
40 | var workItemEditorWidget = this._getWorkItemEditorWidget(workItem);
41 | var page = this._getOverviewPage(workItem);
42 |
43 | if (!workItemEditorWidget || !page) {
44 | return;
45 | }
46 |
47 | // Work on a copy of the page so that the real presentation properties are not affected.
48 | page = lang.clone(page);
49 |
50 | var section = this._getDetailsSection(page);
51 |
52 | if (!section) {
53 | return;
54 | }
55 |
56 | this._filterSectionPresentationsByAttributes(section, this.attributesToShow);
57 | this._setSectionTitle(section, "Some values for the new work items");
58 |
59 | // Remove all other sections from the page
60 | page.sections = [section];
61 |
62 | // Arguments used to create a WorkItemOverview object
63 | var createArgs = {
64 | workItem: workItemEditorWidget._workItem,
65 | parentController: workItemEditorWidget,
66 | editorUtil: workItemEditorWidget.editorUtil,
67 | pageProps: page,
68 | retainedState: false,
69 | isCustomAttributeLayout: {}
70 | };
71 |
72 | var workItemOverView = new WorkItemOverview(createArgs);
73 |
74 | // Place the work item overview in the dom
75 | this.attributesContainer.insertAdjacentElement("afterBegin", workItemOverView.domNode);
76 | },
77 |
78 | // Get the work item editor widget instance from the work item page instance
79 | // taken from the cache
80 | _getWorkItemEditorWidget: function (workItem) {
81 | var workItemEditorWidget;
82 |
83 | try {
84 | workItemEditorWidget = jazz.app.currentApplication.workbench._pageWidgetCache[
85 | "com.ibm.team.workitem"
86 | ]._multipaneContentWidget.getCachedWidget("__jazzWorkItemEditor", workItem.getId());
87 | } catch (e) {
88 | workItemEditorWidget = null;
89 | }
90 |
91 | return workItemEditorWidget;
92 | },
93 |
94 | // Get the presentation properties for the overview part of the work item editor page
95 | _getOverviewPage: function (workItem) {
96 | var page;
97 |
98 | try {
99 | page = workItem.workItemSpec.presentationProps.pages.find(function (page) {
100 | return page.layout === "builtInOverviewLayout";
101 | });
102 | } catch (e) {
103 | page = null;
104 | }
105 |
106 | return page;
107 | },
108 |
109 | // Get the details section from the specified page
110 | _getDetailsSection: function (page) {
111 | var section;
112 |
113 | try {
114 | section = page.sections.find(function (section) {
115 | return section.slot === "details";
116 | });
117 | } catch (e) {
118 | section = null;
119 | }
120 |
121 | return section;
122 | },
123 |
124 | // Only keep the section presentations for the specified attributes
125 | _filterSectionPresentationsByAttributes: function (section, attributes) {
126 | section.presentations = section.presentations.filter(function (presentation) {
127 | return attributes.some(function (attribute) {
128 | return attribute === presentation.attributeId;
129 | });
130 | });
131 | },
132 |
133 | // Set the specified title for the specified section
134 | _setSectionTitle: function (section, title) {
135 | var prop = section.properties.find(function (property) {
136 | return property.key === "title";
137 | });
138 |
139 | if (prop) {
140 | prop.value = title;
141 | }
142 | }
143 | }
144 | );
145 | });
146 |
--------------------------------------------------------------------------------
/resources/ui/widget/components/SetNewWorkItemLinks/SetNewWorkItemLinks.css:
--------------------------------------------------------------------------------
1 | .setNewWorkItemLinksContainer {
2 | padding-top: 0.5em;
3 | }
4 |
--------------------------------------------------------------------------------
/resources/ui/widget/components/SetNewWorkItemLinks/SetNewWorkItemLinks.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Set the parent for the new work items
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/resources/ui/widget/components/SetNewWorkItemLinks/SetNewWorkItemLinks.js:
--------------------------------------------------------------------------------
1 | define([
2 | "dojo/_base/declare",
3 | "dojo/_base/lang",
4 | "dojo/dom-construct",
5 | "dojo/dom-style",
6 | "dojo/string",
7 | "../../services/MainDataStore",
8 | "dijit/MenuItem",
9 | "dijit/_WidgetBase",
10 | "dijit/_TemplatedMixin",
11 | "dojo/text!./SetNewWorkItemLinks.html",
12 | "jazz/css!./SetNewWorkItemLinks.css",
13 | "com.ibm.jdojox.util.ArrayList",
14 | "com.ibm.jdojox.util.JDojoX",
15 | "com.ibm.team.rtc.foundation.web.model.Bindable",
16 | "com.ibm.team.rtc.foundation.web.model.BindableList",
17 | "com.ibm.team.rtc.foundation.web.model.Label",
18 | "com.ibm.team.rtc.foundation.web.model.ListBindings",
19 | "com.ibm.team.rtc.foundation.web.ui.util.Sprites",
20 | "com.ibm.team.rtc.foundation.web.ui.views.controller.ActionDropdown",
21 | "com.ibm.team.rtc.foundation.web.ui.views.controller.ArtifactList",
22 | "com.ibm.team.rtc.foundation.web.ui.views.controller.ArtifactMultiList",
23 | "com.ibm.team.workitem.web.model.links.WorkItemEndpoints",
24 | "com.ibm.team.workitem.web.ui.internal.view.editor.presentations.nonattribute.links.LinksDialogLauncher"
25 | ], function (
26 | declare,
27 | lang,
28 | domConstruct,
29 | domStyle,
30 | string,
31 | MainDataStore,
32 | MenuItem,
33 | _WidgetBase,
34 | _TemplatedMixin,
35 | template
36 | ) {
37 | var ArrayList = com.ibm.jdojox.util.ArrayList;
38 | var JDojoX = com.ibm.jdojox.util.JDojoX;
39 | var Bindable = com.ibm.team.rtc.foundation.web.model.Bindable;
40 | var BindableList = com.ibm.team.rtc.foundation.web.model.BindableList;
41 | var Label = com.ibm.team.rtc.foundation.web.model.Label;
42 | var ListBindings = com.ibm.team.rtc.foundation.web.model.ListBindings;
43 | var Sprites = com.ibm.team.rtc.foundation.web.ui.util.Sprites;
44 | var ActionDropdown = com.ibm.team.rtc.foundation.web.ui.views.controller.ActionDropdown;
45 | var ArtifactList = com.ibm.team.rtc.foundation.web.ui.views.controller.ArtifactList;
46 | var ArtifactMultiList = com.ibm.team.rtc.foundation.web.ui.views.controller.ArtifactMultiList;
47 | var WorkItemEndpoints = com.ibm.team.workitem.web.model.links.WorkItemEndpoints;
48 | var LinksDialogLauncher =
49 | com.ibm.team.workitem.web.ui.internal.view.editor.presentations.nonattribute.links.LinksDialogLauncher;
50 |
51 | return declare(
52 | "com.siemens.bt.jazz.workitemeditor.rtcGitConnector.ui.widget.setNewWorkItemLinks",
53 | [_WidgetBase, _TemplatedMixin],
54 | {
55 | templateString: template,
56 | mainDataStore: null,
57 | hasPresentation: false,
58 | enabledEndpoints: null,
59 | enabledEndpointsWithValues: null,
60 | workingCopy: null,
61 |
62 | constructor: function () {
63 | this.mainDataStore = MainDataStore.getInstance();
64 | this.workingCopy = this.mainDataStore.workItem.getWorkingCopy();
65 |
66 | // Create the list of link types to show
67 | this.enabledEndpoints = new ArrayList();
68 | this.enabledEndpoints.add(WorkItemEndpoints.PARENT_WORK_ITEM);
69 |
70 | // Create a list to keep track of what link types have links set
71 | // This is used for the view to dynamically show/hide when links
72 | // are added or removed
73 | this.enabledEndpointsWithValues = new BindableList();
74 | },
75 |
76 | // Only create the presentation once the show method is called
77 | show: function () {
78 | if (!this.hasPresentation) {
79 | this.hasPresentation = true;
80 | this.createLinksDropdown();
81 | this.createLinksList();
82 | }
83 | },
84 |
85 | // Create the dropdown for selecting work items to link. Will be
86 | // styled as a single button if there is only one item
87 | createLinksDropdown: function () {
88 | var self = this;
89 | var workItemReferences = this.workingCopy.getWorkItemReferences();
90 |
91 | // Create a list of endpoints to show in the dropdown
92 | var endpointList = new BindableList();
93 | endpointList.add(this.enabledEndpoints);
94 |
95 | // Set the first endpoint in the list to be the default
96 | var defaultEndpoint = new Bindable();
97 | defaultEndpoint.setValue(this.enabledEndpoints.at(0));
98 |
99 | // Create a div for placing the dropdown in
100 | var actionsMenuDiv = domConstruct.create("div", null, this.linksContainer);
101 |
102 | // Create the ActionDropdown and place it
103 | var actionsMenu = ActionDropdown.create({}, actionsMenuDiv);
104 |
105 | // Setup the ActionDropdown
106 | actionsMenu
107 | .renderer(
108 | lang.hitch(this, function (endpoint) {
109 | return new MenuItem({
110 | label: this._getEndpointLabel(endpoint),
111 | iconClass: Sprites.cssClassName(endpoint.getIcon())
112 | });
113 | })
114 | )
115 | .values(endpointList)
116 | .defaultValue(defaultEndpoint)
117 | .bind();
118 |
119 | // Open the links chooser dialog when a menu item is clicked
120 | actionsMenu.valueChosen.addListener(
121 | lang.hitch(this, function (chosenDescriptor) {
122 | this._launchLinksDialog(self.workingCopy, workItemReferences, chosenDescriptor);
123 | })
124 | );
125 |
126 | // Hide the menu dropdown part when there is only a single item
127 | if (this.enabledEndpoints.size() === 1) {
128 | this._hideDropdown(actionsMenu._view);
129 | }
130 | },
131 |
132 | // Create the presentation of the set links. Can be used to remove the links
133 | createLinksList: function () {
134 | var self = this;
135 | var workItemReferences = this.workingCopy.getWorkItemReferences();
136 |
137 | // Create a div for placing the list view in
138 | var listViewDiv = domConstruct.create("div", null, this.linksContainer);
139 |
140 | // Create the ArtifactMultiList and place it
141 | var listView = new ArtifactMultiList(listViewDiv).listFactory(function () {
142 | return ArtifactList.create();
143 | });
144 |
145 | // Initialize empty BindableLists to bind with the enabledEndpointsWithValues later
146 | var headers = new BindableList();
147 | var readOnly = new BindableList();
148 | var typesMap = new BindableList();
149 |
150 | // Bind the headers to the endpoint display names and icons
151 | ListBindings.bindWithAdapter(this.enabledEndpointsWithValues, headers, function (endpoint) {
152 | return new Label(endpoint.getDisplayName()).iconUrl(endpoint.getIcon().toUri());
153 | });
154 |
155 | // Bind the readOnly attribute to reflect whether links from this endpoint can be deleted or not
156 | ListBindings.bindWithAdapter(this.enabledEndpointsWithValues, readOnly, function (endpoint) {
157 | return new Bindable(!endpoint.isUserDeleteable());
158 | });
159 |
160 | // Bind the typesMap to the work item references for each endpoint
161 | ListBindings.bindWithAdapter(this.enabledEndpointsWithValues, typesMap, function (endpoint) {
162 | var result = new BindableList();
163 | var references = workItemReferences.getReferences(endpoint);
164 |
165 | // Bind result to the work item references for this endpoint
166 | ListBindings.bind(references, result);
167 |
168 | // Listen for changes in the result list
169 | result.onListChanged().addListener(function (callbackArg) {
170 | // Check if a reference has been removed from the result list
171 | if (!JDojoX.isEqual(result, references) && callbackArg.type === "remove") {
172 | // Remove the reference from the work item references
173 | workItemReferences.remove(endpoint, callbackArg.elements[0]);
174 |
175 | // Remove the endpoint from the list of endpoints with values
176 | // if the endpoint doesn't have any more references
177 | if (!workItemReferences.hasReferences(endpoint)) {
178 | self.enabledEndpointsWithValues.remove(endpoint);
179 | }
180 | }
181 | });
182 |
183 | return result;
184 | });
185 |
186 | // Setup the ArtifactMultiList
187 | listView
188 | .renderer(function (itemReference) {
189 | return new Label(itemReference.getComment())
190 | .iconUrl(itemReference.getIconUrl())
191 | .url(itemReference.getUrl());
192 | })
193 | .headers(headers)
194 | .sections(typesMap)
195 | .readOnly(readOnly)
196 | .compact(new Bindable(false))
197 | .bind();
198 | },
199 |
200 | // Get the label for the specified endpoint
201 | _getEndpointLabel: function (endpoint) {
202 | return string.substitute(endpoint.isSingleValued() ? "Set ${0}" : "Add ${0}", [
203 | endpoint.getDisplayName()
204 | ]);
205 | },
206 |
207 | // Launch a dialog for selecting links of a specific type for the specified work item
208 | _launchLinksDialog: function (workItem, workItemReferences, chosenDescriptor) {
209 | var self = this;
210 |
211 | LinksDialogLauncher.launchDialog(workItem, chosenDescriptor, function (endpoint) {
212 | // Get an array of all the endpoint references (passed as multiple arguments after endpoint)
213 | var references = Array.prototype.slice.call(arguments, 1);
214 |
215 | // Remove the existing reference if this is a single valued endpoint
216 | // and the work item already has a reference
217 | if (endpoint.isSingleValued() && workItemReferences.hasReferences(endpoint)) {
218 | workItemReferences.remove(endpoint, workItemReferences.getReferences(endpoint).at(0));
219 | }
220 |
221 | // Add the new references to the endpoint
222 | workItemReferences.add.apply(workItemReferences, [endpoint].concat(references));
223 |
224 | // Add the endpoint to the custom list so that it will be shown in the view
225 | // Only add each endpoint to the list once. The individual references will be added to the endpoint
226 | if (!self.enabledEndpointsWithValues.contains(endpoint)) {
227 | self.enabledEndpointsWithValues.add(endpoint);
228 | }
229 | });
230 | },
231 |
232 | // Hide the arrow drop down from the actions menu. This is useful when the menu only contains a single item
233 | _hideDropdown: function (actionsMenuView) {
234 | domStyle.set(actionsMenuView._dropdownElement, "float", "none");
235 | domStyle.set(actionsMenuView._dropdownElement, "border-right", "none");
236 | domStyle.set(actionsMenuView._dropdownArrow, "display", "none");
237 | }
238 | }
239 | );
240 | });
241 |
--------------------------------------------------------------------------------
/resources/ui/widget/components/SetNewWorkItemValues/SetNewWorkItemValues.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jazz-community/rtc-git-connector/8a59c81bfc85c70ef57d4fa83ded54e545faf6c3/resources/ui/widget/components/SetNewWorkItemValues/SetNewWorkItemValues.css
--------------------------------------------------------------------------------
/resources/ui/widget/components/SetNewWorkItemValues/SetNewWorkItemValues.html:
--------------------------------------------------------------------------------
1 |