diff --git a/src/applications/audit/view/PhabricatorAuditListView.php b/src/applications/audit/view/PhabricatorAuditListView.php index f200d4da9b..20b7ffcf9d 100644 --- a/src/applications/audit/view/PhabricatorAuditListView.php +++ b/src/applications/audit/view/PhabricatorAuditListView.php @@ -1,183 +1,183 @@ handles = $handles; return $this; } public function setAuthorityPHIDs(array $phids) { $this->authorityPHIDs = $phids; return $this; } public function setNoDataString($no_data_string) { $this->noDataString = $no_data_string; return $this; } public function getNoDataString() { return $this->noDataString; } /** * These commits should have both commit data and audit requests attached. */ public function setCommits(array $commits) { assert_instances_of($commits, 'PhabricatorRepositoryCommit'); $this->commits = mpull($commits, null, 'getPHID'); return $this; } public function getCommits() { return $this->commits; } public function getRequiredHandlePHIDs() { $phids = array(); $commits = $this->getCommits(); foreach ($commits as $commit) { $phids[$commit->getPHID()] = true; $phids[$commit->getAuthorPHID()] = true; $audits = $commit->getAudits(); foreach ($audits as $audit) { $phids[$audit->getAuditorPHID()] = true; } } return array_keys($phids); } private function getHandle($phid) { $handle = idx($this->handles, $phid); if (!$handle) { throw new Exception(pht("No handle for '%s'!", $phid)); } return $handle; } private function getCommitDescription($phid) { if ($this->commits === null) { return pht('(Unknown Commit)'); } $commit = idx($this->commits, $phid); if (!$commit) { return pht('(Unknown Commit)'); } $summary = $commit->getCommitData()->getSummary(); if (strlen($summary)) { return $summary; } // No summary, so either this is still impoting or just has an empty // commit message. if (!$commit->isImported()) { return pht('(Importing Commit...)'); } else { return pht('(Untitled Commit)'); } } public function render() { $list = $this->buildList(); $list->setFlush(true); return $list->render(); } public function buildList() { $user = $this->getUser(); if (!$user) { throw new Exception( pht( 'You must %s before %s!', 'setUser()', __FUNCTION__.'()')); } $rowc = array(); $list = new PHUIObjectItemListView(); foreach ($this->commits as $commit) { $commit_phid = $commit->getPHID(); $commit_handle = $this->getHandle($commit_phid); $committed = null; $commit_name = $commit_handle->getName(); $commit_link = $commit_handle->getURI(); $commit_desc = $this->getCommitDescription($commit_phid); $committed = phabricator_datetime($commit->getEpoch(), $user); $audits = mpull($commit->getAudits(), null, 'getAuditorPHID'); $auditors = array(); $reasons = array(); foreach ($audits as $audit) { $auditor_phid = $audit->getAuditorPHID(); $auditors[$auditor_phid] = $this->getHandle($auditor_phid)->renderLink(); } $auditors = phutil_implode_html(', ', $auditors); $authority_audits = array_select_keys($audits, $this->authorityPHIDs); if ($authority_audits) { $audit = reset($authority_audits); } else { $audit = reset($audits); } if ($audit) { $reasons = $audit->getAuditReasons(); $reasons = phutil_implode_html(', ', $reasons); $status_code = $audit->getAuditStatus(); $status_text = PhabricatorAuditStatusConstants::getStatusName($status_code); $status_color = PhabricatorAuditStatusConstants::getStatusColor($status_code); } else { $reasons = null; $status_text = null; $status_color = null; } $author_phid = $commit->getAuthorPHID(); if ($author_phid) { $author_name = $this->getHandle($author_phid)->renderLink(); } else { $author_name = $commit->getCommitData()->getAuthorName(); } $item = id(new PHUIObjectItemView()) ->setObjectName($commit_name) ->setHeader($commit_desc) ->setHref($commit_link) - ->addAttribute($status_text) + ->addAttribute(pht('Author: %s', $author_name)) ->addAttribute($reasons) - ->addIcon('none', $committed) - ->setSubHead(pht('Author: %s', $author_name)); + ->addIcon('none', $committed); if (!empty($auditors)) { $item->addByLine(pht('Auditors: %s', $auditors)); } if ($status_color) { - $item->setStatusIcon('fa-exclamation-triangle '.$status_color); + $item->setStatusIcon( + 'fa-exclamation-triangle '.$status_color, $status_text); } $list->addItem($item); } if ($this->noDataString) { $list->setNoDataString($this->noDataString); } return $list; } } diff --git a/src/applications/harbormaster/query/HarbormasterBuildableSearchEngine.php b/src/applications/harbormaster/query/HarbormasterBuildableSearchEngine.php index 74883c5c10..07ab571a2d 100644 --- a/src/applications/harbormaster/query/HarbormasterBuildableSearchEngine.php +++ b/src/applications/harbormaster/query/HarbormasterBuildableSearchEngine.php @@ -1,221 +1,222 @@ readPHIDsFromRequest( $request, 'revisions', array( DifferentialRevisionPHIDType::TYPECONST, )); $repositories = $this->readPHIDsFromRequest( $request, 'repositories', array( PhabricatorRepositoryRepositoryPHIDType::TYPECONST, )); $container_phids = array_merge($revisions, $repositories); $saved->setParameter('containerPHIDs', $container_phids); $commits = $this->readPHIDsFromRequest( $request, 'commits', array( PhabricatorRepositoryCommitPHIDType::TYPECONST, )); $diffs = $this->readListFromRequest($request, 'diffs'); if ($diffs) { $diffs = id(new DifferentialDiffQuery()) ->setViewer($this->requireViewer()) ->withIDs($diffs) ->execute(); $diffs = mpull($diffs, 'getPHID', 'getPHID'); } $buildable_phids = array_merge($commits, $diffs); $saved->setParameter('buildablePHIDs', $buildable_phids); $saved->setParameter( 'manual', $this->readBoolFromRequest($request, 'manual')); return $saved; } public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { $query = id(new HarbormasterBuildableQuery()) ->needContainerHandles(true) ->needBuildableHandles(true); $container_phids = $saved->getParameter('containerPHIDs', array()); if ($container_phids) { $query->withContainerPHIDs($container_phids); } $buildable_phids = $saved->getParameter('buildablePHIDs', array()); if ($buildable_phids) { $query->withBuildablePHIDs($buildable_phids); } $manual = $saved->getParameter('manual'); if ($manual !== null) { $query->withManualBuildables($manual); } return $query; } public function buildSearchForm( AphrontFormView $form, PhabricatorSavedQuery $saved_query) { $container_phids = $saved_query->getParameter('containerPHIDs', array()); $buildable_phids = $saved_query->getParameter('buildablePHIDs', array()); $all_phids = array_merge($container_phids, $buildable_phids); $revision_names = array(); $diff_names = array(); $repository_names = array(); $commit_names = array(); if ($all_phids) { $objects = id(new PhabricatorObjectQuery()) ->setViewer($this->requireViewer()) ->withPHIDs($all_phids) ->execute(); foreach ($all_phids as $phid) { $object = idx($objects, $phid); if (!$object) { continue; } if ($object instanceof DifferentialRevision) { $revision_names[] = 'D'.$object->getID(); } else if ($object instanceof DifferentialDiff) { $diff_names[] = $object->getID(); } else if ($object instanceof PhabricatorRepository) { $repository_names[] = 'r'.$object->getCallsign(); } else if ($object instanceof PhabricatorRepositoryCommit) { $repository = $object->getRepository(); $commit_names[] = $repository->formatCommitName( $object->getCommitIdentifier()); } } } $form ->appendChild( id(new AphrontFormTextControl()) ->setLabel(pht('Differential Revisions')) ->setName('revisions') ->setValue(implode(', ', $revision_names))) ->appendChild( id(new AphrontFormTextControl()) ->setLabel(pht('Differential Diffs')) ->setName('diffs') ->setValue(implode(', ', $diff_names))) ->appendChild( id(new AphrontFormTextControl()) ->setLabel(pht('Repositories')) ->setName('repositories') ->setValue(implode(', ', $repository_names))) ->appendChild( id(new AphrontFormTextControl()) ->setLabel(pht('Commits')) ->setName('commits') ->setValue(implode(', ', $commit_names))) ->appendChild( id(new AphrontFormSelectControl()) ->setLabel(pht('Origin')) ->setName('manual') ->setValue($this->getBoolFromQuery($saved_query, 'manual')) ->setOptions( array( '' => pht('(All Origins)'), 'true' => pht('Manual Buildables'), 'false' => pht('Automatic Buildables'), ))); } protected function getURI($path) { return '/harbormaster/'.$path; } protected function getBuiltinQueryNames() { return array( 'all' => pht('All Buildables'), ); } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'all': return $query; } return parent::buildSavedQueryFromBuiltin($query_key); } protected function renderResultList( array $buildables, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($buildables, 'HarbormasterBuildable'); $viewer = $this->requireViewer(); $list = new PHUIObjectItemListView(); foreach ($buildables as $buildable) { $id = $buildable->getID(); $item = id(new PHUIObjectItemView()) ->setHeader(pht('Buildable %d', $buildable->getID())); if ($buildable->getContainerHandle() !== null) { $item->addAttribute($buildable->getContainerHandle()->getName()); } if ($buildable->getBuildableHandle() !== null) { $item->addAttribute($buildable->getBuildableHandle()->getFullName()); } if ($id) { $item->setHref("/B{$id}"); } if ($buildable->getIsManualBuildable()) { $item->addIcon('fa-wrench grey', pht('Manual')); } - $item->setBarColor(HarbormasterBuildable::getBuildableStatusColor( + $item->setStatusIcon('fa-wrench '. + HarbormasterBuildable::getBuildableStatusColor( $buildable->getBuildableStatus())); $item->addByline(HarbormasterBuildable::getBuildableStatusName( $buildable->getBuildableStatus())); $list->addItem($item); } return $list; } } diff --git a/src/applications/phortune/controller/PhortuneAccountViewController.php b/src/applications/phortune/controller/PhortuneAccountViewController.php index e2ab3badf4..7199b37799 100644 --- a/src/applications/phortune/controller/PhortuneAccountViewController.php +++ b/src/applications/phortune/controller/PhortuneAccountViewController.php @@ -1,386 +1,387 @@ getViewer(); // TODO: Currently, you must be able to edit an account to view the detail // page, because the account must be broadly visible so merchants can // process orders but merchants should not be able to see all the details // of an account. Ideally this page should be visible to merchants, too, // just with less information. $can_edit = true; $account = id(new PhortuneAccountQuery()) ->setViewer($viewer) ->withIDs(array($request->getURIData('accountID'))) ->requireCapabilities( array( PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT, )) ->executeOne(); if (!$account) { return new Aphront404Response(); } $title = $account->getName(); $invoices = id(new PhortuneCartQuery()) ->setViewer($viewer) ->withAccountPHIDs(array($account->getPHID())) ->needPurchases(true) ->withInvoices(true) ->execute(); $crumbs = $this->buildApplicationCrumbs(); $this->addAccountCrumb($crumbs, $account, $link = false); $header = id(new PHUIHeaderView()) ->setHeader($title); $edit_uri = $this->getApplicationURI('account/edit/'.$account->getID().'/'); $actions = id(new PhabricatorActionListView()) ->setUser($viewer) ->setObjectURI($request->getRequestURI()) ->addAction( id(new PhabricatorActionView()) ->setName(pht('Edit Account')) ->setIcon('fa-pencil') ->setHref($edit_uri) ->setDisabled(!$can_edit) ->setWorkflow(!$can_edit)); $properties = id(new PHUIPropertyListView()) ->setObject($account) ->setUser($viewer); $properties->addProperty( pht('Members'), $viewer->renderHandleList($account->getMemberPHIDs())); $status_items = $this->getStatusItemsForAccount($account, $invoices); $status_view = new PHUIStatusListView(); foreach ($status_items as $item) { $status_view->addItem( id(new PHUIStatusItemView()) ->setIcon( idx($item, 'icon'), idx($item, 'color'), idx($item, 'label')) ->setTarget(idx($item, 'target')) ->setNote(idx($item, 'note'))); } $properties->addProperty( pht('Status'), $status_view); $properties->setActionList($actions); $invoices = $this->buildInvoicesSection($account, $invoices); $purchase_history = $this->buildPurchaseHistorySection($account); $charge_history = $this->buildChargeHistorySection($account); $subscriptions = $this->buildSubscriptionsSection($account); $payment_methods = $this->buildPaymentMethodsSection($account); $timeline = $this->buildTransactionTimeline( $account, new PhortuneAccountTransactionQuery()); $timeline->setShouldTerminate(true); $object_box = id(new PHUIObjectBoxView()) ->setHeader($header) ->addPropertyList($properties); return $this->buildApplicationPage( array( $crumbs, $object_box, $invoices, $purchase_history, $charge_history, $subscriptions, $payment_methods, $timeline, ), array( 'title' => $title, )); } private function buildPaymentMethodsSection(PhortuneAccount $account) { $request = $this->getRequest(); $viewer = $request->getUser(); $can_edit = PhabricatorPolicyFilter::hasCapability( $viewer, $account, PhabricatorPolicyCapability::CAN_EDIT); $id = $account->getID(); $header = id(new PHUIHeaderView()) ->setHeader(pht('Payment Methods')); $list = id(new PHUIObjectItemListView()) ->setUser($viewer) ->setFlush(true) ->setNoDataString( pht('No payment methods associated with this account.')); $methods = id(new PhortunePaymentMethodQuery()) ->setViewer($viewer) ->withAccountPHIDs(array($account->getPHID())) ->execute(); foreach ($methods as $method) { $id = $method->getID(); $item = new PHUIObjectItemView(); $item->setHeader($method->getFullDisplayName()); switch ($method->getStatus()) { case PhortunePaymentMethod::STATUS_ACTIVE: - $item->setBarColor('green'); + $item->setStatusIcon('fa-check green'); $disable_uri = $this->getApplicationURI('card/'.$id.'/disable/'); $item->addAction( id(new PHUIListItemView()) ->setIcon('fa-times') ->setHref($disable_uri) ->setDisabled(!$can_edit) ->setWorkflow(true)); break; case PhortunePaymentMethod::STATUS_DISABLED: + $item->setStatusIcon('fa-ban lightbluetext'); $item->setDisabled(true); break; } $provider = $method->buildPaymentProvider(); $item->addAttribute($provider->getPaymentMethodProviderDescription()); $edit_uri = $this->getApplicationURI('card/'.$id.'/edit/'); $item->addAction( id(new PHUIListItemView()) ->setIcon('fa-pencil') ->setHref($edit_uri) ->setDisabled(!$can_edit) ->setWorkflow(!$can_edit)); $list->addItem($item); } return id(new PHUIObjectBoxView()) ->setHeader($header) ->setObjectList($list); } private function buildInvoicesSection( PhortuneAccount $account, array $carts) { $request = $this->getRequest(); $viewer = $request->getUser(); $phids = array(); foreach ($carts as $cart) { $phids[] = $cart->getPHID(); $phids[] = $cart->getMerchantPHID(); foreach ($cart->getPurchases() as $purchase) { $phids[] = $purchase->getPHID(); } } $handles = $this->loadViewerHandles($phids); $table = id(new PhortuneOrderTableView()) ->setNoDataString(pht('You have no unpaid invoices.')) ->setIsInvoices(true) ->setUser($viewer) ->setCarts($carts) ->setHandles($handles); $header = id(new PHUIHeaderView()) ->setHeader(pht('Invoices Due')); return id(new PHUIObjectBoxView()) ->setHeader($header) ->setTable($table); } private function buildPurchaseHistorySection(PhortuneAccount $account) { $request = $this->getRequest(); $viewer = $request->getUser(); $carts = id(new PhortuneCartQuery()) ->setViewer($viewer) ->withAccountPHIDs(array($account->getPHID())) ->needPurchases(true) ->withStatuses( array( PhortuneCart::STATUS_PURCHASING, PhortuneCart::STATUS_CHARGED, PhortuneCart::STATUS_HOLD, PhortuneCart::STATUS_REVIEW, PhortuneCart::STATUS_PURCHASED, )) ->setLimit(10) ->execute(); $phids = array(); foreach ($carts as $cart) { $phids[] = $cart->getPHID(); foreach ($cart->getPurchases() as $purchase) { $phids[] = $purchase->getPHID(); } } $handles = $this->loadViewerHandles($phids); $orders_uri = $this->getApplicationURI($account->getID().'/order/'); $table = id(new PhortuneOrderTableView()) ->setUser($viewer) ->setCarts($carts) ->setHandles($handles); $header = id(new PHUIHeaderView()) ->setHeader(pht('Recent Orders')) ->addActionLink( id(new PHUIButtonView()) ->setTag('a') ->setIcon( id(new PHUIIconView()) ->setIconFont('fa-list')) ->setHref($orders_uri) ->setText(pht('View All Orders'))); return id(new PHUIObjectBoxView()) ->setHeader($header) ->setTable($table); } private function buildChargeHistorySection(PhortuneAccount $account) { $request = $this->getRequest(); $viewer = $request->getUser(); $charges = id(new PhortuneChargeQuery()) ->setViewer($viewer) ->withAccountPHIDs(array($account->getPHID())) ->needCarts(true) ->setLimit(10) ->execute(); $phids = array(); foreach ($charges as $charge) { $phids[] = $charge->getProviderPHID(); $phids[] = $charge->getCartPHID(); $phids[] = $charge->getMerchantPHID(); $phids[] = $charge->getPaymentMethodPHID(); } $handles = $this->loadViewerHandles($phids); $charges_uri = $this->getApplicationURI($account->getID().'/charge/'); $table = id(new PhortuneChargeTableView()) ->setUser($viewer) ->setCharges($charges) ->setHandles($handles); $header = id(new PHUIHeaderView()) ->setHeader(pht('Recent Charges')) ->addActionLink( id(new PHUIButtonView()) ->setTag('a') ->setIcon( id(new PHUIIconView()) ->setIconFont('fa-list')) ->setHref($charges_uri) ->setText(pht('View All Charges'))); return id(new PHUIObjectBoxView()) ->setHeader($header) ->setTable($table); } private function buildSubscriptionsSection(PhortuneAccount $account) { $request = $this->getRequest(); $viewer = $request->getUser(); $subscriptions = id(new PhortuneSubscriptionQuery()) ->setViewer($viewer) ->withAccountPHIDs(array($account->getPHID())) ->setLimit(10) ->execute(); $subscriptions_uri = $this->getApplicationURI( $account->getID().'/subscription/'); $handles = $this->loadViewerHandles(mpull($subscriptions, 'getPHID')); $table = id(new PhortuneSubscriptionTableView()) ->setUser($viewer) ->setHandles($handles) ->setSubscriptions($subscriptions); $header = id(new PHUIHeaderView()) ->setHeader(pht('Recent Subscriptions')) ->addActionLink( id(new PHUIButtonView()) ->setTag('a') ->setIcon( id(new PHUIIconView()) ->setIconFont('fa-list')) ->setHref($subscriptions_uri) ->setText(pht('View All Subscriptions'))); return id(new PHUIObjectBoxView()) ->setHeader($header) ->setTable($table); } protected function buildApplicationCrumbs() { $crumbs = parent::buildApplicationCrumbs(); $crumbs->addAction( id(new PHUIListItemView()) ->setIcon('fa-exchange') ->setHref($this->getApplicationURI('account/')) ->setName(pht('Switch Accounts'))); return $crumbs; } private function getStatusItemsForAccount( PhortuneAccount $account, array $invoices) { assert_instances_of($invoices, 'PhortuneCart'); $items = array(); if ($invoices) { $items[] = array( 'icon' => PHUIStatusItemView::ICON_WARNING, 'color' => 'yellow', 'target' => pht('Invoices'), 'note' => pht('You have %d unpaid invoice(s).', count($invoices)), ); } else { $items[] = array( 'icon' => PHUIStatusItemView::ICON_ACCEPT, 'color' => 'green', 'target' => pht('Invoices'), 'note' => pht('This account has no unpaid invoices.'), ); } // TODO: If a payment method has expired or is expiring soon, we should // add a status check for it. return $items; } } diff --git a/src/applications/phortune/controller/PhortuneMerchantViewController.php b/src/applications/phortune/controller/PhortuneMerchantViewController.php index 6b072bcc13..5821dccb32 100644 --- a/src/applications/phortune/controller/PhortuneMerchantViewController.php +++ b/src/applications/phortune/controller/PhortuneMerchantViewController.php @@ -1,300 +1,300 @@ id = $data['id']; } public function processRequest() { $request = $this->getRequest(); $viewer = $request->getUser(); $merchant = id(new PhortuneMerchantQuery()) ->setViewer($viewer) ->withIDs(array($this->id)) ->executeOne(); if (!$merchant) { return new Aphront404Response(); } $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb($merchant->getName()); $title = pht( 'Merchant %d %s', $merchant->getID(), $merchant->getName()); $header = id(new PHUIHeaderView()) ->setObjectName(pht('Merchant %d', $merchant->getID())) ->setHeader($merchant->getName()) ->setUser($viewer) ->setPolicyObject($merchant); $providers = id(new PhortunePaymentProviderConfigQuery()) ->setViewer($viewer) ->withMerchantPHIDs(array($merchant->getPHID())) ->execute(); $properties = $this->buildPropertyListView($merchant, $providers); $actions = $this->buildActionListView($merchant); $properties->setActionList($actions); $provider_list = $this->buildProviderList( $merchant, $providers); $box = id(new PHUIObjectBoxView()) ->setHeader($header) ->addPropertyList($properties); $timeline = $this->buildTransactionTimeline( $merchant, new PhortuneMerchantTransactionQuery()); $timeline->setShouldTerminate(true); return $this->buildApplicationPage( array( $crumbs, $box, $provider_list, $timeline, ), array( 'title' => $title, )); } private function buildPropertyListView( PhortuneMerchant $merchant, array $providers) { $viewer = $this->getRequest()->getUser(); $view = id(new PHUIPropertyListView()) ->setUser($viewer) ->setObject($merchant); $status_view = new PHUIStatusListView(); $have_any = false; $any_test = false; foreach ($providers as $provider_config) { $provider = $provider_config->buildProvider(); if ($provider->isEnabled()) { $have_any = true; } if (!$provider->isAcceptingLivePayments()) { $any_test = true; } } if ($have_any) { $status_view->addItem( id(new PHUIStatusItemView()) ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') ->setTarget(pht('Accepts Payments')) ->setNote(pht('This merchant can accept payments.'))); if ($any_test) { $status_view->addItem( id(new PHUIStatusItemView()) ->setIcon(PHUIStatusItemView::ICON_WARNING, 'yellow') ->setTarget(pht('Test Mode')) ->setNote(pht('This merchant is accepting test payments.'))); } else { $status_view->addItem( id(new PHUIStatusItemView()) ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') ->setTarget(pht('Live Mode')) ->setNote(pht('This merchant is accepting live payments.'))); } } else if ($providers) { $status_view->addItem( id(new PHUIStatusItemView()) ->setIcon(PHUIStatusItemView::ICON_REJECT, 'red') ->setTarget(pht('No Enabled Providers')) ->setNote( pht( 'All of the payment providers for this merchant are '. 'disabled.'))); } else { $status_view->addItem( id(new PHUIStatusItemView()) ->setIcon(PHUIStatusItemView::ICON_WARNING, 'yellow') ->setTarget(pht('No Providers')) ->setNote( pht( 'This merchant does not have any payment providers configured '. 'yet, so it can not accept payments. Add a provider.'))); } $view->addProperty(pht('Status'), $status_view); $view->addProperty( pht('Members'), $viewer->renderHandleList($merchant->getMemberPHIDs())); $view->invokeWillRenderEvent(); $description = $merchant->getDescription(); if (strlen($description)) { $description = PhabricatorMarkupEngine::renderOneObject( id(new PhabricatorMarkupOneOff())->setContent($description), 'default', $viewer); $view->addSectionHeader(pht('Description')); $view->addTextContent($description); } return $view; } private function buildActionListView(PhortuneMerchant $merchant) { $viewer = $this->getRequest()->getUser(); $id = $merchant->getID(); $can_edit = PhabricatorPolicyFilter::hasCapability( $viewer, $merchant, PhabricatorPolicyCapability::CAN_EDIT); $view = id(new PhabricatorActionListView()) ->setUser($viewer) ->setObject($merchant); $view->addAction( id(new PhabricatorActionView()) ->setName(pht('Edit Merchant')) ->setIcon('fa-pencil') ->setDisabled(!$can_edit) ->setWorkflow(!$can_edit) ->setHref($this->getApplicationURI("merchant/edit/{$id}/"))); $view->addAction( id(new PhabricatorActionView()) ->setName(pht('View Orders')) ->setIcon('fa-shopping-cart') ->setHref($this->getApplicationURI("merchant/orders/{$id}/")) ->setDisabled(!$can_edit) ->setWorkflow(!$can_edit)); $view->addAction( id(new PhabricatorActionView()) ->setName(pht('View Subscriptions')) ->setIcon('fa-moon-o') ->setHref($this->getApplicationURI("merchant/{$id}/subscription/")) ->setDisabled(!$can_edit) ->setWorkflow(!$can_edit)); $view->addAction( id(new PhabricatorActionView()) ->setName(pht('New Invoice')) ->setIcon('fa-fax') ->setHref($this->getApplicationURI("merchant/{$id}/invoice/new/")) ->setDisabled(!$can_edit) ->setWorkflow(!$can_edit)); return $view; } private function buildProviderList( PhortuneMerchant $merchant, array $providers) { $viewer = $this->getRequest()->getUser(); $id = $merchant->getID(); $can_edit = PhabricatorPolicyFilter::hasCapability( $viewer, $merchant, PhabricatorPolicyCapability::CAN_EDIT); $provider_list = id(new PHUIObjectItemListView()) ->setFlush(true) ->setNoDataString(pht('This merchant has no payment providers.')); foreach ($providers as $provider_config) { $provider = $provider_config->buildProvider(); $provider_id = $provider_config->getID(); $item = id(new PHUIObjectItemView()) ->setHeader($provider->getName()); if ($provider->isEnabled()) { if ($provider->isAcceptingLivePayments()) { - $item->setBarColor('green'); + $item->setStatusIcon('fa-check green'); } else { - $item->setBarColor('yellow'); + $item->setStatusIcon('fa-warning yellow'); $item->addIcon('fa-exclamation-triangle', pht('Test Mode')); } $item->addAttribute($provider->getConfigureProvidesDescription()); } else { // Don't show disabled providers to users who can't manage the merchant // account. if (!$can_edit) { continue; } $item->setDisabled(true); $item->addAttribute( phutil_tag('em', array(), pht('This payment provider is disabled.'))); } if ($can_edit) { $edit_uri = $this->getApplicationURI( "/provider/edit/{$provider_id}/"); $disable_uri = $this->getApplicationURI( "/provider/disable/{$provider_id}/"); if ($provider->isEnabled()) { $disable_icon = 'fa-times'; $disable_name = pht('Disable'); } else { $disable_icon = 'fa-check'; $disable_name = pht('Enable'); } $item->addAction( id(new PHUIListItemView()) ->setIcon($disable_icon) ->setHref($disable_uri) ->setName($disable_name) ->setWorkflow(true)); $item->addAction( id(new PHUIListItemView()) ->setIcon('fa-pencil') ->setHref($edit_uri) ->setName(pht('Edit'))); } $provider_list->addItem($item); } $add_action = id(new PHUIButtonView()) ->setTag('a') ->setHref($this->getApplicationURI('provider/edit/?merchantID='.$id)) ->setText(pht('Add Payment Provider')) ->setDisabled(!$can_edit) ->setWorkflow(!$can_edit) ->setIcon(id(new PHUIIconView())->setIconFont('fa-plus')); $header = id(new PHUIHeaderView()) ->setHeader(pht('Payment Providers')) ->addActionLink($add_action); return id(new PHUIObjectBoxView()) ->setHeader($header) ->setObjectList($provider_list); } } diff --git a/src/applications/phrequent/query/PhrequentSearchEngine.php b/src/applications/phrequent/query/PhrequentSearchEngine.php index 4b520ab36b..107b4fd51f 100644 --- a/src/applications/phrequent/query/PhrequentSearchEngine.php +++ b/src/applications/phrequent/query/PhrequentSearchEngine.php @@ -1,195 +1,195 @@ getParameter('limit', 1000); } public function buildSavedQueryFromRequest(AphrontRequest $request) { $saved = new PhabricatorSavedQuery(); $saved->setParameter( 'userPHIDs', $this->readUsersFromRequest($request, 'users')); $saved->setParameter('ended', $request->getStr('ended')); $saved->setParameter('order', $request->getStr('order')); return $saved; } public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { $query = id(new PhrequentUserTimeQuery()) ->needPreemptingEvents(true); $user_phids = $saved->getParameter('userPHIDs'); if ($user_phids) { $query->withUserPHIDs($user_phids); } $ended = $saved->getParameter('ended'); if ($ended != null) { $query->withEnded($ended); } $order = $saved->getParameter('order'); if ($order != null) { $query->setOrder($order); } return $query; } public function buildSearchForm( AphrontFormView $form, PhabricatorSavedQuery $saved_query) { $user_phids = $saved_query->getParameter('userPHIDs', array()); $ended = $saved_query->getParameter( 'ended', PhrequentUserTimeQuery::ENDED_ALL); $order = $saved_query->getParameter( 'order', PhrequentUserTimeQuery::ORDER_ENDED_DESC); $form ->appendControl( id(new AphrontFormTokenizerControl()) ->setDatasource(new PhabricatorPeopleDatasource()) ->setName('users') ->setLabel(pht('Users')) ->setValue($user_phids)) ->appendChild( id(new AphrontFormSelectControl()) ->setLabel(pht('Ended')) ->setName('ended') ->setValue($ended) ->setOptions(PhrequentUserTimeQuery::getEndedSearchOptions())) ->appendChild( id(new AphrontFormSelectControl()) ->setLabel(pht('Order')) ->setName('order') ->setValue($order) ->setOptions(PhrequentUserTimeQuery::getOrderSearchOptions())); } protected function getURI($path) { return '/phrequent/'.$path; } protected function getBuiltinQueryNames() { return array( 'tracking' => pht('Currently Tracking'), 'all' => pht('All Tracked'), ); } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'all': return $query ->setParameter('order', PhrequentUserTimeQuery::ORDER_ENDED_DESC); case 'tracking': return $query ->setParameter('ended', PhrequentUserTimeQuery::ENDED_NO) ->setParameter('order', PhrequentUserTimeQuery::ORDER_ENDED_DESC); } return parent::buildSavedQueryFromBuiltin($query_key); } protected function getRequiredHandlePHIDsForResultList( array $usertimes, PhabricatorSavedQuery $query) { return array_mergev( array( mpull($usertimes, 'getUserPHID'), mpull($usertimes, 'getObjectPHID'), )); } protected function renderResultList( array $usertimes, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($usertimes, 'PhrequentUserTime'); $viewer = $this->requireViewer(); $view = id(new PHUIObjectItemListView()) ->setUser($viewer); foreach ($usertimes as $usertime) { $item = new PHUIObjectItemView(); if ($usertime->getObjectPHID() === null) { $item->setHeader($usertime->getNote()); } else { $obj = $handles[$usertime->getObjectPHID()]; $item->setHeader($obj->getLinkName()); $item->setHref($obj->getURI()); } $item->setObject($usertime); $item->addByline( pht( 'Tracked: %s', $handles[$usertime->getUserPHID()]->renderLink())); $started_date = phabricator_date($usertime->getDateStarted(), $viewer); $item->addIcon('none', $started_date); $block = new PhrequentTimeBlock(array($usertime)); $time_spent = $block->getTimeSpentOnObject( $usertime->getObjectPHID(), PhabricatorTime::getNow()); $time_spent = $time_spent == 0 ? 'none' : phutil_format_relative_time_detailed($time_spent); if ($usertime->getDateEnded() !== null) { $item->addAttribute( pht( 'Tracked %s', $time_spent)); $item->addAttribute( pht( 'Ended on %s', phabricator_datetime($usertime->getDateEnded(), $viewer))); } else { $item->addAttribute( pht( 'Tracked %s so far', $time_spent)); if ($usertime->getObjectPHID() !== null && $usertime->getUserPHID() === $viewer->getPHID()) { $item->addAction( id(new PHUIListItemView()) ->setIcon('fa-stop') ->addSigil('phrequent-stop-tracking') ->setWorkflow(true) ->setRenderNameAsTooltip(true) ->setName(pht('Stop')) ->setHref( '/phrequent/track/stop/'. $usertime->getObjectPHID().'/')); } - $item->setBarColor('green'); + $item->setStatusIcon('fa-clock-o green'); } $view->addItem($item); } return $view; } } diff --git a/src/applications/ponder/constants/PonderQuestionStatus.php b/src/applications/ponder/constants/PonderQuestionStatus.php index 3877380b30..2d26b9cb66 100644 --- a/src/applications/ponder/constants/PonderQuestionStatus.php +++ b/src/applications/ponder/constants/PonderQuestionStatus.php @@ -1,31 +1,41 @@ pht('Open'), self::STATUS_CLOSED => pht('Closed'), ); } public static function getQuestionStatusFullName($status) { $map = array( self::STATUS_OPEN => pht('Open'), self::STATUS_CLOSED => pht('Closed by author'), ); return idx($map, $status, pht('Unknown')); } public static function getQuestionStatusTagColor($status) { $map = array( + self::STATUS_OPEN => PHUITagView::COLOR_BLUE, self::STATUS_CLOSED => PHUITagView::COLOR_BLACK, ); return idx($map, $status); } + public static function getQuestionStatusIcon($status) { + $map = array( + self::STATUS_OPEN => 'fa-question-circle', + self::STATUS_CLOSED => 'fa-check-square-o', + ); + + return idx($map, $status); + } + } diff --git a/src/applications/ponder/query/PonderQuestionSearchEngine.php b/src/applications/ponder/query/PonderQuestionSearchEngine.php index 823b6aaf3c..cb0ab70d74 100644 --- a/src/applications/ponder/query/PonderQuestionSearchEngine.php +++ b/src/applications/ponder/query/PonderQuestionSearchEngine.php @@ -1,172 +1,176 @@ setParameter( 'authorPHIDs', $this->readUsersFromRequest($request, 'authors')); $saved->setParameter( 'answererPHIDs', $this->readUsersFromRequest($request, 'answerers')); $saved->setParameter('status', $request->getStr('status')); return $saved; } public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { $query = id(new PonderQuestionQuery()); $author_phids = $saved->getParameter('authorPHIDs'); if ($author_phids) { $query->withAuthorPHIDs($author_phids); } $answerer_phids = $saved->getParameter('answererPHIDs'); if ($answerer_phids) { $query->withAnswererPHIDs($answerer_phids); } $status = $saved->getParameter('status'); if ($status != null) { switch ($status) { case 0: $query->withStatus(PonderQuestionQuery::STATUS_OPEN); break; case 1: $query->withStatus(PonderQuestionQuery::STATUS_CLOSED); break; } } return $query; } public function buildSearchForm( AphrontFormView $form, PhabricatorSavedQuery $saved_query) { $author_phids = $saved_query->getParameter('authorPHIDs', array()); $answerer_phids = $saved_query->getParameter('answererPHIDs', array()); $status = $saved_query->getParameter( 'status', PonderQuestionStatus::STATUS_OPEN); $form ->appendControl( id(new AphrontFormTokenizerControl()) ->setDatasource(new PhabricatorPeopleDatasource()) ->setName('authors') ->setLabel(pht('Authors')) ->setValue($author_phids)) ->appendControl( id(new AphrontFormTokenizerControl()) ->setDatasource(new PhabricatorPeopleDatasource()) ->setName('answerers') ->setLabel(pht('Answered By')) ->setValue($answerer_phids)) ->appendChild( id(new AphrontFormSelectControl()) ->setLabel(pht('Status')) ->setName('status') ->setValue($status) ->setOptions(PonderQuestionStatus::getQuestionStatusMap())); } protected function getURI($path) { return '/ponder/'.$path; } protected function getBuiltinQueryNames() { $names = array( 'open' => pht('Open Questions'), 'all' => pht('All Questions'), ); if ($this->requireViewer()->isLoggedIn()) { $names['authored'] = pht('Authored'); $names['answered'] = pht('Answered'); } return $names; } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'all': return $query; case 'open': return $query->setParameter('status', PonderQuestionQuery::STATUS_OPEN); case 'authored': return $query->setParameter( 'authorPHIDs', array($this->requireViewer()->getPHID())); case 'answered': return $query->setParameter( 'answererPHIDs', array($this->requireViewer()->getPHID())); } return parent::buildSavedQueryFromBuiltin($query_key); } protected function getRequiredHandlePHIDsForResultList( array $questions, PhabricatorSavedQuery $query) { return mpull($questions, 'getAuthorPHID'); } protected function renderResultList( array $questions, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($questions, 'PonderQuestion'); $viewer = $this->requireViewer(); $view = id(new PHUIObjectItemListView()) ->setUser($viewer); foreach ($questions as $question) { + $color = PonderQuestionStatus::getQuestionStatusTagColor( + $question->getStatus()); + $icon = PonderQuestionStatus::getQuestionStatusIcon( + $question->getStatus()); + $full_status = PonderQuestionStatus::getQuestionStatusFullName( + $question->getStatus()); $item = new PHUIObjectItemView(); $item->setObjectName('Q'.$question->getID()); $item->setHeader($question->getTitle()); $item->setHref('/Q'.$question->getID()); $item->setObject($question); - $item->setBarColor( - PonderQuestionStatus::getQuestionStatusTagColor( - $question->getStatus())); + $item->setStatusIcon($icon.' '.$color, $full_status); $created_date = phabricator_date($question->getDateCreated(), $viewer); $item->addIcon('none', $created_date); $item->addByline( pht( 'Asked by %s', $handles[$question->getAuthorPHID()]->renderLink())); $item->addAttribute( pht('%d Answer(s)', $question->getAnswerCount())); $view->addItem($item); } return $view; } } diff --git a/src/applications/releeph/controller/product/ReleephProductViewController.php b/src/applications/releeph/controller/product/ReleephProductViewController.php index 8b6cc03272..dae9672def 100644 --- a/src/applications/releeph/controller/product/ReleephProductViewController.php +++ b/src/applications/releeph/controller/product/ReleephProductViewController.php @@ -1,247 +1,247 @@ productID = idx($data, 'projectID'); $this->queryKey = idx($data, 'queryKey'); } public function processRequest() { $request = $this->getRequest(); $viewer = $request->getUser(); $product = id(new ReleephProductQuery()) ->setViewer($viewer) ->withIDs(array($this->productID)) ->executeOne(); if (!$product) { return new Aphront404Response(); } $this->setProduct($product); $controller = id(new PhabricatorApplicationSearchController()) ->setQueryKey($this->queryKey) ->setPreface($this->renderPreface()) ->setSearchEngine( id(new ReleephBranchSearchEngine()) ->setProduct($product)) ->setNavigation($this->buildSideNavView()); return $this->delegateToController($controller); } public function renderResultsList( array $branches, PhabricatorSavedQuery $saved) { assert_instances_of($branches, 'ReleephBranch'); $viewer = $this->getRequest()->getUser(); $products = mpull($branches, 'getProduct'); $repo_phids = mpull($products, 'getRepositoryPHID'); $repos = id(new PhabricatorRepositoryQuery()) ->setViewer($viewer) ->withPHIDs($repo_phids) ->execute(); $repos = mpull($repos, null, 'getPHID'); $requests = array(); if ($branches) { $requests = id(new ReleephRequestQuery()) ->setViewer($viewer) ->withBranchIDs(mpull($branches, 'getID')) ->withStatus(ReleephRequestQuery::STATUS_OPEN) ->execute(); $requests = mgroup($requests, 'getBranchID'); } $list = id(new PHUIObjectItemListView()) ->setUser($viewer); foreach ($branches as $branch) { $diffusion_href = null; $repo = idx($repos, $branch->getProduct()->getRepositoryPHID()); if ($repo) { $drequest = DiffusionRequest::newFromDictionary( array( 'user' => $viewer, 'repository' => $repo, )); $diffusion_href = $drequest->generateURI( array( 'action' => 'branch', 'branch' => $branch->getName(), )); } $branch_link = $branch->getName(); if ($diffusion_href) { $branch_link = phutil_tag( 'a', array( 'href' => $diffusion_href, ), $branch_link); } $item = id(new PHUIObjectItemView()) ->setHeader($branch->getDisplayName()) ->setHref($this->getApplicationURI('branch/'.$branch->getID().'/')) ->addAttribute($branch_link); if (!$branch->getIsActive()) { $item->setDisabled(true); } $commit = $branch->getCutPointCommit(); if ($commit) { $item->addIcon( 'none', phabricator_datetime($commit->getEpoch(), $viewer)); } $open_count = count(idx($requests, $branch->getID(), array())); if ($open_count) { - $item->setBarColor('orange'); + $item->setStatusIcon('fa-code-fork orange'); $item->addIcon( 'fa-code-fork', pht('%d Open Pull Request(s)', new PhutilNumber($open_count))); } $list->addItem($item); } return $list; } public function buildSideNavView($for_app = false) { $viewer = $this->getRequest()->getUser(); $product = $this->getProduct(); $nav = new AphrontSideNavFilterView(); $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); if ($for_app) { $nav->addFilter('product/create/', pht('Create Product')); } id(new ReleephBranchSearchEngine()) ->setProduct($product) ->setViewer($viewer) ->addNavigationItems($nav->getMenu()); $nav->selectFilter(null); return $nav; } protected function buildApplicationCrumbs() { $crumbs = parent::buildApplicationCrumbs(); $product = $this->getProduct(); if ($product) { $crumbs->addAction( id(new PHUIListItemView()) ->setHref($product->getURI('cutbranch/')) ->setName(pht('Cut New Branch')) ->setIcon('fa-plus')); } return $crumbs; } private function renderPreface() { $viewer = $this->getRequest()->getUser(); $product = $this->getProduct(); $id = $product->getID(); $header = id(new PHUIHeaderView()) ->setHeader($product->getName()) ->setUser($viewer) ->setPolicyObject($product); if ($product->getIsActive()) { $header->setStatus('fa-check', 'bluegrey', pht('Active')); } else { $header->setStatus('fa-ban', 'dark', pht('Inactive')); } $actions = id(new PhabricatorActionListView()) ->setUser($viewer) ->setObject($product) ->setObjectURI($this->getRequest()->getRequestURI()); $can_edit = PhabricatorPolicyFilter::hasCapability( $viewer, $product, PhabricatorPolicyCapability::CAN_EDIT); $edit_uri = $this->getApplicationURI("product/{$id}/edit/"); $history_uri = $this->getApplicationURI("product/{$id}/history/"); $actions->addAction( id(new PhabricatorActionView()) ->setName(pht('Edit Product')) ->setHref($edit_uri) ->setIcon('fa-pencil') ->setDisabled(!$can_edit) ->setWorkflow(!$can_edit)); if ($product->getIsActive()) { $status_name = pht('Deactivate Product'); $status_href = "product/{$id}/action/deactivate/"; $status_icon = 'fa-times'; } else { $status_name = pht('Reactivate Product'); $status_href = "product/{$id}/action/activate/"; $status_icon = 'fa-plus-circle-o'; } $actions->addAction( id(new PhabricatorActionView()) ->setName($status_name) ->setHref($this->getApplicationURI($status_href)) ->setIcon($status_icon) ->setDisabled(!$can_edit) ->setWorkflow(true)); $actions->addAction( id(new PhabricatorActionView()) ->setName(pht('View History')) ->setHref($history_uri) ->setIcon('fa-list')); $properties = id(new PHUIPropertyListView()) ->setUser($viewer) ->setObject($product); $properties->addProperty( pht('Repository'), $product->getRepository()->getName()); $properties->setActionList($actions); $pushers = $product->getPushers(); if ($pushers) { $properties->addProperty( pht('Pushers'), $viewer->renderHandleList($pushers)); } return id(new PHUIObjectBoxView()) ->setHeader($header) ->addPropertyList($properties); } } diff --git a/src/infrastructure/customfield/config/PhabricatorCustomFieldConfigOptionType.php b/src/infrastructure/customfield/config/PhabricatorCustomFieldConfigOptionType.php index 1de963c177..fc305a1de3 100644 --- a/src/infrastructure/customfield/config/PhabricatorCustomFieldConfigOptionType.php +++ b/src/infrastructure/customfield/config/PhabricatorCustomFieldConfigOptionType.php @@ -1,131 +1,131 @@ getStr('value'); $in_value = phutil_json_decode($storage_value); // When we submit from JS, we submit a list (since maps are not guaranteed // to retain order). Convert it into a map for storage (since it's far more // convenient for us elsewhere). $storage_value = ipull($in_value, null, 'key'); $display_value = $storage_value; return array($e_value, $errors, $storage_value, $display_value); } public function renderControl( PhabricatorConfigOption $option, $display_value, $e_value) { $field_base_class = $option->getCustomData(); $field_spec = $display_value; if (!is_array($field_spec)) { $field_spec = PhabricatorEnv::getEnvConfig($option->getKey()); } // TODO: We might need to build a real object here eventually. $faux_object = null; $fields = PhabricatorCustomField::buildFieldList( $field_base_class, $field_spec, $faux_object, array( 'withDisabled' => true, )); $list_id = celerity_generate_unique_node_id(); $input_id = celerity_generate_unique_node_id(); $list = id(new PHUIObjectItemListView()) ->setFlush(true) ->setID($list_id); foreach ($fields as $key => $field) { $item = id(new PHUIObjectItemView()) ->addSigil('field-spec') ->setMetadata(array('fieldKey' => $key)) ->setGrippable(true) ->addAttribute($field->getFieldDescription()) ->setHeader($field->getFieldName()); $spec = idx($field_spec, $key, array()); $is_disabled = idx($spec, 'disabled', $field->shouldDisableByDefault()); $disabled_item = clone $item; $enabled_item = clone $item; if ($is_disabled) { $list->addItem($disabled_item); } else { $list->addItem($enabled_item); } $disabled_item->addIcon('none', pht('Disabled')); $disabled_item->setDisabled(true); $disabled_item->addAction( id(new PHUIListItemView()) ->setHref('#') ->addSigil('field-spec-toggle') ->setIcon('fa-plus')); - $enabled_item->setBarColor('green'); + $enabled_item->setStatusIcon('fa-check green'); if (!$field->canDisableField()) { $enabled_item->addAction( id(new PHUIListItemView()) ->setIcon('fa-lock grey')); $enabled_item->addIcon('none', pht('Permanent Field')); } else { $enabled_item->addAction( id(new PHUIListItemView()) ->setHref('#') ->addSigil('field-spec-toggle') ->setIcon('fa-times')); } $fields[$key] = array( 'disabled' => $is_disabled, 'disabledMarkup' => $disabled_item->render(), 'enabledMarkup' => $enabled_item->render(), ); } $input = phutil_tag( 'input', array( 'id' => $input_id, 'type' => 'hidden', 'name' => 'value', 'value' => '', )); Javelin::initBehavior( 'config-reorder-fields', array( 'listID' => $list_id, 'inputID' => $input_id, 'fields' => $fields, )); return id(new AphrontFormMarkupControl()) ->setLabel(pht('Value')) ->setError($e_value) ->setValue( array( $list, $input, )); } }