Restore highlighting when jumping to transactions using URI anchors
[phabricator/blender.git] / src / view / layout / PhabricatorActionView.php
blob3de60a2374c3af9312c1bbe9b2fe3b0dc6a97082
1 <?php
3 final class PhabricatorActionView extends AphrontView {
5 private $name;
6 private $icon;
7 private $href;
8 private $disabled;
9 private $label;
10 private $workflow;
11 private $renderAsForm;
12 private $download;
13 private $sigils = array();
14 private $metadata;
15 private $selected;
16 private $openInNewWindow;
17 private $submenu = array();
18 private $hidden;
19 private $depth;
20 private $id;
21 private $order;
22 private $color;
23 private $type;
25 const TYPE_DIVIDER = 'type-divider';
26 const TYPE_LABEL = 'label';
27 const RED = 'action-item-red';
28 const GREEN = 'action-item-green';
30 public function setSelected($selected) {
31 $this->selected = $selected;
32 return $this;
35 public function getSelected() {
36 return $this->selected;
39 public function setMetadata($metadata) {
40 $this->metadata = $metadata;
41 return $this;
44 public function getMetadata() {
45 return $this->metadata;
48 public function setDownload($download) {
49 $this->download = $download;
50 return $this;
53 public function getDownload() {
54 return $this->download;
57 public function setHref($href) {
58 $this->href = $href;
59 return $this;
62 public function setColor($color) {
63 $this->color = $color;
64 return $this;
67 public function addSigil($sigil) {
68 $this->sigils[] = $sigil;
69 return $this;
72 public function getHref() {
73 return $this->href;
76 public function setIcon($icon) {
77 $this->icon = $icon;
78 return $this;
81 public function setName($name) {
82 $this->name = $name;
83 return $this;
86 public function getName() {
87 return $this->name;
90 public function setLabel($label) {
91 $this->label = $label;
92 return $this;
95 public function setDisabled($disabled) {
96 $this->disabled = $disabled;
97 return $this;
100 public function getDisabled() {
101 return $this->disabled;
104 public function setWorkflow($workflow) {
105 $this->workflow = $workflow;
106 return $this;
109 public function setRenderAsForm($form) {
110 $this->renderAsForm = $form;
111 return $this;
114 public function setOpenInNewWindow($open_in_new_window) {
115 $this->openInNewWindow = $open_in_new_window;
116 return $this;
119 public function getOpenInNewWindow() {
120 return $this->openInNewWindow;
123 public function setID($id) {
124 $this->id = $id;
125 return $this;
128 public function getID() {
129 if (!$this->id) {
130 $this->id = celerity_generate_unique_node_id();
132 return $this->id;
135 public function setOrder($order) {
136 $this->order = $order;
137 return $this;
140 public function getOrder() {
141 return $this->order;
144 public function setType($type) {
145 $this->type = $type;
146 return $this;
149 public function getType() {
150 return $this->type;
153 public function setSubmenu(array $submenu) {
154 $this->submenu = $submenu;
156 if (!$this->getHref()) {
157 $this->setHref('#');
160 return $this;
163 public function getItems($depth = 0) {
164 $items = array();
166 $items[] = $this;
167 foreach ($this->submenu as $action) {
168 foreach ($action->getItems($depth + 1) as $item) {
169 $item
170 ->setHidden(true)
171 ->setDepth($depth + 1);
173 $items[] = $item;
177 return $items;
180 public function setHidden($hidden) {
181 $this->hidden = $hidden;
182 return $this;
185 public function getHidden() {
186 return $this->hidden;
189 public function setDepth($depth) {
190 $this->depth = $depth;
191 return $this;
194 public function getDepth() {
195 return $this->depth;
198 public function render() {
199 $caret_id = celerity_generate_unique_node_id();
201 $icon = null;
202 if ($this->icon) {
203 $color = '';
204 if ($this->disabled) {
205 $color = ' grey';
207 $icon = id(new PHUIIconView())
208 ->addClass('phabricator-action-view-icon')
209 ->setIcon($this->icon.$color);
212 $sigils = array();
213 if ($this->workflow) {
214 $sigils[] = 'workflow';
217 if ($this->download) {
218 $sigils[] = 'download';
221 if ($this->submenu) {
222 $sigils[] = 'keep-open';
225 if ($this->sigils) {
226 $sigils = array_merge($sigils, $this->sigils);
229 $sigils = $sigils ? implode(' ', $sigils) : null;
231 if ($this->href) {
232 if ($this->renderAsForm) {
233 if (!$this->hasViewer()) {
234 throw new Exception(
235 pht(
236 'Call %s when rendering an action as a form.',
237 'setViewer()'));
240 $item = javelin_tag(
241 'button',
242 array(
243 'class' => 'phabricator-action-view-item',
245 array($icon, $this->name));
247 $item = phabricator_form(
248 $this->getViewer(),
249 array(
250 'action' => $this->getHref(),
251 'method' => 'POST',
252 'sigil' => $sigils,
253 'meta' => $this->metadata,
255 $item);
256 } else {
257 if ($this->getOpenInNewWindow()) {
258 $target = '_blank';
259 $rel = 'noreferrer';
260 } else {
261 $target = null;
262 $rel = null;
265 if ($this->submenu) {
266 $caret = javelin_tag(
267 'span',
268 array(
269 'class' => 'caret-right',
270 'id' => $caret_id,
272 '');
273 } else {
274 $caret = null;
277 $item = javelin_tag(
278 'a',
279 array(
280 'href' => $this->getHref(),
281 'class' => 'phabricator-action-view-item',
282 'target' => $target,
283 'rel' => $rel,
284 'sigil' => $sigils,
285 'meta' => $this->metadata,
287 array($icon, $this->name, $caret));
289 } else {
290 $item = javelin_tag(
291 'span',
292 array(
293 'class' => 'phabricator-action-view-item',
294 'sigil' => $sigils,
296 array($icon, $this->name, $this->renderChildren()));
299 $classes = array();
300 $classes[] = 'phabricator-action-view';
302 if ($this->disabled) {
303 $classes[] = 'phabricator-action-view-disabled';
306 if ($this->label) {
307 $classes[] = 'phabricator-action-view-label';
310 if ($this->selected) {
311 $classes[] = 'phabricator-action-view-selected';
314 if ($this->submenu) {
315 $classes[] = 'phabricator-action-view-submenu';
318 if ($this->getHref()) {
319 $classes[] = 'phabricator-action-view-href';
322 if ($this->icon) {
323 $classes[] = 'action-has-icon';
326 if ($this->color) {
327 $classes[] = $this->color;
330 if ($this->type) {
331 $classes[] = 'phabricator-action-view-'.$this->type;
334 $style = array();
336 if ($this->hidden) {
337 $style[] = 'display: none;';
340 if ($this->depth) {
341 $indent = ($this->depth * 16);
342 $style[] = "margin-left: {$indent}px;";
345 $sigil = null;
346 $meta = null;
348 if ($this->submenu) {
349 Javelin::initBehavior('phui-submenu');
350 $sigil = 'phui-submenu';
352 $item_ids = array();
353 foreach ($this->submenu as $subitem) {
354 $item_ids[] = $subitem->getID();
357 $meta = array(
358 'itemIDs' => $item_ids,
359 'caretID' => $caret_id,
363 return javelin_tag(
364 'li',
365 array(
366 'id' => $this->getID(),
367 'class' => implode(' ', $classes),
368 'style' => implode(' ', $style),
369 'sigil' => $sigil,
370 'meta' => $meta,
372 $item);