Add basic edit history to herald rules
Summary: Add a very basic edit history table to herald rules. This table is updated whenever saving a herald rule. The contents of the save are not examined, and the edit history contains no information about the rule itself *yet*. Edit history can be viewed by anyone through /herald/history/<rule id>/. Task ID: # Blame Rev: Test Plan: Made a test rule, saved some stuff. Revert Plan: Tags: Reviewers: epriestley, jungejason Reviewed By: epriestley CC: zizzy, aran, xela, epriestley Differential Revision: https://secure.phabricator.com/D1387
This commit is contained in:
		
							
								
								
									
										8
									
								
								resources/sql/patches/103.heraldedithistory.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								resources/sql/patches/103.heraldedithistory.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | CREATE TABLE phabricator_herald.herald_ruleedit ( | ||||||
|  |        id int unsigned not null auto_increment primary key, | ||||||
|  |        ruleID int unsigned not null, | ||||||
|  |        editorPHID varchar(64) BINARY not null, | ||||||
|  |        dateCreated int unsigned not null, | ||||||
|  |        dateModified int unsigned not null, | ||||||
|  |        KEY (ruleID, dateCreated) | ||||||
|  | ) ENGINE=InnoDB; | ||||||
| @@ -332,14 +332,13 @@ celerity_register_resource_map(array( | |||||||
|   ), |   ), | ||||||
|   0 => |   0 => | ||||||
|   array( |   array( | ||||||
|     'uri' => '/res/b6096fdd/rsrc/js/javelin/lib/__tests__/URI.js', |     'uri' => '/res/14c48a9f/rsrc/js/javelin/lib/__tests__/behavior.js', | ||||||
|     'type' => 'js', |     'type' => 'js', | ||||||
|     'requires' => |     'requires' => | ||||||
|     array( |     array( | ||||||
|       0 => 'javelin-uri', |       0 => 'javelin-behavior', | ||||||
|       1 => 'javelin-php-serializer', |  | ||||||
|     ), |     ), | ||||||
|     'disk' => '/rsrc/js/javelin/lib/__tests__/URI.js', |     'disk' => '/rsrc/js/javelin/lib/__tests__/behavior.js', | ||||||
|   ), |   ), | ||||||
|   'javelin-behavior-aphront-basic-tokenizer' => |   'javelin-behavior-aphront-basic-tokenizer' => | ||||||
|   array( |   array( | ||||||
|   | |||||||
| @@ -358,6 +358,9 @@ phutil_register_library_map(array( | |||||||
|     'HeraldRepetitionPolicyConfig' => 'applications/herald/config/repetitionpolicy', |     'HeraldRepetitionPolicyConfig' => 'applications/herald/config/repetitionpolicy', | ||||||
|     'HeraldRule' => 'applications/herald/storage/rule', |     'HeraldRule' => 'applications/herald/storage/rule', | ||||||
|     'HeraldRuleController' => 'applications/herald/controller/rule', |     'HeraldRuleController' => 'applications/herald/controller/rule', | ||||||
|  |     'HeraldRuleEdit' => 'applications/herald/storage/edithistory', | ||||||
|  |     'HeraldRuleEditHistoryController' => 'applications/herald/controller/edithistory', | ||||||
|  |     'HeraldRuleEditHistoryView' => 'applications/herald/view/edithistory', | ||||||
|     'HeraldRuleListView' => 'applications/herald/view/rulelist', |     'HeraldRuleListView' => 'applications/herald/view/rulelist', | ||||||
|     'HeraldRuleTranscript' => 'applications/herald/storage/transcript/rule', |     'HeraldRuleTranscript' => 'applications/herald/storage/transcript/rule', | ||||||
|     'HeraldRuleTypeConfig' => 'applications/herald/config/ruletype', |     'HeraldRuleTypeConfig' => 'applications/herald/config/ruletype', | ||||||
| @@ -1097,6 +1100,9 @@ phutil_register_library_map(array( | |||||||
|     'HeraldNewController' => 'HeraldController', |     'HeraldNewController' => 'HeraldController', | ||||||
|     'HeraldRule' => 'HeraldDAO', |     'HeraldRule' => 'HeraldDAO', | ||||||
|     'HeraldRuleController' => 'HeraldController', |     'HeraldRuleController' => 'HeraldController', | ||||||
|  |     'HeraldRuleEdit' => 'HeraldDAO', | ||||||
|  |     'HeraldRuleEditHistoryController' => 'HeraldController', | ||||||
|  |     'HeraldRuleEditHistoryView' => 'AphrontView', | ||||||
|     'HeraldRuleListView' => 'AphrontView', |     'HeraldRuleListView' => 'AphrontView', | ||||||
|     'HeraldTestConsoleController' => 'HeraldController', |     'HeraldTestConsoleController' => 'HeraldController', | ||||||
|     'HeraldTranscript' => 'HeraldDAO', |     'HeraldTranscript' => 'HeraldDAO', | ||||||
|   | |||||||
| @@ -283,6 +283,7 @@ class AphrontDefaultApplicationConfiguration | |||||||
|         ), |         ), | ||||||
|         'new/(?:(?P<type>[^/]+)/)?$' => 'HeraldNewController', |         'new/(?:(?P<type>[^/]+)/)?$' => 'HeraldNewController', | ||||||
|         'rule/(?:(?P<id>\d+)/)?$' => 'HeraldRuleController', |         'rule/(?:(?P<id>\d+)/)?$' => 'HeraldRuleController', | ||||||
|  |         'history/(?P<id>\d+)/$' => 'HeraldRuleEditHistoryController', | ||||||
|         'delete/(?P<id>\d+)/$' => 'HeraldDeleteController', |         'delete/(?P<id>\d+)/$' => 'HeraldDeleteController', | ||||||
|         'test/$' => 'HeraldTestConsoleController', |         'test/$' => 'HeraldTestConsoleController', | ||||||
|         'all/' => array( |         'all/' => array( | ||||||
|   | |||||||
| @@ -0,0 +1,55 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * Copyright 2012 Facebook, Inc. | ||||||
|  |  * | ||||||
|  |  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |  * you may not use this file except in compliance with the License. | ||||||
|  |  * You may obtain a copy of the License at | ||||||
|  |  * | ||||||
|  |  *   http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  * | ||||||
|  |  * Unless required by applicable law or agreed to in writing, software | ||||||
|  |  * distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |  * See the License for the specific language governing permissions and | ||||||
|  |  * limitations under the License. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | class HeraldRuleEditHistoryController extends HeraldController { | ||||||
|  |  | ||||||
|  |   private $id; | ||||||
|  |  | ||||||
|  |   public function willProcessRequest(array $data) { | ||||||
|  |     $this->id = $data['id']; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public function processRequest() { | ||||||
|  |     $rule = id(new HeraldRule())->load($this->id); | ||||||
|  |     if ($rule === null) { | ||||||
|  |       return new Aphront404Response(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     $edits = $rule->loadEdits(); | ||||||
|  |     $rule->attachEdits($edits); | ||||||
|  |  | ||||||
|  |     $need_phids = mpull($edits, 'getEditorPHID'); | ||||||
|  |     $handles = id(new PhabricatorObjectHandleData($need_phids)) | ||||||
|  |       ->loadHandles(); | ||||||
|  |  | ||||||
|  |     $list_view = id(new HeraldRuleEditHistoryView()) | ||||||
|  |       ->setRule($rule) | ||||||
|  |       ->setHandles($handles) | ||||||
|  |       ->setUser($this->getRequest()->getUser()); | ||||||
|  |  | ||||||
|  |     return $this->buildStandardPageResponse( | ||||||
|  |       $list_view->render(), | ||||||
|  |       array( | ||||||
|  |         'title' => 'Rule Edit History', | ||||||
|  |       )); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public function getFilter() { | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										18
									
								
								src/applications/herald/controller/edithistory/__init__.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/applications/herald/controller/edithistory/__init__.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * This file is automatically generated. Lint this module to rebuild it. | ||||||
|  |  * @generated | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | phutil_require_module('phabricator', 'aphront/response/404'); | ||||||
|  | phutil_require_module('phabricator', 'applications/herald/controller/base'); | ||||||
|  | phutil_require_module('phabricator', 'applications/herald/storage/rule'); | ||||||
|  | phutil_require_module('phabricator', 'applications/herald/view/edithistory'); | ||||||
|  | phutil_require_module('phabricator', 'applications/phid/handle/data'); | ||||||
|  |  | ||||||
|  | phutil_require_module('phutil', 'utils'); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | phutil_require_source('HeraldRuleEditHistoryController.php'); | ||||||
| @@ -63,6 +63,11 @@ class HeraldHomeController extends HeraldController { | |||||||
|         $user->getPHID()); |         $user->getPHID()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     foreach ($rules as $rule) { | ||||||
|  |       $edits = $rule->loadEdits(); | ||||||
|  |       $rule->attachEdits($edits); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     $need_phids = mpull($rules, 'getAuthorPHID'); |     $need_phids = mpull($rules, 'getAuthorPHID'); | ||||||
|     $handles = id(new PhabricatorObjectHandleData($need_phids)) |     $handles = id(new PhabricatorObjectHandleData($need_phids)) | ||||||
|       ->loadHandles(); |       ->loadHandles(); | ||||||
| @@ -72,7 +77,8 @@ class HeraldHomeController extends HeraldController { | |||||||
|       ->setHandles($handles) |       ->setHandles($handles) | ||||||
|       ->setMap($map) |       ->setMap($map) | ||||||
|       ->setAllowCreation(true) |       ->setAllowCreation(true) | ||||||
|       ->setView($this->view); |       ->setView($this->view) | ||||||
|  |       ->setUser($user); | ||||||
|     $panel = $list_view->render(); |     $panel = $list_view->render(); | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -352,6 +352,7 @@ class HeraldRuleController extends HeraldController { | |||||||
|           $rule->save(); |           $rule->save(); | ||||||
|           $rule->saveConditions($conditions); |           $rule->saveConditions($conditions); | ||||||
|           $rule->saveActions($actions); |           $rule->saveActions($actions); | ||||||
|  |           $rule->saveEdit($request->getUser()->getPHID()); | ||||||
| //          $rule->saveTransaction(); | //          $rule->saveTransaction(); | ||||||
|  |  | ||||||
|       } catch (AphrontQueryDuplicateKeyException $ex) { |       } catch (AphrontQueryDuplicateKeyException $ex) { | ||||||
|   | |||||||
| @@ -0,0 +1,24 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * Copyright 2012 Facebook, Inc. | ||||||
|  |  * | ||||||
|  |  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |  * you may not use this file except in compliance with the License. | ||||||
|  |  * You may obtain a copy of the License at | ||||||
|  |  * | ||||||
|  |  *   http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  * | ||||||
|  |  * Unless required by applicable law or agreed to in writing, software | ||||||
|  |  * distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |  * See the License for the specific language governing permissions and | ||||||
|  |  * limitations under the License. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | class HeraldRuleEdit extends HeraldDAO { | ||||||
|  |  | ||||||
|  |   protected $editorPHID; | ||||||
|  |   protected $ruleID; | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										12
									
								
								src/applications/herald/storage/edithistory/__init__.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/applications/herald/storage/edithistory/__init__.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * This file is automatically generated. Lint this module to rebuild it. | ||||||
|  |  * @generated | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | phutil_require_module('phabricator', 'applications/herald/storage/base'); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | phutil_require_source('HeraldRuleEdit.php'); | ||||||
| @@ -125,6 +125,36 @@ class HeraldRule extends HeraldDAO { | |||||||
|     return $this->actions; |     return $this->actions; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   public function loadEdits() { | ||||||
|  |     if (!$this->getID()) { | ||||||
|  |       return array(); | ||||||
|  |     } | ||||||
|  |     $edits = id(new HeraldRuleEdit())->loadAllWhere( | ||||||
|  |       'ruleID = %d ORDER BY dateCreated DESC', | ||||||
|  |       $this->getID()); | ||||||
|  |  | ||||||
|  |     return $edits; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public function attachEdits(array $edits) { | ||||||
|  |     $this->edits = $edits; | ||||||
|  |     return $this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public function getEdits() { | ||||||
|  |     if ($this->edits === null) { | ||||||
|  |       throw new Exception("Attach edits before accessing them!"); | ||||||
|  |     } | ||||||
|  |     return $this->edits; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public function saveEdit($editor_phid) { | ||||||
|  |     $edit = new HeraldRuleEdit(); | ||||||
|  |     $edit->setRuleID($this->getID()); | ||||||
|  |     $edit->setEditorPHID($editor_phid); | ||||||
|  |     $edit->save(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   public function saveConditions(array $conditions) { |   public function saveConditions(array $conditions) { | ||||||
|     return $this->saveChildren( |     return $this->saveChildren( | ||||||
|       id(new HeraldCondition())->getTableName(), |       id(new HeraldCondition())->getTableName(), | ||||||
|   | |||||||
| @@ -9,6 +9,7 @@ | |||||||
| phutil_require_module('phabricator', 'applications/herald/storage/action'); | phutil_require_module('phabricator', 'applications/herald/storage/action'); | ||||||
| phutil_require_module('phabricator', 'applications/herald/storage/base'); | phutil_require_module('phabricator', 'applications/herald/storage/base'); | ||||||
| phutil_require_module('phabricator', 'applications/herald/storage/condition'); | phutil_require_module('phabricator', 'applications/herald/storage/condition'); | ||||||
|  | phutil_require_module('phabricator', 'applications/herald/storage/edithistory'); | ||||||
| phutil_require_module('phabricator', 'storage/queryfx'); | phutil_require_module('phabricator', 'storage/queryfx'); | ||||||
|  |  | ||||||
| phutil_require_module('phutil', 'utils'); | phutil_require_module('phutil', 'utils'); | ||||||
|   | |||||||
| @@ -0,0 +1,73 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * Copyright 2012 Facebook, Inc. | ||||||
|  |  * | ||||||
|  |  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |  * you may not use this file except in compliance with the License. | ||||||
|  |  * You may obtain a copy of the License at | ||||||
|  |  * | ||||||
|  |  *   http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  * | ||||||
|  |  * Unless required by applicable law or agreed to in writing, software | ||||||
|  |  * distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |  * See the License for the specific language governing permissions and | ||||||
|  |  * limitations under the License. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | final class HeraldRuleEditHistoryView extends AphrontView { | ||||||
|  |   private $rule; | ||||||
|  |   private $handles; | ||||||
|  |  | ||||||
|  |   public function setRule($rule) { | ||||||
|  |     $this->rule = $rule; | ||||||
|  |     return $this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public function setHandles(array $handles) { | ||||||
|  |     $this->handles = $handles; | ||||||
|  |     return $this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public function setUser($user) { | ||||||
|  |     $this->user = $user; | ||||||
|  |     return $this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public function render() { | ||||||
|  |     $rows = array(); | ||||||
|  |  | ||||||
|  |     foreach ($this->rule->getEdits() as $edit) { | ||||||
|  |       $editor = $this->handles[$edit->getEditorPHID()]->renderLink(); | ||||||
|  |  | ||||||
|  |       $edit_date = phabricator_datetime($edit->getDateCreated(), $this->user); | ||||||
|  |  | ||||||
|  |       // Something useful could totally go here | ||||||
|  |       $details = ""; | ||||||
|  |  | ||||||
|  |       $rows[] = array( | ||||||
|  |         $editor, | ||||||
|  |         $edit_date, | ||||||
|  |         $details, | ||||||
|  |       ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     $rule_name = phutil_escape_html($this->rule->getName()); | ||||||
|  |     $table = new AphrontTableView($rows); | ||||||
|  |     $table->setNoDataString( | ||||||
|  |       "No edits for \"${rule_name}\""); | ||||||
|  |     $table->setHeaders( | ||||||
|  |       array( | ||||||
|  |         'Editor', | ||||||
|  |         'Edit Date', | ||||||
|  |         'Details', | ||||||
|  |       )); | ||||||
|  |  | ||||||
|  |     $panel = new AphrontPanelView(); | ||||||
|  |     $panel->setHeader("Edit History for \"${rule_name}\""); | ||||||
|  |     $panel->appendChild($table); | ||||||
|  |  | ||||||
|  |     return $panel; | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										17
									
								
								src/applications/herald/view/edithistory/__init__.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/applications/herald/view/edithistory/__init__.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * This file is automatically generated. Lint this module to rebuild it. | ||||||
|  |  * @generated | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | phutil_require_module('phabricator', 'view/base'); | ||||||
|  | phutil_require_module('phabricator', 'view/control/table'); | ||||||
|  | phutil_require_module('phabricator', 'view/layout/panel'); | ||||||
|  | phutil_require_module('phabricator', 'view/utils'); | ||||||
|  |  | ||||||
|  | phutil_require_module('phutil', 'markup'); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | phutil_require_source('HeraldRuleEditHistoryView.php'); | ||||||
| @@ -1,7 +1,7 @@ | |||||||
| <?php | <?php | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Copyright 2011 Facebook, Inc. |  * Copyright 2012 Facebook, Inc. | ||||||
|  * |  * | ||||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); |  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  * you may not use this file except in compliance with the License. |  * you may not use this file except in compliance with the License. | ||||||
| @@ -48,8 +48,14 @@ final class HeraldRuleListView extends AphrontView { | |||||||
|     return $this; |     return $this; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   public function setUser($user) { | ||||||
|  |     $this->user = $user; | ||||||
|  |     return $this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   public function render() { |   public function render() { | ||||||
|     $rows = array(); |     $rows = array(); | ||||||
|  |  | ||||||
|     foreach ($this->rules as $rule) { |     foreach ($this->rules as $rule) { | ||||||
|       $owner = $this->handles[$rule->getAuthorPHID()]->renderLink(); |       $owner = $this->handles[$rule->getAuthorPHID()]->renderLink(); | ||||||
|  |  | ||||||
| @@ -60,6 +66,22 @@ final class HeraldRuleListView extends AphrontView { | |||||||
|         ), |         ), | ||||||
|         phutil_escape_html($rule->getName())); |         phutil_escape_html($rule->getName())); | ||||||
|  |  | ||||||
|  |       $last_edit_date = phabricator_datetime($rule->getDateModified(), | ||||||
|  |                                              $this->user); | ||||||
|  |  | ||||||
|  |       $view_edits = phutil_render_tag( | ||||||
|  |         'a', | ||||||
|  |         array( | ||||||
|  |           'href' => '/herald/history/' . $rule->getID() . '/', | ||||||
|  |         ), | ||||||
|  |         '(View Edits)'); | ||||||
|  |  | ||||||
|  |       $last_edited = phutil_render_tag( | ||||||
|  |         'span', | ||||||
|  |         array(), | ||||||
|  |         "Last edited on $last_edit_date ${view_edits}"); | ||||||
|  |  | ||||||
|  |  | ||||||
|       $delete = javelin_render_tag( |       $delete = javelin_render_tag( | ||||||
|         'a', |         'a', | ||||||
|         array( |         array( | ||||||
| @@ -73,6 +95,7 @@ final class HeraldRuleListView extends AphrontView { | |||||||
|         $this->map[$rule->getContentType()], |         $this->map[$rule->getContentType()], | ||||||
|         $owner, |         $owner, | ||||||
|         $name, |         $name, | ||||||
|  |         $last_edited, | ||||||
|         $delete, |         $delete, | ||||||
|       ); |       ); | ||||||
|     } |     } | ||||||
| @@ -88,6 +111,7 @@ final class HeraldRuleListView extends AphrontView { | |||||||
|         'Type', |         'Type', | ||||||
|         'Owner', |         'Owner', | ||||||
|         'Rule Name', |         'Rule Name', | ||||||
|  |         'Last Edited', | ||||||
|         '', |         '', | ||||||
|       )); |       )); | ||||||
|     $table->setColumnClasses( |     $table->setColumnClasses( | ||||||
| @@ -95,6 +119,7 @@ final class HeraldRuleListView extends AphrontView { | |||||||
|         '', |         '', | ||||||
|         '', |         '', | ||||||
|         'wide wrap pri', |         'wide wrap pri', | ||||||
|  |         '', | ||||||
|         'action' |         'action' | ||||||
|       )); |       )); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ phutil_require_module('phabricator', 'infrastructure/javelin/markup'); | |||||||
| phutil_require_module('phabricator', 'view/base'); | phutil_require_module('phabricator', 'view/base'); | ||||||
| phutil_require_module('phabricator', 'view/control/table'); | phutil_require_module('phabricator', 'view/control/table'); | ||||||
| phutil_require_module('phabricator', 'view/layout/panel'); | phutil_require_module('phabricator', 'view/layout/panel'); | ||||||
|  | phutil_require_module('phabricator', 'view/utils'); | ||||||
|  |  | ||||||
| phutil_require_module('phutil', 'markup'); | phutil_require_module('phutil', 'markup'); | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 awyler
					awyler