@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Separate Herald transcripts into several different views

Summary: Ref T13586. The Herald transcript page has become more and more complicated over time, and recently added "Transactions" and "Profiler" sections. Split these across separate navigation tabs to limit the maximum complexity of any single view and make it easier to navigate to particular sections, like the profiler section.

Test Plan: Viewed various transcripts, saw nice digestible sections.

Maniphest Tasks: T13586

Differential Revision: https://secure.phabricator.com/D21493

+166 -57
+2 -2
src/applications/herald/application/PhabricatorHeraldApplication.php
··· 57 57 'new/' => 'HeraldNewController', 58 58 'create/' => 'HeraldNewController', 59 59 'edit/(?:(?P<id>[1-9]\d*)/)?' => 'HeraldRuleController', 60 - 'disable/(?P<id>[1-9]\d*)/(?P<action>\w+)/' 60 + 'disable/(?P<id>[1-9]\d*)/(?P<action>[^/]+)/' 61 61 => 'HeraldDisableController', 62 62 'test/' => 'HeraldTestConsoleController', 63 63 'transcript/' => array( 64 64 '' => 'HeraldTranscriptListController', 65 65 '(?:query/(?P<queryKey>[^/]+)/)?' => 'HeraldTranscriptListController', 66 - '(?P<id>[1-9]\d*)/' 66 + '(?P<id>[1-9]\d*)/(?:(?P<view>[^/]+)/)?' 67 67 => 'HeraldTranscriptController', 68 68 ), 69 69 'webhook/' => array(
+164 -55
src/applications/herald/controller/HeraldTranscriptController.php
··· 9 9 return $this->adapter; 10 10 } 11 11 12 + public function buildApplicationMenu() { 13 + // Use the menu we build in this controller, not the default menu for 14 + // Herald. 15 + return null; 16 + } 17 + 12 18 public function handleRequest(AphrontRequest $request) { 13 19 $viewer = $this->getViewer(); 14 20 ··· 19 25 if (!$xscript) { 20 26 return new Aphront404Response(); 21 27 } 28 + 29 + $view_key = $this->getViewKey($request); 30 + if (!$view_key) { 31 + return new Aphront404Response(); 32 + } 33 + 34 + $navigation = $this->newSideNavView($xscript, $view_key); 22 35 23 36 $object = $xscript->getObject(); 24 37 ··· 56 69 57 70 $handles = $this->loadViewerHandles($phids); 58 71 $this->handles = $handles; 59 - 60 - if ($xscript->getDryRun()) { 61 - $notice = new PHUIInfoView(); 62 - $notice->setSeverity(PHUIInfoView::SEVERITY_NOTICE); 63 - $notice->setTitle(pht('Dry Run')); 64 - $notice->appendChild( 65 - pht( 66 - 'This was a dry run to test Herald rules, '. 67 - 'no actions were executed.')); 68 - $content[] = $notice; 69 - } 70 72 71 73 $warning_panel = $this->buildWarningPanel($xscript); 72 74 $content[] = $warning_panel; 73 75 74 - $content[] = array( 75 - $this->buildActionTranscriptPanel($xscript), 76 - $this->buildObjectTranscriptPanel($xscript), 77 - $this->buildTransactionsTranscriptPanel( 78 - $object, 79 - $xscript), 80 - $this->buildProfilerTranscriptPanel($xscript), 81 - ); 76 + $content[] = $this->newContentView($xscript, $view_key); 82 77 } 83 78 84 79 $crumbs = id($this->buildApplicationCrumbs()) 85 80 ->addTextCrumb( 86 81 pht('Transcripts'), 87 82 $this->getApplicationURI('/transcript/')) 88 - ->addTextCrumb($xscript->getID()) 83 + ->addTextCrumb(pht('Transcript %d', $xscript->getID())) 89 84 ->setBorder(true); 90 85 91 - $title = pht('Transcript: %s', $xscript->getID()); 92 - 93 - $header = id(new PHUIHeaderView()) 94 - ->setHeader($title) 95 - ->setHeaderIcon('fa-file'); 86 + $title = pht('Herald Transcript %s', $xscript->getID()); 87 + $header = $this->newHeaderView($xscript, $title); 96 88 97 89 $view = id(new PHUITwoColumnView()) 98 90 ->setHeader($header) ··· 101 93 return $this->newPage() 102 94 ->setTitle($title) 103 95 ->setCrumbs($crumbs) 104 - ->appendChild( 105 - array( 106 - $view, 107 - )); 96 + ->setNavigation($navigation) 97 + ->appendChild($view); 108 98 } 109 99 110 100 protected function renderConditionTestValue($condition, $handles) { ··· 443 433 ->setHeaderText(pht('Rule Transcript')) 444 434 ->appendChild($rule_list); 445 435 446 - return $box; 436 + $content = array(); 437 + 438 + if ($xscript->getDryRun()) { 439 + $notice = new PHUIInfoView(); 440 + $notice->setSeverity(PHUIInfoView::SEVERITY_NOTICE); 441 + $notice->setTitle(pht('Dry Run')); 442 + $notice->appendChild( 443 + pht( 444 + 'This was a dry run to test Herald rules, '. 445 + 'no actions were executed.')); 446 + $content[] = $notice; 447 + } 448 + 449 + $content[] = $box; 450 + 451 + return $content; 447 452 } 448 453 449 454 private function buildObjectTranscriptPanel(HeraldTranscript $xscript) { ··· 520 525 return $box; 521 526 } 522 527 523 - private function buildTransactionsTranscriptPanel( 524 - $object, 525 - HeraldTranscript $xscript) { 528 + private function buildTransactionsTranscriptPanel(HeraldTranscript $xscript) { 526 529 $viewer = $this->getViewer(); 527 530 528 - $object_xscript = $xscript->getObjectTranscript(); 529 - 530 - $xaction_phids = $object_xscript->getAppliedTransactionPHIDs(); 531 - 532 - // If the value is "null", this is an older transcript or this adapter 533 - // does not use transactions. We render nothing. 534 - // 535 - // If the value is "array()", this is a modern transcript which uses 536 - // transactions, there just weren't any applied. Below, we'll render a 537 - // "No Transactions Applied" state. 538 - if ($xaction_phids === null) { 539 - return null; 540 - } 541 - 542 - // If this object doesn't implement the right interface, we won't be 543 - // able to load the transactions. Just bail. 544 - if (!($object instanceof PhabricatorApplicationTransactionInterface)) { 545 - return null; 546 - } 547 - 548 - $query = PhabricatorApplicationTransactionQuery::newQueryForObject( 549 - $object); 531 + $xaction_phids = $this->getTranscriptTransactionPHIDs($xscript); 550 532 551 533 if ($xaction_phids) { 534 + $object = $xscript->getObject(); 535 + $query = PhabricatorApplicationTransactionQuery::newQueryForObject( 536 + $object); 552 537 $xactions = $query 553 538 ->setViewer($viewer) 554 539 ->withPHIDs($xaction_phids) ··· 702 687 ->setTable($table_view); 703 688 704 689 return $box_view; 690 + } 691 + 692 + private function getViewKey(AphrontRequest $request) { 693 + $view_key = $request->getURIData('view'); 694 + 695 + if ($view_key === null) { 696 + return 'rules'; 697 + } 698 + 699 + switch ($view_key) { 700 + case 'fields': 701 + case 'xactions': 702 + case 'profile': 703 + return $view_key; 704 + default: 705 + return null; 706 + } 707 + } 708 + 709 + private function newSideNavView( 710 + HeraldTranscript $xscript, 711 + $view_key) { 712 + 713 + $base_uri = urisprintf( 714 + 'transcript/%d/', 715 + $xscript->getID()); 716 + 717 + $base_uri = $this->getApplicationURI($base_uri); 718 + $base_uri = new PhutilURI($base_uri); 719 + 720 + $nav = id(new AphrontSideNavFilterView()) 721 + ->setBaseURI($base_uri); 722 + 723 + $nav->newLink('rules') 724 + ->setHref($base_uri) 725 + ->setName(pht('Rules')) 726 + ->setIcon('fa-list-ul'); 727 + 728 + $nav->newLink('fields') 729 + ->setName(pht('Field Values')) 730 + ->setIcon('fa-file-text-o'); 731 + 732 + $xaction_phids = $this->getTranscriptTransactionPHIDs($xscript); 733 + $has_xactions = (bool)$xaction_phids; 734 + 735 + $nav->newLink('xactions') 736 + ->setName(pht('Transactions')) 737 + ->setIcon('fa-forward') 738 + ->setDisabled(!$has_xactions); 739 + 740 + $nav->newLink('profile') 741 + ->setName(pht('Profiler')) 742 + ->setIcon('fa-tachometer'); 743 + 744 + $nav->selectFilter($view_key); 745 + 746 + return $nav; 747 + } 748 + 749 + private function newContentView( 750 + HeraldTranscript $xscript, 751 + $view_key) { 752 + 753 + switch ($view_key) { 754 + case 'rules': 755 + $content = $this->buildActionTranscriptPanel($xscript); 756 + break; 757 + case 'fields': 758 + $content = $this->buildObjectTranscriptPanel($xscript); 759 + break; 760 + case 'xactions': 761 + $content = $this->buildTransactionsTranscriptPanel($xscript); 762 + break; 763 + case 'profile': 764 + $content = $this->buildProfilerTranscriptPanel($xscript); 765 + break; 766 + default: 767 + throw new Exception(pht('Unknown view key "%s".', $view_key)); 768 + } 769 + 770 + return $content; 771 + } 772 + 773 + private function getTranscriptTransactionPHIDs(HeraldTranscript $xscript) { 774 + 775 + $object_xscript = $xscript->getObjectTranscript(); 776 + $xaction_phids = $object_xscript->getAppliedTransactionPHIDs(); 777 + 778 + // If the value is "null", this is an older transcript or this adapter 779 + // does not use transactions. 780 + // 781 + // (If the value is "array()", this is a modern transcript which uses 782 + // transactions, there just weren't any applied.) 783 + if ($xaction_phids === null) { 784 + return array(); 785 + } 786 + 787 + $object = $xscript->getObject(); 788 + 789 + // If this object doesn't implement the right interface, we won't be 790 + // able to load the transactions. 791 + if (!($object instanceof PhabricatorApplicationTransactionInterface)) { 792 + return array(); 793 + } 794 + 795 + return $xaction_phids; 796 + } 797 + 798 + private function newHeaderView(HeraldTranscript $xscript, $title) { 799 + $header = id(new PHUIHeaderView()) 800 + ->setHeader($title) 801 + ->setHeaderIcon('fa-list-ul'); 802 + 803 + if ($xscript->getDryRun()) { 804 + $dry_run_tag = id(new PHUITagView()) 805 + ->setType(PHUITagView::TYPE_SHADE) 806 + ->setColor(PHUITagView::COLOR_VIOLET) 807 + ->setName(pht('Dry Run')) 808 + ->setIcon('fa-exclamation-triangle'); 809 + 810 + $header->addTag($dry_run_tag); 811 + } 812 + 813 + return $header; 705 814 } 706 815 707 816 }