Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/maniphest/config/PhabricatorManiphestConfigOptions.php
12256 views
1
<?php
2
3
final class PhabricatorManiphestConfigOptions
4
extends PhabricatorApplicationConfigOptions {
5
6
public function getName() {
7
return pht('Maniphest');
8
}
9
10
public function getDescription() {
11
return pht('Configure Maniphest.');
12
}
13
14
public function getIcon() {
15
return 'fa-anchor';
16
}
17
18
public function getGroup() {
19
return 'apps';
20
}
21
22
public function getOptions() {
23
$priority_type = 'maniphest.priorities';
24
$priority_defaults = array(
25
100 => array(
26
'name' => pht('Unbreak Now!'),
27
'keywords' => array('unbreak'),
28
'short' => pht('Unbreak!'),
29
'color' => 'pink',
30
),
31
90 => array(
32
'name' => pht('Needs Triage'),
33
'keywords' => array('triage'),
34
'short' => pht('Triage'),
35
'color' => 'violet',
36
),
37
80 => array(
38
'name' => pht('High'),
39
'keywords' => array('high'),
40
'short' => pht('High'),
41
'color' => 'red',
42
),
43
50 => array(
44
'name' => pht('Normal'),
45
'keywords' => array('normal'),
46
'short' => pht('Normal'),
47
'color' => 'orange',
48
),
49
25 => array(
50
'name' => pht('Low'),
51
'keywords' => array('low'),
52
'short' => pht('Low'),
53
'color' => 'yellow',
54
),
55
0 => array(
56
'name' => pht('Wishlist'),
57
'keywords' => array('wish', 'wishlist'),
58
'short' => pht('Wish'),
59
'color' => 'sky',
60
),
61
);
62
63
$status_type = 'maniphest.statuses';
64
$status_defaults = array(
65
'open' => array(
66
'name' => pht('Open'),
67
'special' => ManiphestTaskStatus::SPECIAL_DEFAULT,
68
'prefixes' => array(
69
'open',
70
'opens',
71
'reopen',
72
'reopens',
73
),
74
),
75
'resolved' => array(
76
'name' => pht('Resolved'),
77
'name.full' => pht('Closed, Resolved'),
78
'closed' => true,
79
'special' => ManiphestTaskStatus::SPECIAL_CLOSED,
80
'transaction.icon' => 'fa-check-circle',
81
'prefixes' => array(
82
'closed',
83
'closes',
84
'close',
85
'fix',
86
'fixes',
87
'fixed',
88
'resolve',
89
'resolves',
90
'resolved',
91
),
92
'suffixes' => array(
93
'as resolved',
94
'as fixed',
95
),
96
'keywords' => array('closed', 'fixed', 'resolved'),
97
),
98
'wontfix' => array(
99
'name' => pht('Wontfix'),
100
'name.full' => pht('Closed, Wontfix'),
101
'transaction.icon' => 'fa-ban',
102
'closed' => true,
103
'prefixes' => array(
104
'wontfix',
105
'wontfixes',
106
'wontfixed',
107
),
108
'suffixes' => array(
109
'as wontfix',
110
),
111
),
112
'invalid' => array(
113
'name' => pht('Invalid'),
114
'name.full' => pht('Closed, Invalid'),
115
'transaction.icon' => 'fa-minus-circle',
116
'closed' => true,
117
'claim' => false,
118
'prefixes' => array(
119
'invalidate',
120
'invalidates',
121
'invalidated',
122
),
123
'suffixes' => array(
124
'as invalid',
125
),
126
),
127
'duplicate' => array(
128
'name' => pht('Duplicate'),
129
'name.full' => pht('Closed, Duplicate'),
130
'transaction.icon' => 'fa-files-o',
131
'special' => ManiphestTaskStatus::SPECIAL_DUPLICATE,
132
'closed' => true,
133
'claim' => false,
134
),
135
'spite' => array(
136
'name' => pht('Spite'),
137
'name.full' => pht('Closed, Spite'),
138
'name.action' => pht('Spited'),
139
'transaction.icon' => 'fa-thumbs-o-down',
140
'silly' => true,
141
'closed' => true,
142
'prefixes' => array(
143
'spite',
144
'spites',
145
'spited',
146
),
147
'suffixes' => array(
148
'out of spite',
149
'as spite',
150
),
151
),
152
);
153
154
$status_description = $this->deformat(pht(<<<EOTEXT
155
Allows you to edit, add, or remove the task statuses available in Maniphest,
156
like "Open", "Resolved" and "Invalid". The configuration should contain a map
157
of status constants to status specifications (see defaults below for examples).
158
159
The constant for each status should be 1-12 characters long and contain only
160
lowercase letters and digits. Valid examples are "open", "closed", and
161
"invalid". Users will not normally see these values.
162
163
The keys you can provide in a specification are:
164
165
- `name` //Required string.// Name of the status, like "Invalid".
166
- `name.full` //Optional string.// Longer name, like "Closed, Invalid". This
167
appears on the task detail view in the header.
168
- `name.action` //Optional string.// Action name for email subjects, like
169
"Marked Invalid".
170
- `closed` //Optional bool.// Statuses are either "open" or "closed".
171
Specifying `true` here will mark the status as closed (like "Resolved" or
172
"Invalid"). By default, statuses are open.
173
- `special` //Optional string.// Mark this status as special. The special
174
statuses are:
175
- `default` This is the default status for newly created tasks. You must
176
designate one status as default, and it must be an open status.
177
- `closed` This is the default status for closed tasks (for example, tasks
178
closed via the "!close" action in email or via the quick close button in
179
Maniphest). You must designate one status as the default closed status,
180
and it must be a closed status.
181
- `duplicate` This is the status used when tasks are merged into one
182
another as duplicates. You must designate one status for duplicates,
183
and it must be a closed status.
184
- `transaction.icon` //Optional string.// Allows you to choose a different
185
icon to use for this status when showing status changes in the transaction
186
log. Please see UIExamples, Icons and Images for a list.
187
- `transaction.color` //Optional string.// Allows you to choose a different
188
color to use for this status when showing status changes in the transaction
189
log.
190
- `silly` //Optional bool.// Marks this status as silly, and thus wholly
191
inappropriate for use by serious businesses.
192
- `prefixes` //Optional list<string>.// Allows you to specify a list of
193
text prefixes which will trigger a task transition into this status
194
when mentioned in a commit message. For example, providing "closes" here
195
will allow users to move tasks to this status by writing `Closes T123` in
196
commit messages.
197
- `suffixes` //Optional list<string>.// Allows you to specify a list of
198
text suffixes which will trigger a task transition into this status
199
when mentioned in a commit message, after a valid prefix. For example,
200
providing "as invalid" here will allow users to move tasks
201
to this status by writing `Closes T123 as invalid`, even if another status
202
is selected by the "Closes" prefix.
203
- `keywords` //Optional list<string>.// Allows you to specify a list
204
of keywords which can be used with `!status` commands in email to select
205
this status.
206
- `disabled` //Optional bool.// Marks this status as no longer in use so
207
tasks can not be created or edited to have this status. Existing tasks with
208
this status will not be affected, but you can batch edit them or let them
209
die out on their own.
210
- `claim` //Optional bool.// By default, closing an unassigned task claims
211
it. You can set this to `false` to disable this behavior for a particular
212
status.
213
- `locked` //Optional string.// Lock tasks in this status. Specify "comments"
214
to lock comments (users who can edit the task may override this lock).
215
Specify "edits" to prevent anyone except the task owner from making edits.
216
- `mfa` //Optional bool.// Require all edits to this task to be signed with
217
multi-factor authentication.
218
219
Statuses will appear in the UI in the order specified. Note the status marked
220
`special` as `duplicate` is not settable directly and will not appear in UI
221
elements, and that any status marked `silly` does not appear if the software
222
is configured with `phabricator.serious-business` set to true.
223
224
Examining the default configuration and examples below will probably be helpful
225
in understanding these options.
226
227
EOTEXT
228
));
229
230
$status_example = array(
231
'open' => array(
232
'name' => pht('Open'),
233
'special' => 'default',
234
),
235
'closed' => array(
236
'name' => pht('Closed'),
237
'special' => 'closed',
238
'closed' => true,
239
),
240
'duplicate' => array(
241
'name' => pht('Duplicate'),
242
'special' => 'duplicate',
243
'closed' => true,
244
),
245
);
246
247
$json = new PhutilJSON();
248
$status_example = $json->encodeFormatted($status_example);
249
250
// This is intentionally blank for now, until we can move more Maniphest
251
// logic to custom fields.
252
$default_fields = array();
253
254
foreach ($default_fields as $key => $enabled) {
255
$default_fields[$key] = array(
256
'disabled' => !$enabled,
257
);
258
}
259
260
$custom_field_type = 'custom:PhabricatorCustomFieldConfigOptionType';
261
262
$fields_example = array(
263
'mycompany.estimated-hours' => array(
264
'name' => pht('Estimated Hours'),
265
'type' => 'int',
266
'caption' => pht('Estimated number of hours this will take.'),
267
),
268
);
269
$fields_json = id(new PhutilJSON())->encodeFormatted($fields_example);
270
271
$points_type = 'maniphest.points';
272
273
$points_example_1 = array(
274
'enabled' => true,
275
'label' => pht('Story Points'),
276
'action' => pht('Change Story Points'),
277
);
278
$points_json_1 = id(new PhutilJSON())->encodeFormatted($points_example_1);
279
280
$points_example_2 = array(
281
'enabled' => true,
282
'label' => pht('Estimated Hours'),
283
'action' => pht('Change Estimate'),
284
);
285
$points_json_2 = id(new PhutilJSON())->encodeFormatted($points_example_2);
286
287
$points_description = $this->deformat(pht(<<<EOTEXT
288
Activates a points field on tasks. You can use points for estimation or
289
planning. If configured, points will appear on workboards.
290
291
To activate points, set this value to a map with these keys:
292
293
- `enabled` //Optional bool.// Use `true` to enable points, or
294
`false` to disable them.
295
- `label` //Optional string.// Label for points, like "Story Points" or
296
"Estimated Hours". If omitted, points will be called "Points".
297
- `action` //Optional string.// Label for the action which changes points
298
in Maniphest, like "Change Estimate". If omitted, the action will
299
be called "Change Points".
300
301
See the example below for a starting point.
302
EOTEXT
303
));
304
305
$subtype_type = 'maniphest.subtypes';
306
$subtype_default_key = PhabricatorEditEngineSubtype::SUBTYPE_DEFAULT;
307
$subtype_example = array(
308
array(
309
'key' => $subtype_default_key,
310
'name' => pht('Task'),
311
),
312
array(
313
'key' => 'bug',
314
'name' => pht('Bug'),
315
),
316
array(
317
'key' => 'feature',
318
'name' => pht('Feature Request'),
319
),
320
);
321
$subtype_example = id(new PhutilJSON())->encodeAsList($subtype_example);
322
323
$subtype_default = array(
324
array(
325
'key' => $subtype_default_key,
326
'name' => pht('Task'),
327
),
328
);
329
330
$subtype_description = $this->deformat(pht(<<<EOTEXT
331
Allows you to define task subtypes. Subtypes let you hide fields you don't
332
need to simplify the workflows for editing tasks.
333
334
To define subtypes, provide a list of subtypes. Each subtype should be a
335
dictionary with these keys:
336
337
- `key` //Required string.// Internal identifier for the subtype, like
338
"task", "feature", or "bug".
339
- `name` //Required string.// Human-readable name for this subtype, like
340
"Task", "Feature Request" or "Bug Report".
341
- `tag` //Optional string.// Tag text for this subtype.
342
- `color` //Optional string.// Display color for this subtype.
343
- `icon` //Optional string.// Icon for the subtype.
344
- `children` //Optional map.// Configure options shown to the user when
345
they "Create Subtask". See below.
346
- `fields` //Optional map.// Configure field behaviors. See below.
347
- `mutations` //Optional list.// Configure which subtypes this subtype
348
can easily be converted to by using the "Change Subtype" action. See below.
349
350
Each subtype must have a unique key, and you must define a subtype with
351
the key "%s", which is used as a default subtype.
352
353
The tag text (`tag`) is used to set the text shown in the subtype tag on list
354
views and workboards. If you do not configure it, the default subtype will have
355
no subtype tag and other subtypes will use their name as tag text.
356
357
The `children` key allows you to configure which options are presented to the
358
user when they "Create Subtask" from a task of this subtype. You can specify
359
these keys:
360
361
- `subtypes`: //Optional list<string>.// Show users creation forms for these
362
task subtypes.
363
- `forms`: //Optional list<string|int>.// Show users these specific forms,
364
in order.
365
366
If you don't specify either constraint, users will be shown creation forms
367
for the same subtype.
368
369
For example, if you have a "quest" subtype and do not configure `children`,
370
users who click "Create Subtask" will be presented with all create forms for
371
"quest" tasks.
372
373
If you want to present them with forms for a different task subtype or set of
374
subtypes instead, use `subtypes`:
375
376
```
377
{
378
...
379
"children": {
380
"subtypes": ["objective", "boss", "reward"]
381
}
382
...
383
}
384
```
385
386
If you want to present them with specific forms, use `forms` and specify form
387
IDs:
388
389
```
390
{
391
...
392
"children": {
393
"forms": [12, 16]
394
}
395
...
396
}
397
```
398
399
When specifying forms by ID explicitly, the order you specify the forms in will
400
be used when presenting options to the user.
401
402
If only one option would be presented, the user will be taken directly to the
403
appropriate form instead of being prompted to choose a form.
404
405
The `fields` key can configure the behavior of custom fields on specific
406
task subtypes. For example:
407
408
```
409
{
410
...
411
"fields": {
412
"custom.some-field": {
413
"disabled": true
414
}
415
}
416
...
417
}
418
```
419
420
Each field supports these options:
421
422
- `disabled` //Optional bool.// Allows you to disable fields on certain
423
subtypes.
424
- `name` //Optional string.// Custom name of this field for the subtype.
425
426
427
The `mutations` key allows you to control the behavior of the "Change Subtype"
428
action above the comment area. By default, this action allows users to change
429
the task subtype into any other subtype.
430
431
If you'd prefer to make it more difficult to change subtypes or offer only a
432
subset of subtypes, you can specify the list of subtypes that "Change Subtypes"
433
offers. For example, if you have several similar subtypes and want to allow
434
tasks to be converted between them but not easily converted to other types,
435
you can make the "Change Subtypes" control show only these options like this:
436
437
```
438
{
439
...
440
"mutations": ["bug", "issue", "defect"]
441
...
442
}
443
```
444
445
If you specify an empty list, the "Change Subtypes" action will be completely
446
hidden.
447
448
This mutation list is advisory and only configures the UI. Tasks may still be
449
converted across subtypes freely by using the Bulk Editor or API.
450
451
EOTEXT
452
,
453
$subtype_default_key));
454
455
$priorities_description = $this->deformat(pht(<<<EOTEXT
456
Allows you to edit or override the default priorities available in Maniphest,
457
like "High", "Normal" and "Low". The configuration should contain a map of
458
numeric priority values (where larger numbers correspond to higher priorities)
459
to priority specifications (see defaults below for examples).
460
461
The keys you can define for a priority are:
462
463
- `name` //Required string.// Name of the priority.
464
- `keywords` //Required list<string>.// List of unique keywords which identify
465
this priority, like "high" or "low". Each priority must have at least one
466
keyword and two priorities may not share the same keyword.
467
- `short` //Optional string.// Alternate shorter name, used in UIs where
468
there is less space available.
469
- `color` //Optional string.// Color for this priority, like "red" or
470
"blue".
471
- `disabled` //Optional bool.// Set to true to prevent users from choosing
472
this priority when creating or editing tasks. Existing tasks will not be
473
affected, and can be batch edited to a different priority or left to
474
eventually die out.
475
476
You can choose the default priority for newly created tasks with
477
"maniphest.default-priority".
478
EOTEXT
479
));
480
481
$fields_description = $this->deformat(pht(<<<EOTEXT
482
List of custom fields for Maniphest tasks.
483
484
For details on adding custom fields to Maniphest, see [[ %s | %s ]] in the
485
documentation.
486
EOTEXT
487
,
488
PhabricatorEnv::getDoclink('Configuring Custom Fields'),
489
pht('Configuring Custom Fields')));
490
491
return array(
492
$this->newOption('maniphest.custom-field-definitions', 'wild', array())
493
->setSummary(pht('Custom Maniphest fields.'))
494
->setDescription($fields_description)
495
->addExample($fields_json, pht('Valid setting')),
496
$this->newOption('maniphest.fields', $custom_field_type, $default_fields)
497
->setCustomData(id(new ManiphestTask())->getCustomFieldBaseClass())
498
->setDescription(pht('Select and reorder task fields.')),
499
$this->newOption(
500
'maniphest.priorities',
501
$priority_type,
502
$priority_defaults)
503
->setSummary(pht('Configure Maniphest priority names.'))
504
->setDescription($priorities_description),
505
$this->newOption('maniphest.statuses', $status_type, $status_defaults)
506
->setSummary(pht('Configure Maniphest task statuses.'))
507
->setDescription($status_description)
508
->addExample($status_example, pht('Minimal Valid Config')),
509
$this->newOption('maniphest.default-priority', 'int', 90)
510
->setSummary(pht('Default task priority for create flows.'))
511
->setDescription(
512
pht(
513
'Choose a default priority for newly created tasks. You can '.
514
'review and adjust available priorities by using the '.
515
'%s configuration option. The default value (`90`) '.
516
'corresponds to the default "Needs Triage" priority.',
517
'maniphest.priorities')),
518
$this->newOption('maniphest.points', $points_type, array())
519
->setSummary(pht('Configure point values for tasks.'))
520
->setDescription($points_description)
521
->addExample($points_json_1, pht('Points Config'))
522
->addExample($points_json_2, pht('Hours Config')),
523
$this->newOption('maniphest.subtypes', $subtype_type, $subtype_default)
524
->setSummary(pht('Define task subtypes.'))
525
->setDescription($subtype_description)
526
->addExample($subtype_example, pht('Simple Subtypes')),
527
);
528
}
529
530
}
531
532