Summary: Makes this more consistent. Also clean up spacing. Ref T9414
Test Plan: Archive/Activate Paste, Edit Paste
Reviewers: epriestley
Reviewed By: epriestley
Subscribers: Korvin
Maniphest Tasks: T9414
Differential Revision: https://secure.phabricator.com/D14724
Summary: Ref T9908. Move all the "pro" stuff into the old locations.
Test Plan: Created/edited tasks, looked at URIs, saw non-pro ones. Grepped for `editpro`.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T9908
Differential Revision: https://secure.phabricator.com/D14717
Summary:
Ref T9908. No more callsites. Also:
- Phurl a couple of documentation URIs.
- Get rid of "task:" in the global search since it doesn't really make sense anymore.
Test Plan: `grep`, edited/created tasks.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T9908
Differential Revision: https://secure.phabricator.com/D14716
Summary: Ref T9908. This fixes "Create Subtask" so it works with the new stuff. Mostly straightforward.
Test Plan: Created some subtasks.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T9908
Differential Revision: https://secure.phabricator.com/D14706
Summary:
Ref T9908. This removes the "Create Another Empty Task", "Create A Similar Task" and "Create Another Subtask of Same Parent Task" workflow callouts on the task detail page, which are actions that show up after creating a task or creating a subtask.
- I think "Create Empty" isn't relevant now that we have "Create Task" nearby and the quick create menu?
- I'm not sure if "Create Similar" is worth keeping. If we do want to retain it, I'd maybe like to find a way to do it generically.
- I'm likewise not sure if "Create another subtask" is worth keeping.
Overall, these actions are weird/unusual and I'm not sure how valuable they are. I'm open to keeping "Similar" and/or "Subtask" but I'd like to verify that they're still valuable and make sure we have a reasonable design for them if we retain them.
For example, if we want to retain "Similar", maybe a better approach is just to add "Create Similar Object" to every action menu (which is now possible for EditEngine applications)? There's at least some interest in "Create Similar Repository" in Diffusion.
Also removes a very very old piece of "attached files" code.
Test Plan: Created and viewed some tasks.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T9908
Differential Revision: https://secure.phabricator.com/D14705
Summary:
Ref T9132. Ref T9908. Puts reordering UI in place:
- For create forms, this just lets you pick a UI display order other than alphabetical. Seems nice to have.
- For edit forms, this lets you create a hierarchy of advanced-to-basic forms and give them different visibility policies, if you want.
Test Plan:
{F1017842}
- Verified that "Edit Thing" now takes me to the highest-ranked edit form.
- Verified that create menu and quick create menu reflect application order.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T9132, T9908
Differential Revision: https://secure.phabricator.com/D14704
Summary:
Ref T9132. Ref T9908. This attempts to move us forward on answering this question:
> Which form gets used when a user clicks "Edit Task"?
One answer is "the same form that was used to create the task". There are several problems with that:
- The form might not exist anymore.
- The user might not have permission to see it.
- Some of the fields might be hidden, essentially preventing them from being edited.
- We have to store the value somewhere and old tasks won't have a value.
- Any instructions on the form probably don't apply to edits.
One answer is "force the default, full form". That's not as problematic, but it means we have no ability to create limited access users who see fewer fields.
The answer in this diff is:
- Forms can be marked as "edit forms".
- We take the user to the first edit form they have permission to see, from a master list.
This allows you to create several forms like:
- Advanced Edit Form (say, all fields -- visible to administrators).
- Basic Edit Form (say, no policies -- visible to trusted users).
- Noob Edit Form (say, no policies, priorities, or status -- visible to everyone).
Then you can give everyone access to "noob", some people access to "basic", and a few people access to "advanced".
This might only be part of the answer. In particular, you can still //use// any edit form you can see, so we could do these things in the future:
- Give you an option to switch to a different form if you want.
- Save the form the task was created with, and use that form by default.
If we do pursue those, we can fall back to this behavior if there's a problem with them (e.g., original form doesn't exist or wasn't recorded).
There's also no "reorder" UI yet, that'll be coming in the next diff.
I'm also going to try to probably make the "create" and "edit" stuff a little more consistent / less weird in a bit.
Test Plan: Marked various forms as edit forms or not edit forms, made edits, hit permissions errors, etc.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T9132, T9908
Differential Revision: https://secure.phabricator.com/D14702
Summary: Moves New Post and Move Post to be separate Controllers with Dialogs. Ref T9897
Test Plan: Move a post to a new blog, see message and see post. Click New Post, get dialog, pick blog, edit new post.
Reviewers: epriestley
Reviewed By: epriestley
Subscribers: Korvin
Maniphest Tasks: T9897
Differential Revision: https://secure.phabricator.com/D14698
Summary: Fixes T6132. We currently allow invalid configuration here; validate it.
Test Plan: Tried to save invalid config (negative priorities, string priorities, etc).
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T6132
Differential Revision: https://secure.phabricator.com/D14689
Summary: Fixes T5788. We already have this as a pre-commit field, add it as a post-commit field too.
Test Plan: Ran this rule on a merge commit. Also ran it on a non-merge commit. Both got the correct value.
Reviewers: avivey, chad
Reviewed By: avivey, chad
Subscribers: avivey
Maniphest Tasks: T5788
Differential Revision: https://secure.phabricator.com/D14685
Summary:
Ref T7848. This is a companion to "Change status to: ...".
(I'm pretty sure the only reason I didn't originally write these was the tokenizer bug in D14682, I just forgot about it).
This is basically a copy/paste of the "status" action.
Test Plan:
- Wrote a rule to change task priorities.
- Edited a task.
- Saw rule fire properly.
- Tokens also stick around correctly.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T7848
Differential Revision: https://secure.phabricator.com/D14683
Summary:
Ref T7848. This patch is incomplete and has the following issues:
- Multiple statuses can be entered on the edit rule page (only the first one is used).
- Statuses are not rendered correctly when re-editing a rule.
Test Plan: Applied to our local phab instance and verified it works with our task workflow.
Reviewers: #blessed_reviewers, epriestley
Reviewed By: #blessed_reviewers, epriestley
Subscribers: joshuaspence, revi, epriestley, jsmith
Maniphest Tasks: T7848
Differential Revision: https://secure.phabricator.com/D14359
Summary:
Ref T9132. This is kind of a mess because the tokenizer rewrite left rendering tokenizers in Javascript a little rough. This causes bugs like icons not showing up on tokens in the "Policy" dialog, which there's a task for somewhere I think.
I think I've fixed it enough that the beahavior is now correct (i.e., icons show up properly), but some of the code is a bit iffy. I'll eventually clean this up properly, but it's fairly well contained for now.
Test Plan:
- Reassigned a task.
- Put a task up for grabs.
- No reassign on closed tasks.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T9132
Differential Revision: https://secure.phabricator.com/D14669
Summary:
Ref T9132. Like D14659, I'll hold this until after the cut.
This swaps commenting in Maniphest over to EditEngine / stackable actions. New code doesn't have parity yet, although none of the things we're missing should technically be //strictly mandatory//. There's a list inline. I'll restore these in the next diffs.
Briefly -- comments, subscribers and projects work. Status, owners and priority do not yet.
Test Plan:
- Made comments and added subscribers and projects.
- Read through the old code to look for missing features and tried to document them all.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T9132
Differential Revision: https://secure.phabricator.com/D14663
Summary:
Ref T9132. I'm going hold this until after the release cut since it isn't going to land completely smoothly, but I think I can prep it today/tomorrow and hopefully get it close enough to working to put in HEAD on Saturday after the push.
This adds the basics: new EditEngine, new EditController, and new `maniphest.edit` API endpoint.
I put the new stuff at `editpro/` for now until it works a little better.
Some notes on stuff this is dropping/changing/not-working-yet:
- Preview for the description. I'd rather solve this by putting a "Preview" button on every Remarkup area if we want to retain it. Particularly, it does not generalize to adding custom remarkup fields in its current form. See also T3967.
- Per-field policies are no longer enforced. They were never truly enforced anyway (for example, any user who can edit a task has always been able to edit every field via Conduit or email actions or Herald, where Herald supports things), and only really served as a hint to users. I think we can obsolete this by having installs hide/lock these fields instead. This is a desirable outcome for me, since I don't like retaining these policies and the idea of truly enforcing them properly is worrisome. These were originally added for Uber as an onboarding sort of thing. I'll prepare users for this in greater detail in the documentation.
- Couple of minor bugs with ordering / defaults / only-one-owner-allowed in this diff that I'll clean up in future diffs before this stuff lands.
- I don't have a concrete plan on "Create Similar Task" / "Clone" yet (do you have thoughts? Is this worth trying to do in every application?). I'll probably just mostly mimic the current behavior.
Test Plan: I'll vet this more thoroughly in followups, just banged around some tasks for now and created/edited via the API.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T9132
Differential Revision: https://secure.phabricator.com/D14659
Summary: Make this function re-usable in other views. Ref T9897
Test Plan: View a blog, see the same information
Reviewers: epriestley
Reviewed By: epriestley
Subscribers: Korvin
Maniphest Tasks: T9897
Differential Revision: https://secure.phabricator.com/D14658
Summary:
Ref T9132. Fixes T5031. This approximately implements the plan described in T5031#67988:
When we recieve a preview request, don't write a draft if the form is from a version of the object before the last update the viewer made.
This should fix the race-related (?) zombie draft comments that sometimes show up.
I just added a new object for this stuff to make it easier to do stacked actions (or whatever we end up with) a little later, since I needed to do some schema adjustments anyway.
Test Plan:
- Typed some text.
- Reloaded page.
- Draft stayed there.
- Tried real hard to get it to ghost by submitting stuff in multiple windows and typing a lot and couldn't, although I didn't bother specifically narrowing down the race condition.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T5031, T9132
Differential Revision: https://secure.phabricator.com/D14640
Summary:
Ref T9132. This just replaces the "Add Comment" form in Paste with a generic flow in EditEngine.
No actual field-awareness or action stacking or anything quite yet, but that will come in a bit. This mildly regresses drafts (which don't seem like a big deal for Pastes). I'll hook those up again in the next diff, but I want to build them in a better way that will work with multiple actions in a generic way, and solve T5031.
Big practical advantage here is that applications don't need copy/pasted preview controllers.
Test Plan:
- Saw previews.
- Added comments.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T9132
Differential Revision: https://secure.phabricator.com/D14637
Summary: This adds a separate Publish/Unpublish step aside from Preview in Phame Posts. This allows easier access to publishing without previewing, though I left publish in tact on the preview page. Also cleaned up some minor transaction issues with mail.
Test Plan: New Post, Publish Post, Preview Post. Check mail logs. Get mail upon publish.
Reviewers: epriestley
Reviewed By: epriestley
Subscribers: Korvin
Differential Revision: https://secure.phabricator.com/D14642
Summary:
Ref T9132. This allows you to prefill custom fields with `?custom.x.y=value`, for most types of custom fields.
Dates (which are substantially more complicated) aren't supported. I'll just do those once the dust settles. Other types should work, I think.
Test Plan:
- Verified custom fields appear on "HTTP Parameters" help UI.
- Used `?x=y` to prefill custom fields on edit form.
- Performed various normal edits.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T9132
Differential Revision: https://secure.phabricator.com/D14634
Summary:
Ref T9132. This isn't perfect, but doesn't break any existing functionality. This stuff works:
- Editing values.
- Reordering fields.
- All builtin field tyepes.
This stuff may not work yet:
- Assigning custom field defaults.
- Some conduit stuff.
- Fully custom fields?
- Locking/hiding fields? Didn't actually test this one.
I'll keep chipping away at that stuff. In some cases, it may be easier to convert all the CustomField apps first, although Differential might be a fair bit of work.
Test Plan:
Created a bunch of custom fields of every avialable type and edited them.
{F1008789}
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T9132
Differential Revision: https://secure.phabricator.com/D14617
Summary:
Ref T9132. Paste is in fairly good shape so Owners is up next. Reasoning:
- One install wants API access for it.
- It's a simple application for getting CustomFields working with EditEngine.
This only does the EditEngine part, so CustomFields are no longer editable until I make that work. That will be up next, and I'll hold this until that's ready.
Test Plan:
- Created and edited packages via web UI.
- Created and edited package editing forms via web UI.
- Created and edited packages via Conduit.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T9132
Differential Revision: https://secure.phabricator.com/D14598
Summary: Sends `/phame/` to PhameHomeController, which is all published posts. Still some rough edges to work out for new posts, new blogs, but I think this is the right direction.
Test Plan:
go to Phame, see most recent posts, no drafts. click on find posts, see post list, click on find blogs, see blogs.
{F1008800}
Reviewers: epriestley
Reviewed By: epriestley
Subscribers: Korvin
Maniphest Tasks: T9742
Differential Revision: https://secure.phabricator.com/D14618
Summary: Ref T9132. I had some hacks in place for dealing with Edge/Subscribers stuff. Clean that up so it's structured a little better.
Test Plan:
- Edited subscribers and projects.
- Verified things still show up in Conduit.
- Made concurrent edits (added a project in one window, removed it in another window, got a clean result with a correct merge of the two edits).
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T9132
Differential Revision: https://secure.phabricator.com/D14601
Summary:
Ref T9132. Currently, EditEngine had some branchy-`instanceof` code like this:
```
if ($object instanceof Whatever) {
do_magic();
}
if ($object instanceof SomethingElse) {
do_other_magic();
}
```
...where `Whatever` and `SomethingElse` are first-party applications like ProjectsInterface and SubscribersInterface.
This kind of code is generally bad because third-parties can't add new stuff, and it suggest something is kind of hacky in its architecture. Ideally, we would eventually get rid of almost all of this.
T9789 is a similar discussion of this for the next layer down (`TransactionEditor`) and plans to get rid of branchy-instanceofs there too.
Since I'm about to add more stuff here (for Custom Fields), split it out first so I'm not digging us any deeper than I already dug us.
Broadly, this allows third-party extensions to add fields to every EditEngine UI if they want, like we do for Policies, Subscribers, Projects and Comments today (and CustomFields soon).
Test Plan:
{F1007575}
- Observed that all fields still appear on the form and seem to work correctly.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T9132
Differential Revision: https://secure.phabricator.com/D14599
Summary: Creates a new PhameBlogView which is more of a blog landing page with the latest posts. Management has moved to PhameManageController with a new timeline.
Test Plan:
Edit Blog, Publish, Subscribe, view posts.
{F1008400}
Reviewers: epriestley
Reviewed By: epriestley
Subscribers: Korvin
Maniphest Tasks: T9360
Differential Revision: https://secure.phabricator.com/D14608
Summary:
Ref T9132.
Let configurations be enabled/disabled. This doesn't do much right now.
Let configurations be marked as default entries in the application "Create" menu. This makes them show up in the application in a dropdown, so you can replace the default form and/or provide several forms.
In Maniphest, we'll do this to provide a menu something like this:
- New Bug Report
- New Feature Request
- ADVANCED TASK CREATION!!11~ (only available for Community members)
Test Plan: {F1005679}
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T9132
Differential Revision: https://secure.phabricator.com/D14584
Summary: Will use these more in the upcoming unbeta design of PhameBlog, likely. Also curious how this works.
Test Plan: Add an image to a blog, remove an image from a blog.
Reviewers: epriestley
Reviewed By: epriestley
Subscribers: Korvin
Differential Revision: https://secure.phabricator.com/D14587
Summary: Allows Blogs and Posts to be destroyed. Fixes T9756
Test Plan: Test `bin/remove destroy POST` and `bin/remove destroy BLOG` to great success.
Reviewers: epriestley
Reviewed By: epriestley
Subscribers: Korvin
Maniphest Tasks: T9756
Differential Revision: https://secure.phabricator.com/D14586
Summary: Ref T9756, removes the ability to delete a PhamePost
Test Plan: See link removed, unpublish post, publish post, new post.
Reviewers: epriestley
Reviewed By: epriestley
Subscribers: Korvin
Maniphest Tasks: T9756
Differential Revision: https://secure.phabricator.com/D14581
Summary: Reuse PHUIMarkupPreviewView in Phame for consistency, less custom code. Also, doesn't work (JS issue).
Test Plan: New Post, Edit Post, Save Post
Reviewers: epriestley
Reviewed By: epriestley
Subscribers: Korvin
Differential Revision: https://secure.phabricator.com/D14552
Summary:
Ref T9132. This adds an automatic "Comments" field, like the Subscribers/Projects/Policy fields.
The primary goals here are:
- Allow users to make comments via Conduit.
- In the future, get stackable action support.
As a side effect, this also allows you to put comments on create forms. This is a little silly but seems fine, and may be relevant on edit forms (which I'm not 100% sure how I want to handle yet). I've just hidden them by default for now.
Test Plan:
{F976036}
{F976037}
{F976038}
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T9132
Differential Revision: https://secure.phabricator.com/D14515
Summary:
Ref T9132. Allows fields to be locked (shown, but not modifiable) and hidden (not shown).
In both cases, default values are still respected.
This lets you do things like create a form that generates objects with specific projects, policies, etc.
Test Plan:
- Set defaults.
- Locked and hid a bunch of fields.
- Created new objects using the resulting form.
{F975801}
{F975802}
{F975803}
{F975804}
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T9132
Differential Revision: https://secure.phabricator.com/D14509
Summary: Ref T9132. Allow form configurations to include defaults (like default projects, spaces, policies, etc).
Test Plan:
Defaulted "Language" to "Rainbow", plus other adjustments:
{F975746}
{F975747}
{F975748}
{F975749}
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T9132
Differential Revision: https://secure.phabricator.com/D14508
Summary:
Ref T9132. This just makes edited forms do //something//, albeit not anything very useful yet.
You can now edit a form and:
- Retitle it;
- add a preamble (instructions on top of the form); and
- reorder the form's fields.
Test Plan:
{F974632}
{F974633}
{F974634}
{F974635}
{F974636}
Reviewers: chad
Reviewed By: chad
Subscribers: hach-que
Maniphest Tasks: T9132
Differential Revision: https://secure.phabricator.com/D14503
Summary: Removes "delete" and uses "archive/activate" instead for Phame Blogs. Ref T9756
Test Plan: Archive a blog, see in search, activate blog, see in other search.
Reviewers: epriestley
Reviewed By: epriestley
Subscribers: joshuaspence, Korvin
Maniphest Tasks: T9756
Differential Revision: https://secure.phabricator.com/D14465
Summary: Ref T6049, Add Phurl URL create capability
Test Plan:
- Change {nav Home > Applications > Phurl > Configure} to allow no one to create Phurl URLs
- Attempt {nav Phurl > Shorten URL}. Should not be able to create a Phurl.
Reviewers: epriestley, #blessed_reviewers
Reviewed By: epriestley, #blessed_reviewers
Subscribers: Korvin
Maniphest Tasks: T6049
Differential Revision: https://secure.phabricator.com/D14510
Summary: Ref T6049, remarkup links to use short URLs and make commenting on Phurl's actually work
Test Plan:
- Create Phurl `U123`
- Comment on that Phurl `((123))`
Comment should link to `/u/123`
Reviewers: epriestley, #blessed_reviewers
Reviewed By: epriestley, #blessed_reviewers
Subscribers: Korvin
Maniphest Tasks: T6049
Differential Revision: https://secure.phabricator.com/D14477
Summary:
Ref T9787. To fix this, I want to change how file PHIDs are extracted slightly: specifically, I'm going to extract them later in the editing process.
Before doing this, clean up a couple of bad implementations:
- Owners extracts its description as a file PHID. This is an error.
- Extract the description as a remarkup block instead.
- Add an edge table so stuff like file attachment works properly.
- Differential has a no-op extract method. This is presumably just a copy/paste issue from long ago.
Test Plan:
- Edited a revision in Differential.
- Dropped a file into the description of an Owners package.
- Before change: this did not attach the file.
- After change: the file now attaches properly and shows up as "Attached" in the file details.
Reviewers: chad, joshuaspence
Reviewed By: joshuaspence
Subscribers: joshuaspence
Maniphest Tasks: T9787
Differential Revision: https://secure.phabricator.com/D14493
Summary: Fixes T9757.
Test Plan: Created a Herald rule and then subscribed to it with a different account.
Reviewers: #blessed_reviewers, epriestley
Reviewed By: #blessed_reviewers, epriestley
Subscribers: Korvin
Maniphest Tasks: T9757
Differential Revision: https://secure.phabricator.com/D14468
Summary: Move some `PhabricatorPolicyRule` implementations to a subdirectory of the parent application.
Test Plan: N/A
Reviewers: #blessed_reviewers, epriestley
Reviewed By: #blessed_reviewers, epriestley
Subscribers: Korvin
Differential Revision: https://secure.phabricator.com/D14478
Summary: Ref T9762. Currently it is not possible to destroy an Alamanac device because any associate bindings cannot be destroyed.
Test Plan: Destroyed an Almanac device.
Reviewers: #blessed_reviewers, epriestley
Reviewed By: #blessed_reviewers, epriestley
Subscribers: Korvin
Maniphest Tasks: T9762
Differential Revision: https://secure.phabricator.com/D14461
Summary: Rename the XHPAST database from `{$NAMESPACE}_xpastview` to `{$NAMESPACE}_xhpast`.
Test Plan: Ran `./bin/storage --namespace test upgrade --no-quickstart`.
Reviewers: #blessed_reviewers, epriestley
Reviewed By: #blessed_reviewers, epriestley
Subscribers: Korvin
Differential Revision: https://secure.phabricator.com/D14442
Summary: Fixes T7053. Depends on D14452.
Test Plan:
Created a custom daemon which dumps out the config hash (by querying `PhabricatorEnv::calculateEnvironmentHash()`). Ran this daemon with `./bin/phd debug PhabricatorDebugDaemon` and saw the config hash update within 30 seconds.
{P1886}
Reviewers: #blessed_reviewers, epriestley
Reviewed By: #blessed_reviewers, epriestley
Subscribers: Korvin
Maniphest Tasks: T7053
Differential Revision: https://secure.phabricator.com/D14458
Summary:
Ref T9132. This diff doesn't do anything interesting, it just lays the groundwork for more interesting future diffs.
Broadly, the idea here is to let you create multiple views of each edit form. For example, we might create several different "Create Task" forms, like:
- "New Bug Report"
- "New Feature Request"
These would be views of the "Create Task" form, but with various adjustments:
- A form might have additional instructions ("how to file a good bug report").
- A form might have prefilled values for some fields (like particular projects, subscribers, or policies).
- A form might have some fields locked (so they can not be edited) or hidden.
- A form might have a different field order.
- A form might have a limited visibility policy, so only some users can access it.
This diff adds a new storage object (`EditEngineConfiguration`) to keep track of all those customizations and represent "a form which has been configured to look and work a certain way".
This doesn't let these configurations do anything useful/interesting, and you can't access them directly yet, it's just all the boring plumbing to enable more interesting behavior in the future.
Test Plan:
ApplicationEditor forms now let you manage available forms and edit the current form:
{F959025}
There's a new (bare bones) list of all available engines:
{F959030}
And if you jump into an engine, you can see all the forms for it:
{F959038}
The actual form configurations have standard detail/edit pages. The edit pages are themselves driven by ApplicationEditor, of course, so you can edit the form for editing forms.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T9132
Differential Revision: https://secure.phabricator.com/D14453
Summary: Adds mail reply support to Phame Posts.
Test Plan: Comment on a post, get mail.
Reviewers: epriestley
Reviewed By: epriestley
Subscribers: Korvin
Maniphest Tasks: T9746
Differential Revision: https://secure.phabricator.com/D14454