mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-10 00:42:41 +01:00
Very basic Object Selector interface.
Summary: Interface for selecting objects to attach to other objects (e.g., Maniphest tasks to Differential diffs and vice versa). Test Plan: still rough Reviewers: CC:
This commit is contained in:
parent
0b1450c5f9
commit
258e0cdded
14 changed files with 533 additions and 65 deletions
|
@ -215,6 +215,16 @@ celerity_register_resource_map(array(
|
||||||
),
|
),
|
||||||
'disk' => '/rsrc/css/application/maniphest/transaction-detail.css',
|
'disk' => '/rsrc/css/application/maniphest/transaction-detail.css',
|
||||||
),
|
),
|
||||||
|
'phabricator-object-selector-css' =>
|
||||||
|
array(
|
||||||
|
'uri' => '/res/270ce107/rsrc/css/application/objectselector/object-selector.css',
|
||||||
|
'type' => 'css',
|
||||||
|
'requires' =>
|
||||||
|
array(
|
||||||
|
0 => 'aphront-dialog-view-css',
|
||||||
|
),
|
||||||
|
'disk' => '/rsrc/css/application/objectselector/object-selector.css',
|
||||||
|
),
|
||||||
'phabricator-core-buttons-css' =>
|
'phabricator-core-buttons-css' =>
|
||||||
array(
|
array(
|
||||||
'uri' => '/res/ee35ffe1/rsrc/css/core/buttons.css',
|
'uri' => '/res/ee35ffe1/rsrc/css/core/buttons.css',
|
||||||
|
@ -233,15 +243,6 @@ celerity_register_resource_map(array(
|
||||||
),
|
),
|
||||||
'disk' => '/rsrc/css/core/core.css',
|
'disk' => '/rsrc/css/core/core.css',
|
||||||
),
|
),
|
||||||
'phabricator-core-dialog-css' =>
|
|
||||||
array(
|
|
||||||
'uri' => '/res/f66cec41/rsrc/css/core/dialog.css',
|
|
||||||
'type' => 'css',
|
|
||||||
'requires' =>
|
|
||||||
array(
|
|
||||||
),
|
|
||||||
'disk' => '/rsrc/css/core/dialog.css',
|
|
||||||
),
|
|
||||||
'phabricator-remarkup-css' =>
|
'phabricator-remarkup-css' =>
|
||||||
array(
|
array(
|
||||||
'uri' => '/res/786989c3/rsrc/css/core/remarkup.css',
|
'uri' => '/res/786989c3/rsrc/css/core/remarkup.css',
|
||||||
|
@ -269,6 +270,16 @@ celerity_register_resource_map(array(
|
||||||
),
|
),
|
||||||
'disk' => '/rsrc/js/application/core/behavior-dark-console.js',
|
'disk' => '/rsrc/js/application/core/behavior-dark-console.js',
|
||||||
),
|
),
|
||||||
|
'javelin-behavior-phabricator-object-selector' =>
|
||||||
|
array(
|
||||||
|
'uri' => '/res/7f7eda6a/rsrc/js/application/core/behavior-object-selector.js',
|
||||||
|
'type' => 'js',
|
||||||
|
'requires' =>
|
||||||
|
array(
|
||||||
|
0 => 'javelin-lib-dev',
|
||||||
|
),
|
||||||
|
'disk' => '/rsrc/js/application/core/behavior-object-selector.js',
|
||||||
|
),
|
||||||
'javelin-behavior-aphront-basic-tokenizer' =>
|
'javelin-behavior-aphront-basic-tokenizer' =>
|
||||||
array(
|
array(
|
||||||
'uri' => '/res/8317d761/rsrc/js/application/core/behavior-tokenizer.js',
|
'uri' => '/res/8317d761/rsrc/js/application/core/behavior-tokenizer.js',
|
||||||
|
|
|
@ -145,6 +145,8 @@ phutil_register_library_map(array(
|
||||||
'ManiphestTaskListController' => 'applications/maniphest/controller/tasklist',
|
'ManiphestTaskListController' => 'applications/maniphest/controller/tasklist',
|
||||||
'ManiphestTaskListView' => 'applications/maniphest/view/tasklist',
|
'ManiphestTaskListView' => 'applications/maniphest/view/tasklist',
|
||||||
'ManiphestTaskPriority' => 'applications/maniphest/constants/priority',
|
'ManiphestTaskPriority' => 'applications/maniphest/constants/priority',
|
||||||
|
'ManiphestTaskSelectorController' => 'applications/maniphest/controller/taskselector',
|
||||||
|
'ManiphestTaskSelectorSearchController' => 'applications/maniphest/controller/taskselectorsearch',
|
||||||
'ManiphestTaskStatus' => 'applications/maniphest/constants/status',
|
'ManiphestTaskStatus' => 'applications/maniphest/constants/status',
|
||||||
'ManiphestTaskSummaryView' => 'applications/maniphest/view/tasksummary',
|
'ManiphestTaskSummaryView' => 'applications/maniphest/view/tasksummary',
|
||||||
'ManiphestTransaction' => 'applications/maniphest/storage/transaction',
|
'ManiphestTransaction' => 'applications/maniphest/storage/transaction',
|
||||||
|
@ -207,6 +209,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorMetaMTAViewController' => 'applications/metamta/controller/view',
|
'PhabricatorMetaMTAViewController' => 'applications/metamta/controller/view',
|
||||||
'PhabricatorObjectHandle' => 'applications/phid/handle',
|
'PhabricatorObjectHandle' => 'applications/phid/handle',
|
||||||
'PhabricatorObjectHandleData' => 'applications/phid/handle/data',
|
'PhabricatorObjectHandleData' => 'applications/phid/handle/data',
|
||||||
|
'PhabricatorObjectSelectorDialog' => 'view/control/objectselector',
|
||||||
'PhabricatorPHID' => 'applications/phid/storage/phid',
|
'PhabricatorPHID' => 'applications/phid/storage/phid',
|
||||||
'PhabricatorPHIDAllocateController' => 'applications/phid/controller/allocate',
|
'PhabricatorPHIDAllocateController' => 'applications/phid/controller/allocate',
|
||||||
'PhabricatorPHIDController' => 'applications/phid/controller/base',
|
'PhabricatorPHIDController' => 'applications/phid/controller/base',
|
||||||
|
@ -377,6 +380,8 @@ phutil_register_library_map(array(
|
||||||
'ManiphestTaskDetailController' => 'ManiphestController',
|
'ManiphestTaskDetailController' => 'ManiphestController',
|
||||||
'ManiphestTaskListController' => 'ManiphestController',
|
'ManiphestTaskListController' => 'ManiphestController',
|
||||||
'ManiphestTaskListView' => 'AphrontView',
|
'ManiphestTaskListView' => 'AphrontView',
|
||||||
|
'ManiphestTaskSelectorController' => 'ManiphestController',
|
||||||
|
'ManiphestTaskSelectorSearchController' => 'ManiphestController',
|
||||||
'ManiphestTaskSummaryView' => 'AphrontView',
|
'ManiphestTaskSummaryView' => 'AphrontView',
|
||||||
'ManiphestTransaction' => 'ManiphestDAO',
|
'ManiphestTransaction' => 'ManiphestDAO',
|
||||||
'ManiphestTransactionDetailView' => 'AphrontView',
|
'ManiphestTransactionDetailView' => 'AphrontView',
|
||||||
|
@ -430,6 +435,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorMetaMTAMailingListsController' => 'PhabricatorMetaMTAController',
|
'PhabricatorMetaMTAMailingListsController' => 'PhabricatorMetaMTAController',
|
||||||
'PhabricatorMetaMTASendController' => 'PhabricatorMetaMTAController',
|
'PhabricatorMetaMTASendController' => 'PhabricatorMetaMTAController',
|
||||||
'PhabricatorMetaMTAViewController' => 'PhabricatorMetaMTAController',
|
'PhabricatorMetaMTAViewController' => 'PhabricatorMetaMTAController',
|
||||||
|
'PhabricatorObjectSelectorDialog' => 'AphrontDialogView',
|
||||||
'PhabricatorPHID' => 'PhabricatorPHIDDAO',
|
'PhabricatorPHID' => 'PhabricatorPHIDDAO',
|
||||||
'PhabricatorPHIDAllocateController' => 'PhabricatorPHIDController',
|
'PhabricatorPHIDAllocateController' => 'PhabricatorPHIDController',
|
||||||
'PhabricatorPHIDController' => 'PhabricatorController',
|
'PhabricatorPHIDController' => 'PhabricatorController',
|
||||||
|
|
|
@ -143,6 +143,8 @@ class AphrontDefaultApplicationConfiguration
|
||||||
'transaction/' => array(
|
'transaction/' => array(
|
||||||
'save/' => 'ManiphestTransactionSaveController',
|
'save/' => 'ManiphestTransactionSaveController',
|
||||||
),
|
),
|
||||||
|
'select/$' => 'ManiphestTaskSelectorController',
|
||||||
|
'select/search/$' => 'ManiphestTaskSelectorSearchController',
|
||||||
),
|
),
|
||||||
|
|
||||||
'/T(?P<id>\d+)$' => 'ManiphestTaskDetailController',
|
'/T(?P<id>\d+)$' => 'ManiphestTaskDetailController',
|
||||||
|
|
|
@ -0,0 +1,163 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class ManiphestTaskSelectorController extends ManiphestController {
|
||||||
|
|
||||||
|
public function processRequest() {
|
||||||
|
$request = $this->getRequest();
|
||||||
|
$user = $request->getUser();
|
||||||
|
|
||||||
|
$filter_id = celerity_generate_unique_node_id();
|
||||||
|
$query_id = celerity_generate_unique_node_id();
|
||||||
|
$search_id = celerity_generate_unique_node_id();
|
||||||
|
$results_id = celerity_generate_unique_node_id();
|
||||||
|
$current_id = celerity_generate_unique_node_id();
|
||||||
|
|
||||||
|
$search_box =
|
||||||
|
'<table class="phabricator-object-selector-search">
|
||||||
|
<tr>
|
||||||
|
<td class="phabricator-object-selector-search-filter">
|
||||||
|
<select id="'.$filter_id.'">
|
||||||
|
<option>Assigned To Me</option>
|
||||||
|
<option>Created By Me</option>
|
||||||
|
<option>All Open Tasks</option>
|
||||||
|
<option>All Tasks</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
<td class="phabricator-object-selector-search-text">
|
||||||
|
<input type="text" id="'.$query_id.'" />
|
||||||
|
</td>
|
||||||
|
<td class="phabricator-object-selector-search-button">
|
||||||
|
<a href="#" class="button" id="'.$search_id.'">Search</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>';
|
||||||
|
$result_box =
|
||||||
|
'<div class="phabricator-object-selector-results" id="'.$results_id.'">'.
|
||||||
|
|
||||||
|
'</div>';
|
||||||
|
$attached_box =
|
||||||
|
'<div class="phabricator-object-selector-current">'.
|
||||||
|
'<div class="phabricator-object-selector-currently-attached">'.
|
||||||
|
'<div class="phabricator-object-selector-header">'.
|
||||||
|
'Currently Attached Tasks'.
|
||||||
|
'</div>'.
|
||||||
|
'<div id="'.$current_id.'">'.
|
||||||
|
'</div>'.
|
||||||
|
'</div>'.
|
||||||
|
'</div>';
|
||||||
|
|
||||||
|
require_celerity_resource('phabricator-object-selector-css');
|
||||||
|
|
||||||
|
Javelin::initBehavior(
|
||||||
|
'phabricator-object-selector',
|
||||||
|
array(
|
||||||
|
'filter' => $filter_id,
|
||||||
|
'query' => $query_id,
|
||||||
|
'search' => $search_id,
|
||||||
|
'results' => $results_id,
|
||||||
|
'current' => $current_id,
|
||||||
|
'uri' => '/maniphest/select/search/',
|
||||||
|
));
|
||||||
|
|
||||||
|
$dialog = new PhabricatorObjectSelectorDialog();
|
||||||
|
$dialog
|
||||||
|
->setUser($user)
|
||||||
|
->setTitle('Manage Attached Tasks')
|
||||||
|
->setClass('phabricator-object-selector-dialog')
|
||||||
|
->appendChild($search_box)
|
||||||
|
->appendChild($result_box)
|
||||||
|
->appendChild($attached_box)
|
||||||
|
->addCancelButton('#')
|
||||||
|
->addSubmitButton('Save Tasks');
|
||||||
|
|
||||||
|
return id(new AphrontDialogResponse())->setDialog($dialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
'<table class="phabricator-object-selector-handle">
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
<input type="checkbox" />
|
||||||
|
</th>
|
||||||
|
<td>
|
||||||
|
<a href="#">T20: Internet Attack Internets</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>'.
|
||||||
|
'<table class="phabricator-object-selector-handle">
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
<input type="checkbox" />
|
||||||
|
</th>
|
||||||
|
<td>
|
||||||
|
<a href="#">T21: Internet Attack Internets</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>'.
|
||||||
|
'<table class="phabricator-object-selector-handle">
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
<input type="checkbox" />
|
||||||
|
</th>
|
||||||
|
<td>
|
||||||
|
<a href="#">T22: Internet Attack Internets</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>'.
|
||||||
|
'more results<br />'.
|
||||||
|
'more results<br />'.
|
||||||
|
'more results<br />'.
|
||||||
|
'more results<br />'.
|
||||||
|
'more results<br />'.
|
||||||
|
'more results<br />'.
|
||||||
|
'more results<br />'.
|
||||||
|
'more results<br />'.
|
||||||
|
'more results<br />'.
|
||||||
|
'more results<br />'.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
'<table class="phabricator-object-selector-handle">
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
<input type="checkbox" />
|
||||||
|
</th>
|
||||||
|
<td>
|
||||||
|
<a href="#">T22: Internet Attack Internets</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>'.
|
||||||
|
'<table class="phabricator-object-selector-handle">
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
<input type="checkbox" />
|
||||||
|
</th>
|
||||||
|
<td>
|
||||||
|
<a href="#">T22: Internet Attack Internets</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>'.
|
||||||
|
|
||||||
|
*/
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'aphront/response/dialog');
|
||||||
|
phutil_require_module('phabricator', 'applications/maniphest/controller/base');
|
||||||
|
phutil_require_module('phabricator', 'infrastructure/celerity/api');
|
||||||
|
phutil_require_module('phabricator', 'infrastructure/javelin/api');
|
||||||
|
phutil_require_module('phabricator', 'view/control/objectselector');
|
||||||
|
|
||||||
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('ManiphestTaskSelectorController.php');
|
|
@ -0,0 +1,43 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class ManiphestTaskSelectorSearchController extends ManiphestController {
|
||||||
|
|
||||||
|
public function processRequest() {
|
||||||
|
$request = $this->getRequest();
|
||||||
|
$user = $request->getUser();
|
||||||
|
|
||||||
|
$query = new PhabricatorSearchQuery();
|
||||||
|
$query->setQuery($request->getStr('query'));
|
||||||
|
$query->setParameter('type', 'TASK');
|
||||||
|
|
||||||
|
$exec = new PhabricatorSearchMySQLExecutor();
|
||||||
|
$results = $exec->executeSearch($query);
|
||||||
|
|
||||||
|
$data = array();
|
||||||
|
foreach ($results as $result) {
|
||||||
|
$data[] = array(
|
||||||
|
'phid' => $result['phid'],
|
||||||
|
'name' => $result['documentTitle'],
|
||||||
|
'href' => '#',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return id(new AphrontAjaxResponse())->setContent($data);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'aphront/response/ajax');
|
||||||
|
phutil_require_module('phabricator', 'applications/maniphest/controller/base');
|
||||||
|
phutil_require_module('phabricator', 'applications/search/execute/mysql');
|
||||||
|
phutil_require_module('phabricator', 'applications/search/storage/query');
|
||||||
|
|
||||||
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('ManiphestTaskSelectorSearchController.php');
|
|
@ -106,6 +106,7 @@ class PhabricatorSearchMySQLExecutor extends PhabricatorSearchExecutor {
|
||||||
'SELECT DISTINCT
|
'SELECT DISTINCT
|
||||||
document.phid,
|
document.phid,
|
||||||
document.documentType,
|
document.documentType,
|
||||||
|
document.documentTitle,
|
||||||
document.documentCreated FROM %T document %Q %Q %Q
|
document.documentCreated FROM %T document %Q %Q %Q
|
||||||
LIMIT 50',
|
LIMIT 50',
|
||||||
$t_doc,
|
$t_doc,
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class PhabricatorObjectSelectorDialog extends AphrontDialogView {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
12
src/view/control/objectselector/__init__.php
Normal file
12
src/view/control/objectselector/__init__.php
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'view/dialog');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorObjectSelectorDialog.php');
|
|
@ -24,6 +24,7 @@ class AphrontDialogView extends AphrontView {
|
||||||
private $submitURI;
|
private $submitURI;
|
||||||
private $user;
|
private $user;
|
||||||
private $hidden = array();
|
private $hidden = array();
|
||||||
|
private $class;
|
||||||
|
|
||||||
public function setUser(PhabricatorUser $user) {
|
public function setUser(PhabricatorUser $user) {
|
||||||
$this->user = $user;
|
$this->user = $user;
|
||||||
|
@ -59,6 +60,11 @@ class AphrontDialogView extends AphrontView {
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setClass($class) {
|
||||||
|
$this->class = $class;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
final public function render() {
|
final public function render() {
|
||||||
require_celerity_resource('aphront-dialog-view-css');
|
require_celerity_resource('aphront-dialog-view-css');
|
||||||
|
|
||||||
|
@ -103,10 +109,12 @@ class AphrontDialogView extends AphrontView {
|
||||||
}
|
}
|
||||||
$hidden_inputs = implode("\n", $hidden_inputs);
|
$hidden_inputs = implode("\n", $hidden_inputs);
|
||||||
|
|
||||||
|
$more = $this->class;
|
||||||
|
|
||||||
return javelin_render_tag(
|
return javelin_render_tag(
|
||||||
'form',
|
'form',
|
||||||
array(
|
array(
|
||||||
'class' => 'aphront-dialog-view',
|
'class' => 'aphront-dialog-view '.$more,
|
||||||
'action' => $this->submitURI,
|
'action' => $this->submitURI,
|
||||||
'method' => 'post',
|
'method' => 'post',
|
||||||
'sigil' => 'jx-dialog',
|
'sigil' => 'jx-dialog',
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
/**
|
||||||
|
* @provides phabricator-object-selector-css
|
||||||
|
* @requires aphront-dialog-view-css
|
||||||
|
*/
|
||||||
|
|
||||||
|
form.phabricator-object-selector-dialog {
|
||||||
|
width: 800px;
|
||||||
|
}
|
||||||
|
|
||||||
|
form.phabricator-object-selector-dialog .aphront-dialog-body {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.phabricator-object-selector-search {
|
||||||
|
width: 100%;
|
||||||
|
background: #ededed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.phabricator-object-selector-search td {
|
||||||
|
padding: 4px 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.phabricator-object-selector-search-text {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.phabricator-object-selector-search-text input {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.phabricator-object-selector-results {
|
||||||
|
position: relative;
|
||||||
|
height: 16em;
|
||||||
|
border: solid #bbbbbb;
|
||||||
|
border-width: 1px 0px;
|
||||||
|
overflow-y: scroll;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.phabricator-object-selector-handle {
|
||||||
|
width: 100%;
|
||||||
|
background: #e9e9e9;
|
||||||
|
margin-bottom: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.phabricator-object-selector-handle td {
|
||||||
|
padding: 4px 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.phabricator-object-selector-handle th {
|
||||||
|
padding: 4px 1em;
|
||||||
|
font-weight: bold;
|
||||||
|
vertical-align: middle;
|
||||||
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.phabricator-object-selector-header {
|
||||||
|
padding: 2px;
|
||||||
|
border-bottom: 1px solid #d0d0d0;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
color: #444444;
|
||||||
|
}
|
||||||
|
|
||||||
|
.phabricator-object-selector-attach-explicit {
|
||||||
|
padding: 4px;
|
||||||
|
background: #f3f3f3;
|
||||||
|
border: solid #bbbbbb;
|
||||||
|
border-width: 1px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.phabricator-object-selector-currently-attached {
|
||||||
|
background: #fff;
|
||||||
|
padding: 16px;
|
||||||
|
border: 1px solid #dddddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.phabricator-object-selector-current {
|
||||||
|
background: #ededed;
|
||||||
|
padding: 8px 8px;
|
||||||
|
}
|
|
@ -1,55 +0,0 @@
|
||||||
/**
|
|
||||||
* @provides phabricator-core-dialog-css
|
|
||||||
*/
|
|
||||||
|
|
||||||
.jx-dialog {
|
|
||||||
display: block;
|
|
||||||
width: 480px;
|
|
||||||
padding: 8px;
|
|
||||||
background: #666;
|
|
||||||
margin: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.jx-client-dialog {
|
|
||||||
position: absolute;
|
|
||||||
z-index: 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.jx-dialog .dialog-title {
|
|
||||||
background: #6d84b4;
|
|
||||||
border: none;
|
|
||||||
font-size: 15px;
|
|
||||||
font-weight: bold;
|
|
||||||
padding: 5px 12px 6px;
|
|
||||||
color: #ffffff;
|
|
||||||
}
|
|
||||||
.jx-dialog .dialog-body {
|
|
||||||
background: #ffffff;
|
|
||||||
padding: 16px 12px;
|
|
||||||
border: none;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.jx-dialog .dialog-foot {
|
|
||||||
border: none;
|
|
||||||
background: #ededed;
|
|
||||||
padding: .5em;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.jx-dialog button {
|
|
||||||
margin-left: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.jx-dialog input {
|
|
||||||
padding: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.jx-dialog .fields {
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.jx-dialog input.block {
|
|
||||||
display: block;
|
|
||||||
margin: 3px 0 0 0;
|
|
||||||
}
|
|
139
webroot/rsrc/js/application/core/behavior-object-selector.js
Normal file
139
webroot/rsrc/js/application/core/behavior-object-selector.js
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
/**
|
||||||
|
* @provides javelin-behavior-phabricator-object-selector
|
||||||
|
* @requires javelin-lib-dev
|
||||||
|
*/
|
||||||
|
|
||||||
|
JX.behavior('phabricator-object-selector', function(config) {
|
||||||
|
var n = 0;
|
||||||
|
|
||||||
|
var phids = {};
|
||||||
|
var handles = {};
|
||||||
|
var attach_list = {};
|
||||||
|
|
||||||
|
function onreceive(seq, r) {
|
||||||
|
if (seq != n) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var display = [];
|
||||||
|
attach_list = {};
|
||||||
|
for (var k in r) {
|
||||||
|
handles[r[k].phid] = r[k];
|
||||||
|
display.push(renderHandle(r[k], true));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!display.length) {
|
||||||
|
display = renderNote('No results.');
|
||||||
|
}
|
||||||
|
|
||||||
|
JX.DOM.setContent(JX.$(config.results), display);
|
||||||
|
}
|
||||||
|
|
||||||
|
function redrawAttached() {
|
||||||
|
var display = [];
|
||||||
|
|
||||||
|
for (var k in phids) {
|
||||||
|
display.push(renderHandle(handles[k], false));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!display.length) {
|
||||||
|
display = renderNote('Nothing attached.');
|
||||||
|
}
|
||||||
|
|
||||||
|
JX.DOM.setContent(JX.$(config.current), display);
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderHandle(h, attach) {
|
||||||
|
|
||||||
|
var td = JX.$N('td');
|
||||||
|
var table = JX.$N(
|
||||||
|
'table',
|
||||||
|
{className: 'phabricator-object-selector-handle'},
|
||||||
|
JX.$N(
|
||||||
|
'tbody',
|
||||||
|
{},
|
||||||
|
[JX.$N('th', {}, h.name), td]));
|
||||||
|
var btn = JX.$N(
|
||||||
|
'a',
|
||||||
|
{className: 'button small grey'},
|
||||||
|
attach ? 'Attach' : 'Remove');
|
||||||
|
|
||||||
|
JX.Stratcom.addSigil(btn, 'object-attach-button');
|
||||||
|
JX.Stratcom.addData(btn, {handle : h, table : table});
|
||||||
|
if (attach) {
|
||||||
|
attach_list[h.phid] = btn;
|
||||||
|
}
|
||||||
|
|
||||||
|
JX.DOM.setContent(td, btn);
|
||||||
|
|
||||||
|
return table;
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderNote(note) {
|
||||||
|
return JX.$N('div', {}, note);
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendQuery() {
|
||||||
|
JX.DOM.setContent(JX.$(config.results), renderNote('Loading...'))
|
||||||
|
new JX.Request(config.uri, JX.bind(null, onreceive, ++n))
|
||||||
|
.setData({
|
||||||
|
filter: JX.$(config.filter).value,
|
||||||
|
query: JX.$(config.query).value
|
||||||
|
})
|
||||||
|
.send();
|
||||||
|
}
|
||||||
|
|
||||||
|
JX.DOM.listen(
|
||||||
|
JX.$(config.search),
|
||||||
|
'click',
|
||||||
|
null,
|
||||||
|
function(e) {
|
||||||
|
e.kill();
|
||||||
|
sendQuery();
|
||||||
|
});
|
||||||
|
|
||||||
|
JX.DOM.listen(
|
||||||
|
JX.$(config.results),
|
||||||
|
'click',
|
||||||
|
'object-attach-button',
|
||||||
|
function(e) {
|
||||||
|
e.kill();
|
||||||
|
var button = e.getNode('object-attach-button');
|
||||||
|
if (button.disabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var data = e.getNodeData('object-attach-button');
|
||||||
|
phids[data.handle.phid] = true;
|
||||||
|
JX.DOM.alterClass(button, 'disabled', true);
|
||||||
|
button.disabled = true;
|
||||||
|
|
||||||
|
redrawAttached();
|
||||||
|
});
|
||||||
|
|
||||||
|
JX.DOM.listen(
|
||||||
|
JX.$(config.current),
|
||||||
|
'click',
|
||||||
|
'object-attach-button',
|
||||||
|
function(e) {
|
||||||
|
e.kill();
|
||||||
|
var button = e.getNode('object-attach-button');
|
||||||
|
if (button.disabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var data = e.getNodeData('object-attach-button');
|
||||||
|
delete phids[data.handle.phid];
|
||||||
|
|
||||||
|
if (attach_list[data.handle.phid]) {
|
||||||
|
JX.DOM.alterClass(attach_list[data.handle.phid], 'disabled', false);
|
||||||
|
attach_list[data.handle.phid].disabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
redrawAttached();
|
||||||
|
});
|
||||||
|
|
||||||
|
sendQuery();
|
||||||
|
redrawAttached();
|
||||||
|
|
||||||
|
});
|
Loading…
Reference in a new issue