From c8061d5da8f5c9c276dfa80929bc1c68d84a64e3 Mon Sep 17 00:00:00 2001 From: epriestley Date: Tue, 13 Aug 2013 16:27:26 -0700 Subject: [PATCH] Implement ApplicationSearch in Flags Summary: Ref T1809. Provide ApplicationSearch to Flags and allow the user to select flags by color. @chad might have some design feedback on my control. Test Plan: {F54131} Reviewers: btrahan, chad Reviewed By: chad CC: aran Maniphest Tasks: T1809 Differential Revision: https://secure.phabricator.com/D6747 --- src/__celerity_resource_map__.php | 134 +++++++++--------- src/__phutil_library_map__.php | 12 +- .../PhabricatorApplicationFlags.php | 6 +- .../controller/PhabricatorFlagController.php | 19 +-- .../PhabricatorFlagListController.php | 101 +++++++------ .../query/PhabricatorFlagSearchEngine.php | 62 ++++++++ .../flag/view/PhabricatorFlagListView.php | 74 ---------- .../view/PhabricatorFlagSelectControl.php | 65 +++++++++ webroot/rsrc/css/application/flag/flag.css | 26 ++++ 9 files changed, 304 insertions(+), 195 deletions(-) create mode 100644 src/applications/flag/query/PhabricatorFlagSearchEngine.php delete mode 100644 src/applications/flag/view/PhabricatorFlagListView.php create mode 100644 src/applications/flag/view/PhabricatorFlagSelectControl.php diff --git a/src/__celerity_resource_map__.php b/src/__celerity_resource_map__.php index 1cab206bba..4a328f02c6 100644 --- a/src/__celerity_resource_map__.php +++ b/src/__celerity_resource_map__.php @@ -1617,7 +1617,7 @@ celerity_register_resource_map(array( ), 'javelin-behavior-differential-toggle-files' => array( - 'uri' => '/res/2b266946/rsrc/js/application/differential/behavior-toggle-files.js', + 'uri' => '/res/beb89813/rsrc/js/application/differential/behavior-toggle-files.js', 'type' => 'js', 'requires' => array( @@ -3174,7 +3174,7 @@ celerity_register_resource_map(array( ), 'phabricator-flag-css' => array( - 'uri' => '/res/237234d7/rsrc/css/application/flag/flag.css', + 'uri' => '/res/7c3dd9ea/rsrc/css/application/flag/flag.css', 'type' => 'css', 'requires' => array( @@ -4172,7 +4172,7 @@ celerity_register_resource_map(array( ), array( 'packages' => array( - '638c9d42' => + '566968f8' => array( 'name' => 'core.pkg.css', 'symbols' => @@ -4220,7 +4220,7 @@ celerity_register_resource_map(array( 40 => 'phabricator-property-list-view-css', 41 => 'phabricator-tag-view-css', ), - 'uri' => '/res/pkg/638c9d42/core.pkg.css', + 'uri' => '/res/pkg/566968f8/core.pkg.css', 'type' => 'css', ), '4f81c788' => @@ -4302,7 +4302,7 @@ celerity_register_resource_map(array( 'uri' => '/res/pkg/09216861/differential.pkg.css', 'type' => 'css', ), - '025bdd77' => + 'd07a3bc2' => array( 'name' => 'differential.pkg.js', 'symbols' => @@ -4327,7 +4327,7 @@ celerity_register_resource_map(array( 17 => 'javelin-behavior-differential-toggle-files', 18 => 'javelin-behavior-differential-user-select', ), - 'uri' => '/res/pkg/025bdd77/differential.pkg.js', + 'uri' => '/res/pkg/d07a3bc2/differential.pkg.js', 'type' => 'js', ), 'c8ce2d88' => @@ -4411,19 +4411,19 @@ celerity_register_resource_map(array( ), 'reverse' => array( - 'aphront-dialog-view-css' => '638c9d42', - 'aphront-error-view-css' => '638c9d42', - 'aphront-form-view-css' => '638c9d42', - 'aphront-list-filter-view-css' => '638c9d42', - 'aphront-pager-view-css' => '638c9d42', - 'aphront-panel-view-css' => '638c9d42', - 'aphront-table-view-css' => '638c9d42', - 'aphront-tokenizer-control-css' => '638c9d42', - 'aphront-tooltip-css' => '638c9d42', - 'aphront-typeahead-control-css' => '638c9d42', + 'aphront-dialog-view-css' => '566968f8', + 'aphront-error-view-css' => '566968f8', + 'aphront-form-view-css' => '566968f8', + 'aphront-list-filter-view-css' => '566968f8', + 'aphront-pager-view-css' => '566968f8', + 'aphront-panel-view-css' => '566968f8', + 'aphront-table-view-css' => '566968f8', + 'aphront-tokenizer-control-css' => '566968f8', + 'aphront-tooltip-css' => '566968f8', + 'aphront-typeahead-control-css' => '566968f8', 'differential-changeset-view-css' => '09216861', 'differential-core-view-css' => '09216861', - 'differential-inline-comment-editor' => '025bdd77', + 'differential-inline-comment-editor' => 'd07a3bc2', 'differential-local-commits-view-css' => '09216861', 'differential-results-table-css' => '09216861', 'differential-revision-add-comment-css' => '09216861', @@ -4434,30 +4434,30 @@ celerity_register_resource_map(array( 'differential-table-of-contents-css' => '09216861', 'diffusion-commit-view-css' => 'c8ce2d88', 'diffusion-icons-css' => 'c8ce2d88', - 'global-drag-and-drop-css' => '638c9d42', + 'global-drag-and-drop-css' => '566968f8', 'inline-comment-summary-css' => '09216861', 'javelin-aphlict' => '4f81c788', 'javelin-behavior' => '2dbbb7d1', 'javelin-behavior-aphlict-dropdown' => '4f81c788', 'javelin-behavior-aphlict-listen' => '4f81c788', 'javelin-behavior-aphront-basic-tokenizer' => '4f81c788', - 'javelin-behavior-aphront-drag-and-drop-textarea' => '025bdd77', + 'javelin-behavior-aphront-drag-and-drop-textarea' => 'd07a3bc2', 'javelin-behavior-aphront-form-disable-on-submit' => '4f81c788', 'javelin-behavior-audit-preview' => '96909266', 'javelin-behavior-dark-console' => '4ccfeb47', 'javelin-behavior-device' => '4f81c788', - 'javelin-behavior-differential-accept-with-errors' => '025bdd77', - 'javelin-behavior-differential-add-reviewers-and-ccs' => '025bdd77', - 'javelin-behavior-differential-comment-jump' => '025bdd77', - 'javelin-behavior-differential-diff-radios' => '025bdd77', - 'javelin-behavior-differential-dropdown-menus' => '025bdd77', - 'javelin-behavior-differential-edit-inline-comments' => '025bdd77', - 'javelin-behavior-differential-feedback-preview' => '025bdd77', - 'javelin-behavior-differential-keyboard-navigation' => '025bdd77', - 'javelin-behavior-differential-populate' => '025bdd77', - 'javelin-behavior-differential-show-more' => '025bdd77', - 'javelin-behavior-differential-toggle-files' => '025bdd77', - 'javelin-behavior-differential-user-select' => '025bdd77', + 'javelin-behavior-differential-accept-with-errors' => 'd07a3bc2', + 'javelin-behavior-differential-add-reviewers-and-ccs' => 'd07a3bc2', + 'javelin-behavior-differential-comment-jump' => 'd07a3bc2', + 'javelin-behavior-differential-diff-radios' => 'd07a3bc2', + 'javelin-behavior-differential-dropdown-menus' => 'd07a3bc2', + 'javelin-behavior-differential-edit-inline-comments' => 'd07a3bc2', + 'javelin-behavior-differential-feedback-preview' => 'd07a3bc2', + 'javelin-behavior-differential-keyboard-navigation' => 'd07a3bc2', + 'javelin-behavior-differential-populate' => 'd07a3bc2', + 'javelin-behavior-differential-show-more' => 'd07a3bc2', + 'javelin-behavior-differential-toggle-files' => 'd07a3bc2', + 'javelin-behavior-differential-user-select' => 'd07a3bc2', 'javelin-behavior-diffusion-commit-graph' => '96909266', 'javelin-behavior-diffusion-pull-lastmodified' => '96909266', 'javelin-behavior-error-log' => '4ccfeb47', @@ -4465,7 +4465,7 @@ celerity_register_resource_map(array( 'javelin-behavior-history-install' => '4f81c788', 'javelin-behavior-konami' => '4f81c788', 'javelin-behavior-lightbox-attachments' => '4f81c788', - 'javelin-behavior-load-blame' => '025bdd77', + 'javelin-behavior-load-blame' => 'd07a3bc2', 'javelin-behavior-maniphest-batch-selector' => '98f64f07', 'javelin-behavior-maniphest-subpriority-editor' => '98f64f07', 'javelin-behavior-maniphest-transaction-controls' => '98f64f07', @@ -4477,7 +4477,7 @@ celerity_register_resource_map(array( 'javelin-behavior-phabricator-hovercards' => '4f81c788', 'javelin-behavior-phabricator-keyboard-shortcuts' => '4f81c788', 'javelin-behavior-phabricator-nav' => '4f81c788', - 'javelin-behavior-phabricator-object-selector' => '025bdd77', + 'javelin-behavior-phabricator-object-selector' => 'd07a3bc2', 'javelin-behavior-phabricator-oncopy' => '4f81c788', 'javelin-behavior-phabricator-remarkup-assist' => '4f81c788', 'javelin-behavior-phabricator-reveal-content' => '4f81c788', @@ -4485,7 +4485,7 @@ celerity_register_resource_map(array( 'javelin-behavior-phabricator-tooltips' => '4f81c788', 'javelin-behavior-phabricator-watch-anchor' => '4f81c788', 'javelin-behavior-refresh-csrf' => '4f81c788', - 'javelin-behavior-repository-crossreference' => '025bdd77', + 'javelin-behavior-repository-crossreference' => 'd07a3bc2', 'javelin-behavior-toggle-class' => '4f81c788', 'javelin-behavior-workflow' => '4f81c788', 'javelin-dom' => '2dbbb7d1', @@ -4507,55 +4507,55 @@ celerity_register_resource_map(array( 'javelin-util' => '2dbbb7d1', 'javelin-vector' => '2dbbb7d1', 'javelin-workflow' => '2dbbb7d1', - 'lightbox-attachment-css' => '638c9d42', + 'lightbox-attachment-css' => '566968f8', 'maniphest-task-summary-css' => '06bacb9a', 'maniphest-transaction-detail-css' => '06bacb9a', - 'phabricator-action-list-view-css' => '638c9d42', - 'phabricator-application-launch-view-css' => '638c9d42', + 'phabricator-action-list-view-css' => '566968f8', + 'phabricator-application-launch-view-css' => '566968f8', 'phabricator-busy' => '4f81c788', 'phabricator-content-source-view-css' => '09216861', - 'phabricator-core-css' => '638c9d42', - 'phabricator-crumbs-view-css' => '638c9d42', - 'phabricator-drag-and-drop-file-upload' => '025bdd77', + 'phabricator-core-css' => '566968f8', + 'phabricator-crumbs-view-css' => '566968f8', + 'phabricator-drag-and-drop-file-upload' => 'd07a3bc2', 'phabricator-dropdown-menu' => '4f81c788', 'phabricator-file-upload' => '4f81c788', - 'phabricator-filetree-view-css' => '638c9d42', - 'phabricator-flag-css' => '638c9d42', - 'phabricator-form-view-css' => '638c9d42', - 'phabricator-header-view-css' => '638c9d42', + 'phabricator-filetree-view-css' => '566968f8', + 'phabricator-flag-css' => '566968f8', + 'phabricator-form-view-css' => '566968f8', + 'phabricator-header-view-css' => '566968f8', 'phabricator-hovercard' => '4f81c788', - 'phabricator-jump-nav' => '638c9d42', + 'phabricator-jump-nav' => '566968f8', 'phabricator-keyboard-shortcut' => '4f81c788', 'phabricator-keyboard-shortcut-manager' => '4f81c788', - 'phabricator-main-menu-view' => '638c9d42', + 'phabricator-main-menu-view' => '566968f8', 'phabricator-menu-item' => '4f81c788', - 'phabricator-nav-view-css' => '638c9d42', + 'phabricator-nav-view-css' => '566968f8', 'phabricator-notification' => '4f81c788', - 'phabricator-notification-css' => '638c9d42', - 'phabricator-notification-menu-css' => '638c9d42', - 'phabricator-object-item-list-view-css' => '638c9d42', + 'phabricator-notification-css' => '566968f8', + 'phabricator-notification-menu-css' => '566968f8', + 'phabricator-object-item-list-view-css' => '566968f8', 'phabricator-object-selector-css' => '09216861', 'phabricator-phtize' => '4f81c788', 'phabricator-prefab' => '4f81c788', 'phabricator-project-tag-css' => '06bacb9a', - 'phabricator-property-list-view-css' => '638c9d42', - 'phabricator-remarkup-css' => '638c9d42', - 'phabricator-shaped-request' => '025bdd77', - 'phabricator-side-menu-view-css' => '638c9d42', - 'phabricator-standard-page-view' => '638c9d42', - 'phabricator-tag-view-css' => '638c9d42', + 'phabricator-property-list-view-css' => '566968f8', + 'phabricator-remarkup-css' => '566968f8', + 'phabricator-shaped-request' => 'd07a3bc2', + 'phabricator-side-menu-view-css' => '566968f8', + 'phabricator-standard-page-view' => '566968f8', + 'phabricator-tag-view-css' => '566968f8', 'phabricator-textareautils' => '4f81c788', 'phabricator-tooltip' => '4f81c788', - 'phabricator-transaction-view-css' => '638c9d42', - 'phabricator-zindex-css' => '638c9d42', - 'phui-button-css' => '638c9d42', - 'phui-form-css' => '638c9d42', - 'phui-icon-view-css' => '638c9d42', - 'phui-spacing-css' => '638c9d42', - 'sprite-apps-large-css' => '638c9d42', - 'sprite-gradient-css' => '638c9d42', - 'sprite-icons-css' => '638c9d42', - 'sprite-menu-css' => '638c9d42', - 'syntax-highlighting-css' => '638c9d42', + 'phabricator-transaction-view-css' => '566968f8', + 'phabricator-zindex-css' => '566968f8', + 'phui-button-css' => '566968f8', + 'phui-form-css' => '566968f8', + 'phui-icon-view-css' => '566968f8', + 'phui-spacing-css' => '566968f8', + 'sprite-apps-large-css' => '566968f8', + 'sprite-gradient-css' => '566968f8', + 'sprite-icons-css' => '566968f8', + 'sprite-menu-css' => '566968f8', + 'syntax-highlighting-css' => '566968f8', ), )); diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 87759b4ebc..65d81d142d 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1184,8 +1184,9 @@ phutil_register_library_map(array( 'PhabricatorFlagDeleteController' => 'applications/flag/controller/PhabricatorFlagDeleteController.php', 'PhabricatorFlagEditController' => 'applications/flag/controller/PhabricatorFlagEditController.php', 'PhabricatorFlagListController' => 'applications/flag/controller/PhabricatorFlagListController.php', - 'PhabricatorFlagListView' => 'applications/flag/view/PhabricatorFlagListView.php', 'PhabricatorFlagQuery' => 'applications/flag/query/PhabricatorFlagQuery.php', + 'PhabricatorFlagSearchEngine' => 'applications/flag/query/PhabricatorFlagSearchEngine.php', + 'PhabricatorFlagSelectControl' => 'applications/flag/view/PhabricatorFlagSelectControl.php', 'PhabricatorFlagsUIEventListener' => 'applications/flag/events/PhabricatorFlagsUIEventListener.php', 'PhabricatorFormExample' => 'applications/uiexample/examples/PhabricatorFormExample.php', 'PhabricatorGarbageCollectorConfigOptions' => 'applications/config/option/PhabricatorGarbageCollectorConfigOptions.php', @@ -3261,9 +3262,14 @@ phutil_register_library_map(array( 'PhabricatorFlagDAO' => 'PhabricatorLiskDAO', 'PhabricatorFlagDeleteController' => 'PhabricatorFlagController', 'PhabricatorFlagEditController' => 'PhabricatorFlagController', - 'PhabricatorFlagListController' => 'PhabricatorFlagController', - 'PhabricatorFlagListView' => 'AphrontView', + 'PhabricatorFlagListController' => + array( + 0 => 'PhabricatorFlagController', + 1 => 'PhabricatorApplicationSearchResultsControllerInterface', + ), 'PhabricatorFlagQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', + 'PhabricatorFlagSearchEngine' => 'PhabricatorApplicationSearchEngine', + 'PhabricatorFlagSelectControl' => 'AphrontFormControl', 'PhabricatorFlagsUIEventListener' => 'PhutilEventListener', 'PhabricatorFormExample' => 'PhabricatorUIExample', 'PhabricatorGarbageCollectorConfigOptions' => 'PhabricatorApplicationConfigOptions', diff --git a/src/applications/flag/application/PhabricatorApplicationFlags.php b/src/applications/flag/application/PhabricatorApplicationFlags.php index 74c1f7d73d..51737fed67 100644 --- a/src/applications/flag/application/PhabricatorApplicationFlags.php +++ b/src/applications/flag/application/PhabricatorApplicationFlags.php @@ -20,6 +20,10 @@ final class PhabricatorApplicationFlags extends PhabricatorApplication { ); } + public function getTitleGlyph() { + return "\xE2\x9A\x90"; + } + public function getApplicationGroup() { return self::GROUP_ORGANIZATION; } @@ -45,7 +49,7 @@ final class PhabricatorApplicationFlags extends PhabricatorApplication { public function getRoutes() { return array( '/flag/' => array( - '' => 'PhabricatorFlagListController', + '(?:query/(?P[^/]+)/)?' => 'PhabricatorFlagListController', 'view/(?P[^/]+)/' => 'PhabricatorFlagListController', 'edit/(?P[^/]+)/' => 'PhabricatorFlagEditController', 'delete/(?P[1-9]\d*)/' => 'PhabricatorFlagDeleteController', diff --git a/src/applications/flag/controller/PhabricatorFlagController.php b/src/applications/flag/controller/PhabricatorFlagController.php index 1fbe0662ee..fa49c38a3c 100644 --- a/src/applications/flag/controller/PhabricatorFlagController.php +++ b/src/applications/flag/controller/PhabricatorFlagController.php @@ -2,18 +2,19 @@ abstract class PhabricatorFlagController extends PhabricatorController { - public function buildStandardPageResponse($view, array $data) { + public function buildSideNavView() { + $user = $this->getRequest()->getUser(); - $page = $this->buildStandardPageView(); + $nav = new AphrontSideNavFilterView(); + $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); - $page->setApplicationName(pht('Flag')); - $page->setBaseURI('/flag/'); - $page->setTitle(idx($data, 'title')); - $page->setGlyph("\xE2\x9A\x90"); // Subtle! - $page->appendChild($view); + id(new PhabricatorFlagSearchEngine()) + ->setViewer($user) + ->addNavigationItems($nav->getMenu()); - $response = new AphrontWebpageResponse(); - return $response->setContent($page->render()); + $nav->selectFilter(null); + return $nav; } + } diff --git a/src/applications/flag/controller/PhabricatorFlagListController.php b/src/applications/flag/controller/PhabricatorFlagListController.php index c5c416253b..2258f252fb 100644 --- a/src/applications/flag/controller/PhabricatorFlagListController.php +++ b/src/applications/flag/controller/PhabricatorFlagListController.php @@ -1,59 +1,78 @@ queryKey = idx($data, 'queryKey'); + } public function processRequest() { $request = $this->getRequest(); - $user = $request->getUser(); - $flag_order = $request->getStr('o', 'n'); + $controller = id(new PhabricatorApplicationSearchController($request)) + ->setQueryKey($this->queryKey) + ->setSearchEngine(new PhabricatorFlagSearchEngine()) + ->setNavigation($this->buildSideNavView()); - $nav = new AphrontSideNavFilterView(); - $nav->setBaseURI(new PhutilURI('/flag/view/')); - $nav->addLabel(pht('Flags')); - $nav->addFilter('all', pht('Your Flags')); - $nav->selectFilter('all', 'all'); + return $this->delegateToController($controller); + } - $crumbs = $this->buildApplicationCrumbs(); - $crumbs->addCrumb(id(new PhabricatorCrumbView) - ->setName(pht('Flags')) - ->setHref($request->getRequestURI())); - $nav->setCrumbs($crumbs); + public function renderResultsList( + array $flags, + PhabricatorSavedQuery $query) { + assert_instances_of($flags, 'PhabricatorFlag'); - $query = new PhabricatorFlagQuery(); - $query->withOwnerPHIDs(array($user->getPHID())); - $query->setViewer($user); - $query->needHandles(true); + $viewer = $this->getRequest()->getUser(); - $flags = $query->execute(); + $list = id(new PhabricatorObjectItemListView()) + ->setUser($viewer); + foreach ($flags as $flag) { + $id = $flag->getID(); + $phid = $flag->getObjectPHID(); - $views = array(); - $view = new PhabricatorFlagListView(); - $view->setFlags($flags); - $view->setUser($user); - $view->setFlush(true); - $views[] = array( - 'view' => $view, - ); + $class = PhabricatorFlagColor::getCSSClass($flag->getColor()); - foreach ($views as $view) { - $panel = new AphrontPanelView(); - $panel->setNoBackground(); + $flag_icon = phutil_tag( + 'div', + array( + 'class' => 'phabricator-flag-icon '.$class, + ), + ''); - $title = idx($view, 'title'); - if ($title) { - $panel->setHeader($title); + $item = id(new PhabricatorObjectItemView()) + ->addHeadIcon($flag_icon) + ->setHeader($flag->getHandle()->renderLink()); + + $item->addAction( + id(new PHUIListItemView()) + ->setIcon('edit') + ->setHref($this->getApplicationURI("edit/{$phid}/")) + ->setWorkflow(true)); + + $item->addAction( + id(new PHUIListItemView()) + ->setIcon('delete') + ->setHref($this->getApplicationURI("delete/{$id}/")) + ->setWorkflow(true)); + + if ($flag->getNote()) { + $item->addAttribute($flag->getNote()); } - $panel->appendChild($view['view']); - $nav->appendChild($panel); + + $item->addIcon( + 'none', + phabricator_datetime($flag->getDateCreated(), $viewer)); + + $list->addItem($item); } - return $this->buildApplicationPage( - $nav, - array( - 'title' => pht('Flags'), - 'device' => true, - 'dust' => true, - )); + return $list; } } diff --git a/src/applications/flag/query/PhabricatorFlagSearchEngine.php b/src/applications/flag/query/PhabricatorFlagSearchEngine.php new file mode 100644 index 0000000000..acca9b5d71 --- /dev/null +++ b/src/applications/flag/query/PhabricatorFlagSearchEngine.php @@ -0,0 +1,62 @@ +setParameter('colors', $request->getArr('colors')); + return $saved; + } + + public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { + $query = id(new PhabricatorFlagQuery()) + ->needHandles(true) + ->withOwnerPHIDs(array($this->requireViewer()->getPHID())); + + $colors = $saved->getParameter('colors'); + if ($colors) { + $query->withColors($colors); + } + + return $query; + } + + public function buildSearchForm( + AphrontFormView $form, + PhabricatorSavedQuery $saved_query) { + + $form->appendChild( + id(new PhabricatorFlagSelectControl()) + ->setName('colors') + ->setLabel(pht('Colors')) + ->setValue($saved_query->getParameter('colors', array()))); + + } + + protected function getURI($path) { + return '/flag/'.$path; + } + + public function getBuiltinQueryNames() { + $names = array( + 'all' => pht('Flagged'), + ); + + return $names; + } + + public function buildSavedQueryFromBuiltin($query_key) { + + $query = $this->newSavedQuery(); + $query->setQueryKey($query_key); + + switch ($query_key) { + case 'all': + return $query; + } + + return parent::buildSavedQueryFromBuiltin($query_key); + } + +} diff --git a/src/applications/flag/view/PhabricatorFlagListView.php b/src/applications/flag/view/PhabricatorFlagListView.php deleted file mode 100644 index 2b31ddf887..0000000000 --- a/src/applications/flag/view/PhabricatorFlagListView.php +++ /dev/null @@ -1,74 +0,0 @@ -flags = $flags; - return $this; - } - - public function setFlush($flush) { - $this->flush = $flush; - return $this; - } - - public function render() { - $user = $this->user; - - require_celerity_resource('phabricator-flag-css'); - - $list = new PhabricatorObjectItemListView(); - $list->setCards(true); - $list->setNoDataString(pht('No flags.')); - $list->setFlush($this->flush); - - $rows = array(); - foreach ($this->flags as $flag) { - $class = PhabricatorFlagColor::getCSSClass($flag->getColor()); - - $flag_icon = phutil_tag( - 'div', - array( - 'class' => 'phabricator-flag-icon '.$class, - ), - ''); - - $edit_link = javelin_tag( - 'a', - array( - 'href' => '/flag/edit/'.$flag->getObjectPHID().'/', - 'sigil' => 'workflow', - ), - pht('Edit')); - - $remove_link = javelin_tag( - 'a', - array( - 'href' => '/flag/delete/'.$flag->getID().'/', - 'sigil' => 'workflow', - ), - pht('Remove')); - - $item = new PhabricatorObjectItemView(); - $item->addIcon('edit', $edit_link); - $item->addIcon('delete', $remove_link); - - $item->addHeadIcon($flag_icon); - $item->setHeader($flag->getHandle()->renderLink()); - - $item->addAttribute(phabricator_datetime($flag->getDateCreated(), $user)); - - if ($flag->getNote()) { - $item->addAttribute($flag->getNote()); - } - - $list->addItem($item); - } - - return $list; - } -} diff --git a/src/applications/flag/view/PhabricatorFlagSelectControl.php b/src/applications/flag/view/PhabricatorFlagSelectControl.php new file mode 100644 index 0000000000..f3a9c20aa2 --- /dev/null +++ b/src/applications/flag/view/PhabricatorFlagSelectControl.php @@ -0,0 +1,65 @@ +getValue()); + + $file_map = array( + PhabricatorFlagColor::COLOR_RED => 'red', + PhabricatorFlagColor::COLOR_ORANGE => 'orange', + PhabricatorFlagColor::COLOR_YELLOW => 'yellow', + PhabricatorFlagColor::COLOR_GREEN => 'green', + PhabricatorFlagColor::COLOR_BLUE => 'blue', + PhabricatorFlagColor::COLOR_PINK => 'pink', + PhabricatorFlagColor::COLOR_PURPLE => 'purple', + PhabricatorFlagColor::COLOR_CHECKERED => 'finish', + ); + + $out = array(); + foreach ($colors as $const => $name) { + // TODO: This should probably be a sprite sheet. + $partial = $file_map[$const]; + $uri = '/rsrc/image/icon/fatcow/flag_'.$partial.'.png'; + $uri = celerity_get_resource_uri($uri); + + $icon = id(new PHUIIconView()) + ->setImage($uri); + + $input = phutil_tag( + 'input', + array( + 'type' => 'checkbox', + 'name' => $this->getName().'[]', + 'value' => $const, + 'checked' => isset($value_map[$const]) + ? 'checked' + : null, + 'class' => 'phabricator-flag-select-checkbox', + )); + + $label = phutil_tag( + 'label', + array( + 'class' => 'phabricator-flag-select-label', + ), + array( + $icon, + $input, + )); + + $out[] = $label; + } + + return $out; + } + +} diff --git a/webroot/rsrc/css/application/flag/flag.css b/webroot/rsrc/css/application/flag/flag.css index b5a1a8c17b..1863be060d 100644 --- a/webroot/rsrc/css/application/flag/flag.css +++ b/webroot/rsrc/css/application/flag/flag.css @@ -55,3 +55,29 @@ .phabricator-flag-ghost { background-image: url(/rsrc/image/icon/fatcow/flag_ghost.png); } + +.phabricator-flag-select-control .phabricator-flag-select-label { + border: 1px solid #aaaaaa; + width: 48px; + height: 24px; + border-radius: 4px; + position: relative; + display: inline-block; + cursor: pointer; + margin: 0 4px 4px 0; +} + +.phabricator-flag-select-control .phabricator-flag-select-checkbox { + position: absolute; + top: 2px; + left: 4px; + width: auto; +} + +.phabricator-flag-select-control .phui-icon-view { + position: absolute; + width: 16px; + height: 16px; + top: 4px; + left: 24px; +}