Page MenuHomePhabricator

D12446.diff
No OneTemporary

D12446.diff

diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -1206,6 +1206,7 @@
'PHUITimelineEventView' => 'view/phui/PHUITimelineEventView.php',
'PHUITimelineExample' => 'applications/uiexample/examples/PHUITimelineExample.php',
'PHUITimelineView' => 'view/phui/PHUITimelineView.php',
+ 'PHUITypeaheadExample' => 'applications/uiexample/examples/PHUITypeaheadExample.php',
'PHUIWorkboardView' => 'view/phui/PHUIWorkboardView.php',
'PHUIWorkpanelView' => 'view/phui/PHUIWorkpanelView.php',
'PackageCreateMail' => 'applications/owners/mail/PackageCreateMail.php',
@@ -4489,6 +4490,7 @@
'PHUITimelineEventView' => 'AphrontView',
'PHUITimelineExample' => 'PhabricatorUIExample',
'PHUITimelineView' => 'AphrontView',
+ 'PHUITypeaheadExample' => 'PhabricatorUIExample',
'PHUIWorkboardView' => 'AphrontTagView',
'PHUIWorkpanelView' => 'AphrontTagView',
'PackageCreateMail' => 'PackageMail',
diff --git a/src/applications/people/typeahead/PhabricatorViewerDatasource.php b/src/applications/people/typeahead/PhabricatorViewerDatasource.php
--- a/src/applications/people/typeahead/PhabricatorViewerDatasource.php
+++ b/src/applications/people/typeahead/PhabricatorViewerDatasource.php
@@ -50,6 +50,7 @@
return $this->newFunctionResult()
->setName(pht('Current Viewer'))
->setPHID('viewer()')
+ ->setIcon('fa-user')
->setUnique(true);
}
diff --git a/src/applications/phid/PhabricatorObjectHandle.php b/src/applications/phid/PhabricatorObjectHandle.php
--- a/src/applications/phid/PhabricatorObjectHandle.php
+++ b/src/applications/phid/PhabricatorObjectHandle.php
@@ -56,9 +56,17 @@
if ($this->tagColor) {
return $this->tagColor;
}
+
return 'blue';
}
+ public function getIconColor() {
+ if ($this->tagColor) {
+ return $this->tagColor;
+ }
+ return null;
+ }
+
public function getTypeIcon() {
if ($this->getPHIDType()) {
return $this->getPHIDType()->getTypeIcon();
diff --git a/src/applications/project/typeahead/PhabricatorProjectDatasource.php b/src/applications/project/typeahead/PhabricatorProjectDatasource.php
--- a/src/applications/project/typeahead/PhabricatorProjectDatasource.php
+++ b/src/applications/project/typeahead/PhabricatorProjectDatasource.php
@@ -63,7 +63,7 @@
->setDisplayType('Project')
->setURI('/tag/'.$proj->getPrimarySlug().'/')
->setPHID($proj->getPHID())
- ->setIcon($proj->getIcon().' bluegrey')
+ ->setIcon($proj->getIcon().' '.$proj->getColor())
->setPriorityType('proj')
->setClosed($closed);
diff --git a/src/applications/project/typeahead/PhabricatorProjectMembersDatasource.php b/src/applications/project/typeahead/PhabricatorProjectMembersDatasource.php
--- a/src/applications/project/typeahead/PhabricatorProjectMembersDatasource.php
+++ b/src/applications/project/typeahead/PhabricatorProjectMembersDatasource.php
@@ -116,6 +116,7 @@
->setDisplayName(pht('Members: %s', $project->getName()))
->setURI('/tag/'.$project->getPrimarySlug().'/')
->setPHID('members('.$project->getPHID().')')
+ ->setIcon('fa-users')
->setClosed($closed);
}
diff --git a/src/applications/typeahead/datasource/PhabricatorTypeaheadDatasource.php b/src/applications/typeahead/datasource/PhabricatorTypeaheadDatasource.php
--- a/src/applications/typeahead/datasource/PhabricatorTypeaheadDatasource.php
+++ b/src/applications/typeahead/datasource/PhabricatorTypeaheadDatasource.php
@@ -187,16 +187,16 @@
}
protected function newFunctionResult() {
- // TODO: Find a more consistent design.
return id(new PhabricatorTypeaheadResult())
- ->setIcon('fa-magic indigo');
+ ->setTokenType(PhabricatorTypeaheadTokenView::TYPE_FUNCTION)
+ ->setIcon('fa-asterisk');
}
public function newInvalidToken($name) {
return id(new PhabricatorTypeaheadTokenView())
- ->setKey(PhabricatorTypeaheadTokenView::KEY_INVALID)
->setValue($name)
- ->setIcon('fa-exclamation-circle red');
+ ->setIcon('fa-exclamation-circle')
+ ->setTokenType(PhabricatorTypeaheadTokenView::TYPE_INVALID);
}
/* -( Token Functions )---------------------------------------------------- */
diff --git a/src/applications/typeahead/storage/PhabricatorTypeaheadResult.php b/src/applications/typeahead/storage/PhabricatorTypeaheadResult.php
--- a/src/applications/typeahead/storage/PhabricatorTypeaheadResult.php
+++ b/src/applications/typeahead/storage/PhabricatorTypeaheadResult.php
@@ -13,6 +13,7 @@
private $imageSprite;
private $icon;
private $closed;
+ private $tokenType;
private $unique;
public function setIcon($icon) {
@@ -91,6 +92,18 @@
return $this;
}
+ public function setTokenType($type) {
+ $this->tokenType = $type;
+ return $this;
+ }
+
+ public function getTokenType() {
+ if ($this->closed && !$this->tokenType) {
+ return PhabricatorTypeaheadTokenView::TYPE_DISABLED;
+ }
+ return $this->tokenType;
+ }
+
public function getSortKey() {
// Put unique results (special parameter functions) ahead of other
// results.
@@ -116,6 +129,7 @@
$this->getIcon(),
$this->closed,
$this->imageSprite ? (string)$this->imageSprite : null,
+ $this->tokenType,
$this->unique ? 1 : null,
);
while (end($data) === null) {
diff --git a/src/applications/typeahead/view/PhabricatorTypeaheadTokenView.php b/src/applications/typeahead/view/PhabricatorTypeaheadTokenView.php
--- a/src/applications/typeahead/view/PhabricatorTypeaheadTokenView.php
+++ b/src/applications/typeahead/view/PhabricatorTypeaheadTokenView.php
@@ -3,12 +3,16 @@
final class PhabricatorTypeaheadTokenView
extends AphrontTagView {
+ const TYPE_OBJECT = 'object';
+ const TYPE_DISABLED = 'disabled';
+ const TYPE_FUNCTION = 'function';
+ const TYPE_INVALID = 'invalid';
+
private $key;
private $icon;
private $inputName;
private $value;
-
- const KEY_INVALID = '<invalid>';
+ private $tokenType = self::TYPE_OBJECT;
public static function newFromTypeaheadResult(
PhabricatorTypeaheadResult $result) {
@@ -16,16 +20,24 @@
return id(new PhabricatorTypeaheadTokenView())
->setKey($result->getPHID())
->setIcon($result->getIcon())
- ->setValue($result->getDisplayName());
+ ->setValue($result->getDisplayName())
+ ->setTokenType($result->getTokenType());
}
public static function newFromHandle(
PhabricatorObjectHandle $handle) {
- return id(new PhabricatorTypeaheadTokenView())
+ $token = id(new PhabricatorTypeaheadTokenView())
->setKey($handle->getPHID())
->setValue($handle->getFullName())
- ->setIcon($handle->getIcon());
+ ->setIcon(rtrim($handle->getIcon().' '.$handle->getIconColor()));
+
+ if ($handle->isDisabled() ||
+ $handle->getStatus() == PhabricatorObjectHandleStatus::STATUS_CLOSED) {
+ $token->setTokenType(self::TYPE_DISABLED);
+ }
+
+ return $token;
}
public function setKey($key) {
@@ -37,6 +49,15 @@
return $this->key;
}
+ public function setTokenType($token_type) {
+ $this->tokenType = $token_type;
+ return $this;
+ }
+
+ public function getTokenType() {
+ return $this->tokenType;
+ }
+
public function setInputName($input_name) {
$this->inputName = $input_name;
return $this;
@@ -69,8 +90,25 @@
}
protected function getTagAttributes() {
+ $classes = array();
+ $classes[] = 'jx-tokenizer-token';
+ switch ($this->getTokenType()) {
+ case self::TYPE_FUNCTION:
+ $classes[] = 'jx-tokenizer-token-function';
+ break;
+ case self::TYPE_INVALID:
+ $classes[] = 'jx-tokenizer-token-invalid';
+ break;
+ case self::TYPE_DISABLED:
+ $classes[] = 'jx-tokenizer-token-disabled';
+ break;
+ case self::TYPE_OBJECT:
+ default:
+ break;
+ }
+
return array(
- 'class' => 'jx-tokenizer-token',
+ 'class' => $classes,
);
}
diff --git a/src/applications/uiexample/examples/PHUITypeaheadExample.php b/src/applications/uiexample/examples/PHUITypeaheadExample.php
new file mode 100644
--- /dev/null
+++ b/src/applications/uiexample/examples/PHUITypeaheadExample.php
@@ -0,0 +1,57 @@
+<?php
+
+final class PHUITypeaheadExample extends PhabricatorUIExample {
+
+ public function getName() {
+ return 'Typeaheads';
+ }
+
+ public function getDescription() {
+ return pht('Typeaheads, tokenizers and tokens.');
+ }
+
+ public function renderExample() {
+
+ $token_list = array();
+
+ $token_list[] = id(new PhabricatorTypeaheadTokenView())
+ ->setValue(pht('Normal Object'))
+ ->setIcon('fa-user');
+
+ $token_list[] = id(new PhabricatorTypeaheadTokenView())
+ ->setValue(pht('Disabled Object'))
+ ->setTokenType(PhabricatorTypeaheadTokenView::TYPE_DISABLED)
+ ->setIcon('fa-user');
+
+ $token_list[] = id(new PhabricatorTypeaheadTokenView())
+ ->setValue(pht('Custom Object'))
+ ->setIcon('fa-tag green');
+
+ $token_list[] = id(new PhabricatorTypeaheadTokenView())
+ ->setValue(pht('Function Token'))
+ ->setTokenType(PhabricatorTypeaheadTokenView::TYPE_FUNCTION)
+ ->setIcon('fa-users');
+
+ $token_list[] = id(new PhabricatorTypeaheadTokenView())
+ ->setValue(pht('Invalid Token'))
+ ->setTokenType(PhabricatorTypeaheadTokenView::TYPE_INVALID)
+ ->setIcon('fa-exclamation-circle');
+
+
+ $token_list = phutil_tag(
+ 'div',
+ array(
+ 'class' => 'grouped',
+ 'style' => 'padding: 8px',
+ ),
+ $token_list);
+
+ $output = array();
+
+ $output[] = id(new PHUIObjectBoxView())
+ ->setHeaderText('Tokens')
+ ->appendChild($token_list);
+
+ return $output;
+ }
+}
diff --git a/src/view/form/control/AphrontFormTokenizerControl.php b/src/view/form/control/AphrontFormTokenizerControl.php
--- a/src/view/form/control/AphrontFormTokenizerControl.php
+++ b/src/view/form/control/AphrontFormTokenizerControl.php
@@ -51,7 +51,9 @@
}
$datasource = $this->datasource;
- $datasource->setViewer($this->getUser());
+ if ($datasource) {
+ $datasource->setViewer($this->getUser());
+ }
$placeholder = null;
if (!strlen($this->placeholder)) {
@@ -84,7 +86,8 @@
$token = $datasource->newInvalidToken($name);
}
- if ($token->getKey() == PhabricatorTypeaheadTokenView::KEY_INVALID) {
+ $type = $token->getTokenType();
+ if ($type == PhabricatorTypeaheadTokenView::TYPE_INVALID) {
$token->setKey($value);
}
}
@@ -117,12 +120,13 @@
if (!$this->disableBehavior) {
Javelin::initBehavior('aphront-basic-tokenizer', array(
- 'id' => $id,
- 'src' => $datasource_uri,
- 'value' => mpull($tokens, 'getValue', 'getKey'),
- 'icons' => mpull($tokens, 'getIcon', 'getKey'),
- 'limit' => $this->limit,
- 'username' => $username,
+ 'id' => $id,
+ 'src' => $datasource_uri,
+ 'value' => mpull($tokens, 'getValue', 'getKey'),
+ 'icons' => mpull($tokens, 'getIcon', 'getKey'),
+ 'types' => mpull($tokens, 'getTokenType', 'getKey'),
+ 'limit' => $this->limit,
+ 'username' => $username,
'placeholder' => $placeholder,
'browseURI' => $browse_uri,
));
diff --git a/webroot/rsrc/css/aphront/tokenizer.css b/webroot/rsrc/css/aphront/tokenizer.css
--- a/webroot/rsrc/css/aphront/tokenizer.css
+++ b/webroot/rsrc/css/aphront/tokenizer.css
@@ -83,6 +83,51 @@
color: {$bluetext};
}
+a.jx-tokenizer-token-function {
+ border-color: {$sh-lightyellowborder};
+ background: {$sh-yellowbackground};
+ color: {$sh-yellowtext};
+}
+
+a.jx-tokenizer-token-function:hover {
+ border-color: {$sh-yellowborder};
+ background: {$lightyellow};
+}
+
+.jx-tokenizer-token-function .phui-icon-view {
+ color: {$sh-yellowicon};
+}
+
+a.jx-tokenizer-token-disabled {
+ border-color: {$sh-lightgreyborder};
+ background: {$sh-greybackground};
+ color: {$sh-greytext};
+}
+
+a.jx-tokenizer-token-disabled:hover {
+ border-color: {$sh-greyborder};
+ background: {$greybackground};
+}
+
+.jx-tokenizer-token-disabled .phui-icon-view {
+ color: {$sh-greyicon};
+}
+
+a.jx-tokenizer-token-invalid {
+ border-color: {$sh-lightredborder};
+ background: {$sh-redbackground};
+ color: {$sh-redtext};
+}
+
+a.jx-tokenizer-token-invalid:hover {
+ border-color: {$sh-redborder};
+ background: {$lightred};
+}
+
+.jx-tokenizer-token-invalid .phui-icon-view {
+ color: {$sh-redicon};
+}
+
.tokenizer-result {
position: relative;
padding: 5px 8px 5px 28px;
diff --git a/webroot/rsrc/externals/javelin/lib/control/tokenizer/Tokenizer.js b/webroot/rsrc/externals/javelin/lib/control/tokenizer/Tokenizer.js
--- a/webroot/rsrc/externals/javelin/lib/control/tokenizer/Tokenizer.js
+++ b/webroot/rsrc/externals/javelin/lib/control/tokenizer/Tokenizer.js
@@ -348,16 +348,22 @@
}, '\u00d7'); // U+00D7 multiplication sign
var display_token = value;
- var render_callback = this.getRenderTokenCallback();
- if (render_callback) {
- display_token = render_callback(value, key);
- }
- return JX.$N('a', {
+ var attrs = {
className: 'jx-tokenizer-token',
sigil: 'token',
meta: {key: key}
- }, [display_token, input, remove]);
+ };
+ var container = JX.$N('a', attrs);
+
+ var render_callback = this.getRenderTokenCallback();
+ if (render_callback) {
+ display_token = render_callback(value, key, container);
+ }
+
+ JX.DOM.setContent(container, [display_token, input, remove]);
+
+ return container;
},
getTokens : function() {
diff --git a/webroot/rsrc/js/core/Prefab.js b/webroot/rsrc/js/core/Prefab.js
--- a/webroot/rsrc/js/core/Prefab.js
+++ b/webroot/rsrc/js/core/Prefab.js
@@ -172,23 +172,27 @@
var tokenizer = new JX.Tokenizer(root);
tokenizer.setTypeahead(typeahead);
- tokenizer.setRenderTokenCallback(function(value, key) {
+ tokenizer.setRenderTokenCallback(function(value, key, container) {
var result = datasource.getResult(key);
var icon;
+ var type;
if (result) {
icon = result.icon;
value = result.displayName;
+ type = result.tokenType;
} else {
icon = config.icons[key];
+ type = config.types[key];
}
if (icon) {
icon = JX.Prefab._renderIcon(icon);
}
- // TODO: Maybe we should render these closed tags in grey? Figure out
- // how we're going to use color.
+ if (type) {
+ JX.DOM.alterClass(container, 'jx-tokenizer-token-' + type, true);
+ }
return [icon, value];
});
@@ -288,7 +292,8 @@
closed: closed,
type: fields[5],
sprite: fields[10],
- unique: fields[11] || false
+ tokenType: fields[11],
+ unique: fields[12] || false
};
},

File Metadata

Mime Type
text/plain
Expires
Mon, May 13, 11:45 PM (3 w, 3 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6281433
Default Alt Text
D12446.diff (14 KB)

Event Timeline