Correct Aphlict websocket URI construction after PHP8 compatibility changes
[phabricator.git] / src / applications / drydock / view / DrydockRepositoryOperationStatusView.php
blobaa7d1e3873089e700f67df76d6bbc5f2602ff5f7
1 <?php
3 final class DrydockRepositoryOperationStatusView
4 extends AphrontView {
6 private $operation;
7 private $boxView;
9 public function setOperation(DrydockRepositoryOperation $operation) {
10 $this->operation = $operation;
11 return $this;
14 public function getOperation() {
15 return $this->operation;
18 public function setBoxView(PHUIObjectBoxView $box_view) {
19 $this->boxView = $box_view;
20 return $this;
23 public function getBoxView() {
24 return $this->boxView;
27 public function render() {
28 $viewer = $this->getUser();
29 $operation = $this->getOperation();
31 $list = $this->renderUnderwayState();
33 // If the operation is currently underway, refresh the status view.
34 if ($operation->isUnderway()) {
35 $status_id = celerity_generate_unique_node_id();
36 $id = $operation->getID();
38 $list->setID($status_id);
40 Javelin::initBehavior(
41 'drydock-live-operation-status',
42 array(
43 'statusID' => $status_id,
44 'updateURI' => "/drydock/operation/{$id}/status/",
45 ));
48 $box_view = $this->getBoxView();
49 if (!$box_view) {
50 $box_view = id(new PHUIObjectBoxView())
51 ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
52 ->setHeaderText(pht('Operation Status'));
54 $box_view->setObjectList($list);
56 return $box_view;
59 public function renderUnderwayState() {
60 $viewer = $this->getUser();
61 $operation = $this->getOperation();
63 $id = $operation->getID();
65 $state = $operation->getOperationState();
66 $icon = DrydockRepositoryOperation::getOperationStateIcon($state);
67 $name = DrydockRepositoryOperation::getOperationStateName($state);
69 $item = id(new PHUIObjectItemView())
70 ->setHref("/drydock/operation/{$id}/")
71 ->setObjectName(pht('Operation %d', $id))
72 ->setHeader($operation->getOperationDescription($viewer))
73 ->setStatusIcon($icon, $name);
75 if ($state != DrydockRepositoryOperation::STATE_FAIL) {
76 $item->addAttribute($operation->getOperationCurrentStatus($viewer));
77 } else {
78 $vcs_error = $operation->getCommandError();
79 if ($vcs_error) {
80 switch ($vcs_error['phase']) {
81 case DrydockWorkingCopyBlueprintImplementation::PHASE_SQUASHMERGE:
82 $message = pht(
83 'This change did not merge cleanly. This usually indicates '.
84 'that the change is out of date and needs to be updated.');
85 break;
86 case DrydockWorkingCopyBlueprintImplementation::PHASE_REMOTEFETCH:
87 $message = pht(
88 'This change could not be fetched from the remote.');
89 break;
90 case DrydockWorkingCopyBlueprintImplementation::PHASE_MERGEFETCH:
91 $message = pht(
92 'This change could not be fetched from the remote staging '.
93 'area. It may not have been pushed, or may have been removed.');
94 break;
95 case DrydockLandRepositoryOperation::PHASE_COMMIT:
96 $message = pht(
97 'Committing this change failed. It may already have been '.
98 'merged.');
99 break;
100 case DrydockLandRepositoryOperation::PHASE_PUSH:
101 $message = pht(
102 'The push failed. This usually indicates '.
103 'that the change is breaking some rules or '.
104 'some custom commit hook has failed.');
105 break;
106 default:
107 $message = pht(
108 'Operation encountered an error while performing repository '.
109 'operations.');
110 break;
113 $item->addAttribute($message);
115 $table = $this->renderVCSErrorTable($vcs_error);
116 list($links, $info) = $this->renderDetailToggles($table);
118 $item->addAttribute($links);
119 $item->appendChild($info);
120 } else {
121 $item->addAttribute(pht('Operation encountered an error.'));
124 $is_dismissed = $operation->getIsDismissed();
126 $item->addAction(
127 id(new PHUIListItemView())
128 ->setName('Dismiss')
129 ->setIcon('fa-times')
130 ->setDisabled($is_dismissed)
131 ->setWorkflow(true)
132 ->setHref("/drydock/operation/{$id}/dismiss/"));
135 return id(new PHUIObjectItemListView())
136 ->addItem($item);
139 private function renderVCSErrorTable(array $vcs_error) {
140 $rows = array();
142 $rows[] = array(
143 pht('Command'),
144 phutil_censor_credentials($vcs_error['command']),
147 $rows[] = array(pht('Error'), $vcs_error['err']);
149 $rows[] = array(
150 pht('Stdout'),
151 phutil_censor_credentials($vcs_error['stdout']),
154 $rows[] = array(
155 pht('Stderr'),
156 phutil_censor_credentials($vcs_error['stderr']),
159 $table = id(new AphrontTableView($rows))
160 ->setColumnClasses(
161 array(
162 'header',
163 'wide prewrap',
166 return $table;
169 private function renderDetailToggles(AphrontTableView $table) {
170 $show_id = celerity_generate_unique_node_id();
171 $hide_id = celerity_generate_unique_node_id();
172 $info_id = celerity_generate_unique_node_id();
174 Javelin::initBehavior('phabricator-reveal-content');
176 $show_details = javelin_tag(
177 'a',
178 array(
179 'id' => $show_id,
180 'href' => '#',
181 'sigil' => 'reveal-content',
182 'mustcapture' => true,
183 'meta' => array(
184 'hideIDs' => array($show_id),
185 'showIDs' => array($hide_id, $info_id),
188 pht('Show Details'));
190 $hide_details = javelin_tag(
191 'a',
192 array(
193 'id' => $hide_id,
194 'href' => '#',
195 'sigil' => 'reveal-content',
196 'mustcapture' => true,
197 'style' => 'display: none',
198 'meta' => array(
199 'hideIDs' => array($hide_id, $info_id),
200 'showIDs' => array($show_id),
203 pht('Hide Details'));
205 $info = javelin_tag(
206 'div',
207 array(
208 'id' => $info_id,
209 'style' => 'display: none',
211 $table);
213 $links = array(
214 $show_details,
215 $hide_details,
218 return array($links, $info);