@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
at upstream/main 170 lines 5.0 kB view raw
1<?php 2 3final class PhabricatorDaemonBulkJobMonitorController 4 extends PhabricatorDaemonBulkJobController { 5 6 public function handleRequest(AphrontRequest $request) { 7 $viewer = $this->getViewer(); 8 9 $job = id(new PhabricatorWorkerBulkJobQuery()) 10 ->setViewer($viewer) 11 ->withIDs(array($request->getURIData('id'))) 12 ->executeOne(); 13 if (!$job) { 14 return new Aphront404Response(); 15 } 16 17 // If the user clicks "Continue" on a completed job, take them back to 18 // whatever application sent them here. 19 if ($request->getStr('done')) { 20 if ($request->isFormPost()) { 21 $done_uri = $job->getDoneURI(); 22 return id(new AphrontRedirectResponse())->setURI($done_uri); 23 } 24 } 25 26 $title = pht('Bulk Job %d', $job->getID()); 27 28 if ($job->getStatus() == PhabricatorWorkerBulkJob::STATUS_CONFIRM) { 29 $can_edit = PhabricatorPolicyFilter::hasCapability( 30 $viewer, 31 $job, 32 PhabricatorPolicyCapability::CAN_EDIT); 33 34 if ($can_edit) { 35 if ($request->isFormPost()) { 36 $type_status = PhabricatorWorkerBulkJobTransaction::TYPE_STATUS; 37 38 $xactions = array(); 39 $xactions[] = id(new PhabricatorWorkerBulkJobTransaction()) 40 ->setTransactionType($type_status) 41 ->setNewValue(PhabricatorWorkerBulkJob::STATUS_WAITING); 42 43 $editor = id(new PhabricatorWorkerBulkJobEditor()) 44 ->setActor($viewer) 45 ->setContentSourceFromRequest($request) 46 ->setContinueOnMissingFields(true) 47 ->applyTransactions($job, $xactions); 48 49 return id(new AphrontRedirectResponse()) 50 ->setURI($job->getMonitorURI()); 51 } else { 52 $dialog = $this->newDialog() 53 ->setTitle(pht('Confirm Bulk Job')); 54 55 $confirm = $job->getDescriptionForConfirm(); 56 $confirm = (array)$confirm; 57 foreach ($confirm as $paragraph) { 58 $dialog->appendParagraph($paragraph); 59 } 60 61 $dialog 62 ->appendParagraph( 63 pht('Start work on this bulk job?')) 64 ->addCancelButton($job->getManageURI(), pht('Details')) 65 ->addSubmitButton(pht('Start Work')); 66 67 return $dialog; 68 } 69 } else { 70 return $this->newDialog() 71 ->setTitle(pht('Waiting For Confirmation')) 72 ->appendParagraph( 73 pht( 74 'This job is waiting for confirmation before work begins.')) 75 ->addCancelButton($job->getManageURI(), pht('Details')); 76 } 77 } 78 79 80 $dialog = $this->newDialog() 81 ->setTitle(pht('%s: %s', $title, $job->getStatusName())) 82 ->addCancelButton($job->getManageURI(), pht('Details')); 83 84 switch ($job->getStatus()) { 85 case PhabricatorWorkerBulkJob::STATUS_WAITING: 86 $dialog->appendParagraph( 87 pht('This job is waiting for tasks to be queued.')); 88 break; 89 case PhabricatorWorkerBulkJob::STATUS_RUNNING: 90 $dialog->appendParagraph( 91 pht('This job is running.')); 92 break; 93 case PhabricatorWorkerBulkJob::STATUS_COMPLETE: 94 $dialog->appendParagraph( 95 pht('This job is complete.')); 96 break; 97 } 98 99 $counts = $job->loadTaskStatusCounts(); 100 if ($counts) { 101 $dialog->appendParagraph($this->renderProgress($counts)); 102 } 103 104 switch ($job->getStatus()) { 105 case PhabricatorWorkerBulkJob::STATUS_COMPLETE: 106 $dialog->addHiddenInput('done', true); 107 $dialog->addSubmitButton(pht('Continue')); 108 break; 109 default: 110 Javelin::initBehavior('bulk-job-reload'); 111 break; 112 } 113 114 return $dialog; 115 } 116 117 private function renderProgress(array $counts) { 118 $this->requireResource('bulk-job-css'); 119 120 $states = array( 121 PhabricatorWorkerBulkTask::STATUS_DONE => array( 122 'class' => 'bulk-job-progress-slice-green', 123 ), 124 PhabricatorWorkerBulkTask::STATUS_RUNNING => array( 125 'class' => 'bulk-job-progress-slice-blue', 126 ), 127 PhabricatorWorkerBulkTask::STATUS_WAITING => array( 128 'class' => 'bulk-job-progress-slice-empty', 129 ), 130 PhabricatorWorkerBulkTask::STATUS_FAIL => array( 131 'class' => 'bulk-job-progress-slice-red', 132 ), 133 ); 134 135 $total = array_sum($counts); 136 $offset = 0; 137 $bars = array(); 138 foreach ($states as $state => $spec) { 139 $size = idx($counts, $state, 0); 140 if (!$size) { 141 continue; 142 } 143 144 $classes = array(); 145 $classes[] = 'bulk-job-progress-slice'; 146 $classes[] = $spec['class']; 147 148 $width = ($size / $total); 149 $bars[] = phutil_tag( 150 'div', 151 array( 152 'class' => implode(' ', $classes), 153 'style' => 154 'left: '.sprintf('%.2f%%', 100 * $offset).'; '. 155 'width: '.sprintf('%.2f%%', 100 * $width).';', 156 ), 157 ''); 158 159 $offset += $width; 160 } 161 162 return phutil_tag( 163 'div', 164 array( 165 'class' => 'bulk-job-progress-bar', 166 ), 167 $bars); 168 } 169 170}