diff --git a/resources/celerity/map.php b/resources/celerity/map.php --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -18,7 +18,6 @@ 'maniphest.pkg.css' => 'f1887d71', 'maniphest.pkg.js' => '2fe8af22', 'rsrc/css/aphront/aphront-bars.css' => '231ac33c', - 'rsrc/css/aphront/aphront-notes.css' => '6acadd3f', 'rsrc/css/aphront/context-bar.css' => '1c3b0529', 'rsrc/css/aphront/dark-console.css' => '6378ef3d', 'rsrc/css/aphront/dialog-view.css' => 'c01d24b4', @@ -95,15 +94,10 @@ 'rsrc/css/application/ponder/vote.css' => '8ed6ed8b', 'rsrc/css/application/profile/profile-view.css' => '33e6f703', 'rsrc/css/application/projects/project-tag.css' => '095c9404', - 'rsrc/css/application/releeph/releeph-branch.css' => 'b8821d2d', - 'rsrc/css/application/releeph/releeph-colors.css' => '2d2d6aa8', - 'rsrc/css/application/releeph/releeph-core.css' => '140b959d', - 'rsrc/css/application/releeph/releeph-intents.css' => '39065521', + 'rsrc/css/application/releeph/releeph-core.css' => '9b3c5733', 'rsrc/css/application/releeph/releeph-preview-branch.css' => 'b7a6f4a5', - 'rsrc/css/application/releeph/releeph-project.css' => 'ee1f9f57', 'rsrc/css/application/releeph/releeph-request-differential-create-dialog.css' => '8d8b92cd', 'rsrc/css/application/releeph/releeph-request-typeahead.css' => '667a48ae', - 'rsrc/css/application/releeph/releeph-status.css' => 'd119a005', 'rsrc/css/application/search/search-results.css' => 'f240504c', 'rsrc/css/application/settings/settings.css' => 'ea8f5915', 'rsrc/css/application/slowvote/slowvote.css' => '266df6a1', @@ -127,7 +121,7 @@ 'rsrc/css/phui/calendar/phui-calendar-list.css' => 'c1d0ca59', 'rsrc/css/phui/calendar/phui-calendar-month.css' => '5e762971', 'rsrc/css/phui/calendar/phui-calendar.css' => '5e1ad989', - 'rsrc/css/phui/phui-box.css' => 'a36cf3a5', + 'rsrc/css/phui/phui-box.css' => '7b3a2eed', 'rsrc/css/phui/phui-button.css' => '653ac588', 'rsrc/css/phui/phui-document.css' => '3b078dc0', 'rsrc/css/phui/phui-feed-story.css' => '3a59c2cf', @@ -406,7 +400,7 @@ 'rsrc/js/application/projects/behavior-project-boards.js' => 'd8e135db', 'rsrc/js/application/projects/behavior-project-create.js' => '065227cc', 'rsrc/js/application/releeph/releeph-preview-branch.js' => '9eb2cedb', - 'rsrc/js/application/releeph/releeph-request-state-change.js' => 'fe7fc914', + 'rsrc/js/application/releeph/releeph-request-state-change.js' => 'd259e7c9', 'rsrc/js/application/releeph/releeph-request-typeahead.js' => 'cd9e7094', 'rsrc/js/application/repository/repository-crossreference.js' => '8ab282be', 'rsrc/js/application/search/behavior-reorder-queries.js' => '37871df4', @@ -489,7 +483,6 @@ 'aphront-error-view-css' => '9f1d5518', 'aphront-list-filter-view-css' => 'ef989c67', 'aphront-multi-column-view-css' => '12f65921', - 'aphront-notes' => '6acadd3f', 'aphront-pager-view-css' => '2e3539af', 'aphront-panel-view-css' => '5846dfa2', 'aphront-request-failure-view-css' => 'da14df31', @@ -616,7 +609,7 @@ 'javelin-behavior-project-create' => '065227cc', 'javelin-behavior-refresh-csrf' => 'c4b31646', 'javelin-behavior-releeph-preview-branch' => '9eb2cedb', - 'javelin-behavior-releeph-request-state-change' => 'fe7fc914', + 'javelin-behavior-releeph-request-state-change' => 'd259e7c9', 'javelin-behavior-releeph-request-typeahead' => 'cd9e7094', 'javelin-behavior-remarkup-preview' => 'f7379f45', 'javelin-behavior-repository-crossreference' => '8ab282be', @@ -738,7 +731,7 @@ 'phortune-credit-card-form-css' => 'b25b4beb', 'phrequent-css' => 'ffc185ad', 'phriction-document-css' => '7d7f0071', - 'phui-box-css' => 'a36cf3a5', + 'phui-box-css' => '7b3a2eed', 'phui-button-css' => '653ac588', 'phui-calendar-css' => '5e1ad989', 'phui-calendar-day-css' => 'de035c8a', @@ -774,15 +767,10 @@ 'raphael-core' => '51ee6b43', 'raphael-g' => '40dde778', 'raphael-g-line' => '40da039e', - 'releeph-branch' => 'b8821d2d', - 'releeph-colors' => '2d2d6aa8', - 'releeph-core' => '140b959d', - 'releeph-intents' => '39065521', + 'releeph-core' => '9b3c5733', 'releeph-preview-branch' => 'b7a6f4a5', - 'releeph-project' => 'ee1f9f57', 'releeph-request-differential-create-dialog' => '8d8b92cd', 'releeph-request-typeahead-css' => '667a48ae', - 'releeph-status' => 'd119a005', 'setup-issue-css' => '69e640e7', 'sprite-actions-css' => '969ad0e5', 'sprite-apps-css' => '6973a52b', @@ -1722,6 +1710,15 @@ array( 0 => 'javelin-util', ), + 'd259e7c9' => + array( + 0 => 'javelin-behavior', + 1 => 'javelin-dom', + 2 => 'javelin-stratcom', + 3 => 'javelin-workflow', + 4 => 'javelin-util', + 5 => 'phabricator-keyboard-shortcut', + ), 'd4a14807' => array( 0 => 'javelin-install', @@ -1945,15 +1942,6 @@ 4 => 'javelin-dom', 5 => 'javelin-magical-init', ), - 'fe7fc914' => - array( - 0 => 'javelin-behavior', - 1 => 'javelin-dom', - 2 => 'javelin-stratcom', - 3 => 'javelin-request', - 4 => 'phabricator-keyboard-shortcut', - 5 => 'phabricator-notification', - ), 'fe80fb6d' => array( 0 => 'javelin-behavior', 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 @@ -65,7 +65,6 @@ 'AphrontMoreView' => 'view/layout/AphrontMoreView.php', 'AphrontMultiColumnView' => 'view/layout/AphrontMultiColumnView.php', 'AphrontMySQLDatabaseConnectionTestCase' => 'infrastructure/storage/__tests__/AphrontMySQLDatabaseConnectionTestCase.php', - 'AphrontNoteView' => 'view/widget/AphrontNoteView.php', 'AphrontNullView' => 'view/AphrontNullView.php', 'AphrontPHPHTTPSink' => 'aphront/sink/AphrontPHPHTTPSink.php', 'AphrontPageView' => 'view/page/AphrontPageView.php', @@ -1712,7 +1711,6 @@ 'PhabricatorMySQLFileStorageEngine' => 'applications/files/engine/PhabricatorMySQLFileStorageEngine.php', 'PhabricatorNamedQuery' => 'applications/search/storage/PhabricatorNamedQuery.php', 'PhabricatorNamedQueryQuery' => 'applications/search/query/PhabricatorNamedQueryQuery.php', - 'PhabricatorNoteExample' => 'applications/uiexample/examples/PhabricatorNoteExample.php', 'PhabricatorNotificationAdHocFeedStory' => 'applications/notification/feed/PhabricatorNotificationAdHocFeedStory.php', 'PhabricatorNotificationBuilder' => 'applications/notification/builder/PhabricatorNotificationBuilder.php', 'PhabricatorNotificationClearController' => 'applications/notification/controller/PhabricatorNotificationClearController.php', @@ -2541,7 +2539,6 @@ 'ReleephProductTransactionQuery' => 'applications/releeph/query/ReleephProductTransactionQuery.php', 'ReleephProductViewController' => 'applications/releeph/controller/project/ReleephProductViewController.php', 'ReleephProject' => 'applications/releeph/storage/ReleephProject.php', - 'ReleephProjectController' => 'applications/releeph/controller/ReleephProjectController.php', 'ReleephProjectQuery' => 'applications/releeph/query/ReleephProjectQuery.php', 'ReleephReasonFieldSpecification' => 'applications/releeph/field/specification/ReleephReasonFieldSpecification.php', 'ReleephRequest' => 'applications/releeph/storage/ReleephRequest.php', @@ -2550,26 +2547,22 @@ 'ReleephRequestController' => 'applications/releeph/controller/request/ReleephRequestController.php', 'ReleephRequestDifferentialCreateController' => 'applications/releeph/controller/request/ReleephRequestDifferentialCreateController.php', 'ReleephRequestEditController' => 'applications/releeph/controller/request/ReleephRequestEditController.php', - 'ReleephRequestHeaderListView' => 'applications/releeph/view/request/header/ReleephRequestHeaderListView.php', - 'ReleephRequestHeaderView' => 'applications/releeph/view/request/header/ReleephRequestHeaderView.php', - 'ReleephRequestIntentsView' => 'applications/releeph/view/request/ReleephRequestIntentsView.php', 'ReleephRequestMailReceiver' => 'applications/releeph/mail/ReleephRequestMailReceiver.php', 'ReleephRequestQuery' => 'applications/releeph/query/ReleephRequestQuery.php', 'ReleephRequestReplyHandler' => 'applications/releeph/mail/ReleephRequestReplyHandler.php', 'ReleephRequestSearchEngine' => 'applications/releeph/query/ReleephRequestSearchEngine.php', 'ReleephRequestStatus' => 'applications/releeph/constants/ReleephRequestStatus.php', - 'ReleephRequestStatusView' => 'applications/releeph/view/request/ReleephRequestStatusView.php', 'ReleephRequestTransaction' => 'applications/releeph/storage/ReleephRequestTransaction.php', 'ReleephRequestTransactionComment' => 'applications/releeph/storage/ReleephRequestTransactionComment.php', 'ReleephRequestTransactionQuery' => 'applications/releeph/query/ReleephRequestTransactionQuery.php', 'ReleephRequestTransactionalEditor' => 'applications/releeph/editor/ReleephRequestTransactionalEditor.php', 'ReleephRequestTypeaheadControl' => 'applications/releeph/view/request/ReleephRequestTypeaheadControl.php', 'ReleephRequestTypeaheadController' => 'applications/releeph/controller/request/ReleephRequestTypeaheadController.php', + 'ReleephRequestView' => 'applications/releeph/view/ReleephRequestView.php', 'ReleephRequestViewController' => 'applications/releeph/controller/request/ReleephRequestViewController.php', 'ReleephRequestorFieldSpecification' => 'applications/releeph/field/specification/ReleephRequestorFieldSpecification.php', 'ReleephRevisionFieldSpecification' => 'applications/releeph/field/specification/ReleephRevisionFieldSpecification.php', 'ReleephSeverityFieldSpecification' => 'applications/releeph/field/specification/ReleephSeverityFieldSpecification.php', - 'ReleephStatusFieldSpecification' => 'applications/releeph/field/specification/ReleephStatusFieldSpecification.php', 'ReleephSummaryFieldSpecification' => 'applications/releeph/field/specification/ReleephSummaryFieldSpecification.php', 'ShellLogView' => 'applications/harbormaster/view/ShellLogView.php', 'SlowvoteEmbedView' => 'applications/slowvote/view/SlowvoteEmbedView.php', @@ -2657,7 +2650,6 @@ 'AphrontMoreView' => 'AphrontView', 'AphrontMultiColumnView' => 'AphrontView', 'AphrontMySQLDatabaseConnectionTestCase' => 'PhabricatorTestCase', - 'AphrontNoteView' => 'AphrontView', 'AphrontNullView' => 'AphrontView', 'AphrontPHPHTTPSink' => 'AphrontHTTPSink', 'AphrontPageView' => 'AphrontView', @@ -4516,7 +4508,6 @@ 1 => 'PhabricatorPolicyInterface', ), 'PhabricatorNamedQueryQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', - 'PhabricatorNoteExample' => 'PhabricatorUIExample', 'PhabricatorNotificationAdHocFeedStory' => 'PhabricatorFeedStory', 'PhabricatorNotificationClearController' => 'PhabricatorNotificationController', 'PhabricatorNotificationConfigOptions' => 'PhabricatorApplicationConfigOptions', @@ -5522,7 +5513,7 @@ 'ReleephPHIDTypeRequest' => 'PhabricatorPHIDType', 'ReleephProductActionController' => 'ReleephProductController', 'ReleephProductController' => 'ReleephController', - 'ReleephProductCreateController' => 'ReleephProjectController', + 'ReleephProductCreateController' => 'ReleephProductController', 'ReleephProductEditController' => 'ReleephProductController', 'ReleephProductEditor' => 'PhabricatorApplicationTransactionEditor', 'ReleephProductHistoryController' => 'ReleephProductController', @@ -5544,7 +5535,6 @@ 0 => 'ReleephDAO', 1 => 'PhabricatorPolicyInterface', ), - 'ReleephProjectController' => 'ReleephController', 'ReleephProjectQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'ReleephReasonFieldSpecification' => 'ReleephFieldSpecification', 'ReleephRequest' => @@ -5553,30 +5543,26 @@ 1 => 'PhabricatorPolicyInterface', 2 => 'PhabricatorCustomFieldInterface', ), - 'ReleephRequestActionController' => 'ReleephProjectController', - 'ReleephRequestCommentController' => 'ReleephProjectController', + 'ReleephRequestActionController' => 'ReleephRequestController', + 'ReleephRequestCommentController' => 'ReleephRequestController', 'ReleephRequestController' => 'ReleephController', - 'ReleephRequestDifferentialCreateController' => 'ReleephProjectController', - 'ReleephRequestEditController' => 'ReleephProjectController', - 'ReleephRequestHeaderListView' => 'AphrontView', - 'ReleephRequestHeaderView' => 'AphrontView', - 'ReleephRequestIntentsView' => 'AphrontView', + 'ReleephRequestDifferentialCreateController' => 'ReleephController', + 'ReleephRequestEditController' => 'ReleephBranchController', 'ReleephRequestMailReceiver' => 'PhabricatorObjectMailReceiver', 'ReleephRequestQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'ReleephRequestReplyHandler' => 'PhabricatorMailReplyHandler', 'ReleephRequestSearchEngine' => 'PhabricatorApplicationSearchEngine', - 'ReleephRequestStatusView' => 'AphrontView', 'ReleephRequestTransaction' => 'PhabricatorApplicationTransaction', 'ReleephRequestTransactionComment' => 'PhabricatorApplicationTransactionComment', 'ReleephRequestTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'ReleephRequestTransactionalEditor' => 'PhabricatorApplicationTransactionEditor', 'ReleephRequestTypeaheadControl' => 'AphrontFormControl', 'ReleephRequestTypeaheadController' => 'PhabricatorTypeaheadDatasourceController', - 'ReleephRequestViewController' => 'ReleephRequestController', + 'ReleephRequestView' => 'AphrontView', + 'ReleephRequestViewController' => 'ReleephBranchController', 'ReleephRequestorFieldSpecification' => 'ReleephFieldSpecification', 'ReleephRevisionFieldSpecification' => 'ReleephFieldSpecification', 'ReleephSeverityFieldSpecification' => 'ReleephLevelFieldSpecification', - 'ReleephStatusFieldSpecification' => 'ReleephFieldSpecification', 'ReleephSummaryFieldSpecification' => 'ReleephFieldSpecification', 'ShellLogView' => 'AphrontView', 'SlowvoteEmbedView' => 'AphrontView', diff --git a/src/applications/releeph/config/PhabricatorApplicationReleephConfigOptions.php b/src/applications/releeph/config/PhabricatorApplicationReleephConfigOptions.php --- a/src/applications/releeph/config/PhabricatorApplicationReleephConfigOptions.php +++ b/src/applications/releeph/config/PhabricatorApplicationReleephConfigOptions.php @@ -14,20 +14,19 @@ public function getOptions() { $default_fields = array( - new ReleephCommitMessageFieldSpecification(), new ReleephSummaryFieldSpecification(), + new ReleephRequestorFieldSpecification(), + new ReleephSeverityFieldSpecification(), + new ReleephIntentFieldSpecification(), new ReleephReasonFieldSpecification(), new ReleephAuthorFieldSpecification(), new ReleephRevisionFieldSpecification(), - new ReleephRequestorFieldSpecification(), - new ReleephSeverityFieldSpecification(), new ReleephOriginalCommitFieldSpecification(), - new ReleephDiffMessageFieldSpecification(), - new ReleephStatusFieldSpecification(), - new ReleephIntentFieldSpecification(), new ReleephBranchCommitFieldSpecification(), new ReleephDiffSizeFieldSpecification(), new ReleephDiffChurnFieldSpecification(), + new ReleephDiffMessageFieldSpecification(), + new ReleephCommitMessageFieldSpecification(), ); $default = array(); diff --git a/src/applications/releeph/constants/ReleephRequestStatus.php b/src/applications/releeph/constants/ReleephRequestStatus.php --- a/src/applications/releeph/constants/ReleephRequestStatus.php +++ b/src/applications/releeph/constants/ReleephRequestStatus.php @@ -15,9 +15,9 @@ self::STATUS_REQUESTED => pht('Requested'), self::STATUS_REJECTED => pht('Rejected'), self::STATUS_ABANDONED => pht('Abandoned'), - self::STATUS_PICKED => pht('Picked'), + self::STATUS_PICKED => pht('Pulled'), self::STATUS_REVERTED => pht('Reverted'), - self::STATUS_NEEDS_PICK => pht('Needs Pick'), + self::STATUS_NEEDS_PICK => pht('Needs Pull'), self::STATUS_NEEDS_REVERT => pht('Needs Revert'), ); return idx($descriptions, $status, '??'); diff --git a/src/applications/releeph/controller/branch/ReleephBranchViewController.php b/src/applications/releeph/controller/branch/ReleephBranchViewController.php --- a/src/applications/releeph/controller/branch/ReleephBranchViewController.php +++ b/src/applications/releeph/controller/branch/ReleephBranchViewController.php @@ -44,19 +44,40 @@ assert_instances_of($requests, 'ReleephRequest'); $viewer = $this->getRequest()->getUser(); - $branch = $this->getBranch(); - - // TODO: Really really gross. - $branch->populateReleephRequestHandles( - $viewer, - $requests); + // TODO: This is generally a bit sketchy, but we don't do this kind of + // thing elsewhere at the moment. For the moment it shouldn't be hugely + // costly, and we can batch things later. Generally, this commits fewer + // sins than the old code did. + + $engine = id(new PhabricatorMarkupEngine()) + ->setViewer($viewer); + + $list = array(); + foreach ($requests as $pull) { + $field_list = PhabricatorCustomField::getObjectFields( + $pull, + PhabricatorCustomField::ROLE_VIEW); + + $field_list + ->setViewer($viewer) + ->readFieldsFromStorage($pull); + + foreach ($field_list->getFields() as $field) { + if ($field->shouldMarkup()) { + $field->setMarkupEngine($engine); + } + } + + $list[] = id(new ReleephRequestView()) + ->setUser($viewer) + ->setCustomFields($field_list) + ->setPullRequest($pull) + ->setIsListView(true); + } - $list = id(new ReleephRequestHeaderListView()) - ->setUser($viewer) - ->setAphrontRequest($this->getRequest()) - ->setReleephProject($branch->getProduct()) - ->setReleephBranch($branch) - ->setReleephRequests($requests); + // This is quite sketchy, but the list has not actually rendered yet, so + // this still allows us to batch the markup rendering. + $engine->process(); return $list; } diff --git a/src/applications/releeph/controller/request/ReleephRequestActionController.php b/src/applications/releeph/controller/request/ReleephRequestActionController.php --- a/src/applications/releeph/controller/request/ReleephRequestActionController.php +++ b/src/applications/releeph/controller/request/ReleephRequestActionController.php @@ -15,6 +15,8 @@ $request = $this->getRequest(); $viewer = $request->getUser(); + $request->validateCSRF(); + $pull = id(new ReleephRequestQuery()) ->setViewer($viewer) ->withIDs(array($this->requestID)) @@ -26,8 +28,6 @@ $branch = $pull->getBranch(); $product = $branch->getProduct(); - $branch->populateReleephRequestHandles($viewer, array($pull)); - $action = $this->action; $origin_uri = '/'.$pull->getMonogram(); @@ -93,22 +93,37 @@ $editor->applyTransactions($pull, $xactions); - // If we're adding a new user to userIntents, we'll have to re-populate - // request handles to load that user's data. - // - // This is cheap enough to do every time. - $branch->populateReleephRequestHandles($viewer, array($pull)); - - $list = id(new ReleephRequestHeaderListView()) - ->setReleephProject($product) - ->setReleephBranch($branch) - ->setReleephRequests(array($pull)) - ->setUser($viewer) - ->setAphrontRequest($request); - - return id(new AphrontAjaxResponse())->setContent( - array( - 'markup' => hsprintf('%s', $list->renderInner()), - )); + if ($request->getBool('render')) { + $field_list = PhabricatorCustomField::getObjectFields( + $pull, + PhabricatorCustomField::ROLE_VIEW); + + $field_list + ->setViewer($viewer) + ->readFieldsFromStorage($pull); + + // TODO: This should be more modern and general. + $engine = id(new PhabricatorMarkupEngine()) + ->setViewer($viewer); + foreach ($field_list->getFields() as $field) { + if ($field->shouldMarkup()) { + $field->setMarkupEngine($engine); + } + } + $engine->process(); + + $pull_box = id(new ReleephRequestView()) + ->setUser($viewer) + ->setCustomFields($field_list) + ->setPullRequest($pull) + ->setIsListView(true); + + return id(new AphrontAjaxResponse())->setContent( + array( + 'markup' => hsprintf('%s', $pull_box), + )); + } + + return id(new AphrontRedirectResponse())->setURI($origin_uri); } } diff --git a/src/applications/releeph/controller/request/ReleephRequestViewController.php b/src/applications/releeph/controller/request/ReleephRequestViewController.php --- a/src/applications/releeph/controller/request/ReleephRequestViewController.php +++ b/src/applications/releeph/controller/request/ReleephRequestViewController.php @@ -33,21 +33,28 @@ // TODO: Break this 1:1 stuff? $branch = $pull->getBranch(); - // TODO: Very gross. - $branch->populateReleephRequestHandles( - $viewer, - array($pull)); + $field_list = PhabricatorCustomField::getObjectFields( + $pull, + PhabricatorCustomField::ROLE_VIEW); - $rq_view = id(new ReleephRequestHeaderListView()) - ->setReleephProject($branch->getProduct()) - ->setReleephBranch($branch) - ->setReleephRequests(array($pull)) - ->setUser($viewer) - ->setAphrontRequest($request) - ->setReloadOnStateChange(true); + $field_list + ->setViewer($viewer) + ->readFieldsFromStorage($pull); + // TODO: This should be more modern and general. $engine = id(new PhabricatorMarkupEngine()) ->setViewer($viewer); + foreach ($field_list->getFields() as $field) { + if ($field->shouldMarkup()) { + $field->setMarkupEngine($engine); + } + } + $engine->process(); + + $pull_box = id(new ReleephRequestView()) + ->setUser($viewer) + ->setCustomFields($field_list) + ->setPullRequest($pull); $xactions = id(new ReleephRequestTransactionQuery()) ->setViewer($viewer) @@ -85,12 +92,15 @@ return $this->buildStandardPageResponse( array( $crumbs, - $rq_view, + $pull_box, $timeline, $add_comment_form, ), array( - 'title' => $title + 'title' => $title, + 'device' => true, )); } + + } diff --git a/src/applications/releeph/field/selector/ReleephDefaultFieldSelector.php b/src/applications/releeph/field/selector/ReleephDefaultFieldSelector.php --- a/src/applications/releeph/field/selector/ReleephDefaultFieldSelector.php +++ b/src/applications/releeph/field/selector/ReleephDefaultFieldSelector.php @@ -37,7 +37,6 @@ new ReleephFacebookSeverityFieldSpecification(), new ReleephOriginalCommitFieldSpecification(), new ReleephDiffMessageFieldSpecification(), - new ReleephStatusFieldSpecification(), new ReleephIntentFieldSpecification(), new ReleephBranchCommitFieldSpecification(), new ReleephDiffSizeFieldSpecification(), @@ -57,7 +56,6 @@ new ReleephSeverityFieldSpecification(), new ReleephOriginalCommitFieldSpecification(), new ReleephDiffMessageFieldSpecification(), - new ReleephStatusFieldSpecification(), new ReleephIntentFieldSpecification(), new ReleephBranchCommitFieldSpecification(), new ReleephDiffSizeFieldSpecification(), @@ -85,7 +83,6 @@ 'ReleephFacebookKarmaFieldSpecification', 'ReleephFacebookSeverityFieldSpecification', 'ReleephFacebookTagFieldSpecification', - 'ReleephStatusFieldSpecification', 'ReleephIntentFieldSpecification', 'ReleephBranchCommitFieldSpecification', )) @@ -115,7 +112,6 @@ 'right' => self::selectFields($fields, array( 'ReleephRequestorFieldSpecification', 'ReleephSeverityFieldSpecification', - 'ReleephStatusFieldSpecification', 'ReleephIntentFieldSpecification', 'ReleephBranchCommitFieldSpecification', )) @@ -137,14 +133,12 @@ public function arrangeFieldsForSelectForm(array $fields) { if (self::isFacebook()) { return self::selectFields($fields, array( - 'ReleephStatusFieldSpecification', 'ReleephFacebookSeverityFieldSpecification', 'ReleephRequestorFieldSpecification', 'ReleephFacebookTagFieldSpecification', )); } else { return self::selectFields($fields, array( - 'ReleephStatusFieldSpecification', 'ReleephSeverityFieldSpecification', 'ReleephRequestorFieldSpecification', )); diff --git a/src/applications/releeph/field/selector/ReleephFieldSelector.php b/src/applications/releeph/field/selector/ReleephFieldSelector.php --- a/src/applications/releeph/field/selector/ReleephFieldSelector.php +++ b/src/applications/releeph/field/selector/ReleephFieldSelector.php @@ -1,9 +1,5 @@ <?php -/** - * Control the rendering of ReleephRequestHeaderView, and the layout of the - * ReleephRequest search dialog (in ReleephBranchViewController.) - */ abstract class ReleephFieldSelector { final public function __construct() { diff --git a/src/applications/releeph/field/specification/ReleephAuthorFieldSpecification.php b/src/applications/releeph/field/specification/ReleephAuthorFieldSpecification.php --- a/src/applications/releeph/field/specification/ReleephAuthorFieldSpecification.php +++ b/src/applications/releeph/field/specification/ReleephAuthorFieldSpecification.php @@ -24,17 +24,23 @@ } public function renderValueForHeaderView() { - $rr = $this->getReleephRequest(); - $author_phid = idx(self::$authorMap, $rr->getPHID()); - if ($author_phid) { - $handle = id(new PhabricatorHandleQuery()) - ->setViewer($this->getUser()) - ->withPHIDs(array($author_phid)) - ->executeOne(); - return $handle->renderLink(); - } else { - return 'Unknown Author'; + $pull = $this->getReleephRequest(); + $commit = $pull->loadPhabricatorRepositoryCommit(); + if (!$commit) { + return null; } + + $author_phid = $commit->getAuthorPHID(); + if (!$author_phid) { + return null; + } + + $handle = id(new PhabricatorHandleQuery()) + ->setViewer($this->getUser()) + ->withPHIDs(array($author_phid)) + ->executeOne(); + + return $handle->renderLink(); } } diff --git a/src/applications/releeph/field/specification/ReleephCommitMessageFieldSpecification.php b/src/applications/releeph/field/specification/ReleephCommitMessageFieldSpecification.php --- a/src/applications/releeph/field/specification/ReleephCommitMessageFieldSpecification.php +++ b/src/applications/releeph/field/specification/ReleephCommitMessageFieldSpecification.php @@ -11,6 +11,10 @@ return '__only_for_commit_message!'; } + public function shouldAppearInPropertyView() { + return false; + } + public function shouldAppearOnCommitMessage() { return true; } diff --git a/src/applications/releeph/field/specification/ReleephDiffMessageFieldSpecification.php b/src/applications/releeph/field/specification/ReleephDiffMessageFieldSpecification.php --- a/src/applications/releeph/field/specification/ReleephDiffMessageFieldSpecification.php +++ b/src/applications/releeph/field/specification/ReleephDiffMessageFieldSpecification.php @@ -15,18 +15,17 @@ return null; } + public function getStyleForPropertyView() { + return 'block'; + } + public function renderValueForHeaderView() { - $markup = phutil_tag( + return phutil_tag( 'div', array( 'class' => 'phabricator-remarkup', ), $this->getMarkupEngineOutput()); - - return id(new AphrontNoteView()) - ->setTitle('Commit Message') - ->appendChild($markup) - ->render(); } public function shouldMarkup() { diff --git a/src/applications/releeph/field/specification/ReleephFieldSpecification.php b/src/applications/releeph/field/specification/ReleephFieldSpecification.php --- a/src/applications/releeph/field/specification/ReleephFieldSpecification.php +++ b/src/applications/releeph/field/specification/ReleephFieldSpecification.php @@ -13,6 +13,30 @@ return $this; } + public function shouldAppearInPropertyView() { + return true; + } + + public function renderPropertyViewLabel() { + return $this->getName(); + } + + public function renderPropertyViewValue(array $handles) { + $value = $this->renderValueForHeaderView(); + if ($value === '') { + return null; + } + return $value; + } + + public function slowlyLoadHandle($phid) { + // TODO: Remove this, it's transitional as fields modernize. + return id(new PhabricatorHandleQuery()) + ->withPHIDs(array($phid)) + ->setViewer($this->getUser()) + ->executeOne(); + } + abstract public function getName(); /* -( Storage )------------------------------------------------------------ */ @@ -148,18 +172,30 @@ } final public function getReleephProject() { + if (!$this->releephProject) { + return $this->getReleephBranch()->getProduct(); + } return $this->releephProject; } final public function getReleephBranch() { + if (!$this->releephBranch) { + return $this->getReleephRequest()->getBranch(); + } return $this->releephBranch; } final public function getReleephRequest() { + if (!$this->releephRequest) { + return $this->getObject(); + } return $this->releephRequest; } final public function getUser() { + if (!$this->user) { + return $this->getViewer(); + } return $this->user; } diff --git a/src/applications/releeph/field/specification/ReleephIntentFieldSpecification.php b/src/applications/releeph/field/specification/ReleephIntentFieldSpecification.php --- a/src/applications/releeph/field/specification/ReleephIntentFieldSpecification.php +++ b/src/applications/releeph/field/specification/ReleephIntentFieldSpecification.php @@ -12,10 +12,67 @@ } public function renderValueForHeaderView() { - return id(new ReleephRequestIntentsView()) - ->setReleephRequest($this->getReleephRequest()) - ->setReleephProject($this->getReleephProject()) - ->render(); + $pull = $this->getReleephRequest(); + + $intents = $pull->getUserIntents(); + $product = $this->getReleephProject(); + + if (!$intents) { + return null; + } + + $user_phids = array_keys($intents); + if ($user_phids) { + $handles = id(new PhabricatorHandleQuery()) + ->withPHIDs($user_phids) + ->setViewer(PhabricatorUser::getOmnipotentUser()) + ->execute(); + } else { + $handles = array(); + } + + $pushers = array(); + $others = array(); + + foreach ($intents as $phid => $intent) { + if ($product->isAuthoritativePHID($phid)) { + $pushers[$phid] = $intent; + } else { + $others[$phid] = $intent; + } + } + + $intents = $pushers + $others; + + $view = id(new PHUIStatusListView()); + foreach ($intents as $phid => $intent) { + switch ($intent) { + case ReleephRequest::INTENT_WANT: + $icon = 'accept-green'; + $label = pht('Want'); + break; + case ReleephRequest::INTENT_PASS: + $icon = 'reject-red'; + $label = pht('Pass'); + break; + default: + $icon = 'question'; + $label = pht('Unknown Intent (%s)', $intent); + break; + } + + $target = $handles[$phid]->renderLink(); + if ($product->isAuthoritativePHID($phid)) { + $target = phutil_tag('strong', array(), $target); + } + + $view->addItem( + id(new PHUIStatusItemView()) + ->setIcon($icon, $label) + ->setTarget($target)); + } + + return $view; } public function shouldAppearOnCommitMessage() { diff --git a/src/applications/releeph/field/specification/ReleephOriginalCommitFieldSpecification.php b/src/applications/releeph/field/specification/ReleephOriginalCommitFieldSpecification.php --- a/src/applications/releeph/field/specification/ReleephOriginalCommitFieldSpecification.php +++ b/src/applications/releeph/field/specification/ReleephOriginalCommitFieldSpecification.php @@ -12,9 +12,8 @@ } public function renderValueForHeaderView() { - $rr = $this->getReleephRequest(); - $handles = $rr->getHandles(); - return $handles[$rr->getRequestCommitPHID()]->renderLink(); + $pull = $this->getReleephRequest(); + return $this->slowlyLoadHandle($pull->getRequestCommitPHID())->renderLink(); } } diff --git a/src/applications/releeph/field/specification/ReleephReasonFieldSpecification.php b/src/applications/releeph/field/specification/ReleephReasonFieldSpecification.php --- a/src/applications/releeph/field/specification/ReleephReasonFieldSpecification.php +++ b/src/applications/releeph/field/specification/ReleephReasonFieldSpecification.php @@ -15,22 +15,25 @@ return 'reason'; } + public function getStyleForPropertyView() { + return 'block'; + } + public function renderLabelForHeaderView() { return null; } + public function getIconForPropertyView() { + return PHUIPropertyListView::ICON_SUMMARY; + } + public function renderValueForHeaderView() { - $markup = phutil_tag( + return phutil_tag( 'div', array( 'class' => 'phabricator-remarkup', ), $this->getMarkupEngineOutput()); - - return id(new AphrontNoteView()) - ->setTitle('Reason') - ->appendChild($markup) - ->render(); } private $error = true; diff --git a/src/applications/releeph/field/specification/ReleephStatusFieldSpecification.php b/src/applications/releeph/field/specification/ReleephStatusFieldSpecification.php deleted file mode 100644 --- a/src/applications/releeph/field/specification/ReleephStatusFieldSpecification.php +++ /dev/null @@ -1,20 +0,0 @@ -<?php - -final class ReleephStatusFieldSpecification - extends ReleephFieldSpecification { - - public function getFieldKey() { - return 'status'; - } - - public function getName() { - return 'Status'; - } - - public function renderValueForHeaderView() { - return id(new ReleephRequestStatusView()) - ->setReleephRequest($this->getReleephRequest()) - ->render(); - } - -} diff --git a/src/applications/releeph/field/specification/ReleephSummaryFieldSpecification.php b/src/applications/releeph/field/specification/ReleephSummaryFieldSpecification.php --- a/src/applications/releeph/field/specification/ReleephSummaryFieldSpecification.php +++ b/src/applications/releeph/field/specification/ReleephSummaryFieldSpecification.php @@ -5,6 +5,10 @@ const MAX_SUMMARY_LENGTH = 60; + public function shouldAppearInPropertyView() { + return false; + } + public function getFieldKey() { return 'summary'; } diff --git a/src/applications/releeph/storage/ReleephRequest.php b/src/applications/releeph/storage/ReleephRequest.php --- a/src/applications/releeph/storage/ReleephRequest.php +++ b/src/applications/releeph/storage/ReleephRequest.php @@ -187,38 +187,21 @@ return $reason; } - public function getSummary() { - /** - * Instead, you can use: - * - getDetail('summary') // the actual user-chosen summary - * - getSummaryForDisplay() // falls back to the original commit title - * - * Or for the fastidious: - * - id(new ReleephSummaryFieldSpecification()) - * ->setReleephRequest($rr) - * ->getValue() // programmatic equivalent to getDetail() - */ - throw new Exception( - "getSummary() has been deprecated!"); - } - /** * Allow a null summary, and fall back to the title of the commit. */ public function getSummaryForDisplay() { $summary = $this->getDetail('summary'); - if (!$summary) { - $pr_commit_data = $this->loadPhabricatorRepositoryCommitData(); - if ($pr_commit_data) { - $message_lines = explode("\n", $pr_commit_data->getCommitMessage()); - $message_lines = array_filter($message_lines); - $summary = head($message_lines); + if (!strlen($summary)) { + $commit = $this->loadPhabricatorRepositoryCommit(); + if ($commit) { + $summary = $commit->getSummary(); } } - if (!$summary) { - $summary = '(no summary given and commit message empty or unparsed)'; + if (!strlen($summary)) { + $summary = pht('None'); } return $summary; diff --git a/src/applications/releeph/view/ReleephRequestView.php b/src/applications/releeph/view/ReleephRequestView.php new file mode 100644 --- /dev/null +++ b/src/applications/releeph/view/ReleephRequestView.php @@ -0,0 +1,249 @@ +<?php + +final class ReleephRequestView extends AphrontView { + + private $pullRequest; + private $customFields; + private $isListView; + + public function setIsListView($is_list_view) { + $this->isListView = $is_list_view; + return $this; + } + + public function getIsListView() { + return $this->isListView; + } + + public function setCustomFields(PhabricatorCustomFieldList $custom_fields) { + $this->customFields = $custom_fields; + return $this; + } + + public function getCustomFields() { + return $this->customFields; + } + + public function setPullRequest(ReleephRequest $pull_request) { + $this->pullRequest = $pull_request; + return $this; + } + + public function getPullRequest() { + return $this->pullRequest; + } + + public function render() { + $viewer = $this->getUser(); + + $field_list = $this->getCustomFields(); + $pull = $this->getPullRequest(); + + $header = $this->buildHeader($pull); + + $action_list = $this->buildActionList($pull); + + $property_list = id(new PHUIPropertyListView()) + ->setUser($viewer) + ->setActionList($action_list); + + $field_list->appendFieldsToPropertyList( + $pull, + $viewer, + $property_list); + + $warnings = $this->getWarnings($pull); + + if ($this->getIsListView()) { + Javelin::initBehavior('releeph-request-state-change'); + } + + return id(new PHUIObjectBoxView()) + ->setHeader($header) + ->setFormErrors($warnings) + ->addSigil('releeph-request-box') + ->setMetadata(array('uri' => '/'.$pull->getMonogram())) + ->appendChild($property_list); + } + + private function buildHeader(ReleephRequest $pull) { + $header_text = $pull->getSummaryForDisplay(); + if ($this->getIsListView()) { + $header_text = phutil_tag( + 'a', + array( + 'href' => '/'.$pull->getMonogram(), + ), + $header_text); + } + + $header = id(new PHUIHeaderView()) + ->setHeader($header_text) + ->setUser($this->getUser()) + ->setPolicyObject($pull); + + switch ($pull->getStatus()) { + case ReleephRequestStatus::STATUS_REQUESTED: + $icon = 'open'; + $color = null; + break; + case ReleephRequestStatus::STATUS_REJECTED: + $icon = 'reject'; + $color = 'red'; + break; + case ReleephRequestStatus::STATUS_PICKED: + $icon = 'accept'; + $color = 'green'; + break; + case ReleephRequestStatus::STATUS_REVERTED: + case ReleephRequestStatus::STATUS_ABANDONED: + $icon = 'reject'; + $color = 'dark'; + break; + case ReleephRequestStatus::STATUS_NEEDS_PICK: + $icon = 'warning'; + $color = 'green'; + break; + case ReleephRequestStatus::STATUS_NEEDS_REVERT: + $icon = 'warning'; + $color = 'red'; + break; + default: + $icon = 'question'; + $color = null; + break; + } + $text = ReleephRequestStatus::getStatusDescriptionFor($pull->getStatus()); + $header->setStatus($icon, $color, $text); + + if ($this->getIsListView()) { + $header->setObjectName($pull->getMonogram()); + } + + return $header; + } + + private function buildActionList(ReleephRequest $pull) { + $viewer = $this->getUser(); + $id = $pull->getID(); + + $edit_uri = '/releeph/request/edit/'.$id.'/'; + + $view = id(new PhabricatorActionListView()) + ->setUser($viewer); + + $product = $pull->getBranch()->getProduct(); + $viewer_is_pusher = $product->isAuthoritativePHID($viewer->getPHID()); + $viewer_is_requestor = ($pull->getRequestUserPHID() == $viewer->getPHID()); + + if ($viewer_is_pusher) { + $yes_text = pht('Approve Pull'); + $no_text = pht('Reject Pull'); + $yes_icon = 'check'; + $no_icon = 'delete'; + } else if ($viewer_is_requestor) { + $yes_text = pht('Request Pull'); + $no_text = pht('Cancel Pull'); + $yes_icon = 'ok'; + $no_icon = 'delete'; + } else { + $yes_text = pht('Support Pull'); + $no_text = pht('Discourage Pull'); + $yes_icon = 'like'; + $no_icon = 'dislike'; + } + + $yes_href = '/releeph/request/action/want/'.$id.'/'; + $no_href = '/releeph/request/action/pass/'.$id.'/'; + + $intents = $pull->getUserIntents(); + $current_intent = idx($intents, $viewer->getPHID()); + + $yes_disabled = ($current_intent == ReleephRequest::INTENT_WANT); + $no_disabled = ($current_intent == ReleephRequest::INTENT_PASS); + + $use_workflow = (!$this->getIsListView()); + + $view->addAction( + id(new PhabricatorActionView()) + ->setName($yes_text) + ->setHref($yes_href) + ->setWorkflow($use_workflow) + ->setRenderAsForm($use_workflow) + ->setDisabled($yes_disabled) + ->addSigil('releeph-request-state-change') + ->addSigil('want') + ->setIcon($yes_icon)); + + $view->addAction( + id(new PhabricatorActionView()) + ->setName($no_text) + ->setHref($no_href) + ->setWorkflow($use_workflow) + ->setRenderAsForm($use_workflow) + ->setDisabled($no_disabled) + ->addSigil('releeph-request-state-change') + ->addSigil('pass') + ->setIcon($no_icon)); + + + if ($viewer_is_pusher || $viewer_is_requestor) { + + $pulled_href = '/releeph/request/action/mark-manually-picked/'.$id.'/'; + $revert_href = '/releeph/request/action/mark-manually-reverted/'.$id.'/'; + + if ($pull->getInBranch()) { + $view->addAction( + id(new PhabricatorActionView()) + ->setName(pht('Mark as Reverted')) + ->setHref($revert_href) + ->setWorkflow($use_workflow) + ->setRenderAsForm($use_workflow) + ->addSigil('releeph-request-state-change') + ->addSigil('mark-manually-reverted') + ->setIcon($no_icon)); + } else { + $view->addAction( + id(new PhabricatorActionView()) + ->setName(pht('Mark as Pulled')) + ->setHref($pulled_href) + ->setWorkflow($use_workflow) + ->setRenderAsForm($use_workflow) + ->addSigil('releeph-request-state-change') + ->addSigil('mark-manually-picked') + ->setIcon('warning')); + } + } + + + if (!$this->getIsListView()) { + $view->addAction( + id(new PhabricatorActionView()) + ->setName(pht('Edit Pull Request')) + ->setIcon('edit') + ->setHref($edit_uri)); + } + + return $view; + } + + private function getWarnings(ReleephRequest $pull) { + $warnings = array(); + + switch ($pull->getStatus()) { + case ReleephRequestStatus::STATUS_NEEDS_PICK: + if ($pull->getPickStatus() == ReleephRequest::PICK_FAILED) { + $warnings[] = pht('Last pull failed!'); + } + break; + case ReleephRequestStatus::STATUS_NEEDS_REVERT: + if ($pull->getPickStatus() == ReleephRequest::REVERT_FAILED) { + $warnings[] = pht('Last revert failed!'); + } + break; + } + + return $warnings; + } + +} diff --git a/src/applications/releeph/view/request/ReleephRequestIntentsView.php b/src/applications/releeph/view/request/ReleephRequestIntentsView.php deleted file mode 100644 --- a/src/applications/releeph/view/request/ReleephRequestIntentsView.php +++ /dev/null @@ -1,99 +0,0 @@ -<?php - -final class ReleephRequestIntentsView extends AphrontView { - - private $releephRequest; - private $releephProject; - - public function setReleephRequest(ReleephRequest $rq) { - $this->releephRequest = $rq; - return $this; - } - - public function setReleephProject(ReleephProject $rp) { - $this->releephProject = $rp; - return $this; - } - - public function render() { - require_celerity_resource('releeph-intents'); - - return phutil_tag( - 'div', - array( - 'class' => 'releeph-intents', - ), - array( - $this->renderIntentList(ReleephRequest::INTENT_WANT), - $this->renderIntentList(ReleephRequest::INTENT_PASS) - )); - } - - private function renderIntentList($render_intent) { - if (!$this->releephProject) { - throw new Exception("Must call setReleephProject() first!"); - } - - $project = $this->releephProject; - $request = $this->releephRequest; - $handles = $request->getHandles(); - - $pusher_links = array(); - $user_links = array(); - - $intents = $request->getUserIntents(); - foreach ($intents as $user_phid => $user_intent) { - if ($user_intent == $render_intent) { - if ($project->isAuthoritativePHID($user_phid)) { - $pusher_links[] = phutil_tag( - 'span', - array( - 'class' => 'pusher' - ), - $handles[$user_phid]->renderLink()); - } else { - $class = 'bystander'; - if ($request->getRequestUserPHID() == $user_phid) { - $class = 'requestor'; - } - $user_links[] = phutil_tag( - 'span', - array( - 'class' => $class, - ), - $handles[$user_phid]->renderLink()); - } - } - } - - // Don't render anything - if (!$pusher_links && !$user_links) { - return null; - } - - $links = array_merge($pusher_links, $user_links); - if ($links) { - $markup = $links; - } else { - $markup = array(' '); - } - - // Stick an arrow up front - $arrow_class = 'arrow '.$render_intent; - array_unshift($markup, phutil_tag( - 'div', - array( - 'class' => $arrow_class, - ), - '')); - - return phutil_tag( - 'div', - array( - 'class' => 'intents', - ), - $markup); - } - - -} diff --git a/src/applications/releeph/view/request/ReleephRequestStatusView.php b/src/applications/releeph/view/request/ReleephRequestStatusView.php deleted file mode 100644 --- a/src/applications/releeph/view/request/ReleephRequestStatusView.php +++ /dev/null @@ -1,53 +0,0 @@ -<?php - -final class ReleephRequestStatusView extends AphrontView { - - private $releephRequest; - - public function setReleephRequest(ReleephRequest $rq) { - $this->releephRequest = $rq; - return $this; - } - - public function render() { - require_celerity_resource('releeph-status'); - - $request = $this->releephRequest; - $status = $request->getStatus(); - $pick_status = $request->getPickStatus(); - - $description = ReleephRequestStatus::getStatusDescriptionFor($status); - - $warning = null; - - if ($status == ReleephRequestStatus::STATUS_NEEDS_PICK) { - if ($pick_status == ReleephRequest::PICK_FAILED) { - $warning = 'Last pick failed!'; - } - } elseif ($status == ReleephRequestStatus::STATUS_NEEDS_REVERT) { - if ($pick_status == ReleephRequest::REVERT_FAILED) { - $warning = 'Last revert failed!'; - } - } - - return phutil_tag( - 'div', - array( - 'class' => 'releeph-status', - ), - array( - phutil_tag( - 'div', - array( - 'class' => 'description', - ), - $description), - phutil_tag( - 'div', - array( - 'class' => 'warning', - ), - $warning))); - } - -} diff --git a/src/applications/releeph/view/request/header/ReleephRequestHeaderListView.php b/src/applications/releeph/view/request/header/ReleephRequestHeaderListView.php deleted file mode 100644 --- a/src/applications/releeph/view/request/header/ReleephRequestHeaderListView.php +++ /dev/null @@ -1,121 +0,0 @@ -<?php - -final class ReleephRequestHeaderListView - extends AphrontView { - - private $releephProject; - private $releephBranch; - private $releephRequests; - private $aphrontRequest; - private $reload = false; - - private $errors = array(); - - public function setReleephProject(ReleephProject $rp) { - $this->releephProject = $rp; - return $this; - } - - public function setReleephBranch(ReleephBranch $rb) { - $this->releephBranch = $rb; - return $this; - } - - public function setReleephRequests(array $requests) { - assert_instances_of($requests, 'ReleephRequest'); - $this->releephRequests = $requests; - return $this; - } - - public function setAphrontRequest(AphrontRequest $request) { - $this->aphrontRequest = $request; - return $this; - } - - public function setReloadOnStateChange($bool) { - $this->reload = $bool; - return $this; - } - - public function render() { - $views = $this->renderInner(); - require_celerity_resource('phabricator-notification-css'); - Javelin::initBehavior('releeph-request-state-change', array( - 'reload' => $this->reload, - )); - - $error_view = null; - if ($this->errors) { - $error_view = id(new AphrontErrorView()) - ->setTitle('Bulk load errors') - ->setSeverity(AphrontErrorView::SEVERITY_WARNING) - ->setErrors($this->errors) - ->render(); - } - - $list = phutil_tag( - 'div', - array( - 'data-sigil' => 'releeph-request-header-list', - ), - $views); - - return array($error_view, $list); - } - - /** - * Required for generating markup for ReleephRequestActionController. - * - * That controller just needs the markup, and doesn't need to start the - * javelin behavior. - */ - public function renderInner() { - $selector = $this->releephProject->getReleephFieldSelector(); - $fields = $selector->getFieldSpecifications(); - foreach ($fields as $field) { - $field - ->setReleephProject($this->releephProject) - ->setReleephBranch($this->releephBranch) - ->setUser($this->user); - try { - $field->bulkLoad($this->releephRequests); - } catch (Exception $ex) { - $this->errors[] = $ex; - } - } - - $engine = id(new PhabricatorMarkupEngine()) - ->setViewer($this->getUser()); - - $views = array(); - foreach ($this->releephRequests as $releeph_request) { - $our_fields = array(); - foreach ($fields as $key => $field) { - $our_fields[$key] = clone $field; - } - - foreach ($our_fields as $field) { - if ($field->shouldMarkup()) { - $field - ->setReleephRequest($releeph_request) - ->setMarkupEngine($engine); - } - } - - $our_field_groups = $selector->arrangeFieldsForHeaderView($our_fields); - - $views[] = id(new ReleephRequestHeaderView()) - ->setUser($this->user) - ->setAphrontRequest($this->aphrontRequest) - ->setReleephProject($this->releephProject) - ->setReleephBranch($this->releephBranch) - ->setReleephRequest($releeph_request) - ->setReleephFieldGroups($our_field_groups); - } - - $engine->process(); - - return $views; - } - -} diff --git a/src/applications/releeph/view/request/header/ReleephRequestHeaderView.php b/src/applications/releeph/view/request/header/ReleephRequestHeaderView.php deleted file mode 100644 --- a/src/applications/releeph/view/request/header/ReleephRequestHeaderView.php +++ /dev/null @@ -1,323 +0,0 @@ -<?php - -final class ReleephRequestHeaderView extends AphrontView { - - const THROW_PARAM = '__releeph_throw'; - - private $aphrontRequest; - private $releephRequest; - private $releephBranch; - private $releephProject; - private $fieldGroups; - - public function setAphrontRequest(AphrontRequest $request) { - $this->aphrontRequest = $request; - return $this; - } - - public function setReleephProject(ReleephProject $rp) { - $this->releephProject = $rp; - return $this; - } - - public function setReleephBranch(ReleephBranch $rb) { - $this->releephBranch = $rb; - return $this; - } - - public function setReleephRequest(ReleephRequest $rr) { - $this->releephRequest = $rr; - return $this; - } - - public function setReleephFieldGroups(array $field_groups) { - $this->fieldGroups = $field_groups; - return $this; - } - - public function render() { - require_celerity_resource('releeph-core'); - $all_properties_table = $this->renderFields(); - - require_celerity_resource('releeph-colors'); - $status = $this->releephRequest->getStatus(); - $rr_div_class = - 'releeph-request-header '. - 'releeph-request-header-border '. - 'releeph-border-color-'. - ReleephRequestStatus::getStatusClassSuffixFor($status); - - $hidden_link = phutil_tag( - 'a', - array( - 'href' => '/RQ'.$this->releephRequest->getID(), - 'target' => '_blank', - 'data-sigil' => 'hidden-link', - ), - ''); - - $focus_char = phutil_tag( - 'div', - array( - 'class' => 'focus-char', - 'data-sigil' => 'focus-char', - ), - "\xE2\x98\x86"); - - $rr_div = phutil_tag( - 'div', - array( - 'data-sigil' => 'releeph-request-header', - 'class' => $rr_div_class, - ), - array( - phutil_tag( - 'div', - array(), - array( - phutil_tag( - 'h1', - array(), - array( - $focus_char, - $this->renderTitleLink(), - $hidden_link - )), - $all_properties_table, - )), - phutil_tag( - 'div', - array( - 'class' => 'button-divider', - ), - $this->renderActionButtonsTable()))); - - return $rr_div; - } - - private function renderFields() { - $field_row_groups = $this->fieldGroups; - - $trs = array(); - foreach ($field_row_groups as $field_column_group) { - $tds = array(); - foreach ($field_column_group as $side => $fields) { - $rows = array(); - foreach ($fields as $field) { - $rows[] = $this->renderOneField($field); - } - $pane = phutil_tag( - 'table', - array( - 'class' => 'fields', - ), - $rows); - $tds[] = phutil_tag( - 'td', - array( - 'class' => 'side '.$side, - ), - $pane); - } - $trs[] = phutil_tag( - 'tr', - array(), - $tds); - } - - return phutil_tag( - 'table', - array( - 'class' => 'panes', - ), - $trs); - } - - private function renderOneField(ReleephFieldSpecification $field) { - $field - ->setUser($this->user) - ->setReleephProject($this->releephProject) - ->setReleephBranch($this->releephBranch) - ->setReleephRequest($this->releephRequest); - - $label = $field->renderLabelForHeaderView(); - try { - $value = $field->renderValueForHeaderView(); - } catch (Exception $ex) { - if ($this->aphrontRequest->getInt(self::THROW_PARAM)) { - throw $ex; - } else { - $value = $this->renderExceptionIcon($ex); - } - } - - if ($value) { - if (!$label) { - return phutil_tag( - 'tr', - array(), - phutil_tag('td', array('colspan' => 2), $value)); - } else { - return phutil_tag( - 'tr', - array(), - array( - phutil_tag('th', array(), $label), - phutil_tag('td', array(), $value))); - } - } - } - - private function renderExceptionIcon(Exception $ex) { - Javelin::initBehavior('phabricator-tooltips'); - require_celerity_resource('aphront-tooltip-css'); - $throw_uri = $this - ->aphrontRequest - ->getRequestURI() - ->setQueryParam(self::THROW_PARAM, 1); - - $message = $ex->getMessage(); - if (!$message) { - $message = get_class($ex).' with no message.'; - } - - return javelin_tag( - 'a', - array( - 'class' => 'releeph-field-error', - 'sigil' => 'has-tooltip', - 'meta' => array( - 'tip' => $message, - 'size' => 400, - 'align' => 'E', - ), - 'href' => $throw_uri, - ), - '!!!'); - } - - private function renderTitleLink() { - $rq_id = $this->releephRequest->getID(); - $summary = $this->releephRequest->getSummaryForDisplay(); - return phutil_tag( - 'a', - array( - 'href' => '/RQ'.$rq_id, - ), - hsprintf( - 'RQ%d: %s', - $rq_id, - $summary)); - } - - private function renderActionButtonsTable() { - $left_buttons = array(); - $right_buttons = array(); - - $user_phid = $this->user->getPHID(); - $is_pusher = $this->releephProject->isAuthoritativePHID($user_phid); - $is_requestor = $this->releephRequest->getRequestUserPHID() === $user_phid; - - $current_intent = idx( - $this->releephRequest->getUserIntents(), - $this->user->getPHID()); - - if ($is_pusher) { - $left_buttons[] = $this->renderIntentButton(true, 'Approve', 'green'); - $left_buttons[] = $this->renderIntentButton(false, 'Reject'); - } else { - if ($is_requestor) { - $right_buttons[] = $this->renderIntentButton(true, 'Request'); - $right_buttons[] = $this->renderIntentButton(false, 'Remove'); - } else { - $right_buttons[] = $this->renderIntentButton(true, 'Want'); - $right_buttons[] = $this->renderIntentButton(false, 'Pass'); - } - } - - // Allow the pusher to mark a request as manually picked or reverted. - if ($is_pusher || $is_requestor) { - if ($this->releephRequest->getInBranch()) { - $left_buttons[] = $this->renderActionButton( - 'Mark Manually Reverted', - 'mark-manually-reverted'); - } else { - $left_buttons[] = $this->renderActionButton( - 'Mark Manually Picked', - 'mark-manually-picked'); - } - } - - $right_buttons[] = phutil_tag( - 'a', - array( - 'href' => '/releeph/request/edit/'.$this->releephRequest->getID().'/', - 'class' => 'small blue button', - ), - 'Edit'); - - if (!$left_buttons && !$right_buttons) { - return; - } - - $cells = array(); - foreach ($left_buttons as $button) { - $cells[] = phutil_tag('td', array('align' => 'left'), $button); - } - $cells[] = phutil_tag('td', array('class' => 'wide'), ''); - foreach ($right_buttons as $button) { - $cells[] = phutil_tag('td', array('align' => 'right'), $button); - } - - $table = phutil_tag( - 'table', - array( - 'class' => 'buttons', - ), - phutil_tag( - 'tr', - array(), - $cells)); - - return $table; - } - - private function renderIntentButton($want, $name, $class = null) { - $current_intent = idx( - $this->releephRequest->getUserIntents(), - $this->user->getPHID()); - - if ($current_intent) { - // If this is a "want" button, and they already want it, disable the - // button (and vice versa for the "pass" case.) - if (($want && $current_intent == ReleephRequest::INTENT_WANT) || - (!$want && $current_intent == ReleephRequest::INTENT_PASS)) { - - $class .= ' disabled'; - } - } - - $action = $want ? 'want' : 'pass'; - return $this->renderActionButton($name, $action, $class); - } - - private function renderActionButton($name, $action, $class=null) { - $attributes = array( - 'class' => 'small button '.$class, - 'sigil' => 'releeph-request-state-change '.$action, - 'meta' => null, - ); - - if ($class != 'disabled') { - // NB the trailing slash on $uri is critical, otherwise the URI will - // redirect to one with a slash, which will turn our GET into a POST. - $attributes['meta'] = sprintf( - '/releeph/request/action/%s/%d/', - $action, - $this->releephRequest->getID()); - } - - return javelin_tag('a', $attributes, $name); - } - -} diff --git a/src/applications/uiexample/examples/PhabricatorNoteExample.php b/src/applications/uiexample/examples/PhabricatorNoteExample.php deleted file mode 100644 --- a/src/applications/uiexample/examples/PhabricatorNoteExample.php +++ /dev/null @@ -1,137 +0,0 @@ -<?php - -final class PhabricatorNoteExample extends PhabricatorUIExample { - - public function getName() { - return "Notes"; - } - - public function getDescription() { - return pht('Bounded boxes of text.'); - } - - public function renderExample() { - $short_note = id(new AphrontNoteView()) - ->setTitle(pht('Short note')) - ->appendChild('xxxx xx x xxxxx xxxx'); - - $longer_note = id(new AphrontNoteView()) - ->setTitle(pht('Longer note')) - ->appendChild($this->buildParagraphs(2)); - - $wide_url = 'protocol://www.'.str_repeat('x', 100).'.com/'; - - $oversize_note = id(new AphrontNoteView()) - ->setTitle(pht('Oversize note')) - ->appendChild( - $this->buildParagraphs(2). - $wide_url."\n\n". - $this->buildParagraphs(15)); - - $out = array(); - - $out[] = id(new AphrontPanelView()) - ->setHeader(pht('Unbounded Oversize Note')) - ->appendChild($oversize_note); - - $out[] = id(new AphrontPanelView()) - ->setHeader(pht('Short notes')) - ->appendChild( - $this->renderTable( - array(array($short_note, $short_note)))); - - $out[] = id(new AphrontPanelView()) - ->setHeader(pht('Mixed notes')) - ->appendChild( - $this->renderTable( - array( - array($longer_note, $short_note), - array($short_note, $short_note) - ))); - - $out[] = id(new AphrontPanelView()) - ->setHeader(pht('Oversize notes')) - ->appendChild( - $this->renderTable( - array( - array($oversize_note, $short_note), - array($short_note, $oversize_note) - ))); - - return $out; - } - - private function renderTable($rows) { - static $td_style = ' - width: 50%; - max-width: 1em; - '; - - $trs = array(); - foreach ($rows as $index => $row) { - $count = $index + 1; - list($left, $right) = $row; - $trs[] = phutil_tag( - 'tr', - array(), - array( - phutil_tag( - 'th', - array(), - "Row {$count}"), - phutil_tag('td'))); - - $trs[] = phutil_tag( - 'tr', - array(), - array( - phutil_tag( - 'td', - array( - 'style' => $td_style, - ), - $left->render()), - phutil_tag( - 'td', - array( - 'style' => $td_style, - ), - $right->render()))); - } - - return phutil_tag( - 'table', - array( - 'style' => 'width: 80%;' - ), - $trs); - } - - private function buildParagraphs($num_paragraphs) { - $body = ''; - for ($pp = 0; $pp < $num_paragraphs; $pp++) { - $scale = 50 * ($pp / 2); - $num_words = 30 + self::getRandom(0, $scale); - for ($ii = 0; $ii < $num_words; $ii++) { - $word = str_repeat('x', self::getRandom(3, 8)); - $body .= $word.' '; - } - $body .= "\n\n"; - } - return $body; - } - - private static function getRandom($lower, $upper) { - // The ZX Spectrum's PRNG! - static $nn = 65537; - static $gg = 75; - static $ii = 1; - $ii = ($ii * $gg) % $nn; - if ($lower == $upper) { - return $lower; - } else { - return $lower + ($ii % ($upper - $lower)); - } - } - -} diff --git a/src/view/layout/PhabricatorActionView.php b/src/view/layout/PhabricatorActionView.php --- a/src/view/layout/PhabricatorActionView.php +++ b/src/view/layout/PhabricatorActionView.php @@ -11,6 +11,7 @@ private $renderAsForm; private $download; private $objectURI; + private $sigils = array(); public function setObjectURI($object_uri) { $this->objectURI = $object_uri; @@ -34,6 +35,11 @@ return $this; } + public function addSigil($sigil) { + $this->sigils[] = $sigil; + return $this; + } + /** * If the user is not logged in and the action is relatively complicated, * give them a generic login link that will re-direct to the page they're @@ -98,6 +104,21 @@ } if ($this->href) { + + $sigils = array(); + if ($this->workflow) { + $sigils[] = 'workflow'; + } + if ($this->download) { + $sigils[] = 'download'; + } + + if ($this->sigils) { + $sigils = array_merge($sigils, $this->sigils); + } + + $sigils = $sigils ? implode(' ', $sigils) : null; + if ($this->renderAsForm) { if (!$this->user) { throw new Exception( @@ -111,20 +132,12 @@ ), $this->name); - $sigils = array(); - if ($this->workflow) { - $sigils[] = 'workflow'; - } - if ($this->download) { - $sigils[] = 'download'; - } - $item = phabricator_form( $this->user, array( 'action' => $this->getHref(), 'method' => 'POST', - 'sigil' => implode(' ', $sigils), + 'sigil' => $sigils, ), $item); } else { @@ -133,7 +146,7 @@ array( 'href' => $this->getHref(), 'class' => 'phabricator-action-view-item', - 'sigil' => $this->workflow ? 'workflow' : null, + 'sigil' => $sigils, ), $this->name); } diff --git a/src/view/phui/PHUIObjectBoxView.php b/src/view/phui/PHUIObjectBoxView.php --- a/src/view/phui/PHUIObjectBoxView.php +++ b/src/view/phui/PHUIObjectBoxView.php @@ -11,10 +11,22 @@ private $header; private $flush; private $id; + private $sigils = array(); + private $metadata; private $tabs = array(); private $propertyLists = array(); + public function addSigil($sigil) { + $this->sigils[] = $sigil; + return $this; + } + + public function setMetadata(array $metadata) { + $this->metadata = $metadata; + return $this; + } + public function addPropertyList( PHUIPropertyListView $property_list, $tab = null) { @@ -246,6 +258,14 @@ $content->addClass('phui-object-box-flush'); } + foreach ($this->sigils as $sigil) { + $content->addSigil($sigil); + } + + if ($this->metadata !== null) { + $content->setMetadata($this->metadata); + } + return $content; } } diff --git a/src/view/widget/AphrontNoteView.php b/src/view/widget/AphrontNoteView.php deleted file mode 100644 --- a/src/view/widget/AphrontNoteView.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php - -final class AphrontNoteView extends AphrontView { - - private $title; - - public function setTitle($title) { - $this->title = $title; - return $this; - } - - public function render() { - $title = phutil_tag( - 'div', - array( - 'class' => 'title', - ), - $this->title); - - $inner = phutil_tag( - 'div', - array( - 'class' => 'inner', - ), - $this->renderChildren()); - - require_celerity_resource('aphront-notes'); - return phutil_tag( - 'div', - array( - 'class' => 'aphront-note', - ), - array( - $title, - $inner)); - } - -} diff --git a/webroot/rsrc/css/aphront/aphront-notes.css b/webroot/rsrc/css/aphront/aphront-notes.css deleted file mode 100644 --- a/webroot/rsrc/css/aphront/aphront-notes.css +++ /dev/null @@ -1,26 +0,0 @@ -/** - * @provides aphront-notes - */ - -div.aphront-note { - margin: 1em; - background: #ffc; - border: 1px solid #ccc; -} - -div.aphront-note div.title { - margin: 0; - padding: 0.2em 0.5em 0.2em; - background: #ffd; - border-bottom: 1px solid #ccc; - color: {$lightgreytext}; - font-size: smaller; -} - -div.aphront-note div.inner { - overflow: auto; - padding: 0.5em; - max-height: 25em; - color: #333; - font-size: smaller; -} diff --git a/webroot/rsrc/css/application/releeph/releeph-branch.css b/webroot/rsrc/css/application/releeph/releeph-branch.css deleted file mode 100644 --- a/webroot/rsrc/css/application/releeph/releeph-branch.css +++ /dev/null @@ -1,79 +0,0 @@ -/** - * @provides releeph-branch - */ - -.releeph-branch-box { - margin-bottom: .5em; - padding: .5em .5em .5em; - - border: 2px solid #d5d5d5; - /*border-top-color: #D5D5D5; - border-right-color: #BBB; - border-bottom-color: #A4A4A4; - border-left-color: #BBB;*/ - - background: #bbb; -} - -/* Types of branch */ - -.releeph-branch-box-named { - background: #ddd; -} - -.releeph-branch-box-latest { - background: #ffd; -} - -/* Branch symbolic name and full name */ - -.releeph-branch-box .names { - width: 25em; - float: left; - margin-bottom: 1em; -} - -.releeph-branch-box .names h1 { - font-size: 125%; - padding: 0px; -} - -.releeph-branch-box .names h2 { - font-weight: normal; - font-size: 85%; -} - -/* Date info */ - -.releeph-branch-box .date-info { - width: 10%; - float: left; - color: #555; - margin-bottom: .3em; -} - -/* Statistics table */ - -.releeph-branch-box .request-statistics { - float: right; - padding-right: 2em; - font-size: 85%; -} - -.releeph-branch-box .request-statistics th { - width: 1em; - text-align: right; - padding-right: .4em; - padding-left: .4em; -} - -.releeph-branch-box .request-statistics td { - white-space: nowrap; - font-style: italic; -} - -/* Buttons */ - -.releeph-branch-box .buttons { - float: right; -} diff --git a/webroot/rsrc/css/application/releeph/releeph-colors.css b/webroot/rsrc/css/application/releeph/releeph-colors.css deleted file mode 100644 --- a/webroot/rsrc/css/application/releeph/releeph-colors.css +++ /dev/null @@ -1,35 +0,0 @@ -/** - * @provides releeph-colors - */ - -.releeph-border-color-failed { - border-color: #d2d; -} - -.releeph-border-color-requested { - border-color: #ddd; -} - -.releeph-border-color-comment { - border-color: #ddd; -} - -.releeph-border-color-needs-pick { - border-color: #096; -} - -.releeph-border-color-rejected { - border-color: #d00; -} - -.releeph-border-color-needs-revert { - border-color: #d00; -} - -.releeph-border-color-abandoned { - border-color: #222; -} - -.releeph-border-color-picked { - border-color: #069; -} diff --git a/webroot/rsrc/css/application/releeph/releeph-core.css b/webroot/rsrc/css/application/releeph/releeph-core.css --- a/webroot/rsrc/css/application/releeph/releeph-core.css +++ b/webroot/rsrc/css/application/releeph/releeph-core.css @@ -2,119 +2,6 @@ * @provides releeph-core */ -.releeph-request-header { - margin: .5em 2em 3em; - - /** - * Copied from the old .differential-panel, present in commit - * f04d8ab1a747dc9719d378d9286088b677ce224c - * - * (As is the <h1> code below) - */ - max-width: 1120px; - border: 1px solid {$greytext}622; - background: #efefdf; - padding: 15px 20px; - font-size: 13px; -} - -.releeph-request-header h1 { - width: 100%; - border-bottom: 1px solid #aaaa99; - padding-bottom: 8px; - margin-bottom: 8px; - position: relative; -} - -.releeph-request-header .focus-char { - left: -10px; - display: none; - float: left; - position: absolute; - top: 0px; - left: -1em; - - font-weight: bold; - - color: #880; - font-family: "Hiragino Kaku Gothic Pro", "Osaka", "Zapf Dingbats"; -} - -.releeph-request-header.focus .focus-char { - display: block; -} - -.releeph-request-header-border { - border-width: 1px 10px 1px; - border-color: #ddd; -} - - -/* Laying out properties / fields */ - -.releeph-request-header table.panes { - width: 100%; -} - -.releeph-request-header table.panes td.side { - width: 50%; - max-width: 1em; -} - -.releeph-request-header table.panes td.side.left { - padding-right: 20px; - border-right: 3px solid #bbb; -} - -.releeph-request-header table.panes td.side.right { - padding-left: 20px; -} - -.releeph-request-header table.panes td.side table.fields { - width: 100%; -} - -.releeph-request-header table.panes td.side table.fields tr { - vertical-align: middle; -} - -.releeph-request-header table.panes td.side table.fields th { - font-weight: bold; - text-align: right; - padding-right: 1em; - white-space: nowrap; -} - -.releeph-request-header table.panes td.side table.fields td { - width: 100%; /* wide! */ - max-width: 1em; -} - - -/* Buttons */ - -.releeph-request-header .button-divider { - clear: both; - margin-top: 1.5em; - border-top: 1px solid #bbb; -} - -.releeph-request-header .buttons { - width: 100%; -} - -.releeph-request-header .buttons tr { - padding: 1em; - margin: 3em; -} - -.releeph-request-header .buttons td { - padding: 1em .5em 0.2em; -} - -.releeph-request-header .buttons td.wide { - width: 100%; -} /* Colors: match differential colors */ @@ -133,11 +20,11 @@ /* The diff size bar */ -.releeph-request-header .diff-bar { +.diff-bar { border: 0px; } -.releeph-request-header .diff-bar div { +.diff-bar div { width: 100px; border: 1px solid; border-top-color: #A4A4A4; @@ -149,51 +36,10 @@ margin-right: 1em; } -.releeph-request-header .diff-bar div div { +.diff-bar div div { height: 10px; } -.releeph-request-header .diff-bar span { +.diff-bar span { color: #555; } - -/* Rendering pick / commit errors, etc. */ - -.releeph-request-pick-failed-event h1:before { - content: '\2014 '; -} - -.releeph-request-pick-failed-event h1:after { - content: ' \2014'; -} - -.releeph-request-pick-failed-event h1 { - padding: 3px 10px 3px; - margin-bottom: 0.5em; - background: #ffb; - font-size: small; -} - -.releeph-request-pick-failed-event div { - font-family: monospace; - margin-bottom: 1.5em; - padding-left: 1em; - width: 70em; -} - -/* History view of request */ - -.releeph-request-event-list { - margin: .5em 2em .5em; -} - - -/* Shorten long header-text */ - -.releeph-header-text-truncated { - width: 100%; - float: left; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} diff --git a/webroot/rsrc/css/application/releeph/releeph-intents.css b/webroot/rsrc/css/application/releeph/releeph-intents.css deleted file mode 100644 --- a/webroot/rsrc/css/application/releeph/releeph-intents.css +++ /dev/null @@ -1,37 +0,0 @@ -/** - * @provides releeph-intents - */ - -.releeph-intents .intents { - clear: left; - width: 100%; - margin-top: 3px; -} - -.releeph-intents .arrow { - float: left; - clear: left; - margin-right: 0.4em; - padding: 8px; - background: transparent 0 0 no-repeat; -} - -.releeph-intents .arrow.want { - /* TODO: Icon. */ -} - -.releeph-intents .arrow.pass { - /* TODO: Icon. */ -} - -.releeph-intents a { - margin-right: 0.4em; -} - -.releeph-intents .pusher { - font-weight: bold; -} - -.releeph-intents .requestor { - font-weight: normal; -} diff --git a/webroot/rsrc/css/application/releeph/releeph-project.css b/webroot/rsrc/css/application/releeph/releeph-project.css deleted file mode 100644 --- a/webroot/rsrc/css/application/releeph/releeph-project.css +++ /dev/null @@ -1,25 +0,0 @@ -/** - * @provides releeph-project - */ - -/** - * ...from aphront-transaction.css - */ - -.releeph-pusher { - background: 2px 2px no-repeat; - margin-top: 1em; - margin-bottom: 1.25em; - margin-right: 1em; - min-height: 50px; - padding: 2px 0px; - - background-color: white; - border: 2px solid gray; - float: left; -} - -.releeph-pusher-body { - margin-left: 54px; - padding: 1em; -} diff --git a/webroot/rsrc/css/application/releeph/releeph-status.css b/webroot/rsrc/css/application/releeph/releeph-status.css deleted file mode 100644 --- a/webroot/rsrc/css/application/releeph/releeph-status.css +++ /dev/null @@ -1,27 +0,0 @@ -/** - * @provides releeph-status - */ - -.releeph-status .description { - background: #d3d3d3; - padding: 2px 6px 3px; - margin-right: 4px; - margin-bottom: 5px; - display: block; - float: left; - border-radius: 8px; - -moz-border-radius: 8px; - -webkit-border-radius: 8px; - text-decoration: none; -} - -.releeph-status .warning { - margin-top: 2px; - margin-left: 0.8em; - float: left; - padding-left: 22px; - background-repeat: no-repeat; - background-size: 16px auto; - - /* TODO: This had a background that's still at Facebook? */ -} diff --git a/webroot/rsrc/css/phui/phui-box.css b/webroot/rsrc/css/phui/phui-box.css --- a/webroot/rsrc/css/phui/phui-box.css +++ b/webroot/rsrc/css/phui/phui-box.css @@ -7,3 +7,7 @@ border-bottom: 1px solid {$blueborder}; background-color: #fff; } + +.phui-box.focus { + box-shadow: 0 0 5px 5px rgba(255, 255, 0, 0.90); +} diff --git a/webroot/rsrc/js/application/releeph/releeph-request-state-change.js b/webroot/rsrc/js/application/releeph/releeph-request-state-change.js --- a/webroot/rsrc/js/application/releeph/releeph-request-state-change.js +++ b/webroot/rsrc/js/application/releeph/releeph-request-state-change.js @@ -3,23 +3,17 @@ * @requires javelin-behavior * javelin-dom * javelin-stratcom - * javelin-request + * javelin-workflow + * javelin-util * phabricator-keyboard-shortcut - * phabricator-notification */ JX.behavior('releeph-request-state-change', function(config) { - var root = JX.DOM.find(document, 'div', 'releeph-request-header-list'); - function getRequestHeaderNodes() { - return JX.DOM.scry(root, 'div', 'releeph-request-header'); + return JX.DOM.scry(document.body, 'div', 'releeph-request-box'); } - /** - * Keyboard navigation - */ var keynav_cursor = -1; - var notification = new JX.Notification(); function keynavJump(manager, delta) { // Calculate this everytime, because the DOM changes. @@ -68,7 +62,7 @@ function keynavNavigateToRequestPage() { var headers = getRequestHeaderNodes(); var header = headers[keynav_cursor]; - JX.DOM.find(header, 'a', 'hidden-link').click(); + window.open(JX.Stratcom.getData(header).uri); } new JX.KeyboardShortcut('j', 'Jump to next request.') @@ -95,51 +89,33 @@ }) .register(); - new JX.KeyboardShortcut('g', "Open selected request's page in a new tab.") + new JX.KeyboardShortcut( + ['g', 'return'], + "Open selected request's page in a new tab.") .setHandler(function(manager) { keynavNavigateToRequestPage(); }) .register(); - - /** - * AJAXy state changes for request buttons. - */ - function request_action(node, url) { - var request = new JX.Request(url, function(response) { - if (config.reload) { - window.location.reload(); - } else { - var markup = JX.$H(response.markup); - JX.DOM.replace(node, markup); - keynavMarkup(); - } - }); - - request.send(); + function onresponse(box, response) { + JX.DOM.replace(box, JX.$H(response.markup)); + keynavMarkup(); } JX.Stratcom.listen( 'click', 'releeph-request-state-change', function(e) { - var button = e.getNode('releeph-request-state-change'); - var node = e.getNode('releeph-request-header'); - var url = e.getNodeData('releeph-request-state-change'); - - // If this button has no action, or we've already responded to the first - // click... - if (!url || button.disabled) { - return; - } + e.kill(); - // There's a race condition here though :( + var box = e.getNode('releeph-request-box'); + var link = e.getNode('releeph-request-state-change'); - JX.DOM.alterClass(button, 'disabled', true); - button.disabled = true; + box.style.opacity = '0.5'; - e.prevent(); - request_action(node, url); - } - ); + JX.Workflow.newFromLink(link) + .setData({render: true}) + .setHandler(JX.bind(null, onresponse, box)) + .start(); + }); });