1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-18 11:30:55 +01:00

Basic Conpherence Search in Thread

Summary: Adds a search bar toggle and results for searching inside a Conpherence Room. The UI of the results itself are not styled yet, and will follow up with another diff.

Test Plan: Go to Conpherence, search for "asdf", get lots of results. Search for nothing, get no change, search for something fictitious, get no threads found (will follow up with search result UI).

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: Korvin

Differential Revision: https://secure.phabricator.com/D16697
This commit is contained in:
Chad Little 2016-10-13 11:09:54 -07:00
parent c2411e3dcc
commit 508a2a1498
16 changed files with 340 additions and 93 deletions

View file

@ -7,9 +7,9 @@
*/
return array(
'names' => array(
'conpherence.pkg.css' => '4601645d',
'conpherence.pkg.js' => '44dd69f5',
'core.pkg.css' => '7ca260a3',
'conpherence.pkg.css' => 'c839a862',
'conpherence.pkg.js' => 'b18c9dc5',
'core.pkg.css' => 'b99bbf5e',
'core.pkg.js' => '30185d95',
'darkconsole.pkg.js' => 'e7393ebb',
'differential.pkg.css' => 'e1d704ce',
@ -47,13 +47,12 @@ return array(
'rsrc/css/application/config/setup-issue.css' => 'f794cfc3',
'rsrc/css/application/config/unhandled-exception.css' => '4c96257a',
'rsrc/css/application/conpherence/durable-column.css' => '44bcaa19',
'rsrc/css/application/conpherence/header-pane.css' => '20a7028c',
'rsrc/css/application/conpherence/header-pane.css' => 'e8acbd37',
'rsrc/css/application/conpherence/menu.css' => '4f51db5a',
'rsrc/css/application/conpherence/message-pane.css' => '0d7dff02',
'rsrc/css/application/conpherence/message-pane.css' => 'eff20ae7',
'rsrc/css/application/conpherence/notification.css' => '965db05b',
'rsrc/css/application/conpherence/participant-pane.css' => '7bba0b56',
'rsrc/css/application/conpherence/transaction.css' => '46253e19',
'rsrc/css/application/conpherence/update.css' => '53bc527a',
'rsrc/css/application/contentsource/content-source-view.css' => '4b8b05d4',
'rsrc/css/application/countdown/timer.css' => '16c52f5c',
'rsrc/css/application/daemon/bulk-job.css' => 'df9c1d4a',
@ -110,7 +109,7 @@ return array(
'rsrc/css/core/core.css' => 'd0801452',
'rsrc/css/core/remarkup.css' => 'cd912f2c',
'rsrc/css/core/syntax.css' => '769d3498',
'rsrc/css/core/z-index.css' => '0d4e5558',
'rsrc/css/core/z-index.css' => 'd1270942',
'rsrc/css/diviner/diviner-shared.css' => 'aa3656aa',
'rsrc/css/font/font-aleo.css' => '8bdb2835',
'rsrc/css/font/font-awesome.css' => '2b7ebbcc',
@ -144,7 +143,7 @@ return array(
'rsrc/css/phui/phui-header-view.css' => '06385974',
'rsrc/css/phui/phui-hovercard.css' => 'de1a2119',
'rsrc/css/phui/phui-icon-set-selector.css' => '1ab67aad',
'rsrc/css/phui/phui-icon.css' => '9bab6f02',
'rsrc/css/phui/phui-icon.css' => '417f80fb',
'rsrc/css/phui/phui-image-mask.css' => 'a8498f9c',
'rsrc/css/phui/phui-info-panel.css' => '27ea50a1',
'rsrc/css/phui/phui-info-view.css' => '28efab79',
@ -437,8 +436,9 @@ return array(
'rsrc/js/application/calendar/behavior-recurring-edit.js' => '5f1c4d5f',
'rsrc/js/application/config/behavior-reorder-fields.js' => 'b6993408',
'rsrc/js/application/conpherence/ConpherenceThreadManager.js' => '01774ab2',
'rsrc/js/application/conpherence/behavior-conpherence-search.js' => '3bc9d2b1',
'rsrc/js/application/conpherence/behavior-durable-column.js' => 'c5238acb',
'rsrc/js/application/conpherence/behavior-menu.js' => '9eb55204',
'rsrc/js/application/conpherence/behavior-menu.js' => '0f82ba76',
'rsrc/js/application/conpherence/behavior-participant-pane.js' => '8604caa8',
'rsrc/js/application/conpherence/behavior-pontificate.js' => 'f2e58483',
'rsrc/js/application/conpherence/behavior-quicksand-blacklist.js' => '7927a7d3',
@ -617,14 +617,13 @@ return array(
'config-options-css' => '0ede4c9b',
'config-page-css' => '8798e14f',
'conpherence-durable-column-view' => '44bcaa19',
'conpherence-header-pane-css' => '20a7028c',
'conpherence-header-pane-css' => 'e8acbd37',
'conpherence-menu-css' => '4f51db5a',
'conpherence-message-pane-css' => '0d7dff02',
'conpherence-message-pane-css' => 'eff20ae7',
'conpherence-notification-css' => '965db05b',
'conpherence-participant-pane-css' => '7bba0b56',
'conpherence-thread-manager' => '01774ab2',
'conpherence-transaction-css' => '46253e19',
'conpherence-update-css' => '53bc527a',
'd3' => 'a11a5ff2',
'differential-changeset-view-css' => '9ef7d354',
'differential-core-view-css' => '5b7b8ff4',
@ -664,9 +663,10 @@ return array(
'javelin-behavior-choose-control' => '327a00d1',
'javelin-behavior-comment-actions' => '0300eae6',
'javelin-behavior-config-reorder-fields' => 'b6993408',
'javelin-behavior-conpherence-menu' => '9eb55204',
'javelin-behavior-conpherence-menu' => '0f82ba76',
'javelin-behavior-conpherence-participant-pane' => '8604caa8',
'javelin-behavior-conpherence-pontificate' => 'f2e58483',
'javelin-behavior-conpherence-search' => '3bc9d2b1',
'javelin-behavior-countdown-timer' => 'e4cc26b3',
'javelin-behavior-dark-console' => 'f411b6ae',
'javelin-behavior-dashboard-async-panel' => '469c0d9e',
@ -880,7 +880,7 @@ return array(
'phabricator-uiexample-reactor-select' => 'a155550f',
'phabricator-uiexample-reactor-sendclass' => '1def2711',
'phabricator-uiexample-reactor-sendproperties' => 'b1f0ccee',
'phabricator-zindex-css' => '0d4e5558',
'phabricator-zindex-css' => 'd1270942',
'phame-css' => '8efb0729',
'pholio-css' => 'ca89d380',
'pholio-edit-css' => '07676f51',
@ -917,7 +917,7 @@ return array(
'phui-hovercard' => '1bd28176',
'phui-hovercard-view-css' => 'de1a2119',
'phui-icon-set-selector-css' => '1ab67aad',
'phui-icon-view-css' => '9bab6f02',
'phui-icon-view-css' => '417f80fb',
'phui-image-mask-css' => 'a8498f9c',
'phui-info-panel-css' => '27ea50a1',
'phui-info-view-css' => '28efab79',
@ -1072,6 +1072,20 @@ return array(
'javelin-install',
'javelin-util',
),
'0f82ba76' => array(
'javelin-behavior',
'javelin-dom',
'javelin-util',
'javelin-stratcom',
'javelin-workflow',
'javelin-behavior-device',
'javelin-history',
'javelin-vector',
'javelin-scrollbar',
'phabricator-title',
'phabricator-shaped-request',
'conpherence-thread-manager',
),
'116cf19b' => array(
'javelin-behavior',
'javelin-stratcom',
@ -1205,6 +1219,13 @@ return array(
'javelin-dom',
'javelin-magical-init',
),
'3bc9d2b1' => array(
'javelin-behavior',
'javelin-dom',
'javelin-util',
'javelin-workflow',
'javelin-stratcom',
),
'3cb0b2fc' => array(
'javelin-behavior',
'javelin-dom',
@ -1745,20 +1766,6 @@ return array(
'javelin-workflow',
'javelin-stratcom',
),
'9eb55204' => array(
'javelin-behavior',
'javelin-dom',
'javelin-util',
'javelin-stratcom',
'javelin-workflow',
'javelin-behavior-device',
'javelin-history',
'javelin-vector',
'javelin-scrollbar',
'phabricator-title',
'phabricator-shaped-request',
'conpherence-thread-manager',
),
'9ef7d354' => array(
'phui-inline-comment-view-css',
),
@ -2292,7 +2299,6 @@ return array(
'conpherence-message-pane-css',
'conpherence-notification-css',
'conpherence-transaction-css',
'conpherence-update-css',
'conpherence-participant-pane-css',
'conpherence-header-pane-css',
),

View file

@ -157,7 +157,6 @@ return array(
'conpherence-message-pane-css',
'conpherence-notification-css',
'conpherence-transaction-css',
'conpherence-update-css',
'conpherence-participant-pane-css',
'conpherence-header-pane-css',
),

View file

@ -320,6 +320,7 @@ phutil_register_library_map(array(
'ConpherenceThreadMembersPolicyRule' => 'applications/conpherence/policyrule/ConpherenceThreadMembersPolicyRule.php',
'ConpherenceThreadQuery' => 'applications/conpherence/query/ConpherenceThreadQuery.php',
'ConpherenceThreadRemarkupRule' => 'applications/conpherence/remarkup/ConpherenceThreadRemarkupRule.php',
'ConpherenceThreadSearchController' => 'applications/conpherence/controller/ConpherenceThreadSearchController.php',
'ConpherenceThreadSearchEngine' => 'applications/conpherence/query/ConpherenceThreadSearchEngine.php',
'ConpherenceThreadTitleNgrams' => 'applications/conpherence/storage/ConpherenceThreadTitleNgrams.php',
'ConpherenceTransaction' => 'applications/conpherence/storage/ConpherenceTransaction.php',
@ -4844,6 +4845,7 @@ phutil_register_library_map(array(
'ConpherenceThreadMembersPolicyRule' => 'PhabricatorPolicyRule',
'ConpherenceThreadQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'ConpherenceThreadRemarkupRule' => 'PhabricatorObjectRemarkupRule',
'ConpherenceThreadSearchController' => 'ConpherenceController',
'ConpherenceThreadSearchEngine' => 'PhabricatorApplicationSearchEngine',
'ConpherenceThreadTitleNgrams' => 'PhabricatorSearchNgrams',
'ConpherenceTransaction' => 'PhabricatorApplicationTransaction',

View file

@ -37,6 +37,8 @@ final class PhabricatorConpherenceApplication extends PhabricatorApplication {
=> 'ConpherenceListController',
'thread/(?P<id>[1-9]\d*)/'
=> 'ConpherenceListController',
'threadsearch/(?P<id>[1-9]\d*)/'
=> 'ConpherenceThreadSearchController',
'(?P<id>[1-9]\d*)/'
=> 'ConpherenceViewController',
'(?P<id>[1-9]\d*)/(?P<messageID>[1-9]\d*)/'

View file

@ -113,6 +113,20 @@ abstract class ConpherenceController extends PhabricatorController {
->setHref('#')
->addClass('conpherence-participant-toggle'));
Javelin::initBehavior(
'conpherence-search',
array(
'searchURI' => '/conpherence/threadsearch/'.$conpherence->getID().'/',
));
$header->addActionItem(
id(new PHUIIconCircleView())
->addSigil('conpherence-search-toggle')
->setIcon('fa-search')
->setHref('#')
->setColor('green')
->addClass('conpherence-search-toggle'));
if ($can_join && !$participating) {
$action = ConpherenceUpdateActions::JOIN_ROOM;
$uri = $this->getApplicationURI('update/'.$conpherence->getID().'/');
@ -149,4 +163,60 @@ abstract class ConpherenceController extends PhabricatorController {
return $header;
}
public function buildSearchForm() {
$viewer = $this->getViewer();
$conpherence = $this->conpherence;
$name = $conpherence->getTitle();
$bar = javelin_tag(
'input',
array(
'type' => 'text',
'id' => 'conpherence-search-input',
'name' => 'fulltext',
'class' => 'conpherence-search-input',
'sigil' => 'conpherence-search-input',
'placeholder' => pht('Search %s...', $name),
));
$id = $conpherence->getID();
$form = phabricator_form(
$viewer,
array(
'method' => 'POST',
'action' => '/conpherence/threadsearch/'.$id.'/',
'sigil' => 'conpherence-search-form',
'class' => 'conpherence-search-form',
),
array(
$bar,
));
$form_view = phutil_tag(
'div',
array(
'class' => 'conpherence-search-form-view',
),
$form);
$results = phutil_tag(
'div',
array(
'id' => 'conpherence-search-results',
'class' => 'conpherence-search-results',
));
$view = phutil_tag(
'div',
array(
'class' => 'conpherence-search-window',
),
array(
$form_view,
$results,
));
return $view;
}
}

View file

@ -0,0 +1,41 @@
<?php
final class ConpherenceThreadSearchController
extends ConpherenceController {
public function shouldAllowPublic() {
return true;
}
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$conpherence_id = $request->getURIData('id');
$fulltext = $request->getStr('fulltext');
$conpherence = id(new ConpherenceThreadQuery())
->setViewer($viewer)
->withIDs(array($conpherence_id))
->executeOne();
if (!$conpherence) {
return new Aphront404Response();
}
$engine = new ConpherenceThreadSearchEngine();
$engine->setViewer($viewer);
$saved = $engine->buildSavedQueryFromBuiltin('all')
->setParameter('phids', array($conpherence->getPHID()))
->setParameter('fulltext', $fulltext);
$pager = $engine->newPagerForSavedQuery($saved);
$pager->setPageSize(15);
$query = $engine->buildQueryFromSavedQuery($saved);
$results = $engine->executeQuery($query, $pager);
$view = $engine->renderResults($results, $saved);
return id(new AphrontAjaxResponse())
->setContent($view->getObjectList());
}
}

View file

@ -327,7 +327,6 @@ final class ConpherenceUpdateController
->setUser($user)
->setDatasource(new PhabricatorPeopleDatasource()));
require_celerity_resource('conpherence-update-css');
$view = id(new AphrontDialogView())
->setTitle(pht('Add Participants'))
->addHiddenInput('action', 'add_person')
@ -407,8 +406,6 @@ final class ConpherenceUpdateController
}
}
require_celerity_resource('conpherence-update-css');
$dialog = id(new AphrontDialogView())
->setTitle($title)
->addHiddenInput('action', 'remove_person')
@ -471,7 +468,6 @@ final class ConpherenceUpdateController
->setCapability(PhabricatorPolicyCapability::CAN_JOIN)
->setPolicies($policies));
require_celerity_resource('conpherence-update-css');
$view = id(new AphrontDialogView())
->setTitle($title)
->addHiddenInput('action', 'metadata')

View file

@ -89,9 +89,11 @@ final class ConpherenceViewController extends
->setObject($conpherence)
->execute();
$header = $this->buildHeaderPaneContent($conpherence, $policy_objects);
$search = $this->buildSearchForm();
$form = $this->renderFormContent();
$content = array(
'header' => $header,
'search' => $search,
'transactions' => $messages,
'form' => $form,
);
@ -128,6 +130,7 @@ final class ConpherenceViewController extends
->setBaseURI($this->getApplicationURI())
->setThread($conpherence)
->setHeader($header)
->setSearch($search)
->setMessages($messages)
->setReplyForm($form)
->setLatestTransactionID($data['latest_transaction_id'])

View file

@ -7,6 +7,7 @@ final class ConpherenceLayoutView extends AphrontTagView {
private $threadView;
private $role;
private $header;
private $search;
private $messages;
private $replyForm;
private $latestTransactionID;
@ -26,6 +27,11 @@ final class ConpherenceLayoutView extends AphrontTagView {
return $this;
}
public function setSearch($search) {
$this->search = $search;
return $this;
}
public function setRole($role) {
$this->role = $role;
return $this;
@ -131,6 +137,12 @@ final class ConpherenceLayoutView extends AphrontTagView {
'class' => 'conpherence-content-pane',
),
array(
phutil_tag(
'div',
array(
'class' => 'conpherence-loading-mask',
),
''),
javelin_tag(
'div',
array(
@ -184,6 +196,14 @@ final class ConpherenceLayoutView extends AphrontTagView {
'sigil' => 'conpherence-messages',
),
nonempty($this->messages, '')),
javelin_tag(
'div',
array(
'class' => 'conpherence-search-main',
'id' => 'conpherence-search-main',
'sigil' => 'conpherence-search-main',
),
nonempty($this->search, '')),
phutil_tag(
'div',
array(

View file

@ -66,7 +66,17 @@
}
.conpherence-participant-toggle.phui-icon-circle .phui-icon-view {
color: {$sky};
color: {$sky};
}
.show-searchbar .conpherence-search-toggle.phui-icon-circle {
text-decoration: none;
border-color: {$green};
cursor: pointer;
}
.show-searchbar .conpherence-search-toggle.phui-icon-circle .phui-icon-view {
color: {$green};
}
.hide-widgets .conpherence-participant-toggle.phui-icon-circle {
@ -76,5 +86,5 @@
}
.hide-widgets .conpherence-participant-toggle.phui-icon-circle .phui-icon-view {
color: {$lightblueborder};
color: {$lightblueborder};
}

View file

@ -400,3 +400,68 @@
margin-top: 0;
margin-bottom: 0;
}
/***** Thread Loading *********************************************************/
.conpherence-layout .conpherence-loading-mask {
height: 0;
opacity: 0;
top: 0;
right: 0;
left: 240px;
bottom: 0;
transition: all 0.3s;
position: fixed;
background-color: #fff;
}
.conpherence-layout.loading .conpherence-loading-mask {
opacity: 1;
height: auto;
}
/***** Thread Search **********************************************************/
.conpherence-search-main {
opacity: 0;
transition: all 0.2s;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
height: 0;
}
.show-searchbar .conpherence-search-main {
opacity: 1;
height: auto;
}
.show-searchbar .conpherence-search-form-view {
display: block;
height: 54px;
background: {$lightbluebackground};
position: absolute;
top: 1px;
left: 0;
right: 0;
}
input.conpherence-search-input {
padding-left: 8px;
width: calc(100% - 24px);
border-radius: 20px;
margin: 12px;
}
.conpherence-search-results {
position: absolute;
background: #fff;
top: 54px;
left: 0;
right: 0;
bottom: 0;
overflow-y: auto;
}

View file

@ -1,13 +0,0 @@
/**
* @provides conpherence-update-css
*/
.aphront-dialog-view .conpherence-dialogue-drag-photo {
border: 1px dashed #bfbfbf;
padding: 10px 0px 10px 10px;
}
.aphront-dialog-view .conpherence-dialogue-upload-photo {
background: {$lightgreen};
border-color: {$green};
}

View file

@ -68,9 +68,8 @@ div.phui-calendar-day-event {
z-index: 4;
}
.loading .messages-loading-mask,
.loading .widgets-loading-mask {
z-index: 5;
.conpherence-message-pane .conpherence-search-main {
z-index: 4;
}
.dark-console {
@ -89,6 +88,11 @@ div.phui-calendar-day-event {
z-index: 6;
}
.loading .messages-loading-mask,
.loading .widgets-loading-mask {
z-index: 6;
}
.conpherence-durable-column {
z-index: 7;
}
@ -154,6 +158,10 @@ div.jx-typeahead-results {
z-index: 25;
}
.conpherence-layout .conpherence-loading-mask {
z-index: 30;
}
.phuix-dropdown-menu {
z-index: 32;
}

View file

@ -101,6 +101,16 @@ a.phui-icon-circle.hover-pink:hover .phui-icon-view {
color: {$pink};
}
a.phui-icon-circle.hover-green:hover {
text-decoration: none;
border-color: {$green};
cursor: pointer;
}
a.phui-icon-circle.hover-green:hover .phui-icon-view {
color: {$green};
}
/* - Icon in a Square ------------------------------------------------------- */
.phui-icon-view.phui-icon-square {

View file

@ -0,0 +1,63 @@
/**
* @provides javelin-behavior-conpherence-search
* @requires javelin-behavior
* javelin-dom
* javelin-util
* javelin-workflow
* javelin-stratcom
*/
JX.behavior('conpherence-search', function(config) {
var shown = true;
var request = null;
function _toggleSearch(e) {
e.kill();
var node = JX.$('conpherence-main-layout');
shown = !shown;
JX.DOM.alterClass(node, 'show-searchbar', !shown);
JX.Stratcom.invoke('resize');
}
function _doSearch(e) {
e.kill();
var search_text = JX.$('conpherence-search-input').value;
var search_node = JX.$('conpherence-search-results');
if (request || !search_text) {
return;
}
request = new JX.Request(config.searchURI, function(response) {
JX.DOM.setContent(search_node, JX.$H(response));
request = null;
});
request.setData({fulltext: search_text});
request.send();
}
JX.Stratcom.listen(
['submit', 'didSyntheticSubmit'],
'conpherence-search-input',
_doSearch);
JX.Stratcom.listen(
'keydown',
'conpherence-search-input',
function(e) {
if (e.getSpecialKey() != 'return') {
return;
}
e.kill();
_doSearch(e);
});
JX.Stratcom.listen(
'click',
'conpherence-search-toggle',
_toggleSearch);
});

View file

@ -36,12 +36,15 @@ JX.behavior('conpherence-menu', function(config) {
});
threadManager.setDidLoadThreadCallback(function(r) {
var header = JX.$H(r.header);
var search = JX.$H(r.search);
var messages = JX.$H(r.transactions);
var form = JX.$H(r.form);
var root = JX.DOM.find(document, 'div', 'conpherence-layout');
var header_root = JX.DOM.find(root, 'div', 'conpherence-header-pane');
var search_root = JX.DOM.find(root, 'div', 'conpherence-search-main');
var form_root = JX.DOM.find(root, 'div', 'conpherence-form');
JX.DOM.setContent(header_root, header);
JX.DOM.setContent(search_root, search);
JX.DOM.setContent(scrollbar.getContentNode(), messages);
JX.DOM.setContent(form_root, form);
@ -210,14 +213,8 @@ JX.behavior('conpherence-menu', function(config) {
}
function markThreadLoading(loading) {
var root = JX.DOM.find(document, 'div', 'conpherence-layout');
var header_root = JX.DOM.find(root, 'div', 'conpherence-header-pane');
var messages_root = JX.DOM.find(root, 'div', 'conpherence-message-pane');
var form_root = JX.DOM.find(root, 'div', 'conpherence-form');
JX.DOM.alterClass(header_root, 'loading', loading);
JX.DOM.alterClass(messages_root, 'loading', loading);
JX.DOM.alterClass(form_root, 'loading', loading);
var root = JX.$('conpherence-main-layout');
JX.DOM.alterClass(root, 'loading', loading);
try {
var textarea = JX.DOM.find(form, 'textarea');
@ -378,38 +375,6 @@ JX.behavior('conpherence-menu', function(config) {
selectThread(e.getNode('conpherence-menu-click'), true);
});
JX.Stratcom.listen('click', 'conpherence-edit-metadata', function (e) {
e.kill();
var root = e.getNode('conpherence-layout');
var form = JX.DOM.find(root, 'form', 'conpherence-pontificate');
var data = e.getNodeData('conpherence-edit-metadata');
var header = JX.DOM.find(root, 'div', 'conpherence-header-pane');
var messages = scrollbar.getContentNode();
new JX.Workflow.newFromForm(form, data)
.setHandler(JX.bind(this, function(r) {
JX.DOM.appendContent(messages, JX.$H(r.transactions));
_scrollMessageWindow();
JX.DOM.setContent(
header,
JX.$H(r.header)
);
try {
// update the menu entry
JX.DOM.replace(
JX.$(r.conpherence_phid + '-nav-item'),
JX.$H(r.nav_item)
);
selectThreadByID(r.conpherence_phid + '-nav-item');
} catch (ex) {
// Ignore; this view may not have a menu.
}
}))
.start();
});
/**
* On devices, we just show a thread list, so we don't want to automatically
* select or load any threads. On desktop, we automatically select the first