Skip to content
This repository was archived by the owner on May 14, 2025. It is now read-only.

Commit b5c44db

Browse files
aclementBoykoAlex
authored andcommitted
Use the new backend support for content assist in bulk task define
Trailing space Trailing space Trailing space
1 parent aa41cf1 commit b5c44db

File tree

3 files changed

+122
-15
lines changed

3 files changed

+122
-15
lines changed

ui/app/scripts/task/controllers/bulk-define-tasks.js

Lines changed: 73 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ define(function (require) {
2929

3030
var angular = require('angular');
3131

32-
return ['$scope', 'DataflowUtils', '$modal', '$state', 'TaskAppService', 'TaskDslValidatorService', '$cookieStore',
33-
function ($scope, utils, $modal, $state, taskAppService, validatorService, $cookieStore) {
32+
return ['$scope', 'DataflowUtils', '$modal', '$state', 'TaskAppService', 'TaskDslValidatorService', '$cookieStore', 'TaskContentAssistService',
33+
function ($scope, utils, $modal, $state, taskAppService, validatorService, $cookieStore, contentAssistService) {
3434

3535
var editor;
3636

@@ -242,21 +242,80 @@ define(function (require) {
242242
$scope.dsl = contents;
243243
};
244244

245-
$scope.hint = {
246-
async: 'true',
247-
hint: function(cm, callback) { // jshint ignore:line
248-
// TODO: calculate completion proposals and return results as shown below
245+
function isDelimiter(c) {
246+
return c && c === ' ';
247+
}
249248

250-
// See https://codemirror.net/doc/manual.html#addons hint/show-hint.js section
249+
/**
250+
* The suggestions provided by rest api are very long and include the whole command typed
251+
* from the start of the line. This function determines the start of the 'interesting' part
252+
* at the end of the prefix, so that we can use it to chop-off the suggestion there.
253+
*/
254+
function interestingPrefixStart(prefix, completions) {
255+
var cursor = prefix.length;
256+
if (completions.every(function (completion) {
257+
return isDelimiter(completion[cursor]);
258+
})) {
259+
return cursor;
260+
}
261+
return prefix.lastIndexOf(' ');
262+
}
251263

252-
// return callback({
253-
// list: listOfStrings
254-
// from: {line: startLine, ch:startCharIndex},
255-
// to: {line: endLine, ch:endCharIndex}
256-
// });
264+
var taskProposalComputer = function(cm, callback) { // jshint ignore:line
265+
var cursor = cm.getDoc().getCursor();
266+
var startOfLine = {line: cursor.line, ch: 0};
267+
var prefix = cm.getDoc().getRange(startOfLine, cursor);
268+
269+
// Handle content assist for the name if not yet specified or followed by equals:
270+
var equalsIndex = prefix.indexOf('=');
271+
if (equalsIndex === -1) {
272+
var trimmed = prefix.trim();
273+
if (trimmed.length !== 0) {
274+
// Suggest they follow the name with an '='
275+
return callback({list:[trimmed+'='],from:{line:cursor.line,ch:0},to:cursor});
276+
} else {
277+
return callback({list:['task'+(cursor.line+1)+'='],from:{line:cursor.line,ch:0},to:cursor});
278+
}
279+
}
280+
var textAfterEquals = prefix.substring(equalsIndex+1);
281+
contentAssistService.getProposals(textAfterEquals).then(function(completions) {
282+
// Example:
283+
// [{"text":"spark-yarn","explanation":"Choose a task app"},
284+
// {"text":"spark-cluster","explanation":"Choose a task app"},
285+
// {"text":"timestamp","explanation":"Choose a task app"},
286+
// {"text":"spark-client","explanation":"Choose a task app"}]
287+
var chopAt = interestingPrefixStart(textAfterEquals, completions);
288+
if (chopAt === -1) {
289+
chopAt = 0;
290+
}
291+
// If all the proposals are options adjust the chopAt
292+
var areAllOptions = true;
293+
for (var c=0;c<completions.length;c++) {
294+
var longCompletion = completions[c];
295+
var text = typeof longCompletion === 'string'?longCompletion: longCompletion.text;
296+
if (!text.substring(textAfterEquals.length).startsWith(' --')) {
297+
areAllOptions = false;
298+
break;
299+
}
300+
}
301+
if (areAllOptions) {
302+
chopAt = textAfterEquals.length;
303+
}
304+
return callback({
305+
list:completions.map(function(longCompletion) {
306+
var text= typeof longCompletion === 'string'?longCompletion: longCompletion.text;
307+
return text.substring(chopAt);
308+
}),
309+
from:{line:cursor.line,ch:chopAt+equalsIndex+1},
310+
to:cursor
311+
});
312+
});
313+
};
314+
taskProposalComputer.async = true;
257315

258-
utils.$log.info('Task DSL Content Assist Invoked!');
259-
}
316+
$scope.hint = {
317+
async: 'true',
318+
hint: taskProposalComputer
260319
};
261320

262321
$scope.nextError = function() {

ui/app/scripts/task/services.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,5 +200,6 @@ define(function(require) {
200200
}
201201
};
202202
})
203-
.factory('TaskDslValidatorService', require('task/services/task-dsl-validator'));
203+
.factory('TaskDslValidatorService', require('task/services/task-dsl-validator')).
204+
factory('TaskContentAssistService', require('task/services/content-assist-service'));
204205
});
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright 2016 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
/**
18+
* Service providing content assist for task definitions.
19+
*
20+
* @author Alex Boyko
21+
* @author Andy Clement
22+
*/
23+
define(function() {
24+
'use strict';
25+
26+
return ['$http', '$q', function ($http, $q) {
27+
28+
function getProposals(prefix) {
29+
var deferred = $q.defer();
30+
$http.get('/completions/task', { params: {
31+
start: prefix,
32+
detailLevel: 1
33+
}}).success(function (completions) {
34+
deferred.resolve(completions.proposals);
35+
}).error(function (err) {
36+
deferred.reject(err);
37+
});
38+
return deferred.promise;
39+
}
40+
41+
return {
42+
'getProposals': getProposals
43+
};
44+
45+
}];
46+
47+
});

0 commit comments

Comments
 (0)