mirror of
https://github.com/gitbucket/gitbucket.git
synced 2025-11-12 16:35:52 +01:00
Merge pull request #1731 from gitbucket/enhance-suggestion-provider
Enhance SuggestionProvider to be able to supply label and value
This commit is contained in:
@@ -121,7 +121,12 @@ trait IndexControllerBase extends ControllerBase {
|
||||
case (true, false) => !t.isGroupAccount
|
||||
case (false, true) => t.isGroupAccount
|
||||
case (false, false) => false
|
||||
}}.map { t => t.userName }
|
||||
}}.map { t =>
|
||||
Map(
|
||||
"label" -> s"<b>@${t.userName}</b> ${t.fullName}",
|
||||
"value" -> t.userName
|
||||
)
|
||||
}
|
||||
))
|
||||
)
|
||||
})
|
||||
|
||||
@@ -3,15 +3,92 @@ package gitbucket.core.plugin
|
||||
import gitbucket.core.controller.Context
|
||||
import gitbucket.core.service.RepositoryService.RepositoryInfo
|
||||
|
||||
/**
|
||||
* The base trait of suggestion providers which supplies completion proposals in some text areas.
|
||||
*/
|
||||
trait SuggestionProvider {
|
||||
|
||||
/**
|
||||
* The identifier of this suggestion provider.
|
||||
* You must specify the unique identifier in the all suggestion providers.
|
||||
*/
|
||||
val id: String
|
||||
|
||||
/**
|
||||
* The trigger of this suggestion provider. When user types this character, the proposal list would be displayed.
|
||||
* Also this is used as the prefix of the replaced string.
|
||||
*/
|
||||
val prefix: String
|
||||
|
||||
/**
|
||||
* The suffix of the replaced string. The default is `" "`.
|
||||
*/
|
||||
val suffix: String = " "
|
||||
|
||||
/**
|
||||
* Which contexts is this suggestion provider enabled. Currently, available contexts are `"issues"` and `"wiki"`.
|
||||
*/
|
||||
val context: Seq[String]
|
||||
|
||||
def values(repository: RepositoryInfo): Seq[String]
|
||||
def template(implicit context: Context): String = "value"
|
||||
/**
|
||||
* If this suggestion provider has static proposal list, override this method to return it.
|
||||
*
|
||||
* The returned sequence is rendered as follows:
|
||||
* <pre>
|
||||
* [
|
||||
* {
|
||||
* "label" -> "value1",
|
||||
* "value" -> "value1"
|
||||
* },
|
||||
* {
|
||||
* "label" -> "value2",
|
||||
* "value" -> "value2"
|
||||
* },
|
||||
* ]
|
||||
* </pre>
|
||||
*
|
||||
* Each element can be accessed as `option` in `template()` or `replace()` method.
|
||||
*/
|
||||
def values(repository: RepositoryInfo): Seq[String] = Nil
|
||||
|
||||
/**
|
||||
* If this suggestion provider has static proposal list, override this method to return it.
|
||||
*
|
||||
* If your proposals have label and value, use this method instead of `values()`.
|
||||
* The first element of tuple is used as a value, and the second element is used as a label.
|
||||
*
|
||||
* The returned sequence is rendered as follows:
|
||||
* <pre>
|
||||
* [
|
||||
* {
|
||||
* "label" -> "label1",
|
||||
* "value" -> "value1"
|
||||
* },
|
||||
* {
|
||||
* "label" -> "label2",
|
||||
* "value" -> "value2"
|
||||
* },
|
||||
* ]
|
||||
* </pre>
|
||||
*
|
||||
* Each element can be accessed as `option` in `template()` or `replace()` method.
|
||||
*/
|
||||
def options(repository: RepositoryInfo): Seq[(String, String)] = values(repository).map { value => (value, value) }
|
||||
|
||||
/**
|
||||
* JavaScript fragment to generate a label of completion proposal. The default is: `option.label`.
|
||||
*/
|
||||
def template(implicit context: Context): String = "option.label"
|
||||
|
||||
/**
|
||||
* JavaScript fragment to generate a replaced value of completion proposal. The default is: `option.value`
|
||||
*/
|
||||
def replace(implicit context: Context): String = "option.value"
|
||||
|
||||
/**
|
||||
* If this suggestion provider needs some additional process to assemble the proposal list (e.g. It need to use Ajax
|
||||
* to get a proposal list from the server), then override this method and return any JavaScript code.
|
||||
*/
|
||||
def additionalScript(implicit context: Context): String = ""
|
||||
|
||||
}
|
||||
@@ -20,8 +97,6 @@ class UserNameSuggestionProvider extends SuggestionProvider {
|
||||
override val id: String = "user"
|
||||
override val prefix: String = "@"
|
||||
override val context: Seq[String] = Seq("issues")
|
||||
override def values(repository: RepositoryInfo): Seq[String] = Nil
|
||||
override def template(implicit context: Context): String = "'@' + value"
|
||||
override def additionalScript(implicit context: Context): String =
|
||||
s"""$$.get('${context.path}/_user/proposals', { query: '', user: true, group: false }, function (data) { user = data.options; });"""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,9 @@
|
||||
$(function(){
|
||||
@gitbucket.core.plugin.PluginRegistry().getSuggestionProviders.map { provider =>
|
||||
@if(provider.context.contains(completionContext)){
|
||||
var @provider.id = @Html(helpers.json(provider.values(repository)));
|
||||
var @provider.id = @Html(helpers.json(provider.options(repository).map { case (value, label) =>
|
||||
Map("value" -> value, "label" -> label)
|
||||
}));
|
||||
@Html(provider.additionalScript)
|
||||
}
|
||||
}
|
||||
@@ -23,14 +25,14 @@ $(function(){
|
||||
match: /\B@{provider.prefix}([\-+\w]*)$/,
|
||||
search: function (term, callback) {
|
||||
callback($.map(@{provider.id}, function (proposal) {
|
||||
return proposal.indexOf(term) === 0 ? proposal : null;
|
||||
return proposal.value.indexOf(term) === 0 ? proposal : null;
|
||||
}));
|
||||
},
|
||||
template: function (value) {
|
||||
template: function (option) {
|
||||
return @{Html(provider.template)};
|
||||
},
|
||||
replace: function (value) {
|
||||
return '@{provider.prefix}' + value + '@{provider.suffix}';
|
||||
replace: function (option) {
|
||||
return '@{provider.prefix}' + @{Html(provider.replace)} + '@{provider.suffix}';
|
||||
},
|
||||
index: 1
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user