Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/applications/maniphest/config/PhabricatorManiphestConfigOptions.php b/src/applications/maniphest/config/PhabricatorManiphestConfigOptions.php
index 4458dc3636..609db0d1b6 100644
--- a/src/applications/maniphest/config/PhabricatorManiphestConfigOptions.php
+++ b/src/applications/maniphest/config/PhabricatorManiphestConfigOptions.php
@@ -1,427 +1,477 @@
<?php
final class PhabricatorManiphestConfigOptions
extends PhabricatorApplicationConfigOptions {
public function getName() {
return pht('Maniphest');
}
public function getDescription() {
return pht('Configure Maniphest.');
}
public function getIcon() {
return 'fa-anchor';
}
public function getGroup() {
return 'apps';
}
public function getOptions() {
$priority_type = 'maniphest.priorities';
$priority_defaults = array(
100 => array(
'name' => pht('Unbreak Now!'),
'keywords' => array('unbreak'),
'short' => pht('Unbreak!'),
'color' => 'pink',
),
90 => array(
'name' => pht('Needs Triage'),
'keywords' => array('triage'),
'short' => pht('Triage'),
'color' => 'violet',
),
80 => array(
'name' => pht('High'),
'keywords' => array('high'),
'short' => pht('High'),
'color' => 'red',
),
50 => array(
'name' => pht('Normal'),
'keywords' => array('normal'),
'short' => pht('Normal'),
'color' => 'orange',
),
25 => array(
'name' => pht('Low'),
'keywords' => array('low'),
'short' => pht('Low'),
'color' => 'yellow',
),
0 => array(
'name' => pht('Wishlist'),
'keywords' => array('wish', 'wishlist'),
'short' => pht('Wish'),
'color' => 'sky',
),
);
$status_type = 'maniphest.statuses';
$status_defaults = array(
'open' => array(
'name' => pht('Open'),
'special' => ManiphestTaskStatus::SPECIAL_DEFAULT,
'prefixes' => array(
'open',
'opens',
'reopen',
'reopens',
),
),
'resolved' => array(
'name' => pht('Resolved'),
'name.full' => pht('Closed, Resolved'),
'closed' => true,
'special' => ManiphestTaskStatus::SPECIAL_CLOSED,
'transaction.icon' => 'fa-check-circle',
'prefixes' => array(
'closed',
'closes',
'close',
'fix',
'fixes',
'fixed',
'resolve',
'resolves',
'resolved',
),
'suffixes' => array(
'as resolved',
'as fixed',
),
'keywords' => array('closed', 'fixed', 'resolved'),
),
'wontfix' => array(
'name' => pht('Wontfix'),
'name.full' => pht('Closed, Wontfix'),
'transaction.icon' => 'fa-ban',
'closed' => true,
'prefixes' => array(
'wontfix',
'wontfixes',
'wontfixed',
),
'suffixes' => array(
'as wontfix',
),
),
'invalid' => array(
'name' => pht('Invalid'),
'name.full' => pht('Closed, Invalid'),
'transaction.icon' => 'fa-minus-circle',
'closed' => true,
'claim' => false,
'prefixes' => array(
'invalidate',
'invalidates',
'invalidated',
),
'suffixes' => array(
'as invalid',
),
),
'duplicate' => array(
'name' => pht('Duplicate'),
'name.full' => pht('Closed, Duplicate'),
'transaction.icon' => 'fa-files-o',
'special' => ManiphestTaskStatus::SPECIAL_DUPLICATE,
'closed' => true,
'claim' => false,
),
'spite' => array(
'name' => pht('Spite'),
'name.full' => pht('Closed, Spite'),
'name.action' => pht('Spited'),
'transaction.icon' => 'fa-thumbs-o-down',
'silly' => true,
'closed' => true,
'prefixes' => array(
'spite',
'spites',
'spited',
),
'suffixes' => array(
'out of spite',
'as spite',
),
),
);
$status_description = $this->deformat(pht(<<<EOTEXT
Allows you to edit, add, or remove the task statuses available in Maniphest,
like "Open", "Resolved" and "Invalid". The configuration should contain a map
of status constants to status specifications (see defaults below for examples).
The constant for each status should be 1-12 characters long and contain only
lowercase letters and digits. Valid examples are "open", "closed", and
"invalid". Users will not normally see these values.
The keys you can provide in a specification are:
- `name` //Required string.// Name of the status, like "Invalid".
- `name.full` //Optional string.// Longer name, like "Closed, Invalid". This
appears on the task detail view in the header.
- `name.action` //Optional string.// Action name for email subjects, like
"Marked Invalid".
- `closed` //Optional bool.// Statuses are either "open" or "closed".
Specifying `true` here will mark the status as closed (like "Resolved" or
"Invalid"). By default, statuses are open.
- `special` //Optional string.// Mark this status as special. The special
statuses are:
- `default` This is the default status for newly created tasks. You must
designate one status as default, and it must be an open status.
- `closed` This is the default status for closed tasks (for example, tasks
closed via the "!close" action in email or via the quick close button in
Maniphest). You must designate one status as the default closed status,
and it must be a closed status.
- `duplicate` This is the status used when tasks are merged into one
another as duplicates. You must designate one status for duplicates,
and it must be a closed status.
- `transaction.icon` //Optional string.// Allows you to choose a different
icon to use for this status when showing status changes in the transaction
log. Please see UIExamples, Icons and Images for a list.
- `transaction.color` //Optional string.// Allows you to choose a different
color to use for this status when showing status changes in the transaction
log.
- `silly` //Optional bool.// Marks this status as silly, and thus wholly
inappropriate for use by serious businesses.
- `prefixes` //Optional list<string>.// Allows you to specify a list of
text prefixes which will trigger a task transition into this status
when mentioned in a commit message. For example, providing "closes" here
will allow users to move tasks to this status by writing `Closes T123` in
commit messages.
- `suffixes` //Optional list<string>.// Allows you to specify a list of
text suffixes which will trigger a task transition into this status
when mentioned in a commit message, after a valid prefix. For example,
providing "as invalid" here will allow users to move tasks
to this status by writing `Closes T123 as invalid`, even if another status
is selected by the "Closes" prefix.
- `keywords` //Optional list<string>.// Allows you to specify a list
of keywords which can be used with `!status` commands in email to select
this status.
- `disabled` //Optional bool.// Marks this status as no longer in use so
tasks can not be created or edited to have this status. Existing tasks with
this status will not be affected, but you can batch edit them or let them
die out on their own.
- `claim` //Optional bool.// By default, closing an unassigned task claims
it. You can set this to `false` to disable this behavior for a particular
status.
- `locked` //Optional bool.// Lock tasks in this status, preventing users
from commenting.
Statuses will appear in the UI in the order specified. Note the status marked
`special` as `duplicate` is not settable directly and will not appear in UI
elements, and that any status marked `silly` does not appear if Phabricator
is configured with `phabricator.serious-business` set to true.
Examining the default configuration and examples below will probably be helpful
in understanding these options.
EOTEXT
));
$status_example = array(
'open' => array(
'name' => pht('Open'),
'special' => 'default',
),
'closed' => array(
'name' => pht('Closed'),
'special' => 'closed',
'closed' => true,
),
'duplicate' => array(
'name' => pht('Duplicate'),
'special' => 'duplicate',
'closed' => true,
),
);
$json = new PhutilJSON();
$status_example = $json->encodeFormatted($status_example);
// This is intentionally blank for now, until we can move more Maniphest
// logic to custom fields.
$default_fields = array();
foreach ($default_fields as $key => $enabled) {
$default_fields[$key] = array(
'disabled' => !$enabled,
);
}
$custom_field_type = 'custom:PhabricatorCustomFieldConfigOptionType';
$fields_example = array(
'mycompany.estimated-hours' => array(
'name' => pht('Estimated Hours'),
'type' => 'int',
'caption' => pht('Estimated number of hours this will take.'),
),
);
$fields_json = id(new PhutilJSON())->encodeFormatted($fields_example);
$points_type = 'maniphest.points';
$points_example_1 = array(
'enabled' => true,
'label' => pht('Story Points'),
'action' => pht('Change Story Points'),
);
$points_json_1 = id(new PhutilJSON())->encodeFormatted($points_example_1);
$points_example_2 = array(
'enabled' => true,
'label' => pht('Estimated Hours'),
'action' => pht('Change Estimate'),
);
$points_json_2 = id(new PhutilJSON())->encodeFormatted($points_example_2);
$points_description = $this->deformat(pht(<<<EOTEXT
Activates a points field on tasks. You can use points for estimation or
planning. If configured, points will appear on workboards.
To activate points, set this value to a map with these keys:
- `enabled` //Optional bool.// Use `true` to enable points, or
`false` to disable them.
- `label` //Optional string.// Label for points, like "Story Points" or
"Estimated Hours". If omitted, points will be called "Points".
- `action` //Optional string.// Label for the action which changes points
in Maniphest, like "Change Estimate". If omitted, the action will
be called "Change Points".
See the example below for a starting point.
EOTEXT
));
$subtype_type = 'maniphest.subtypes';
$subtype_default_key = PhabricatorEditEngineSubtype::SUBTYPE_DEFAULT;
$subtype_example = array(
array(
'key' => $subtype_default_key,
'name' => pht('Task'),
),
array(
'key' => 'bug',
'name' => pht('Bug'),
),
array(
'key' => 'feature',
'name' => pht('Feature Request'),
),
);
$subtype_example = id(new PhutilJSON())->encodeAsList($subtype_example);
$subtype_default = array(
array(
'key' => $subtype_default_key,
'name' => pht('Task'),
),
);
$subtype_description = $this->deformat(pht(<<<EOTEXT
Allows you to define task subtypes. Subtypes let you hide fields you don't
need to simplify the workflows for editing tasks.
To define subtypes, provide a list of subtypes. Each subtype should be a
dictionary with these keys:
- `key` //Required string.// Internal identifier for the subtype, like
"task", "feature", or "bug".
- `name` //Required string.// Human-readable name for this subtype, like
"Task", "Feature Request" or "Bug Report".
- `tag` //Optional string.// Tag text for this subtype.
- `color` //Optional string.// Display color for this subtype.
- `icon` //Optional string.// Icon for the subtype.
+ - `children` //Optional map.// Configure options shown to the user when
+ they "Create Subtask". See below.
Each subtype must have a unique key, and you must define a subtype with
the key "%s", which is used as a default subtype.
The tag text (`tag`) is used to set the text shown in the subtype tag on list
views and workboards. If you do not configure it, the default subtype will have
no subtype tag and other subtypes will use their name as tag text.
+
+The `children` key allows you to configure which options are presented to the
+user when they "Create Subtask" from a task of this subtype. You can specify
+these keys:
+
+ - `subtypes`: //Optional list<string>.// Show users creation forms for these
+ task subtypes.
+ - `forms`: //Optional list<string|int>.// Show users these specific forms,
+ in order.
+
+If you don't specify either constraint, users will be shown creation forms
+for the same subtype.
+
+For example, if you have a "quest" subtype and do not configure `children`,
+users who click "Create Subtask" will be presented with all create forms for
+"quest" tasks.
+
+If you want to present them with forms for a different task subtype or set of
+subtypes instead, use `subtypes`:
+
+```
+ {
+ ...
+ "children": {
+ "subtypes": ["objective", "boss", "reward"]
+ }
+ ...
+ }
+```
+
+If you want to present them with specific forms, use `forms` and specify form
+IDs:
+
+```
+ {
+ ...
+ "children": {
+ "forms": [12, 16]
+ }
+ ...
+ }
+```
+
+When specifying forms by ID explicitly, the order you specify the forms in will
+be used when presenting options to the user.
+
+If only one option would be presented, the user will be taken directly to the
+appropriate form instead of being prompted to choose a form.
EOTEXT
,
$subtype_default_key));
$priorities_description = $this->deformat(pht(<<<EOTEXT
Allows you to edit or override the default priorities available in Maniphest,
like "High", "Normal" and "Low". The configuration should contain a map of
numeric priority values (where larger numbers correspond to higher priorities)
to priority specifications (see defaults below for examples).
The keys you can define for a priority are:
- `name` //Required string.// Name of the priority.
- `keywords` //Required list<string>.// List of unique keywords which identify
this priority, like "high" or "low". Each priority must have at least one
keyword and two priorities may not share the same keyword.
- `short` //Optional string.// Alternate shorter name, used in UIs where
there is less space available.
- `color` //Optional string.// Color for this priority, like "red" or
"blue".
- `disabled` //Optional bool.// Set to true to prevent users from choosing
this priority when creating or editing tasks. Existing tasks will not be
affected, and can be batch edited to a different priority or left to
eventually die out.
You can choose the default priority for newly created tasks with
"maniphest.default-priority".
EOTEXT
));
return array(
$this->newOption('maniphest.custom-field-definitions', 'wild', array())
->setSummary(pht('Custom Maniphest fields.'))
->setDescription(
pht(
'Array of custom fields for Maniphest tasks. For details on '.
'adding custom fields to Maniphest, see "Configuring Custom '.
'Fields" in the documentation.'))
->addExample($fields_json, pht('Valid setting')),
$this->newOption('maniphest.fields', $custom_field_type, $default_fields)
->setCustomData(id(new ManiphestTask())->getCustomFieldBaseClass())
->setDescription(pht('Select and reorder task fields.')),
$this->newOption(
'maniphest.priorities',
$priority_type,
$priority_defaults)
->setSummary(pht('Configure Maniphest priority names.'))
->setDescription($priorities_description),
$this->newOption('maniphest.statuses', $status_type, $status_defaults)
->setSummary(pht('Configure Maniphest task statuses.'))
->setDescription($status_description)
->addExample($status_example, pht('Minimal Valid Config')),
$this->newOption('maniphest.default-priority', 'int', 90)
->setSummary(pht('Default task priority for create flows.'))
->setDescription(
pht(
'Choose a default priority for newly created tasks. You can '.
'review and adjust available priorities by using the '.
'%s configuration option. The default value (`90`) '.
'corresponds to the default "Needs Triage" priority.',
'maniphest.priorities')),
$this->newOption(
'metamta.maniphest.subject-prefix',
'string',
'[Maniphest]')
->setDescription(pht('Subject prefix for Maniphest mail.')),
$this->newOption('maniphest.points', $points_type, array())
->setSummary(pht('Configure point values for tasks.'))
->setDescription($points_description)
->addExample($points_json_1, pht('Points Config'))
->addExample($points_json_2, pht('Hours Config')),
$this->newOption('maniphest.subtypes', $subtype_type, $subtype_default)
->setSummary(pht('Define task subtypes.'))
->setDescription($subtype_description)
->addExample($subtype_example, pht('Simple Subtypes')),
);
}
}
diff --git a/src/applications/transactions/editengine/PhabricatorEditEngineSubtype.php b/src/applications/transactions/editengine/PhabricatorEditEngineSubtype.php
index 23fac106d7..7aad1c9509 100644
--- a/src/applications/transactions/editengine/PhabricatorEditEngineSubtype.php
+++ b/src/applications/transactions/editengine/PhabricatorEditEngineSubtype.php
@@ -1,188 +1,242 @@
<?php
final class PhabricatorEditEngineSubtype
extends Phobject {
const SUBTYPE_DEFAULT = 'default';
private $key;
private $name;
private $icon;
private $tagText;
private $color;
+ private $childSubtypes = array();
+ private $childIdentifiers = array();
public function setKey($key) {
$this->key = $key;
return $this;
}
public function getKey() {
return $this->key;
}
public function setName($name) {
$this->name = $name;
return $this;
}
public function getName() {
return $this->name;
}
public function setIcon($icon) {
$this->icon = $icon;
return $this;
}
public function getIcon() {
return $this->icon;
}
public function setTagText($text) {
$this->tagText = $text;
return $this;
}
public function getTagText() {
return $this->tagText;
}
public function setColor($color) {
$this->color = $color;
return $this;
}
public function getColor() {
return $this->color;
}
+ public function setChildSubtypes(array $child_subtypes) {
+ $this->childSubtypes = $child_subtypes;
+ return $this;
+ }
+
+ public function getChildSubtypes() {
+ return $this->childSubtypes;
+ }
+
+ public function setChildFormIdentifiers(array $child_identifiers) {
+ $this->childIdentifiers = $child_identifiers;
+ return $this;
+ }
+
+ public function getChildFormIdentifiers() {
+ return $this->childIdentifiers;
+ }
+
public function hasTagView() {
return (bool)strlen($this->getTagText());
}
public function newTagView() {
$view = id(new PHUITagView())
->setType(PHUITagView::TYPE_OUTLINE)
->setName($this->getTagText());
$color = $this->getColor();
if ($color) {
$view->setColor($color);
}
return $view;
}
public static function validateSubtypeKey($subtype) {
if (strlen($subtype) > 64) {
throw new Exception(
pht(
'Subtype "%s" is not valid: subtype keys must be no longer than '.
'64 bytes.',
$subtype));
}
if (strlen($subtype) < 3) {
throw new Exception(
pht(
'Subtype "%s" is not valid: subtype keys must have a minimum '.
'length of 3 bytes.',
$subtype));
}
if (!preg_match('/^[a-z]+\z/', $subtype)) {
throw new Exception(
pht(
'Subtype "%s" is not valid: subtype keys may only contain '.
'lowercase latin letters ("a" through "z").',
$subtype));
}
}
public static function validateConfiguration($config) {
if (!is_array($config)) {
throw new Exception(
pht(
'Subtype configuration is invalid: it must be a list of subtype '.
'specifications.'));
}
$map = array();
foreach ($config as $value) {
PhutilTypeSpec::checkMap(
$value,
array(
'key' => 'string',
'name' => 'string',
'tag' => 'optional string',
'color' => 'optional string',
'icon' => 'optional string',
+ 'children' => 'optional map<string, wild>',
));
$key = $value['key'];
self::validateSubtypeKey($key);
if (isset($map[$key])) {
throw new Exception(
pht(
'Subtype configuration is invalid: two subtypes use the same '.
'key ("%s"). Each subtype must have a unique key.',
$key));
}
$map[$key] = true;
$name = $value['name'];
if (!strlen($name)) {
throw new Exception(
pht(
'Subtype configuration is invalid: subtype with key "%s" has '.
'no name. Subtypes must have a name.',
$key));
}
+
+ $children = idx($value, 'children');
+ if ($children) {
+ PhutilTypeSpec::checkMap(
+ $children,
+ array(
+ 'subtypes' => 'optional list<string>',
+ 'forms' => 'optional list<string|int>',
+ ));
+
+ $child_subtypes = idx($children, 'subtypes');
+ $child_forms = idx($children, 'forms');
+
+ if ($child_subtypes && $child_forms) {
+ throw new Exception(
+ pht(
+ 'Subtype configuration is invalid: subtype with key "%s" '.
+ 'specifies both child subtypes and child forms. Specify one '.
+ 'or the other, but not both.'));
+ }
+ }
}
if (!isset($map[self::SUBTYPE_DEFAULT])) {
throw new Exception(
pht(
'Subtype configuration is invalid: there is no subtype defined '.
'with key "%s". This subtype is required and must be defined.',
self::SUBTYPE_DEFAULT));
}
}
public static function newSubtypeMap(array $config) {
$map = array();
foreach ($config as $entry) {
$key = $entry['key'];
$name = $entry['name'];
$tag_text = idx($entry, 'tag');
if ($tag_text === null) {
if ($key != self::SUBTYPE_DEFAULT) {
$tag_text = phutil_utf8_strtoupper($name);
}
}
$color = idx($entry, 'color', 'blue');
$icon = idx($entry, 'icon', 'fa-drivers-license-o');
$subtype = id(new self())
->setKey($key)
->setName($name)
->setTagText($tag_text)
->setIcon($icon);
if ($color) {
$subtype->setColor($color);
}
+ $children = idx($entry, 'children', array());
+ $child_subtypes = idx($children, 'subtypes');
+ $child_forms = idx($children, 'forms');
+
+ if ($child_subtypes) {
+ $subtype->setChildSubtypes($child_subtypes);
+ }
+
+ if ($child_forms) {
+ $subtype->setChildFormIdentifiers($child_forms);
+ }
+
$map[$key] = $subtype;
}
return new PhabricatorEditEngineSubtypeMap($map);
}
}
diff --git a/src/applications/transactions/editengine/PhabricatorEditEngineSubtypeMap.php b/src/applications/transactions/editengine/PhabricatorEditEngineSubtypeMap.php
index c76911dbc3..638b665184 100644
--- a/src/applications/transactions/editengine/PhabricatorEditEngineSubtypeMap.php
+++ b/src/applications/transactions/editengine/PhabricatorEditEngineSubtypeMap.php
@@ -1,85 +1,83 @@
<?php
final class PhabricatorEditEngineSubtypeMap
extends Phobject {
private $subtypes;
public function __construct(array $subtypes) {
assert_instances_of($subtypes, 'PhabricatorEditEngineSubtype');
$this->subtypes = $subtypes;
}
public function getDisplayMap() {
return mpull($this->subtypes, 'getName');
}
public function getCount() {
return count($this->subtypes);
}
public function isValidSubtype($subtype_key) {
return isset($this->subtypes[$subtype_key]);
}
public function getSubtypes() {
return $this->subtypes;
}
public function getSubtype($subtype_key) {
if (!$this->isValidSubtype($subtype_key)) {
throw new Exception(
pht(
'Subtype key "%s" does not identify a valid subtype.',
$subtype_key));
}
return $this->subtypes[$subtype_key];
}
public function getCreateFormsForSubtype(
PhabricatorEditEngine $edit_engine,
PhabricatorEditEngineSubtypeInterface $object) {
$subtype_key = $object->getEditEngineSubtype();
$subtype = $this->getSubtype($subtype_key);
- // TODO: Allow subtype configuration to specify that children should be
- // created from particular forms or subtypes.
- $select_ids = array();
- $select_subtypes = array();
+ $select_identifiers = $subtype->getChildFormIdentifiers();
+ $select_subtypes = $subtype->getChildSubtypes();
$query = $edit_engine->newConfigurationQuery()
->withIsDisabled(false);
- if ($select_ids) {
- $query->withIDs($select_ids);
+ if ($select_identifiers) {
+ $query->withIdentifiers($select_identifiers);
} else {
// If we're selecting by subtype rather than selecting specific forms,
// only select create forms.
$query->withIsDefault(true);
if ($select_subtypes) {
$query->withSubtypes($select_subtypes);
} else {
$query->withSubtypes(array($subtype_key));
}
}
$forms = $query->execute();
$forms = mpull($forms, null, 'getIdentifier');
// If we're selecting by ID, respect the order specified in the
// constraint. Otherwise, use the create form sort order.
- if ($select_ids) {
- $forms = array_select_keys($forms, $select_ids) + $forms;
+ if ($select_identifiers) {
+ $forms = array_select_keys($forms, $select_identifiers) + $forms;
} else {
$forms = msort($forms, 'getCreateSortKey');
}
return $forms;
}
}
diff --git a/src/applications/transactions/query/PhabricatorEditEngineConfigurationSearchEngine.php b/src/applications/transactions/query/PhabricatorEditEngineConfigurationSearchEngine.php
index 52d48f528b..694b4c48b6 100644
--- a/src/applications/transactions/query/PhabricatorEditEngineConfigurationSearchEngine.php
+++ b/src/applications/transactions/query/PhabricatorEditEngineConfigurationSearchEngine.php
@@ -1,148 +1,165 @@
<?php
final class PhabricatorEditEngineConfigurationSearchEngine
extends PhabricatorApplicationSearchEngine {
private $engineKey;
public function setEngineKey($engine_key) {
$this->engineKey = $engine_key;
return $this;
}
public function getEngineKey() {
return $this->engineKey;
}
public function canUseInPanelContext() {
return false;
}
public function getResultTypeDescription() {
return pht('Forms');
}
public function getApplicationClassName() {
return 'PhabricatorTransactionsApplication';
}
public function newQuery() {
return id(new PhabricatorEditEngineConfigurationQuery())
->withEngineKeys(array($this->getEngineKey()));
}
protected function buildQueryFromParameters(array $map) {
$query = $this->newQuery();
$is_create = $map['isCreate'];
if ($is_create !== null) {
$query->withIsDefault($is_create);
}
$is_edit = $map['isEdit'];
if ($is_edit !== null) {
$query->withIsEdit($is_edit);
}
return $query;
}
protected function buildCustomSearchFields() {
return array(
id(new PhabricatorSearchThreeStateField())
->setLabel(pht('Create'))
->setKey('isCreate')
->setOptions(
pht('Show All'),
pht('Hide Create Forms'),
pht('Show Only Create Forms')),
id(new PhabricatorSearchThreeStateField())
->setLabel(pht('Edit'))
->setKey('isEdit')
->setOptions(
pht('Show All'),
pht('Hide Edit Forms'),
pht('Show Only Edit Forms')),
);
}
protected function getDefaultFieldOrder() {
return array();
}
protected function getURI($path) {
return '/transactions/editengine/'.$this->getEngineKey().'/'.$path;
}
protected function getBuiltinQueryNames() {
$names = array(
'all' => pht('All Forms'),
'create' => pht('Create Forms'),
'modify' => pht('Edit Forms'),
);
return $names;
}
public function buildSavedQueryFromBuiltin($query_key) {
$query = $this->newSavedQuery();
$query->setQueryKey($query_key);
switch ($query_key) {
case 'all':
return $query;
case 'create':
return $query->setParameter('isCreate', true);
case 'modify':
return $query->setParameter('isEdit', true);
}
return parent::buildSavedQueryFromBuiltin($query_key);
}
protected function renderResultList(
array $configs,
PhabricatorSavedQuery $query,
array $handles) {
assert_instances_of($configs, 'PhabricatorEditEngineConfiguration');
$viewer = $this->requireViewer();
$engine_key = $this->getEngineKey();
$list = id(new PHUIObjectItemListView())
->setUser($viewer);
foreach ($configs as $config) {
$item = id(new PHUIObjectItemView())
->setHeader($config->getDisplayName());
$id = $config->getID();
- if ($id) {
- $item->addIcon('fa-file-text-o bluegrey', pht('Form %d', $id));
- $key = $id;
- } else {
- $item->addIcon('fa-file-text bluegrey', pht('Builtin'));
- $key = $config->getBuiltinKey();
- }
- $item->setHref("/transactions/editengine/{$engine_key}/view/{$key}/");
if ($config->getIsDefault()) {
$item->addAttribute(pht('Default Create Form'));
}
if ($config->getIsEdit()) {
$item->addAttribute(pht('Edit Form'));
}
if ($config->getIsDisabled()) {
$item->setDisabled(true);
$item->setStatusIcon('fa-ban grey', pht('Disabled'));
} else {
$item->setStatusIcon('fa-file-text-o green', pht('Enabled'));
}
+ $subtype_key = $config->getSubtype();
+ if ($subtype_key !== PhabricatorEditEngineSubtype::SUBTYPE_DEFAULT) {
+ $engine = $config->getEngine();
+ if ($engine->supportsSubtypes()) {
+ $map = $engine->newSubtypeMap();
+ if ($map->isValidSubtype($subtype_key)) {
+ $subtype = $map->getSubtype($subtype_key);
+
+ $icon = $subtype->getIcon();
+ $color = $subtype->getColor();
+
+ $item->addIcon("{$icon} {$color}", $subtype->getName());
+ }
+ }
+ }
+
+ if ($id) {
+ $item->setObjectName(pht('Form %d', $id));
+ $key = $id;
+ } else {
+ $item->addIcon('fa-file-text bluegrey', pht('Builtin'));
+ $key = $config->getBuiltinKey();
+ }
+ $item->setHref("/transactions/editengine/{$engine_key}/view/{$key}/");
+
$list->addItem($item);
}
return id(new PhabricatorApplicationSearchResultView())
->setObjectList($list);
}
}

File Metadata

Mime Type
text/x-diff
Expires
Thu, Aug 14, 9:31 PM (2 d, 20 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
201906
Default Alt Text
(31 KB)

Event Timeline