mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-26 00:32:42 +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:
parent
bf1ac701c3
commit
687fada5af
12 changed files with 132 additions and 11 deletions
|
@ -142,7 +142,7 @@ return array(
|
|||
'rsrc/css/phui/phui-basic-nav-view.css' => '98c11ab3',
|
||||
'rsrc/css/phui/phui-big-info-view.css' => 'acc3492c',
|
||||
'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-cms.css' => '504b4b23',
|
||||
'rsrc/css/phui/phui-comment-form.css' => 'ac68149f',
|
||||
|
@ -532,7 +532,7 @@ return array(
|
|||
'rsrc/js/phuix/PHUIXButtonView.js' => '8a91e1ac',
|
||||
'rsrc/js/phuix/PHUIXDropdownMenu.js' => '04b2ae03',
|
||||
'rsrc/js/phuix/PHUIXExample.js' => '68af71ca',
|
||||
'rsrc/js/phuix/PHUIXFormControl.js' => '68bb05aa',
|
||||
'rsrc/js/phuix/PHUIXFormControl.js' => '1dd0870c',
|
||||
'rsrc/js/phuix/PHUIXIconView.js' => 'bff6884b',
|
||||
),
|
||||
'symbols' => array(
|
||||
|
@ -822,7 +822,7 @@ return array(
|
|||
'phui-basic-nav-view-css' => '98c11ab3',
|
||||
'phui-big-info-view-css' => 'acc3492c',
|
||||
'phui-box-css' => '4bd6cdb9',
|
||||
'phui-bulk-editor-css' => '1fe728a8',
|
||||
'phui-bulk-editor-css' => '9a81e5d5',
|
||||
'phui-button-bar-css' => 'f1ff5494',
|
||||
'phui-button-css' => '1863cc6e',
|
||||
'phui-button-simple-css' => '8e1baf68',
|
||||
|
@ -884,7 +884,7 @@ return array(
|
|||
'phuix-autocomplete' => 'e0731603',
|
||||
'phuix-button-view' => '8a91e1ac',
|
||||
'phuix-dropdown-menu' => '04b2ae03',
|
||||
'phuix-form-control-view' => '68bb05aa',
|
||||
'phuix-form-control-view' => '1dd0870c',
|
||||
'phuix-icon-view' => 'bff6884b',
|
||||
'policy-css' => '957ea14c',
|
||||
'policy-edit-css' => '815c66f7',
|
||||
|
@ -1029,6 +1029,10 @@ return array(
|
|||
'javelin-request',
|
||||
'javelin-uri',
|
||||
),
|
||||
'1dd0870c' => array(
|
||||
'javelin-install',
|
||||
'javelin-dom',
|
||||
),
|
||||
'1e911d0f' => array(
|
||||
'javelin-stratcom',
|
||||
'javelin-request',
|
||||
|
@ -1445,10 +1449,6 @@ return array(
|
|||
'javelin-dom',
|
||||
'phuix-button-view',
|
||||
),
|
||||
'68bb05aa' => array(
|
||||
'javelin-install',
|
||||
'javelin-dom',
|
||||
),
|
||||
'69adf288' => array(
|
||||
'javelin-install',
|
||||
),
|
||||
|
|
|
@ -223,6 +223,7 @@ phutil_register_library_map(array(
|
|||
'AuditQueryConduitAPIMethod' => 'applications/audit/conduit/AuditQueryConduitAPIMethod.php',
|
||||
'AuthManageProvidersCapability' => 'applications/auth/capability/AuthManageProvidersCapability.php',
|
||||
'BulkParameterType' => 'applications/transactions/bulk/type/BulkParameterType.php',
|
||||
'BulkRemarkupParameterType' => 'applications/transactions/bulk/type/BulkRemarkupParameterType.php',
|
||||
'BulkSelectParameterType' => 'applications/transactions/bulk/type/BulkSelectParameterType.php',
|
||||
'BulkStringParameterType' => 'applications/transactions/bulk/type/BulkStringParameterType.php',
|
||||
'CalendarTimeUtil' => 'applications/calendar/util/CalendarTimeUtil.php',
|
||||
|
@ -5245,6 +5246,7 @@ phutil_register_library_map(array(
|
|||
'AuditQueryConduitAPIMethod' => 'AuditConduitAPIMethod',
|
||||
'AuthManageProvidersCapability' => 'PhabricatorPolicyCapability',
|
||||
'BulkParameterType' => 'Phobject',
|
||||
'BulkRemarkupParameterType' => 'BulkParameterType',
|
||||
'BulkSelectParameterType' => 'BulkParameterType',
|
||||
'BulkStringParameterType' => 'BulkParameterType',
|
||||
'CalendarTimeUtil' => 'Phobject',
|
||||
|
|
|
@ -245,6 +245,7 @@ EODOCS
|
|||
$fields[] = id(new PhabricatorRemarkupEditField())
|
||||
->setKey('description')
|
||||
->setLabel(pht('Description'))
|
||||
->setBulkEditLabel(pht('Set description to'))
|
||||
->setDescription(pht('Task description.'))
|
||||
->setConduitDescription(pht('Update the task description.'))
|
||||
->setConduitTypeDescription(pht('New task description.'))
|
||||
|
|
|
@ -70,8 +70,17 @@ final class PhabricatorEditEngineBulkJobType
|
|||
|
||||
foreach ($raw_xactions as $raw_xaction) {
|
||||
$xaction = $object->getApplicationTransactionTemplate()
|
||||
->setTransactionType($raw_xaction['type'])
|
||||
->setNewValue($raw_xaction['value']);
|
||||
->setTransactionType($raw_xaction['type']);
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
final class BulkRemarkupParameterType
|
||||
extends BulkParameterType {
|
||||
|
||||
public function getPHUIXControlType() {
|
||||
return 'remarkup';
|
||||
}
|
||||
|
||||
}
|
|
@ -2450,7 +2450,7 @@ abstract class PhabricatorEditEngine
|
|||
|
||||
$map[] = array(
|
||||
'label' => $bulk_label,
|
||||
'xaction' => $type->getTransactionType(),
|
||||
'xaction' => $key,
|
||||
'control' => array(
|
||||
'type' => $bulk_type->getPHUIXControlType(),
|
||||
'spec' => (object)$bulk_type->getPHUIXControlSpecification(),
|
||||
|
@ -2463,6 +2463,50 @@ abstract class PhabricatorEditEngine
|
|||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,4 +11,8 @@ final class PhabricatorRemarkupEditField
|
|||
return new ConduitStringParameterType();
|
||||
}
|
||||
|
||||
protected function newBulkParameterType() {
|
||||
return new BulkRemarkupParameterType();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,6 +6,21 @@ final class PhabricatorCommentEditType extends PhabricatorEditType {
|
|||
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(
|
||||
PhabricatorApplicationTransaction $template,
|
||||
array $spec) {
|
||||
|
|
|
@ -125,6 +125,11 @@ abstract class PhabricatorEditType extends Phobject {
|
|||
}
|
||||
|
||||
|
||||
public function newRawBulkTransaction(array $xaction) {
|
||||
return $xaction;
|
||||
}
|
||||
|
||||
|
||||
/* -( Conduit )------------------------------------------------------------ */
|
||||
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@ final class PhabricatorCommentEditEngineExtension
|
|||
$comment_field = id(new PhabricatorCommentEditField())
|
||||
->setKey(self::EDITKEY)
|
||||
->setLabel(pht('Comments'))
|
||||
->setBulkEditLabel(pht('Add comment'))
|
||||
->setAliases(array('comments'))
|
||||
->setIsHidden(true)
|
||||
->setIsReorderable(false)
|
||||
|
|
|
@ -20,3 +20,8 @@
|
|||
.bulk-edit-input input {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.bulk-edit-input textarea {
|
||||
width: 100%;
|
||||
height: 8em;
|
||||
}
|
||||
|
|
|
@ -57,6 +57,9 @@ JX.install('PHUIXFormControl', {
|
|||
case 'text':
|
||||
input = this._newText(spec);
|
||||
break;
|
||||
case 'remarkup':
|
||||
input = this._newRemarkup(spec);
|
||||
break;
|
||||
default:
|
||||
// TODO: Default or better error?
|
||||
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) {
|
||||
var value = spec.value || null;
|
||||
|
||||
|
|
Loading…
Reference in a new issue