mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-10 08:52:39 +01:00
Allow transactions to be grouped in the TimelineView
Summary: TimelineView on Maniphest is often kind of hard to parse because related/simultaneous transactions aren't visually grouped. Allow grouping. I'm going to clean this up a little bit more. Test Plan: See screenshot. Reviewers: chad Reviewed By: chad CC: aran Differential Revision: https://secure.phabricator.com/D7107
This commit is contained in:
parent
97b866ee1f
commit
6cfd89fa74
4 changed files with 144 additions and 53 deletions
|
@ -3461,7 +3461,7 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'phabricator-timeline-view-css' =>
|
||||
array(
|
||||
'uri' => '/res/725f6b17/rsrc/css/layout/phabricator-timeline-view.css',
|
||||
'uri' => '/res/79b6d385/rsrc/css/layout/phabricator-timeline-view.css',
|
||||
'type' => 'css',
|
||||
'requires' =>
|
||||
array(
|
||||
|
|
|
@ -111,11 +111,64 @@ final class PhabricatorTimelineExample extends PhabricatorUIExample {
|
|||
->setColor($color);
|
||||
}
|
||||
|
||||
$vhandle = $handle->renderLink();
|
||||
|
||||
$group_event = id(new PhabricatorTimelineEventView())
|
||||
->setUserHandle($handle)
|
||||
->setTitle(pht('%s went to the store.', $vhandle));
|
||||
|
||||
$group_event->addEventToGroup(
|
||||
id(new PhabricatorTimelineEventView())
|
||||
->setUserHandle($handle)
|
||||
->setTitle(pht('%s bought an apple.', $vhandle))
|
||||
->setColor('green')
|
||||
->setIcon('check'));
|
||||
|
||||
$group_event->addEventToGroup(
|
||||
id(new PhabricatorTimelineEventView())
|
||||
->setUserHandle($handle)
|
||||
->setTitle(pht('%s bought a banana.', $vhandle))
|
||||
->setColor('yellow')
|
||||
->setIcon('check'));
|
||||
|
||||
$group_event->addEventToGroup(
|
||||
id(new PhabricatorTimelineEventView())
|
||||
->setUserHandle($handle)
|
||||
->setTitle(pht('%s bought a cherry.', $vhandle))
|
||||
->setColor('red')
|
||||
->setIcon('check'));
|
||||
|
||||
$group_event->addEventToGroup(
|
||||
id(new PhabricatorTimelineEventView())
|
||||
->setUserHandle($handle)
|
||||
->setTitle(pht('%s paid for his goods.', $vhandle)));
|
||||
|
||||
$group_event->addEventToGroup(
|
||||
id(new PhabricatorTimelineEventView())
|
||||
->setUserHandle($handle)
|
||||
->setTitle(pht('%s returned home.', $vhandle))
|
||||
->setIcon('home')
|
||||
->setColor('blue'));
|
||||
|
||||
$group_event->addEventToGroup(
|
||||
id(new PhabricatorTimelineEventView())
|
||||
->setUserHandle($handle)
|
||||
->setTitle(pht('%s related on his adventures.', $vhandle))
|
||||
->appendChild(
|
||||
pht(
|
||||
'Today, I went to the store. I bought an apple. I bought a '.
|
||||
'banana. I bought a cherry. I paid for my goods, then I returned '.
|
||||
'home.')));
|
||||
|
||||
$events[] = $group_event;
|
||||
|
||||
$anchor = 0;
|
||||
foreach ($events as $event) {
|
||||
$event->setUser($user);
|
||||
$event->setDateCreated(time() + ($anchor * 60 * 8));
|
||||
$event->setAnchor(++$anchor);
|
||||
foreach ($events as $group) {
|
||||
foreach ($group->getEventGroup() as $event) {
|
||||
$event->setUser($user);
|
||||
$event->setDateCreated(time() + ($anchor * 60 * 8));
|
||||
$event->setAnchor(++$anchor);
|
||||
}
|
||||
}
|
||||
|
||||
$timeline = id(new PhabricatorTimelineView());
|
||||
|
|
|
@ -14,6 +14,7 @@ final class PhabricatorTimelineEventView extends AphrontView {
|
|||
private $isEdited;
|
||||
private $transactionPHID;
|
||||
private $isPreview;
|
||||
private $eventGroup = array();
|
||||
|
||||
public function setTransactionPHID($transaction_phid) {
|
||||
$this->transactionPHID = $transaction_phid;
|
||||
|
@ -99,7 +100,17 @@ final class PhabricatorTimelineEventView extends AphrontView {
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function render() {
|
||||
public function getEventGroup() {
|
||||
return array_merge(array($this), $this->eventGroup);
|
||||
}
|
||||
|
||||
public function addEventToGroup(PhabricatorTimelineEventView $event) {
|
||||
$this->eventGroup[] = $event;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
public function renderEventTitle() {
|
||||
$title = $this->title;
|
||||
if (($title === null) && !$this->hasChildren()) {
|
||||
$title = '';
|
||||
|
@ -115,10 +126,16 @@ final class PhabricatorTimelineEventView extends AphrontView {
|
|||
if ($this->icon) {
|
||||
$title_classes[] = 'phabricator-timeline-title-with-icon';
|
||||
|
||||
$fill_classes = array();
|
||||
$fill_classes[] = 'phabricator-timeline-icon-fill';
|
||||
if ($this->color) {
|
||||
$fill_classes[] = 'phabricator-timeline-icon-fill-'.$this->color;
|
||||
}
|
||||
|
||||
$icon = phutil_tag(
|
||||
'span',
|
||||
array(
|
||||
'class' => 'phabricator-timeline-icon-fill',
|
||||
'class' => implode(' ', $fill_classes),
|
||||
),
|
||||
phutil_tag(
|
||||
'span',
|
||||
|
@ -134,9 +151,21 @@ final class PhabricatorTimelineEventView extends AphrontView {
|
|||
array(
|
||||
'class' => implode(' ', $title_classes),
|
||||
),
|
||||
array($title, $extra));
|
||||
array($icon, $title, $extra));
|
||||
}
|
||||
|
||||
$title = array($icon, $title);
|
||||
return $title;
|
||||
}
|
||||
|
||||
public function render() {
|
||||
|
||||
$group_titles = array();
|
||||
$group_children = array();
|
||||
foreach ($this->getEventGroup() as $event) {
|
||||
$group_titles[] = $event->renderEventTitle();
|
||||
if ($event->hasChildren()) {
|
||||
$group_children[] = $event->renderChildren();
|
||||
}
|
||||
}
|
||||
|
||||
$wedge = phutil_tag(
|
||||
|
@ -160,43 +189,53 @@ final class PhabricatorTimelineEventView extends AphrontView {
|
|||
|
||||
$classes = array();
|
||||
$classes[] = 'phabricator-timeline-event-view';
|
||||
$classes[] = 'phabricator-timeline-border';
|
||||
if ($this->hasChildren()) {
|
||||
if ($group_children) {
|
||||
$classes[] = 'phabricator-timeline-major-event';
|
||||
$content = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => implode(' ', $content_classes),
|
||||
'class' => 'phabricator-timeline-inner-content',
|
||||
),
|
||||
phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'phabricator-timeline-inner-content',
|
||||
),
|
||||
array(
|
||||
$title,
|
||||
phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'phabricator-timeline-core-content',
|
||||
),
|
||||
$this->renderChildren()),
|
||||
)));
|
||||
$content = array($image, $wedge, $content);
|
||||
array(
|
||||
$group_titles,
|
||||
phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'phabricator-timeline-core-content',
|
||||
),
|
||||
$group_children),
|
||||
));
|
||||
} else {
|
||||
$classes[] = 'phabricator-timeline-minor-event';
|
||||
$content = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => implode(' ', $content_classes),
|
||||
),
|
||||
array($image, $wedge, $title));
|
||||
$content = $group_titles;
|
||||
}
|
||||
|
||||
$content = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'phabricator-timeline-group phabricator-timeline-border',
|
||||
),
|
||||
$content);
|
||||
|
||||
$content = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => implode(' ', $content_classes),
|
||||
),
|
||||
array($image, $wedge, $content));
|
||||
|
||||
$outer_classes = $this->classes;
|
||||
$outer_classes[] = 'phabricator-timeline-shell';
|
||||
if ($this->color) {
|
||||
$outer_classes[] = 'phabricator-timeline-'.$this->color;
|
||||
$color = null;
|
||||
foreach ($this->getEventGroup() as $event) {
|
||||
if ($event->color) {
|
||||
$color = $event->color;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($color) {
|
||||
$outer_classes[] = 'phabricator-timeline-'.$color;
|
||||
}
|
||||
|
||||
$sigil = null;
|
||||
|
|
|
@ -6,11 +6,10 @@
|
|||
background: #eeedf0;
|
||||
}
|
||||
|
||||
.phabricator-timeline-event-view {
|
||||
border-width: 0 0 0 3px;
|
||||
.phabricator-timeline-group {
|
||||
border-width: 0 3px;
|
||||
border-style: solid;
|
||||
border-color: #c0c5d1;
|
||||
|
||||
}
|
||||
|
||||
.device-desktop .phabricator-timeline-event-view {
|
||||
|
@ -21,7 +20,9 @@
|
|||
|
||||
.device-desktop .phabricator-timeline-spacer {
|
||||
min-height: 20px;
|
||||
border-right-width: 0;
|
||||
border-width: 0 0 0 3px;
|
||||
border-style: solid;
|
||||
border-color: #c0c5d1;
|
||||
}
|
||||
|
||||
.device-desktop .phabricator-timeline-major-event,
|
||||
|
@ -91,6 +92,7 @@
|
|||
.phabricator-timeline-title {
|
||||
padding: 0 5px;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
.phabricator-timeline-title-with-icon {
|
||||
|
@ -112,9 +114,6 @@
|
|||
position: relative;
|
||||
margin-left: 3px;
|
||||
margin-right: 3px;
|
||||
|
||||
border-right-width: 3px;
|
||||
border-right-style: solid;
|
||||
}
|
||||
|
||||
.device .phabricator-timeline-image {
|
||||
|
@ -131,7 +130,7 @@
|
|||
width: 30px;
|
||||
height: 30px;
|
||||
background-color: #c0c5d1;
|
||||
top: 0;
|
||||
top: -1px;
|
||||
left: -3px;
|
||||
}
|
||||
|
||||
|
@ -199,43 +198,43 @@
|
|||
border-color: #333;
|
||||
}
|
||||
|
||||
.phabricator-timeline-red .phabricator-timeline-icon-fill {
|
||||
.phabricator-timeline-icon-fill-red {
|
||||
background-color: {$red};
|
||||
}
|
||||
|
||||
.phabricator-timeline-orange .phabricator-timeline-icon-fill {
|
||||
.phabricator-timeline-icon-fill-orange {
|
||||
background-color: {$orange};
|
||||
}
|
||||
|
||||
.phabricator-timeline-yellow .phabricator-timeline-icon-fill {
|
||||
.phabricator-timeline-icon-fill-yellow {
|
||||
background-color: {$yellow};
|
||||
}
|
||||
|
||||
.phabricator-timeline-green .phabricator-timeline-icon-fill {
|
||||
.phabricator-timeline-icon-fill-green {
|
||||
background-color: {$green};
|
||||
}
|
||||
|
||||
.phabricator-timeline-sky .phabricator-timeline-icon-fill {
|
||||
.phabricator-timeline-icon-fill-sky {
|
||||
background-color: {$sky};
|
||||
}
|
||||
|
||||
.phabricator-timeline-blue .phabricator-timeline-icon-fill {
|
||||
.phabricator-timeline-icon-fill-blue {
|
||||
background-color: {$blue};
|
||||
}
|
||||
|
||||
.phabricator-timeline-indigo .phabricator-timeline-icon-fill {
|
||||
.phabricator-timeline-icon-fill-indigo {
|
||||
background-color: {$indigo};
|
||||
}
|
||||
|
||||
.phabricator-timeline-violet .phabricator-timeline-icon-fill {
|
||||
.phabricator-timeline-icon-fill-violet {
|
||||
background-color: {$violet};
|
||||
}
|
||||
|
||||
.phabricator-timeline-grey .phabricator-timeline-icon-fill {
|
||||
.phabricator-timeline-icon-fill-grey {
|
||||
background-color: #888;
|
||||
}
|
||||
|
||||
.phabricator-timeline-black .phabricator-timeline-icon-fill {
|
||||
.phabricator-timeline-icon-fill-black {
|
||||
background-color: #333;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue