mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-26 07:20:57 +01:00
Allow Doorkeeper references to have multiple display variations (full, short, etc.)
Summary: Ref T13102. An install has a custom rule for bridging JIRA references via Doorkeeper and would like to be able to render them as `JIRA-123` instead of `JIRA JIRA-123 Full JIRA title`. I think it's reasonable to imagine future support upstream for `JIRA-123`, `{JIRA-123}`, and so on, although we do not support these today. We can take a small step toward eventual support by letting the rendering pipeline understand different view modes. This adds an optional `name` (the default text rendered before we do the OAuth sync) and an optional `view`, which can be `short` or `full`. Test Plan: I tested this primarily with Asana, since it's less of a pain to set up than JIRA. The logic should be similar, hopefully. I changed `DoorkeeperAsanaRemarkupRule` to specify `name` and `view`, e.g `'view' => (mt_rand(0, 1) ? 'short' : 'full')`. Then I made a bunch of Asana references in a comment and saw them randomly go short or long. Maniphest Tasks: T13102 Differential Revision: https://secure.phabricator.com/D19215
This commit is contained in:
parent
a4a390fe2d
commit
2b19f91936
6 changed files with 98 additions and 30 deletions
|
@ -10,7 +10,7 @@ return array(
|
|||
'conpherence.pkg.css' => 'e68cf1fa',
|
||||
'conpherence.pkg.js' => '15191c65',
|
||||
'core.pkg.css' => 'c218ed53',
|
||||
'core.pkg.js' => '8b7400e7',
|
||||
'core.pkg.js' => '0fabde4f',
|
||||
'darkconsole.pkg.js' => '1f9a31bc',
|
||||
'differential.pkg.css' => '113e692c',
|
||||
'differential.pkg.js' => 'f6d809c0',
|
||||
|
@ -391,7 +391,7 @@ return array(
|
|||
'rsrc/js/application/diffusion/behavior-load-blame.js' => '42126667',
|
||||
'rsrc/js/application/diffusion/behavior-locate-file.js' => '6d3e1947',
|
||||
'rsrc/js/application/diffusion/behavior-pull-lastmodified.js' => 'f01586dc',
|
||||
'rsrc/js/application/doorkeeper/behavior-doorkeeper-tag.js' => 'e5822781',
|
||||
'rsrc/js/application/doorkeeper/behavior-doorkeeper-tag.js' => '1db13e70',
|
||||
'rsrc/js/application/drydock/drydock-live-operation-status.js' => '901935ef',
|
||||
'rsrc/js/application/files/behavior-icon-composer.js' => '8499b6ab',
|
||||
'rsrc/js/application/files/behavior-launch-icon-composer.js' => '48086888',
|
||||
|
@ -608,7 +608,7 @@ return array(
|
|||
'javelin-behavior-diffusion-jump-to' => '73d09eef',
|
||||
'javelin-behavior-diffusion-locate-file' => '6d3e1947',
|
||||
'javelin-behavior-diffusion-pull-lastmodified' => 'f01586dc',
|
||||
'javelin-behavior-doorkeeper-tag' => 'e5822781',
|
||||
'javelin-behavior-doorkeeper-tag' => '1db13e70',
|
||||
'javelin-behavior-drydock-live-operation-status' => '901935ef',
|
||||
'javelin-behavior-durable-column' => '2ae077e1',
|
||||
'javelin-behavior-editengine-reorder-configs' => 'd7a74243',
|
||||
|
@ -1024,6 +1024,13 @@ return array(
|
|||
'javelin-request',
|
||||
'javelin-uri',
|
||||
),
|
||||
'1db13e70' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-dom',
|
||||
'javelin-json',
|
||||
'javelin-workflow',
|
||||
'javelin-magical-init',
|
||||
),
|
||||
'1f6794f6' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-stratcom',
|
||||
|
@ -2087,13 +2094,6 @@ return array(
|
|||
'javelin-behavior',
|
||||
'javelin-dom',
|
||||
),
|
||||
'e5822781' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-dom',
|
||||
'javelin-json',
|
||||
'javelin-workflow',
|
||||
'javelin-magical-init',
|
||||
),
|
||||
'e74b7517' => array(
|
||||
'javelin-install',
|
||||
'phuix-button-view',
|
||||
|
|
|
@ -97,6 +97,7 @@ final class DoorkeeperBridgeJIRA extends DoorkeeperBridge {
|
|||
|
||||
$ref->setAttribute('title', idx($fields, 'summary'));
|
||||
$ref->setAttribute('description', idx($result, 'description'));
|
||||
$ref->setAttribute('shortname', $result['key']);
|
||||
|
||||
$obj = $ref->getExternalObject();
|
||||
if ($obj->getID()) {
|
||||
|
|
|
@ -13,17 +13,13 @@ final class DoorkeeperTagsController extends PhabricatorController {
|
|||
}
|
||||
|
||||
$refs = array();
|
||||
$id_map = array();
|
||||
foreach ($tags as $tag_spec) {
|
||||
foreach ($tags as $key => $tag_spec) {
|
||||
$tag = $tag_spec['ref'];
|
||||
$ref = id(new DoorkeeperObjectRef())
|
||||
->setApplicationType($tag[0])
|
||||
->setApplicationDomain($tag[1])
|
||||
->setObjectType($tag[2])
|
||||
->setObjectID($tag[3]);
|
||||
|
||||
$key = $ref->getObjectKey();
|
||||
$id_map[$key] = $tag_spec['id'];
|
||||
$refs[$key] = $ref;
|
||||
}
|
||||
|
||||
|
@ -43,19 +39,30 @@ final class DoorkeeperTagsController extends PhabricatorController {
|
|||
continue;
|
||||
}
|
||||
|
||||
$id = $id_map[$key];
|
||||
$tag_spec = $tags[$key];
|
||||
|
||||
$id = $tag_spec['id'];
|
||||
$view = idx($tag_spec, 'view');
|
||||
|
||||
$is_short = ($view == 'short');
|
||||
|
||||
if ($is_short) {
|
||||
$name = $ref->getShortName();
|
||||
} else {
|
||||
$name = $ref->getFullName();
|
||||
}
|
||||
|
||||
$tag = id(new PHUITagView())
|
||||
->setID($id)
|
||||
->setName($ref->getFullName())
|
||||
->setName($name)
|
||||
->setHref($uri)
|
||||
->setType(PHUITagView::TYPE_OBJECT)
|
||||
->setExternal(true)
|
||||
->render();
|
||||
|
||||
$results[] = array(
|
||||
'id' => $id,
|
||||
'markup' => $tag,
|
||||
'id' => $id,
|
||||
'markup' => $tag,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -107,6 +107,13 @@ final class DoorkeeperObjectRef extends Phobject {
|
|||
pht('External Object'));
|
||||
}
|
||||
|
||||
public function getShortName() {
|
||||
return coalesce(
|
||||
$this->getAttribute('shortname'),
|
||||
$this->getAttribute('name'),
|
||||
pht('External Object'));
|
||||
}
|
||||
|
||||
public function getObjectKey() {
|
||||
if (!$this->objectKey) {
|
||||
$this->objectKey = PhabricatorHash::digestForIndex(
|
||||
|
|
|
@ -4,11 +4,41 @@ abstract class DoorkeeperRemarkupRule extends PhutilRemarkupRule {
|
|||
|
||||
const KEY_TAGS = 'doorkeeper.tags';
|
||||
|
||||
const VIEW_FULL = 'full';
|
||||
const VIEW_SHORT = 'short';
|
||||
|
||||
public function getPriority() {
|
||||
return 350.0;
|
||||
}
|
||||
|
||||
protected function addDoorkeeperTag(array $spec) {
|
||||
PhutilTypeSpec::checkMap(
|
||||
$spec,
|
||||
array(
|
||||
'href' => 'string',
|
||||
'tag' => 'map<string, wild>',
|
||||
|
||||
'name' => 'optional string',
|
||||
'view' => 'optional string',
|
||||
));
|
||||
|
||||
$spec = $spec + array(
|
||||
'view' => self::VIEW_FULL,
|
||||
);
|
||||
|
||||
$views = array(
|
||||
self::VIEW_FULL,
|
||||
self::VIEW_SHORT,
|
||||
);
|
||||
$views = array_fuse($views);
|
||||
if (!isset($views[$spec['view']])) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Unsupported Doorkeeper tag view mode "%s". Supported modes are: %s.',
|
||||
$spec['view'],
|
||||
implode(', ', $views)));
|
||||
}
|
||||
|
||||
$key = self::KEY_TAGS;
|
||||
$engine = $this->getEngine();
|
||||
$token = $engine->storeText(get_class($this));
|
||||
|
@ -36,19 +66,26 @@ abstract class DoorkeeperRemarkupRule extends PhutilRemarkupRule {
|
|||
|
||||
$refs = array();
|
||||
foreach ($tags as $spec) {
|
||||
$tag_id = celerity_generate_unique_node_id();
|
||||
$href = $spec['href'];
|
||||
$name = idx($spec, 'name', $href);
|
||||
|
||||
$refs[] = array(
|
||||
'id' => $tag_id,
|
||||
) + $spec['tag'];
|
||||
$this->assertFlatText($href);
|
||||
$this->assertFlatText($name);
|
||||
|
||||
if ($this->getEngine()->isTextMode()) {
|
||||
$view = $spec['href'];
|
||||
$view = "{$name} <{$href}>";
|
||||
} else {
|
||||
$tag_id = celerity_generate_unique_node_id();
|
||||
|
||||
$refs[] = array(
|
||||
'id' => $tag_id,
|
||||
'view' => $spec['view'],
|
||||
) + $spec['tag'];
|
||||
|
||||
$view = id(new PHUITagView())
|
||||
->setID($tag_id)
|
||||
->setName($this->assertFlatText($spec['href']))
|
||||
->setHref($this->assertFlatText($spec['href']))
|
||||
->setName($name)
|
||||
->setHref($href)
|
||||
->setType(PHUITagView::TYPE_OBJECT)
|
||||
->setExternal(true);
|
||||
}
|
||||
|
@ -56,7 +93,9 @@ abstract class DoorkeeperRemarkupRule extends PhutilRemarkupRule {
|
|||
$engine->overwriteStoredText($spec['token'], $view);
|
||||
}
|
||||
|
||||
Javelin::initBehavior('doorkeeper-tag', array('tags' => $refs));
|
||||
if ($refs) {
|
||||
Javelin::initBehavior('doorkeeper-tag', array('tags' => $refs));
|
||||
}
|
||||
|
||||
$engine->setTextMetadata($key, array());
|
||||
}
|
||||
|
|
|
@ -40,9 +40,19 @@ JX.behavior('doorkeeper-tag', function(config, statics) {
|
|||
};
|
||||
|
||||
for (var ii = 0; ii < tags.length; ii++) {
|
||||
var tag_key = tags[ii].ref.join('@');
|
||||
var key_parts = [];
|
||||
|
||||
key_parts = key_parts.concat(tags[ii].ref);
|
||||
key_parts.push(tags[ii].view);
|
||||
|
||||
var tag_key = key_parts.join(' ');
|
||||
|
||||
if (tag_key in statics.cache) {
|
||||
have.push({id: tags[ii].id, markup: statics.cache[tag_key]});
|
||||
have.push(
|
||||
{
|
||||
id: tags[ii].id,
|
||||
markup: statics.cache[tag_key]
|
||||
});
|
||||
} else {
|
||||
need.push(tags[ii]);
|
||||
keys[tags[ii].id] = tag_key;
|
||||
|
@ -54,7 +64,11 @@ JX.behavior('doorkeeper-tag', function(config, statics) {
|
|||
}
|
||||
|
||||
if (need.length) {
|
||||
new JX.Workflow('/doorkeeper/tags/', {tags: JX.JSON.stringify(need)})
|
||||
var data = {
|
||||
tags: JX.JSON.stringify(need)
|
||||
};
|
||||
|
||||
new JX.Workflow('/doorkeeper/tags/', data)
|
||||
.setHandler(function(r) { draw(r.tags); })
|
||||
.start();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue