mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-14 02:42:40 +01:00
Share more code between tokenizers and global typeahead
Summary: Ref T4420. Fixes T5306. Currently, the main menubar search has a lot of redundant/unshared code. Move some common functions into `JX.Prefab.whatever()` and call them from the main search. The major change here is that we apply the same "only show closed/disabled/archived objects if there are no matching open objects" logic, fixing T5306. Test Plan: - Used normal typeaheads. - Used global search. - Searched for a prefix shared by open and archived projects, didn't see the archived ones until the open ones were exhausted. Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T5306, T4420 Differential Revision: https://secure.phabricator.com/D9899
This commit is contained in:
parent
c52b3c28e1
commit
a592b32ca4
3 changed files with 127 additions and 117 deletions
|
@ -8,7 +8,7 @@
|
||||||
return array(
|
return array(
|
||||||
'names' => array(
|
'names' => array(
|
||||||
'core.pkg.css' => 'c2c68e64',
|
'core.pkg.css' => 'c2c68e64',
|
||||||
'core.pkg.js' => '80884e9b',
|
'core.pkg.js' => '0095fb2c',
|
||||||
'darkconsole.pkg.js' => 'df001cab',
|
'darkconsole.pkg.js' => 'df001cab',
|
||||||
'differential.pkg.css' => '4a93db37',
|
'differential.pkg.css' => '4a93db37',
|
||||||
'differential.pkg.js' => '7528cfc9',
|
'differential.pkg.js' => '7528cfc9',
|
||||||
|
@ -450,7 +450,7 @@ return array(
|
||||||
'rsrc/js/core/KeyboardShortcutManager.js' => 'ad7a69ca',
|
'rsrc/js/core/KeyboardShortcutManager.js' => 'ad7a69ca',
|
||||||
'rsrc/js/core/MultirowRowManager.js' => '41e47dea',
|
'rsrc/js/core/MultirowRowManager.js' => '41e47dea',
|
||||||
'rsrc/js/core/Notification.js' => '0c6946e7',
|
'rsrc/js/core/Notification.js' => '0c6946e7',
|
||||||
'rsrc/js/core/Prefab.js' => '41ed7994',
|
'rsrc/js/core/Prefab.js' => 'c11bac49',
|
||||||
'rsrc/js/core/ShapedRequest.js' => '7cbe244b',
|
'rsrc/js/core/ShapedRequest.js' => '7cbe244b',
|
||||||
'rsrc/js/core/TextAreaUtils.js' => 'b3ec3cfc',
|
'rsrc/js/core/TextAreaUtils.js' => 'b3ec3cfc',
|
||||||
'rsrc/js/core/ToolTip.js' => '3915d490',
|
'rsrc/js/core/ToolTip.js' => '3915d490',
|
||||||
|
@ -485,7 +485,7 @@ return array(
|
||||||
'rsrc/js/core/behavior-remarkup-preview.js' => 'f7379f45',
|
'rsrc/js/core/behavior-remarkup-preview.js' => 'f7379f45',
|
||||||
'rsrc/js/core/behavior-reorder-applications.js' => '76b9fc3e',
|
'rsrc/js/core/behavior-reorder-applications.js' => '76b9fc3e',
|
||||||
'rsrc/js/core/behavior-reveal-content.js' => '60821bc7',
|
'rsrc/js/core/behavior-reveal-content.js' => '60821bc7',
|
||||||
'rsrc/js/core/behavior-search-typeahead.js' => '5a376f34',
|
'rsrc/js/core/behavior-search-typeahead.js' => 'd712ac5f',
|
||||||
'rsrc/js/core/behavior-select-on-click.js' => '4e3e79a6',
|
'rsrc/js/core/behavior-select-on-click.js' => '4e3e79a6',
|
||||||
'rsrc/js/core/behavior-toggle-class.js' => 'e566f52c',
|
'rsrc/js/core/behavior-toggle-class.js' => 'e566f52c',
|
||||||
'rsrc/js/core/behavior-tokenizer.js' => 'b3a4b884',
|
'rsrc/js/core/behavior-tokenizer.js' => 'b3a4b884',
|
||||||
|
@ -629,7 +629,7 @@ return array(
|
||||||
'javelin-behavior-phabricator-oncopy' => '2926fff2',
|
'javelin-behavior-phabricator-oncopy' => '2926fff2',
|
||||||
'javelin-behavior-phabricator-remarkup-assist' => 'e32d14ab',
|
'javelin-behavior-phabricator-remarkup-assist' => 'e32d14ab',
|
||||||
'javelin-behavior-phabricator-reveal-content' => '60821bc7',
|
'javelin-behavior-phabricator-reveal-content' => '60821bc7',
|
||||||
'javelin-behavior-phabricator-search-typeahead' => '5a376f34',
|
'javelin-behavior-phabricator-search-typeahead' => 'd712ac5f',
|
||||||
'javelin-behavior-phabricator-show-all-transactions' => '7c273581',
|
'javelin-behavior-phabricator-show-all-transactions' => '7c273581',
|
||||||
'javelin-behavior-phabricator-tooltips' => '3ee3408b',
|
'javelin-behavior-phabricator-tooltips' => '3ee3408b',
|
||||||
'javelin-behavior-phabricator-transaction-comment-form' => '9f7309fb',
|
'javelin-behavior-phabricator-transaction-comment-form' => '9f7309fb',
|
||||||
|
@ -737,7 +737,7 @@ return array(
|
||||||
'phabricator-notification-menu-css' => '8ae4a008',
|
'phabricator-notification-menu-css' => '8ae4a008',
|
||||||
'phabricator-object-selector-css' => '029a133d',
|
'phabricator-object-selector-css' => '029a133d',
|
||||||
'phabricator-phtize' => 'd254d646',
|
'phabricator-phtize' => 'd254d646',
|
||||||
'phabricator-prefab' => '41ed7994',
|
'phabricator-prefab' => 'c11bac49',
|
||||||
'phabricator-profile-css' => 'b459416e',
|
'phabricator-profile-css' => 'b459416e',
|
||||||
'phabricator-remarkup-css' => 'ad4c0676',
|
'phabricator-remarkup-css' => 'ad4c0676',
|
||||||
'phabricator-search-results-css' => 'f240504c',
|
'phabricator-search-results-css' => 'f240504c',
|
||||||
|
@ -1126,18 +1126,6 @@ return array(
|
||||||
2 => 'javelin-dom',
|
2 => 'javelin-dom',
|
||||||
3 => 'javelin-util',
|
3 => 'javelin-util',
|
||||||
),
|
),
|
||||||
'41ed7994' => array(
|
|
||||||
0 => 'javelin-install',
|
|
||||||
1 => 'javelin-util',
|
|
||||||
2 => 'javelin-dom',
|
|
||||||
3 => 'javelin-typeahead',
|
|
||||||
4 => 'javelin-tokenizer',
|
|
||||||
5 => 'javelin-typeahead-preloaded-source',
|
|
||||||
6 => 'javelin-typeahead-ondemand-source',
|
|
||||||
7 => 'javelin-dom',
|
|
||||||
8 => 'javelin-stratcom',
|
|
||||||
9 => 'javelin-util',
|
|
||||||
),
|
|
||||||
'44168bad' => array(
|
'44168bad' => array(
|
||||||
0 => 'javelin-behavior',
|
0 => 'javelin-behavior',
|
||||||
1 => 'javelin-dom',
|
1 => 'javelin-dom',
|
||||||
|
@ -1232,15 +1220,6 @@ return array(
|
||||||
2 => 'javelin-vector',
|
2 => 'javelin-vector',
|
||||||
3 => 'javelin-dom',
|
3 => 'javelin-dom',
|
||||||
),
|
),
|
||||||
'5a376f34' => array(
|
|
||||||
0 => 'javelin-behavior',
|
|
||||||
1 => 'javelin-typeahead-ondemand-source',
|
|
||||||
2 => 'javelin-typeahead',
|
|
||||||
3 => 'javelin-dom',
|
|
||||||
4 => 'javelin-uri',
|
|
||||||
5 => 'javelin-util',
|
|
||||||
6 => 'javelin-stratcom',
|
|
||||||
),
|
|
||||||
'5bc2cb21' => array(
|
'5bc2cb21' => array(
|
||||||
0 => 'javelin-behavior',
|
0 => 'javelin-behavior',
|
||||||
1 => 'javelin-stratcom',
|
1 => 'javelin-stratcom',
|
||||||
|
@ -1690,6 +1669,18 @@ return array(
|
||||||
2 => 'javelin-util',
|
2 => 'javelin-util',
|
||||||
3 => 'phabricator-shaped-request',
|
3 => 'phabricator-shaped-request',
|
||||||
),
|
),
|
||||||
|
'c11bac49' => array(
|
||||||
|
0 => 'javelin-install',
|
||||||
|
1 => 'javelin-util',
|
||||||
|
2 => 'javelin-dom',
|
||||||
|
3 => 'javelin-typeahead',
|
||||||
|
4 => 'javelin-tokenizer',
|
||||||
|
5 => 'javelin-typeahead-preloaded-source',
|
||||||
|
6 => 'javelin-typeahead-ondemand-source',
|
||||||
|
7 => 'javelin-dom',
|
||||||
|
8 => 'javelin-stratcom',
|
||||||
|
9 => 'javelin-util',
|
||||||
|
),
|
||||||
'c4569c05' => array(
|
'c4569c05' => array(
|
||||||
0 => 'javelin-magical-init',
|
0 => 'javelin-magical-init',
|
||||||
1 => 'javelin-install',
|
1 => 'javelin-install',
|
||||||
|
@ -1764,6 +1755,16 @@ return array(
|
||||||
2 => 'javelin-stratcom',
|
2 => 'javelin-stratcom',
|
||||||
3 => 'javelin-dom',
|
3 => 'javelin-dom',
|
||||||
),
|
),
|
||||||
|
'd712ac5f' => array(
|
||||||
|
0 => 'javelin-behavior',
|
||||||
|
1 => 'javelin-typeahead-ondemand-source',
|
||||||
|
2 => 'javelin-typeahead',
|
||||||
|
3 => 'javelin-dom',
|
||||||
|
4 => 'javelin-uri',
|
||||||
|
5 => 'javelin-util',
|
||||||
|
6 => 'javelin-stratcom',
|
||||||
|
7 => 'phabricator-prefab',
|
||||||
|
),
|
||||||
'd75709e6' => array(
|
'd75709e6' => array(
|
||||||
0 => 'javelin-behavior',
|
0 => 'javelin-behavior',
|
||||||
1 => 'javelin-workflow',
|
1 => 'javelin-workflow',
|
||||||
|
|
|
@ -31,6 +31,7 @@ JX.install('Prefab', {
|
||||||
return select;
|
return select;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build a Phabricator tokenizer out of a configuration with application
|
* Build a Phabricator tokenizer out of a configuration with application
|
||||||
* sorting, datasource and placeholder rules.
|
* sorting, datasource and placeholder rules.
|
||||||
|
@ -142,82 +143,9 @@ JX.install('Prefab', {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
var render_icon = function(icon) {
|
|
||||||
return JX.$N(
|
|
||||||
'span',
|
|
||||||
{className: 'phui-icon-view phui-font-fa ' + icon});
|
|
||||||
};
|
|
||||||
|
|
||||||
datasource.setSortHandler(JX.bind(datasource, sort_handler));
|
datasource.setSortHandler(JX.bind(datasource, sort_handler));
|
||||||
|
datasource.setFilterHandler(JX.Prefab.filterClosedResults);
|
||||||
// Don't show any closed objects until the query is specific enough that
|
datasource.setTransformer(JX.Prefab.transformDatasourceResults);
|
||||||
// it only selects closed objects. Specifically, if the result list had
|
|
||||||
// any open objects, remove all the closed objects from the list.
|
|
||||||
var filter_handler = function(value, list) {
|
|
||||||
// Look for any open result.
|
|
||||||
var has_open = false;
|
|
||||||
var ii;
|
|
||||||
for (ii = 0; ii < list.length; ii++) {
|
|
||||||
if (!list[ii].closed) {
|
|
||||||
has_open = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!has_open) {
|
|
||||||
// Everything is closed, so just use it as-is.
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, only display the open results.
|
|
||||||
var results = [];
|
|
||||||
for (ii = 0; ii < list.length; ii++) {
|
|
||||||
if (!list[ii].closed) {
|
|
||||||
results.push(list[ii]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return results;
|
|
||||||
};
|
|
||||||
|
|
||||||
datasource.setFilterHandler(filter_handler);
|
|
||||||
|
|
||||||
datasource.setTransformer(
|
|
||||||
function(object) {
|
|
||||||
var closed = object[9];
|
|
||||||
var closed_ui;
|
|
||||||
if (closed) {
|
|
||||||
closed_ui = JX.$N(
|
|
||||||
'div',
|
|
||||||
{className: 'tokenizer-closed'},
|
|
||||||
closed);
|
|
||||||
}
|
|
||||||
|
|
||||||
var icon = object[8];
|
|
||||||
var icon_ui;
|
|
||||||
if (icon) {
|
|
||||||
icon_ui = render_icon(icon);
|
|
||||||
}
|
|
||||||
|
|
||||||
var display = JX.$N(
|
|
||||||
'div',
|
|
||||||
{className: 'tokenizer-result'},
|
|
||||||
[icon_ui, object[0], closed_ui]);
|
|
||||||
if (closed) {
|
|
||||||
JX.DOM.alterClass(display, 'tokenizer-result-closed', true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
name: object[0],
|
|
||||||
display: display,
|
|
||||||
uri: object[1],
|
|
||||||
id: object[2],
|
|
||||||
priority: object[3],
|
|
||||||
priorityType: object[7],
|
|
||||||
icon: icon,
|
|
||||||
closed: closed
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
var typeahead = new JX.Typeahead(
|
var typeahead = new JX.Typeahead(
|
||||||
root,
|
root,
|
||||||
|
@ -238,7 +166,7 @@ JX.install('Prefab', {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
icon = render_icon(icon);
|
icon = JX.Prefab._renderIcon(icon);
|
||||||
|
|
||||||
// TODO: Maybe we should render these closed tags in grey? Figure out
|
// TODO: Maybe we should render these closed tags in grey? Figure out
|
||||||
// how we're going to use color.
|
// how we're going to use color.
|
||||||
|
@ -263,7 +191,89 @@ JX.install('Prefab', {
|
||||||
return {
|
return {
|
||||||
tokenizer: tokenizer
|
tokenizer: tokenizer
|
||||||
};
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter callback for tokenizers and typeaheads which filters out closed
|
||||||
|
* or disabled objects unless they are the only options.
|
||||||
|
*/
|
||||||
|
filterClosedResults: function(value, list) {
|
||||||
|
// Look for any open result.
|
||||||
|
var has_open = false;
|
||||||
|
var ii;
|
||||||
|
for (ii = 0; ii < list.length; ii++) {
|
||||||
|
if (!list[ii].closed) {
|
||||||
|
has_open = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!has_open) {
|
||||||
|
// Everything is closed, so just use it as-is.
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, only display the open results.
|
||||||
|
var results = [];
|
||||||
|
for (ii = 0; ii < list.length; ii++) {
|
||||||
|
if (!list[ii].closed) {
|
||||||
|
results.push(list[ii]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform results from a wire format into a usable format in a standard
|
||||||
|
* way.
|
||||||
|
*/
|
||||||
|
transformDatasourceResults: function(fields) {
|
||||||
|
var closed = fields[9];
|
||||||
|
var closed_ui;
|
||||||
|
if (closed) {
|
||||||
|
closed_ui = JX.$N(
|
||||||
|
'div',
|
||||||
|
{className: 'tokenizer-closed'},
|
||||||
|
closed);
|
||||||
|
}
|
||||||
|
|
||||||
|
var icon = fields[8];
|
||||||
|
var icon_ui;
|
||||||
|
if (icon) {
|
||||||
|
icon_ui = JX.Prefab._renderIcon(icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
var display = JX.$N(
|
||||||
|
'div',
|
||||||
|
{className: 'tokenizer-result'},
|
||||||
|
[icon_ui, fields[4] || fields[0], closed_ui]);
|
||||||
|
if (closed) {
|
||||||
|
JX.DOM.alterClass(display, 'tokenizer-result-closed', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: fields[0],
|
||||||
|
displayName: fields[4] || fields[0],
|
||||||
|
display: display,
|
||||||
|
uri: fields[1],
|
||||||
|
id: fields[2],
|
||||||
|
priority: fields[3],
|
||||||
|
priorityType: fields[7],
|
||||||
|
imageURI: fields[6],
|
||||||
|
icon: icon,
|
||||||
|
closed: closed,
|
||||||
|
type: fields[5],
|
||||||
|
sprite: fields[10]
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
_renderIcon: function(icon) {
|
||||||
|
return JX.$N(
|
||||||
|
'span',
|
||||||
|
{className: 'phui-icon-view phui-font-fa ' + icon});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
* javelin-uri
|
* javelin-uri
|
||||||
* javelin-util
|
* javelin-util
|
||||||
* javelin-stratcom
|
* javelin-stratcom
|
||||||
|
* phabricator-prefab
|
||||||
*/
|
*/
|
||||||
|
|
||||||
JX.behavior('phabricator-search-typeahead', function(config) {
|
JX.behavior('phabricator-search-typeahead', function(config) {
|
||||||
|
@ -14,31 +15,28 @@ JX.behavior('phabricator-search-typeahead', function(config) {
|
||||||
var datasource = new JX.TypeaheadOnDemandSource(config.src);
|
var datasource = new JX.TypeaheadOnDemandSource(config.src);
|
||||||
|
|
||||||
function transform(object) {
|
function transform(object) {
|
||||||
|
object = JX.Prefab.transformDatasourceResults(object);
|
||||||
|
|
||||||
var attr = {
|
var attr = {
|
||||||
className: 'phabricator-main-search-typeahead-result'
|
className: 'phabricator-main-search-typeahead-result'
|
||||||
};
|
};
|
||||||
|
|
||||||
if (object[6]) {
|
if (object.imageURI) {
|
||||||
attr.style = {backgroundImage: 'url('+object[6]+')'};
|
attr.style = {backgroundImage: 'url('+object.imageURI+')'};
|
||||||
}
|
}
|
||||||
|
|
||||||
var render = JX.$N(
|
var render = JX.$N(
|
||||||
'span',
|
'span',
|
||||||
attr,
|
attr,
|
||||||
[
|
[
|
||||||
JX.$N('span', {className: object[10]}),
|
JX.$N('span', {className: object.sprite}),
|
||||||
JX.$N('span', {className: 'result-name'}, object[4] || object[0]),
|
JX.$N('span', {className: 'result-name'}, object.displayName),
|
||||||
JX.$N('span', {className: 'result-type'}, object[5])
|
JX.$N('span', {className: 'result-type'}, object.type)
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return {
|
object.display = render;
|
||||||
name: object[0],
|
|
||||||
display: render,
|
return object;
|
||||||
uri: object[1],
|
|
||||||
id: object[2],
|
|
||||||
priority: object[3],
|
|
||||||
type: object[7]
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
datasource.setTransformer(transform);
|
datasource.setTransformer(transform);
|
||||||
|
@ -76,8 +74,8 @@ JX.behavior('phabricator-search-typeahead', function(config) {
|
||||||
}
|
}
|
||||||
|
|
||||||
list.sort(function(u, v) {
|
list.sort(function(u, v) {
|
||||||
var u_type = type_priority[u.type] || 999;
|
var u_type = type_priority[u.priorityType] || 999;
|
||||||
var v_type = type_priority[v.type] || 999;
|
var v_type = type_priority[v.priorityType] || 999;
|
||||||
|
|
||||||
if (u_type != v_type) {
|
if (u_type != v_type) {
|
||||||
return u_type - v_type;
|
return u_type - v_type;
|
||||||
|
@ -120,6 +118,7 @@ JX.behavior('phabricator-search-typeahead', function(config) {
|
||||||
};
|
};
|
||||||
|
|
||||||
datasource.setSortHandler(JX.bind(datasource, sort_handler));
|
datasource.setSortHandler(JX.bind(datasource, sort_handler));
|
||||||
|
datasource.setFilterHandler(JX.Prefab.filterClosedResults);
|
||||||
datasource.setMaximumResultCount(config.limit);
|
datasource.setMaximumResultCount(config.limit);
|
||||||
|
|
||||||
var typeahead = new JX.Typeahead(JX.$(config.id), JX.$(config.input));
|
var typeahead = new JX.Typeahead(JX.$(config.id), JX.$(config.input));
|
||||||
|
|
Loading…
Reference in a new issue