1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-26 08:42:41 +01:00

Restore bulk edit support for remarkup fields (description, add comment)

Summary:
Depends on D18866. Ref T13025. Fixes T12415. This makes the old "Add Comment" action work, and adds support for a new "Set description to" action (possibly, I could imagine "append description" being useful some day, maybe).

The implementation is just a `<textarea />`, not a whole fancy remarkup box with `[Bold] [Italic] ...` buttons, preview, typeaheads, etc. It would be nice to enrich this eventually but doing the rendering in pure JS is currently very involved.

This requires a little bit of gymnastics to get the transaction populated properly, and adds some extra validation since we need some code there anyway.

Test Plan:
  - Changed the description of a task via bulk editor.
  - Added a comment to a task via bulk editor.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13025, T12415

Differential Revision: https://secure.phabricator.com/D18867
This commit is contained in:
epriestley 2018-01-11 09:48:33 -08:00
parent bf1ac701c3
commit 687fada5af
12 changed files with 132 additions and 11 deletions

View file

@ -142,7 +142,7 @@ return array(
'rsrc/css/phui/phui-basic-nav-view.css' => '98c11ab3', 'rsrc/css/phui/phui-basic-nav-view.css' => '98c11ab3',
'rsrc/css/phui/phui-big-info-view.css' => 'acc3492c', 'rsrc/css/phui/phui-big-info-view.css' => 'acc3492c',
'rsrc/css/phui/phui-box.css' => '4bd6cdb9', 'rsrc/css/phui/phui-box.css' => '4bd6cdb9',
'rsrc/css/phui/phui-bulk-editor.css' => '1fe728a8', 'rsrc/css/phui/phui-bulk-editor.css' => '9a81e5d5',
'rsrc/css/phui/phui-chart.css' => '6bf6f78e', 'rsrc/css/phui/phui-chart.css' => '6bf6f78e',
'rsrc/css/phui/phui-cms.css' => '504b4b23', 'rsrc/css/phui/phui-cms.css' => '504b4b23',
'rsrc/css/phui/phui-comment-form.css' => 'ac68149f', 'rsrc/css/phui/phui-comment-form.css' => 'ac68149f',
@ -532,7 +532,7 @@ return array(
'rsrc/js/phuix/PHUIXButtonView.js' => '8a91e1ac', 'rsrc/js/phuix/PHUIXButtonView.js' => '8a91e1ac',
'rsrc/js/phuix/PHUIXDropdownMenu.js' => '04b2ae03', 'rsrc/js/phuix/PHUIXDropdownMenu.js' => '04b2ae03',
'rsrc/js/phuix/PHUIXExample.js' => '68af71ca', 'rsrc/js/phuix/PHUIXExample.js' => '68af71ca',
'rsrc/js/phuix/PHUIXFormControl.js' => '68bb05aa', 'rsrc/js/phuix/PHUIXFormControl.js' => '1dd0870c',
'rsrc/js/phuix/PHUIXIconView.js' => 'bff6884b', 'rsrc/js/phuix/PHUIXIconView.js' => 'bff6884b',
), ),
'symbols' => array( 'symbols' => array(
@ -822,7 +822,7 @@ return array(
'phui-basic-nav-view-css' => '98c11ab3', 'phui-basic-nav-view-css' => '98c11ab3',
'phui-big-info-view-css' => 'acc3492c', 'phui-big-info-view-css' => 'acc3492c',
'phui-box-css' => '4bd6cdb9', 'phui-box-css' => '4bd6cdb9',
'phui-bulk-editor-css' => '1fe728a8', 'phui-bulk-editor-css' => '9a81e5d5',
'phui-button-bar-css' => 'f1ff5494', 'phui-button-bar-css' => 'f1ff5494',
'phui-button-css' => '1863cc6e', 'phui-button-css' => '1863cc6e',
'phui-button-simple-css' => '8e1baf68', 'phui-button-simple-css' => '8e1baf68',
@ -884,7 +884,7 @@ return array(
'phuix-autocomplete' => 'e0731603', 'phuix-autocomplete' => 'e0731603',
'phuix-button-view' => '8a91e1ac', 'phuix-button-view' => '8a91e1ac',
'phuix-dropdown-menu' => '04b2ae03', 'phuix-dropdown-menu' => '04b2ae03',
'phuix-form-control-view' => '68bb05aa', 'phuix-form-control-view' => '1dd0870c',
'phuix-icon-view' => 'bff6884b', 'phuix-icon-view' => 'bff6884b',
'policy-css' => '957ea14c', 'policy-css' => '957ea14c',
'policy-edit-css' => '815c66f7', 'policy-edit-css' => '815c66f7',
@ -1029,6 +1029,10 @@ return array(
'javelin-request', 'javelin-request',
'javelin-uri', 'javelin-uri',
), ),
'1dd0870c' => array(
'javelin-install',
'javelin-dom',
),
'1e911d0f' => array( '1e911d0f' => array(
'javelin-stratcom', 'javelin-stratcom',
'javelin-request', 'javelin-request',
@ -1445,10 +1449,6 @@ return array(
'javelin-dom', 'javelin-dom',
'phuix-button-view', 'phuix-button-view',
), ),
'68bb05aa' => array(
'javelin-install',
'javelin-dom',
),
'69adf288' => array( '69adf288' => array(
'javelin-install', 'javelin-install',
), ),

View file

@ -223,6 +223,7 @@ phutil_register_library_map(array(
'AuditQueryConduitAPIMethod' => 'applications/audit/conduit/AuditQueryConduitAPIMethod.php', 'AuditQueryConduitAPIMethod' => 'applications/audit/conduit/AuditQueryConduitAPIMethod.php',
'AuthManageProvidersCapability' => 'applications/auth/capability/AuthManageProvidersCapability.php', 'AuthManageProvidersCapability' => 'applications/auth/capability/AuthManageProvidersCapability.php',
'BulkParameterType' => 'applications/transactions/bulk/type/BulkParameterType.php', 'BulkParameterType' => 'applications/transactions/bulk/type/BulkParameterType.php',
'BulkRemarkupParameterType' => 'applications/transactions/bulk/type/BulkRemarkupParameterType.php',
'BulkSelectParameterType' => 'applications/transactions/bulk/type/BulkSelectParameterType.php', 'BulkSelectParameterType' => 'applications/transactions/bulk/type/BulkSelectParameterType.php',
'BulkStringParameterType' => 'applications/transactions/bulk/type/BulkStringParameterType.php', 'BulkStringParameterType' => 'applications/transactions/bulk/type/BulkStringParameterType.php',
'CalendarTimeUtil' => 'applications/calendar/util/CalendarTimeUtil.php', 'CalendarTimeUtil' => 'applications/calendar/util/CalendarTimeUtil.php',
@ -5245,6 +5246,7 @@ phutil_register_library_map(array(
'AuditQueryConduitAPIMethod' => 'AuditConduitAPIMethod', 'AuditQueryConduitAPIMethod' => 'AuditConduitAPIMethod',
'AuthManageProvidersCapability' => 'PhabricatorPolicyCapability', 'AuthManageProvidersCapability' => 'PhabricatorPolicyCapability',
'BulkParameterType' => 'Phobject', 'BulkParameterType' => 'Phobject',
'BulkRemarkupParameterType' => 'BulkParameterType',
'BulkSelectParameterType' => 'BulkParameterType', 'BulkSelectParameterType' => 'BulkParameterType',
'BulkStringParameterType' => 'BulkParameterType', 'BulkStringParameterType' => 'BulkParameterType',
'CalendarTimeUtil' => 'Phobject', 'CalendarTimeUtil' => 'Phobject',

View file

@ -245,6 +245,7 @@ EODOCS
$fields[] = id(new PhabricatorRemarkupEditField()) $fields[] = id(new PhabricatorRemarkupEditField())
->setKey('description') ->setKey('description')
->setLabel(pht('Description')) ->setLabel(pht('Description'))
->setBulkEditLabel(pht('Set description to'))
->setDescription(pht('Task description.')) ->setDescription(pht('Task description.'))
->setConduitDescription(pht('Update the task description.')) ->setConduitDescription(pht('Update the task description.'))
->setConduitTypeDescription(pht('New task description.')) ->setConduitTypeDescription(pht('New task description.'))

View file

@ -70,8 +70,17 @@ final class PhabricatorEditEngineBulkJobType
foreach ($raw_xactions as $raw_xaction) { foreach ($raw_xactions as $raw_xaction) {
$xaction = $object->getApplicationTransactionTemplate() $xaction = $object->getApplicationTransactionTemplate()
->setTransactionType($raw_xaction['type']) ->setTransactionType($raw_xaction['type']);
->setNewValue($raw_xaction['value']);
if (isset($raw_xaction['value'])) {
$xaction->setNewValue($raw_xaction['value']);
}
if (isset($raw_xaction['comment'])) {
$comment = $xaction->getApplicationTransactionCommentObject()
->setContent($raw_xaction['comment']);
$xaction->attachComment($comment);
}
$xactions[] = $xaction; $xactions[] = $xaction;
} }

View file

@ -0,0 +1,10 @@
<?php
final class BulkRemarkupParameterType
extends BulkParameterType {
public function getPHUIXControlType() {
return 'remarkup';
}
}

View file

@ -2450,7 +2450,7 @@ abstract class PhabricatorEditEngine
$map[] = array( $map[] = array(
'label' => $bulk_label, 'label' => $bulk_label,
'xaction' => $type->getTransactionType(), 'xaction' => $key,
'control' => array( 'control' => array(
'type' => $bulk_type->getPHUIXControlType(), 'type' => $bulk_type->getPHUIXControlType(),
'spec' => (object)$bulk_type->getPHUIXControlSpecification(), 'spec' => (object)$bulk_type->getPHUIXControlSpecification(),
@ -2463,6 +2463,50 @@ abstract class PhabricatorEditEngine
final public function newRawBulkTransactions(array $xactions) { final public function newRawBulkTransactions(array $xactions) {
$config = $this->loadDefaultConfiguration();
if (!$config) {
throw new Exception(
pht('No default edit engine configuration for bulk edit.'));
}
$object = $this->newEditableObject();
$fields = $this->buildEditFields($object);
$edit_types = $this->getBulkEditTypesFromFields($fields);
foreach ($xactions as $key => $xaction) {
PhutilTypeSpec::checkMap(
$xaction,
array(
'type' => 'string',
'value' => 'optional wild',
'comment' => 'optional string',
));
$type = $xaction['type'];
if (!isset($edit_types[$type])) {
throw new Exception(
pht(
'Unsupported bulk edit type "%s".',
$type));
}
$edit_type = $edit_types[$type];
// Replace the edit type with the underlying transaction type. Usually
// these are 1:1 and the transaction type just has more internal noise,
// but it's possible that this isn't the case.
$xaction['type'] = $edit_type->getTransactionType();
$xaction = $edit_type->newRawBulkTransaction($xaction);
if ($xaction === null) {
unset($xactions[$key]);
continue;
}
$xactions[$key] = $xaction;
}
return $xactions; return $xactions;
} }

View file

@ -11,4 +11,8 @@ final class PhabricatorRemarkupEditField
return new ConduitStringParameterType(); return new ConduitStringParameterType();
} }
protected function newBulkParameterType() {
return new BulkRemarkupParameterType();
}
} }

View file

@ -6,6 +6,21 @@ final class PhabricatorCommentEditType extends PhabricatorEditType {
return new ConduitStringParameterType(); return new ConduitStringParameterType();
} }
protected function newBulkParameterType() {
return new BulkRemarkupParameterType();
}
public function newRawBulkTransaction(array $xaction) {
if (!strlen($xaction['value'])) {
return null;
}
$xaction['comment'] = $xaction['value'];
unset($xaction['value']);
return $xaction;
}
public function generateTransactions( public function generateTransactions(
PhabricatorApplicationTransaction $template, PhabricatorApplicationTransaction $template,
array $spec) { array $spec) {

View file

@ -125,6 +125,11 @@ abstract class PhabricatorEditType extends Phobject {
} }
public function newRawBulkTransaction(array $xaction) {
return $xaction;
}
/* -( Conduit )------------------------------------------------------------ */ /* -( Conduit )------------------------------------------------------------ */

View file

@ -46,6 +46,7 @@ final class PhabricatorCommentEditEngineExtension
$comment_field = id(new PhabricatorCommentEditField()) $comment_field = id(new PhabricatorCommentEditField())
->setKey(self::EDITKEY) ->setKey(self::EDITKEY)
->setLabel(pht('Comments')) ->setLabel(pht('Comments'))
->setBulkEditLabel(pht('Add comment'))
->setAliases(array('comments')) ->setAliases(array('comments'))
->setIsHidden(true) ->setIsHidden(true)
->setIsReorderable(false) ->setIsReorderable(false)

View file

@ -20,3 +20,8 @@
.bulk-edit-input input { .bulk-edit-input input {
width: 100%; width: 100%;
} }
.bulk-edit-input textarea {
width: 100%;
height: 8em;
}

View file

@ -57,6 +57,9 @@ JX.install('PHUIXFormControl', {
case 'text': case 'text':
input = this._newText(spec); input = this._newText(spec);
break; break;
case 'remarkup':
input = this._newRemarkup(spec);
break;
default: default:
// TODO: Default or better error? // TODO: Default or better error?
JX.$E('Bad Input Type'); JX.$E('Bad Input Type');
@ -312,6 +315,28 @@ JX.install('PHUIXFormControl', {
}; };
}, },
_newRemarkup: function(spec) {
var attrs = {};
// We could imagine a world where this renders a full remarkup control
// with all the hint buttons and client behaviors, but today much of that
// behavior is defined server-side and thus this isn't a world we
// currently live in.
var node = JX.$N('textarea', attrs);
node.value = spec.value || '';
return {
node: node,
get: function() {
return node.value;
},
set: function(value) {
node.value = value;
}
};
},
_newOptgroups: function(spec) { _newOptgroups: function(spec) {
var value = spec.value || null; var value = spec.value || null;