@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Don't show closed typeahead results while open results exist

Summary:
Ref T4420. When a result list contains both open and closed results, hide the closed results. I think this has a good chance of almost always working, and feeling very intuitive. It has a small chance of being a weird mess. It feels reasonable to me so far

The one bad case I can come up with here is that if you have results which shadow each other, like "Apples" (a closed project) and "Apples and Bananas" (an open project), it is impossible to get "Apples" in the result list, because "Apples and Bananas" will always shadow it. Let's wait for someone to hit this before we figure out how to deal with it.

Test Plan: Typed through open stuff to hit closed stuff.

Reviewers: chad, btrahan

Reviewed By: chad

CC: aran

Maniphest Tasks: T4420

Differential Revision: https://secure.phabricator.com/D8238

+85 -33
+26 -26
resources/celerity/map.php
··· 8 8 'names' => 9 9 array( 10 10 'core.pkg.css' => '1ccefdc6', 11 - 'core.pkg.js' => 'ee746639', 11 + 'core.pkg.js' => '92f2c0a7', 12 12 'darkconsole.pkg.js' => 'ca8671ce', 13 13 'differential.pkg.css' => '6aef439e', 14 14 'differential.pkg.js' => '322ea941', 15 15 'diffusion.pkg.css' => '3783278d', 16 16 'diffusion.pkg.js' => '7b51e80a', 17 - 'javelin.pkg.js' => 'da52b0df', 17 + 'javelin.pkg.js' => 'c7ef4e11', 18 18 'maniphest.pkg.css' => 'f1887d71', 19 19 'maniphest.pkg.js' => '1e8f11af', 20 20 'rsrc/css/aphront/aphront-bars.css' => '231ac33c', ··· 213 213 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadCompositeSource.js' => 'dbd9cd11', 214 214 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadOnDemandSource.js' => '7383383f', 215 215 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadPreloadedSource.js' => 'e9b95df3', 216 - 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadSource.js' => '74fe50ac', 216 + 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadSource.js' => '5e18d309', 217 217 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadStaticSource.js' => 'c2b8bf64', 218 218 'rsrc/externals/raphael/g.raphael.js' => '40dde778', 219 219 'rsrc/externals/raphael/g.raphael.line.js' => '40da039e', ··· 432 432 'rsrc/js/core/KeyboardShortcutManager.js' => 'ad7a69ca', 433 433 'rsrc/js/core/MultirowRowManager.js' => 'e7076916', 434 434 'rsrc/js/core/Notification.js' => '95944043', 435 - 'rsrc/js/core/Prefab.js' => '83ee580c', 435 + 'rsrc/js/core/Prefab.js' => '88ca7175', 436 436 'rsrc/js/core/ShapedRequest.js' => 'dfa181a4', 437 437 'rsrc/js/core/TextAreaUtils.js' => 'b3ec3cfc', 438 438 'rsrc/js/core/ToolTip.js' => '0a81ea29', ··· 648 648 'javelin-typeahead-normalizer' => '5f850b5c', 649 649 'javelin-typeahead-ondemand-source' => '7383383f', 650 650 'javelin-typeahead-preloaded-source' => 'e9b95df3', 651 - 'javelin-typeahead-source' => '74fe50ac', 651 + 'javelin-typeahead-source' => '5e18d309', 652 652 'javelin-typeahead-static-source' => 'c2b8bf64', 653 653 'javelin-uri' => 'd9a9b862', 654 654 'javelin-util' => '7501647b', ··· 702 702 'phabricator-object-list-view-css' => '1a1ea560', 703 703 'phabricator-object-selector-css' => '029a133d', 704 704 'phabricator-phtize' => 'd254d646', 705 - 'phabricator-prefab' => '83ee580c', 705 + 'phabricator-prefab' => '88ca7175', 706 706 'phabricator-profile-css' => '3a7e04ca', 707 707 'phabricator-project-tag-css' => '095c9404', 708 708 'phabricator-remarkup-css' => 'ca7f2265', ··· 1163 1163 3 => 'javelin-stratcom', 1164 1164 4 => 'javelin-vector', 1165 1165 ), 1166 + '5e18d309' => 1167 + array( 1168 + 0 => 'javelin-install', 1169 + 1 => 'javelin-util', 1170 + 2 => 'javelin-dom', 1171 + 3 => 'javelin-typeahead-normalizer', 1172 + ), 1166 1173 '5f004630' => 1167 1174 array( 1168 1175 0 => 'javelin-behavior', ··· 1233 1240 1 => 'javelin-util', 1234 1241 2 => 'javelin-request', 1235 1242 3 => 'javelin-typeahead-source', 1236 - ), 1237 - '74fe50ac' => 1238 - array( 1239 - 0 => 'javelin-install', 1240 - 1 => 'javelin-util', 1241 - 2 => 'javelin-dom', 1242 - 3 => 'javelin-typeahead-normalizer', 1243 1243 ), 1244 1244 '75e50c72' => 1245 1245 array( ··· 1308 1308 1 => 'javelin-dom', 1309 1309 2 => 'javelin-reactor-dom', 1310 1310 ), 1311 - '83ee580c' => 1312 - array( 1313 - 0 => 'javelin-install', 1314 - 1 => 'javelin-util', 1315 - 2 => 'javelin-dom', 1316 - 3 => 'javelin-typeahead', 1317 - 4 => 'javelin-tokenizer', 1318 - 5 => 'javelin-typeahead-preloaded-source', 1319 - 6 => 'javelin-typeahead-ondemand-source', 1320 - 7 => 'javelin-dom', 1321 - 8 => 'javelin-stratcom', 1322 - 9 => 'javelin-util', 1323 - ), 1324 1311 '8454ce4f' => 1325 1312 array( 1326 1313 0 => 'javelin-behavior', ··· 1367 1354 5 => 'javelin-behavior-device', 1368 1355 6 => 'javelin-history', 1369 1356 7 => 'javelin-vector', 1357 + ), 1358 + '88ca7175' => 1359 + array( 1360 + 0 => 'javelin-install', 1361 + 1 => 'javelin-util', 1362 + 2 => 'javelin-dom', 1363 + 3 => 'javelin-typeahead', 1364 + 4 => 'javelin-tokenizer', 1365 + 5 => 'javelin-typeahead-preloaded-source', 1366 + 6 => 'javelin-typeahead-ondemand-source', 1367 + 7 => 'javelin-dom', 1368 + 8 => 'javelin-stratcom', 1369 + 9 => 'javelin-util', 1370 1370 ), 1371 1371 '8a3ed18b' => 1372 1372 array(
-1
src/applications/project/search/PhabricatorProjectSearchIndexer.php
··· 28 28 PhabricatorProjectPHIDTypeProject::TYPECONST, 29 29 time()); 30 30 31 - 32 31 // NOTE: This could be more full-featured, but for now we're mostly 33 32 // interested in the side effects of indexing. 34 33
+26 -6
webroot/rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadSource.js
··· 109 109 * 110 110 * @param function 111 111 */ 112 - sortHandler : null 112 + sortHandler : null, 113 + 114 + /** 115 + * Optional function which is used to filter results before display. Inputs 116 + * are the input string and a list of matches. The function should 117 + * return a list of matches to display. This is the minimum useful 118 + * implementation: 119 + * 120 + * function(value, list) { 121 + * return list; 122 + * } 123 + * 124 + * @param function 125 + */ 126 + filterHandler : null 113 127 114 128 }, 115 129 ··· 275 289 } 276 290 } 277 291 278 - this.sortHits(value, hits); 292 + this.filterAndSortHits(value, hits); 279 293 280 294 var nodes = this.renderNodes(value, hits); 281 295 this.invoke('resultsready', nodes); ··· 284 298 } 285 299 }, 286 300 287 - sortHits : function(value, hits) { 301 + filterAndSortHits : function(value, hits) { 288 302 var objs = []; 289 303 var ii; 290 304 for (ii = 0; ii < hits.length; ii++) { 291 305 objs.push(this._raw[hits[ii]]); 292 306 } 293 307 294 - var default_comparator = function(u, v) { 308 + var default_comparator = function(u, v) { 295 309 var key_u = u.sort || u.name; 296 310 var key_v = v.sort || v.name; 297 311 return key_u.localeCompare(key_v); 298 312 }; 299 313 300 - var handler = this.getSortHandler() || function(value, list, cmp) { 314 + var filter_handler = this.getFilterHandler() || function(value, list) { 315 + return list; 316 + }; 317 + 318 + objs = filter_handler(value, objs); 319 + 320 + var sort_handler = this.getSortHandler() || function(value, list, cmp) { 301 321 list.sort(cmp); 302 322 }; 303 323 304 - handler(value, objs, default_comparator); 324 + sort_handler(value, objs, default_comparator); 305 325 306 326 hits.splice(0, hits.length); 307 327 for (ii = 0; ii < objs.length; ii++) {
+33
webroot/rsrc/js/core/Prefab.js
··· 146 146 }; 147 147 148 148 datasource.setSortHandler(JX.bind(datasource, sort_handler)); 149 + 150 + // Don't show any closed objects until the query is specific enough that 151 + // it only selects closed objects. Specifically, if the result list had 152 + // any open objects, remove all the closed objects from the list. 153 + var filter_handler = function(value, list) { 154 + // Look for any open result. 155 + var has_open = false; 156 + var ii; 157 + for (ii = 0; ii < list.length; ii++) { 158 + if (!list[ii].closed) { 159 + has_open = true; 160 + break; 161 + } 162 + } 163 + 164 + if (!has_open) { 165 + // Everything is closed, so just use it as-is. 166 + return list; 167 + } 168 + 169 + // Otherwise, only display the open results. 170 + var results = []; 171 + for (ii = 0; ii < list.length; ii++) { 172 + if (!list[ii].closed) { 173 + results.push(list[ii]); 174 + } 175 + } 176 + 177 + return results; 178 + }; 179 + 180 + datasource.setFilterHandler(filter_handler); 181 + 149 182 datasource.setTransformer( 150 183 function(object) { 151 184 var closed = object[9];