Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/drydock/view/DrydockRepositoryOperationStatusView.php
12256 views
1
<?php
2
3
final class DrydockRepositoryOperationStatusView
4
extends AphrontView {
5
6
private $operation;
7
private $boxView;
8
9
public function setOperation(DrydockRepositoryOperation $operation) {
10
$this->operation = $operation;
11
return $this;
12
}
13
14
public function getOperation() {
15
return $this->operation;
16
}
17
18
public function setBoxView(PHUIObjectBoxView $box_view) {
19
$this->boxView = $box_view;
20
return $this;
21
}
22
23
public function getBoxView() {
24
return $this->boxView;
25
}
26
27
public function render() {
28
$viewer = $this->getUser();
29
$operation = $this->getOperation();
30
31
$list = $this->renderUnderwayState();
32
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();
37
38
$list->setID($status_id);
39
40
Javelin::initBehavior(
41
'drydock-live-operation-status',
42
array(
43
'statusID' => $status_id,
44
'updateURI' => "/drydock/operation/{$id}/status/",
45
));
46
}
47
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'));
53
}
54
$box_view->setObjectList($list);
55
56
return $box_view;
57
}
58
59
public function renderUnderwayState() {
60
$viewer = $this->getUser();
61
$operation = $this->getOperation();
62
63
$id = $operation->getID();
64
65
$state = $operation->getOperationState();
66
$icon = DrydockRepositoryOperation::getOperationStateIcon($state);
67
$name = DrydockRepositoryOperation::getOperationStateName($state);
68
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);
74
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;
111
}
112
113
$item->addAttribute($message);
114
115
$table = $this->renderVCSErrorTable($vcs_error);
116
list($links, $info) = $this->renderDetailToggles($table);
117
118
$item->addAttribute($links);
119
$item->appendChild($info);
120
} else {
121
$item->addAttribute(pht('Operation encountered an error.'));
122
}
123
124
$is_dismissed = $operation->getIsDismissed();
125
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/"));
133
}
134
135
return id(new PHUIObjectItemListView())
136
->addItem($item);
137
}
138
139
private function renderVCSErrorTable(array $vcs_error) {
140
$rows = array();
141
142
$rows[] = array(
143
pht('Command'),
144
phutil_censor_credentials($vcs_error['command']),
145
);
146
147
$rows[] = array(pht('Error'), $vcs_error['err']);
148
149
$rows[] = array(
150
pht('Stdout'),
151
phutil_censor_credentials($vcs_error['stdout']),
152
);
153
154
$rows[] = array(
155
pht('Stderr'),
156
phutil_censor_credentials($vcs_error['stderr']),
157
);
158
159
$table = id(new AphrontTableView($rows))
160
->setColumnClasses(
161
array(
162
'header',
163
'wide prewrap',
164
));
165
166
return $table;
167
}
168
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();
173
174
Javelin::initBehavior('phabricator-reveal-content');
175
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),
186
),
187
),
188
pht('Show Details'));
189
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),
201
),
202
),
203
pht('Hide Details'));
204
205
$info = javelin_tag(
206
'div',
207
array(
208
'id' => $info_id,
209
'style' => 'display: none',
210
),
211
$table);
212
213
$links = array(
214
$show_details,
215
$hide_details,
216
);
217
218
return array($links, $info);
219
}
220
221
}
222
223