diff --git a/resources/celerity/map.php b/resources/celerity/map.php --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -126,6 +126,7 @@ 'rsrc/css/phui/calendar/phui-calendar.css' => 'ccabe893', 'rsrc/css/phui/phui-action-list.css' => 'c5eba19d', 'rsrc/css/phui/phui-action-panel.css' => '3ee9afd5', + 'rsrc/css/phui/phui-badge.css' => 'd6603d7f', 'rsrc/css/phui/phui-box.css' => 'a5bb366d', 'rsrc/css/phui/phui-button.css' => 'cf529a01', 'rsrc/css/phui/phui-crumbs-view.css' => 'd842f867', @@ -774,6 +775,7 @@ 'phrequent-css' => 'ffc185ad', 'phriction-document-css' => 'd1861e06', 'phui-action-panel-css' => '3ee9afd5', + 'phui-badge-view-css' => 'd6603d7f', 'phui-box-css' => 'a5bb366d', 'phui-button-css' => 'cf529a01', 'phui-calendar-css' => 'ccabe893', diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1286,6 +1286,9 @@ 'PHUI' => 'view/phui/PHUI.php', 'PHUIActionPanelExample' => 'applications/uiexample/examples/PHUIActionPanelExample.php', 'PHUIActionPanelView' => 'view/phui/PHUIActionPanelView.php', + 'PHUIBadgeBoxView' => 'view/phui/PHUIBadgeBoxView.php', + 'PHUIBadgeExample' => 'applications/uiexample/examples/PHUIBadgeExample.php', + 'PHUIBadgeView' => 'view/phui/PHUIBadgeView.php', 'PHUIBoxExample' => 'applications/uiexample/examples/PHUIBoxExample.php', 'PHUIBoxView' => 'view/phui/PHUIBoxView.php', 'PHUIButtonBarExample' => 'applications/uiexample/examples/PHUIButtonBarExample.php', @@ -4932,6 +4935,9 @@ 'PHUI' => 'Phobject', 'PHUIActionPanelExample' => 'PhabricatorUIExample', 'PHUIActionPanelView' => 'AphrontTagView', + 'PHUIBadgeBoxView' => 'AphrontTagView', + 'PHUIBadgeExample' => 'PhabricatorUIExample', + 'PHUIBadgeView' => 'AphrontTagView', 'PHUIBoxExample' => 'PhabricatorUIExample', 'PHUIBoxView' => 'AphrontTagView', 'PHUIButtonBarExample' => 'PhabricatorUIExample', diff --git a/src/applications/uiexample/examples/PHUIBadgeExample.php b/src/applications/uiexample/examples/PHUIBadgeExample.php new file mode 100644 --- /dev/null +++ b/src/applications/uiexample/examples/PHUIBadgeExample.php @@ -0,0 +1,132 @@ +setIcon('fa-users') + ->setHeader(pht('Phacility High Command')) + ->setHref('/') + ->setSource('Projects (automatic)') + ->addByline(pht('Dec 31, 1969')) + ->addByline('3 Members'); + + $badges1[] = id(new PHUIBadgeView()) + ->setIcon('fa-lock') + ->setHeader(pht('Blessed Committers')) + ->setSource('Projects (automatic)') + ->addByline(pht('Dec 31, 1969')) + ->addByline('12 Members'); + + $badges1[] = id(new PHUIBadgeView()) + ->setIcon('fa-camera-retro') + ->setHeader(pht('Design')) + ->setSource('Projects (automatic)') + ->addByline(pht('Dec 31, 1969')) + ->addByline('2 Members'); + + $badges1[] = id(new PHUIBadgeView()) + ->setIcon('fa-lock') + ->setHeader(pht('Blessed Reviewers')) + ->setSource('Projects (automatic)') + ->addByline(pht('Dec 31, 1969')) + ->addByline('3 Members'); + + $badges1[] = id(new PHUIBadgeView()) + ->setIcon('fa-umbrella') + ->setHeader(pht('Wikipedia')) + ->setSource('Projects (automatic)') + ->addByline(pht('Dec 31, 1969')) + ->addByline('22 Members'); + + $badges2 = array(); + $badges2[] = id(new PHUIBadgeView()) + ->setIcon('fa-user') + ->setHeader(pht('Phabricator User')) + ->setSubhead(pht('Confirmed your account.')) + ->setQuality(PHUIBadgeView::POOR) + ->setSource(pht('People (automatic)')) + ->addByline(pht('Dec 31, 1969')) + ->addByline('212 Issued (100%)'); + + $badges2[] = id(new PHUIBadgeView()) + ->setIcon('fa-code') + ->setHeader(pht('Code Contributor')) + ->setSubhead(pht('Wrote code that was acceptable')) + ->setQuality(PHUIBadgeView::COMMON) + ->setSource('Diffusion (automatic)') + ->addByline(pht('Dec 31, 1969')) + ->addByline('200 Awarded (98%)'); + + $badges2[] = id(new PHUIBadgeView()) + ->setIcon('fa-bug') + ->setHeader(pht('Task Master')) + ->setSubhead(pht('Closed over 100 tasks')) + ->setQuality(PHUIBadgeView::UNCOMMON) + ->setSource('Maniphest (automatic)') + ->addByline(pht('Dec 31, 1969')) + ->addByline('56 Awarded (43%)'); + + $badges2[] = id(new PHUIBadgeView()) + ->setIcon('fa-star') + ->setHeader(pht('Code Weaver')) + ->setSubhead(pht('Landed 1,000 Commits')) + ->setQuality(PHUIBadgeView::RARE) + ->setSource('Diffusion (automatic)') + ->addByline(pht('Dec 31, 1969')) + ->addByline('42 Awarded (20%)'); + + $badges2[] = id(new PHUIBadgeView()) + ->setIcon('fa-users') + ->setHeader(pht('Security Team')) + ->setSubhead(pht('alert(1);')) + ->setQuality(PHUIBadgeView::EPIC) + ->setSource('Projects (automatic)') + ->addByline(pht('Dec 31, 1969')) + ->addByline('21 Awarded (10%)'); + + $badges2[] = id(new PHUIBadgeView()) + ->setIcon('fa-user') + ->setHeader(pht('Adminstrator')) + ->setSubhead(pht('Drew the short stick')) + ->setQuality(PHUIBadgeView::LEGENDARY) + ->setSource(pht('People (automatic)')) + ->addByline(pht('Dec 31, 1969')) + ->addByline('3 Awarded (1.4%)'); + + $badges2[] = id(new PHUIBadgeView()) + ->setIcon('fa-compass') + ->setHeader(pht('Lead Developer')) + ->setSubhead(pht('Lead Developer of Phabricator')) + ->setQuality(PHUIBadgeView::HEIRLOOM) + ->setSource(pht('Direct Award (epriestley)')) + ->addByline(pht('Dec 31, 1969')) + ->addByline('1 Awarded (0.4%)'); + + $flex1 = new PHUIBadgeBoxView(); + $flex1->addItems($badges1); + + $box1 = id(new PHUIObjectBoxView()) + ->setHeaderText(pht('Project Membership')) + ->appendChild($flex1); + + $flex2 = new PHUIBadgeBoxView(); + $flex2->addItems($badges2); + + $box2 = id(new PHUIObjectBoxView()) + ->setHeaderText(pht('Acheivements')) + ->appendChild($flex2); + + return array($box1, $box2); + } +} diff --git a/src/view/phui/PHUIBadgeBoxView.php b/src/view/phui/PHUIBadgeBoxView.php new file mode 100644 --- /dev/null +++ b/src/view/phui/PHUIBadgeBoxView.php @@ -0,0 +1,48 @@ +items[] = $item; + return $this; + } + + public function addItems($items) { + foreach ($items as $item) { + $this->items[] = $item; + } + return $this; + } + + protected function getTagName() { + return 'ul'; + } + + protected function getTagAttributes() { + require_celerity_resource('phui-badge-view-css'); + + $classes = array(); + $classes[] = 'phui-badge-flex-view'; + $classes[] = 'grouped'; + + return array( + 'class' => implode(' ', $classes), + ); + } + + protected function getTagContent() { + $items = array(); + foreach ($this->items as $item) { + $items[] = phutil_tag( + 'li', + array( + 'class' => 'phui-badge-flex-item', + ), + $item); + } + return $items; + + } +} diff --git a/src/view/phui/PHUIBadgeView.php b/src/view/phui/PHUIBadgeView.php new file mode 100644 --- /dev/null +++ b/src/view/phui/PHUIBadgeView.php @@ -0,0 +1,215 @@ +icon = $icon; + return $this; + } + + public function setHref($href) { + $this->href = $href; + return $this; + } + + public function setQuality($quality) { + $this->quality = $quality; + return $this; + } + + public function setSource($source) { + $this->source = $source; + return $this; + } + + public function setHeader($header) { + $this->header = $header; + return $this; + } + + public function setSubhead($subhead) { + $this->subhead = $subhead; + return $this; + } + + public function addByline($byline) { + $this->bylines[] = $byline; + return $this; + } + + private function getQualityTitle() { + + switch ($this->quality) { + case self::POOR: + return pht('Poor'); + case self::COMMON: + return pht('Common'); + case self::UNCOMMON: + return pht('Uncommon'); + case self::RARE: + return pht('Rare'); + case self::EPIC: + return pht('Epic'); + case self::LEGENDARY: + return pht('Legendary'); + case self::HEIRLOOM: + return pht('Heirloom'); + } + } + + protected function getTagName() { + return 'span'; + } + + protected function getTagAttributes() { + require_celerity_resource('phui-badge-view-css'); + $id = celerity_generate_unique_node_id(); + + $classes = array(); + $classes[] = 'phui-badge-view'; + if ($this->quality) { + $classes[] = 'phui-badge-view-'.$this->quality; + } + + return array( + 'class' => implode(' ', $classes), + 'sigil' => 'jx-toggle-class', + 'id' => $id, + 'meta' => array( + 'map' => array( + $id => 'card-flipped', + ), + ), + ); + } + + protected function getTagContent() { + + $icon = id(new PHUIIconView()) + ->setIconFont($this->icon); + + $illustration = phutil_tag_div('phui-badge-illustration', $icon); + + $header = null; + if ($this->header) { + $header = phutil_tag( + ($this->href) ? 'a' : 'span', + array( + 'class' => 'phui-badge-view-header', + 'href' => $this->href, + ), + $this->header); + } + + $subhead = null; + if ($this->subhead) { + $subhead = phutil_tag_div('phui-badge-view-subhead', $this->subhead); + } + + $information = phutil_tag( + 'div', + array( + 'class' => 'phui-badge-view-information', + ), + array($header, $subhead)); + + $quality = phutil_tag_div('phui-badge-quality', $this->getQualityTitle()); + $source = phutil_tag_div('phui-badge-source', $this->source); + + $bylines = array(); + if ($this->bylines) { + foreach ($this->bylines as $byline) { + $bylines[] = phutil_tag_div('phui-badge-byline', $byline); + } + } + + $card_front_1 = phutil_tag( + 'div', + array( + 'class' => 'phui-badge-inner-front', + ), + array( + $illustration, + )); + + $card_front_2 = phutil_tag( + 'div', + array( + 'class' => 'phui-badge-inner-front', + ), + array( + $information, + )); + + $back_info = phutil_tag( + 'div', + array( + 'class' => 'phui-badge-view-information', + ), + array( + $quality, + $source, + $bylines, + )); + + $card_back = phutil_tag( + 'div', + array( + 'class' => 'phui-badge-inner-back', + ), + array( + $back_info, + )); + + $inner_front = phutil_tag( + 'div', + array( + 'class' => 'phui-badge-front-view', + ), + array( + $card_front_1, + $card_front_2, + )); + + $inner_back = phutil_tag_div('phui-badge-back-view', $card_back); + $front = phutil_tag_div('phui-badge-card-front', $inner_front); + $back = phutil_tag_div('phui-badge-card-back', $inner_back); + + $card = phutil_tag( + 'div', + array( + 'class' => 'phui-badge-card', + ), + array( + $front, + $back, + )); + + return phutil_tag( + 'div', + array( + 'class' => 'phui-badge-card-container', + ), + $card); + + } + +} diff --git a/webroot/rsrc/css/phui/phui-badge.css b/webroot/rsrc/css/phui/phui-badge.css new file mode 100644 --- /dev/null +++ b/webroot/rsrc/css/phui/phui-badge.css @@ -0,0 +1,159 @@ +/** + * @provides phui-badge-view-css + */ + +.phui-badge-flex-view { + padding: 12px 4px 8px; + overflow: hidden; + text-align: center; +} + +.phui-badge-flex-item { + display: inline-block; + padding: 4px 8px; +} + +.phui-badge-view { + display: inline-block; + position: relative; + perspective: 512px; +} + +.phui-badge-card-container { + transform-style: preserve-3d; + -webkit-transform-style: preserve-3d; + + transition: transform 0.5s; + -webkit-transition: -webkit-transform 0.5s; + + transform-origin: right center; + -webkit-transform-origin: right center; + + width: 100%; + height: 100%; +} + +.phui-badge-card { + cursor: pointer; + padding: 12px; + height: 180px; + width: 128px; + border: 1px solid {$lightgreyborder}; + background-color: {$lightbluebackground}; +} + +.card-flipped .phui-badge-card-container { + transform: translateX( -100% ) rotateY( -180deg ); + -webkit-transform: translateX( -100% ) rotateY( -180deg ); +} + +.phui-badge-card-front, +.phui-badge-card-back { + display: block; + position: absolute; + width: 128px; + height: 100%; + + backface-visibility: hidden; + -webkit-backface-visibility: hidden; + -moz-backface-visibility: hidden; +} + + +/* Firefox Fix */ +.phui-badge-card-front { + transform: rotateY(0deg); + -webkit-trasform: rotateY(0deg); +} + +.phui-badge-front-view, +.phui-badge-back-view { + display: table; + width: 100%; +} + +.phui-badge-inner-front, +.phui-badge-inner-back { + display: table-row; +} + +.phui-badge-illustration { + background-color: #fff; + box-shadow: inset 0 -1px 1px 0 rgba(0,0,0,.1); + text-align: center; + height: 100px; + width: 100%; + vertical-align: middle; + display: table-cell; +} + +.phui-badge-illustration .phui-icon-view { + font-size: 48px; + height: 48px; + width: 48px; + color: {$bluetext}; +} + +.phui-badge-view-information { + display: table-cell; + text-align: center; + color: {$greytext}; +} + +.phui-badge-view-header { + color: {$darkgreytext}; + font-weight: bold; + padding-top: 12px; + display: block; +} + +.phui-badge-quality { + padding: 4px 0; + color: {$darkbluetext}; + font-weight: bold; +} + +.phui-badge-view-subhead { + color: {$lightgreytext}; + font-size: {$smallerfontsize}; +} + +.phui-badge-card-back { + transform: rotateY( 180deg ); + -webkit-transform: rotateY( 180deg ); +} + +/** Quality Levels ***********************************************************/ + +.phui-badge-view-grey .phui-badge-card { + background-color: {$lightgreybackground}; +} + +.phui-badge-view-white .phui-badge-card { + background-color: {$lightbluebackground}; +} + +.phui-badge-view-green .phui-badge-card { + background-color: {$sh-greenbackground}; + border-color: {$sh-lightgreenborder}; +} + +.phui-badge-view-blue .phui-badge-card { + background-color: {$sh-bluebackground}; + border-color: {$sh-lightblueborder}; +} + +.phui-badge-view-indigo .phui-badge-card { + background-color: {$sh-indigobackground}; + border-color: {$sh-lightindigoborder}; +} + +.phui-badge-view-orange .phui-badge-card { + background-color: {$sh-orangebackground}; + border-color: {$sh-lightorangeborder}; +} + +.phui-badge-view-yellow .phui-badge-card { + background-color: {$sh-yellowbackground}; + border-color: {$sh-lightyellowborder}; +}