From 771579496fc1fe676de23aa199338388ab6bbab2 Mon Sep 17 00:00:00 2001 From: epriestley Date: Fri, 26 Aug 2016 08:04:30 -0700 Subject: [PATCH 01/25] Make logic for streaming VCS stuff directly to Files more reusable Summary: Ref T11524. Ref T10423. Earlier, I converted `diffusion.filecontentquery` to put the actual file content in Files, then return a PHID for the file, instead of trying to send the content over Conduit. In T11524, we have a similar set of problems with diffs that contain non-UTF8 data (and, in T10423, diffs that are simply enormous). I want to provide an API method to do the same sort of thing with diff output (like from `git diff`), so we call the method, it shoves the data in Files, and then we go pull it out of Files. To support this, take the "shove the output of a Future into Files" logic and put it in a new base `FileFuture` query. This will let me make `RawDiffQuery` share the logic more easily. Test Plan: Browsed Diffusion, ran `diffusion.filecontentquery` to fetch file content. Reviewers: chad Reviewed By: chad Maniphest Tasks: T10423, T11524 Differential Revision: https://secure.phabricator.com/D16458 --- src/__phutil_library_map__.php | 4 +- ...fusionFileContentQueryConduitAPIMethod.php | 40 +---- .../query/DiffusionFileFutureQuery.php | 153 ++++++++++++++++++ .../filecontent/DiffusionFileContentQuery.php | 92 +---------- .../DiffusionGitFileContentQuery.php | 5 - .../DiffusionMercurialFileContentQuery.php | 5 - .../DiffusionSvnFileContentQuery.php | 5 - 7 files changed, 161 insertions(+), 143 deletions(-) create mode 100644 src/applications/diffusion/query/DiffusionFileFutureQuery.php diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index dbe5519547..b0b4ba8622 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -656,6 +656,7 @@ phutil_register_library_map(array( 'DiffusionExternalSymbolsSource' => 'applications/diffusion/symbol/DiffusionExternalSymbolsSource.php', 'DiffusionFileContentQuery' => 'applications/diffusion/query/filecontent/DiffusionFileContentQuery.php', 'DiffusionFileContentQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionFileContentQueryConduitAPIMethod.php', + 'DiffusionFileFutureQuery' => 'applications/diffusion/query/DiffusionFileFutureQuery.php', 'DiffusionFindSymbolsConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionFindSymbolsConduitAPIMethod.php', 'DiffusionGetLintMessagesConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionGetLintMessagesConduitAPIMethod.php', 'DiffusionGetRecentCommitsByPathConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionGetRecentCommitsByPathConduitAPIMethod.php', @@ -5149,8 +5150,9 @@ phutil_register_library_map(array( 'DiffusionExternalController' => 'DiffusionController', 'DiffusionExternalSymbolQuery' => 'Phobject', 'DiffusionExternalSymbolsSource' => 'Phobject', - 'DiffusionFileContentQuery' => 'DiffusionQuery', + 'DiffusionFileContentQuery' => 'DiffusionFileFutureQuery', 'DiffusionFileContentQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod', + 'DiffusionFileFutureQuery' => 'DiffusionQuery', 'DiffusionFindSymbolsConduitAPIMethod' => 'DiffusionConduitAPIMethod', 'DiffusionGetLintMessagesConduitAPIMethod' => 'DiffusionConduitAPIMethod', 'DiffusionGetRecentCommitsByPathConduitAPIMethod' => 'DiffusionConduitAPIMethod', diff --git a/src/applications/diffusion/conduit/DiffusionFileContentQueryConduitAPIMethod.php b/src/applications/diffusion/conduit/DiffusionFileContentQueryConduitAPIMethod.php index 10e4d00b83..d59a498131 100644 --- a/src/applications/diffusion/conduit/DiffusionFileContentQueryConduitAPIMethod.php +++ b/src/applications/diffusion/conduit/DiffusionFileContentQueryConduitAPIMethod.php @@ -19,48 +19,14 @@ final class DiffusionFileContentQueryConduitAPIMethod return array( 'path' => 'required string', 'commit' => 'required string', - 'timeout' => 'optional int', - 'byteLimit' => 'optional int', - ); + ) + DiffusionFileFutureQuery::getConduitParameters(); } protected function getResult(ConduitAPIRequest $request) { $drequest = $this->getDiffusionRequest(); - $file_query = DiffusionFileContentQuery::newFromDiffusionRequest($drequest); - - $timeout = $request->getValue('timeout'); - if ($timeout) { - $file_query->setTimeout($timeout); - } - - $byte_limit = $request->getValue('byteLimit'); - if ($byte_limit) { - $file_query->setByteLimit($byte_limit); - } - - $file = $file_query->execute(); - - $too_slow = (bool)$file_query->getExceededTimeLimit(); - $too_huge = (bool)$file_query->getExceededByteLimit(); - - $file_phid = null; - if (!$too_slow && !$too_huge) { - $repository = $drequest->getRepository(); - $repository_phid = $repository->getPHID(); - - $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); - $file->attachToObject($repository_phid); - unset($unguarded); - - $file_phid = $file->getPHID(); - } - - return array( - 'tooSlow' => $too_slow, - 'tooHuge' => $too_huge, - 'filePHID' => $file_phid, - ); + return DiffusionFileContentQuery::newFromDiffusionRequest($drequest) + ->respondToConduitRequest($request); } } diff --git a/src/applications/diffusion/query/DiffusionFileFutureQuery.php b/src/applications/diffusion/query/DiffusionFileFutureQuery.php new file mode 100644 index 0000000000..595b9fe5ae --- /dev/null +++ b/src/applications/diffusion/query/DiffusionFileFutureQuery.php @@ -0,0 +1,153 @@ + 'optional int', + 'byteLimit' => 'optional int', + ); + } + + public function setTimeout($timeout) { + $this->timeout = $timeout; + return $this; + } + + public function getTimeout() { + return $this->timeout; + } + + public function setByteLimit($byte_limit) { + $this->byteLimit = $byte_limit; + return $this; + } + + public function getByteLimit() { + return $this->byteLimit; + } + + final public function getExceededByteLimit() { + return $this->didHitByteLimit; + } + + final public function getExceededTimeLimit() { + return $this->didHitTimeLimit; + } + + abstract protected function getFileContentFuture(); + + final public function respondToConduitRequest(ConduitAPIRequest $request) { + $drequest = $this->getRequest(); + + $timeout = $request->getValue('timeout'); + if ($timeout) { + $this->setTimeout($timeout); + } + + $byte_limit = $request->getValue('byteLimit'); + if ($byte_limit) { + $this->setByteLimit($byte_limit); + } + + $file = $this->execute(); + + $too_slow = (bool)$this->getExceededTimeLimit(); + $too_huge = (bool)$this->getExceededByteLimit(); + + $file_phid = null; + if (!$too_slow && !$too_huge) { + $repository = $drequest->getRepository(); + $repository_phid = $repository->getPHID(); + + $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); + $file->attachToObject($repository_phid); + unset($unguarded); + + $file_phid = $file->getPHID(); + } + + return array( + 'tooSlow' => $too_slow, + 'tooHuge' => $too_huge, + 'filePHID' => $file_phid, + ); + } + + final public function executeInline() { + $future = $this->getFileContentFuture(); + list($stdout) = $future->resolvex(); + return $future; + } + + final protected function executeQuery() { + $future = $this->newConfiguredFileContentFuture(); + + $drequest = $this->getRequest(); + + $name = basename($drequest->getPath()); + $ttl = PhabricatorTime::getNow() + phutil_units('48 hours in seconds'); + + try { + $threshold = PhabricatorFileStorageEngine::getChunkThreshold(); + $future->setReadBufferSize($threshold); + + $source = id(new PhabricatorExecFutureFileUploadSource()) + ->setName($name) + ->setTTL($ttl) + ->setViewPolicy(PhabricatorPolicies::POLICY_NOONE) + ->setExecFuture($future); + + $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); + $file = $source->uploadFile(); + unset($unguarded); + + } catch (CommandException $ex) { + if (!$future->getWasKilledByTimeout()) { + throw $ex; + } + + $this->didHitTimeLimit = true; + $file = null; + } + + $byte_limit = $this->getByteLimit(); + + if ($byte_limit && ($file->getByteSize() > $byte_limit)) { + $this->didHitByteLimit = true; + + $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); + id(new PhabricatorDestructionEngine()) + ->destroyObject($file); + unset($unguarded); + + $file = null; + } + + return $file; + } + + private function newConfiguredFileContentFuture() { + $future = $this->getFileContentFuture(); + + if ($this->getTimeout()) { + $future->setTimeout($this->getTimeout()); + } + + $byte_limit = $this->getByteLimit(); + if ($byte_limit) { + $future->setStdoutSizeLimit($byte_limit + 1); + } + + return $future; + } + + +} diff --git a/src/applications/diffusion/query/filecontent/DiffusionFileContentQuery.php b/src/applications/diffusion/query/filecontent/DiffusionFileContentQuery.php index df14b49235..4165b4dc72 100644 --- a/src/applications/diffusion/query/filecontent/DiffusionFileContentQuery.php +++ b/src/applications/diffusion/query/filecontent/DiffusionFileContentQuery.php @@ -1,99 +1,11 @@ timeout = $timeout; - return $this; - } - - public function getTimeout() { - return $this->timeout; - } - - public function setByteLimit($byte_limit) { - $this->byteLimit = $byte_limit; - return $this; - } - - public function getByteLimit() { - return $this->byteLimit; - } +abstract class DiffusionFileContentQuery + extends DiffusionFileFutureQuery { final public static function newFromDiffusionRequest( DiffusionRequest $request) { return parent::newQueryObject(__CLASS__, $request); } - final public function getExceededByteLimit() { - return $this->didHitByteLimit; - } - - final public function getExceededTimeLimit() { - return $this->didHitTimeLimit; - } - - abstract protected function getFileContentFuture(); - abstract protected function resolveFileContentFuture(Future $future); - - final protected function executeQuery() { - $future = $this->getFileContentFuture(); - - if ($this->getTimeout()) { - $future->setTimeout($this->getTimeout()); - } - - $byte_limit = $this->getByteLimit(); - if ($byte_limit) { - $future->setStdoutSizeLimit($byte_limit + 1); - } - - $drequest = $this->getRequest(); - - $name = basename($drequest->getPath()); - $ttl = PhabricatorTime::getNow() + phutil_units('48 hours in seconds'); - - try { - $threshold = PhabricatorFileStorageEngine::getChunkThreshold(); - $future->setReadBufferSize($threshold); - - $source = id(new PhabricatorExecFutureFileUploadSource()) - ->setName($name) - ->setTTL($ttl) - ->setViewPolicy(PhabricatorPolicies::POLICY_NOONE) - ->setExecFuture($future); - - $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); - $file = $source->uploadFile(); - unset($unguarded); - - } catch (CommandException $ex) { - if (!$future->getWasKilledByTimeout()) { - throw $ex; - } - - $this->didHitTimeLimit = true; - $file = null; - } - - if ($byte_limit && ($file->getByteSize() > $byte_limit)) { - $this->didHitByteLimit = true; - - $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); - id(new PhabricatorDestructionEngine()) - ->destroyObject($file); - unset($unguarded); - - $file = null; - } - - return $file; - } - } diff --git a/src/applications/diffusion/query/filecontent/DiffusionGitFileContentQuery.php b/src/applications/diffusion/query/filecontent/DiffusionGitFileContentQuery.php index a383aee922..279abe7cce 100644 --- a/src/applications/diffusion/query/filecontent/DiffusionGitFileContentQuery.php +++ b/src/applications/diffusion/query/filecontent/DiffusionGitFileContentQuery.php @@ -15,9 +15,4 @@ final class DiffusionGitFileContentQuery extends DiffusionFileContentQuery { $path); } - protected function resolveFileContentFuture(Future $future) { - list($corpus) = $future->resolvex(); - return $corpus; - } - } diff --git a/src/applications/diffusion/query/filecontent/DiffusionMercurialFileContentQuery.php b/src/applications/diffusion/query/filecontent/DiffusionMercurialFileContentQuery.php index 539f5752c2..e88bf82e63 100644 --- a/src/applications/diffusion/query/filecontent/DiffusionMercurialFileContentQuery.php +++ b/src/applications/diffusion/query/filecontent/DiffusionMercurialFileContentQuery.php @@ -16,9 +16,4 @@ final class DiffusionMercurialFileContentQuery $path); } - protected function resolveFileContentFuture(Future $future) { - list($corpus) = $future->resolvex(); - return $corpus; - } - } diff --git a/src/applications/diffusion/query/filecontent/DiffusionSvnFileContentQuery.php b/src/applications/diffusion/query/filecontent/DiffusionSvnFileContentQuery.php index 0f6f30b355..35f002297c 100644 --- a/src/applications/diffusion/query/filecontent/DiffusionSvnFileContentQuery.php +++ b/src/applications/diffusion/query/filecontent/DiffusionSvnFileContentQuery.php @@ -14,9 +14,4 @@ final class DiffusionSvnFileContentQuery extends DiffusionFileContentQuery { $repository->getSubversionPathURI($path, $commit)); } - protected function resolveFileContentFuture(Future $future) { - list($corpus) = $future->resolvex(); - return $corpus; - } - } From c55de86f0ef0e25d3ba2f6c33b79fb8d203ecbf5 Mon Sep 17 00:00:00 2001 From: epriestley Date: Fri, 26 Aug 2016 09:37:53 -0700 Subject: [PATCH 02/25] Return Diffusion diffs through Files, not directly over Conduit Summary: Fixes T10423. Ref T11524. This changes `diffusion.rawdiffquery` to return a file PHID instead of a blob of data. This is better in general, but particularly better for huge diffs (as in T10423) and diffs with non-utf8 data (as in T10423). Test Plan: - Used `bin/differential extract` to extract a latin1 diff, got a clean diff. - Used `bin/repository reparse --herald` to rerun herald on a latin1 diff, got a clean result. - Pushed latin1 diffs to test commit hooks. - Triggered the the too large / too slow logic. - Viewed latin1 diffs in Diffusion. - Used "blame past this change" in Diffusion to hit the `before` logic. Reviewers: chad Reviewed By: chad Subscribers: eadler Maniphest Tasks: T10423, T11524 Differential Revision: https://secure.phabricator.com/D16460 --- src/__phutil_library_map__.php | 2 +- .../DifferentialDiffExtractionEngine.php | 17 +++++- .../diffusion/DiffusionLintSaveRunner.php | 2 +- .../DiffusionDiffQueryConduitAPIMethod.php | 2 +- .../DiffusionRawDiffQueryConduitAPIMethod.php | 22 ++----- .../controller/DiffusionBrowseController.php | 19 +++++- .../controller/DiffusionCommitController.php | 24 ++++---- .../engine/DiffusionCommitHookEngine.php | 2 +- .../diffusion/herald/HeraldCommitAdapter.php | 37 ++++++++++-- .../query/DiffusionFileFutureQuery.php | 13 ++-- .../DiffusionGitFileContentQuery.php | 2 +- .../DiffusionMercurialFileContentQuery.php | 2 +- .../DiffusionSvnFileContentQuery.php | 2 +- .../rawdiff/DiffusionGitRawDiffQuery.php | 58 ++++++------------ .../DiffusionMercurialRawDiffQuery.php | 12 +--- .../query/rawdiff/DiffusionRawDiffQuery.php | 38 +----------- .../rawdiff/DiffusionSvnRawDiffQuery.php | 7 +-- ...habricatorRepositoryCommitHeraldWorker.php | 60 +++++++++++++------ 18 files changed, 163 insertions(+), 158 deletions(-) diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index b0b4ba8622..60852bface 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -5260,7 +5260,7 @@ phutil_register_library_map(array( 'DiffusionQueryCommitsConduitAPIMethod' => 'DiffusionConduitAPIMethod', 'DiffusionQueryConduitAPIMethod' => 'DiffusionConduitAPIMethod', 'DiffusionQueryPathsConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod', - 'DiffusionRawDiffQuery' => 'DiffusionQuery', + 'DiffusionRawDiffQuery' => 'DiffusionFileFutureQuery', 'DiffusionRawDiffQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod', 'DiffusionReadmeView' => 'DiffusionView', 'DiffusionRefDatasource' => 'PhabricatorTypeaheadDatasource', diff --git a/src/applications/differential/engine/DifferentialDiffExtractionEngine.php b/src/applications/differential/engine/DifferentialDiffExtractionEngine.php index 0fc6391987..05e19bbe71 100644 --- a/src/applications/differential/engine/DifferentialDiffExtractionEngine.php +++ b/src/applications/differential/engine/DifferentialDiffExtractionEngine.php @@ -36,7 +36,7 @@ final class DifferentialDiffExtractionEngine extends Phobject { 'repository' => $repository, )); - $raw_diff = DiffusionQuery::callConduitWithDiffusionRequest( + $diff_info = DiffusionQuery::callConduitWithDiffusionRequest( $viewer, $drequest, 'diffusion.rawdiffquery', @@ -44,6 +44,21 @@ final class DifferentialDiffExtractionEngine extends Phobject { 'commit' => $identifier, )); + $file_phid = $diff_info['filePHID']; + $diff_file = id(new PhabricatorFileQuery()) + ->setViewer($viewer) + ->withPHIDs(array($file_phid)) + ->executeOne(); + if (!$diff_file) { + throw new Exception( + pht( + 'Failed to load file ("%s") returned by "%s".', + $file_phid, + 'diffusion.rawdiffquery')); + } + + $raw_diff = $diff_file->loadFileData(); + // TODO: Support adds, deletes and moves under SVN. if (strlen($raw_diff)) { $changes = id(new ArcanistDiffParser())->parseDiff($raw_diff); diff --git a/src/applications/diffusion/DiffusionLintSaveRunner.php b/src/applications/diffusion/DiffusionLintSaveRunner.php index bcfeefd510..980234f95d 100644 --- a/src/applications/diffusion/DiffusionLintSaveRunner.php +++ b/src/applications/diffusion/DiffusionLintSaveRunner.php @@ -262,7 +262,7 @@ final class DiffusionLintSaveRunner extends Phobject { $query = DiffusionFileContentQuery::newFromDiffusionRequest($drequest); $queries[$path] = $query; - $futures[$path] = $query->getFileContentFuture(); + $futures[$path] = new ImmediateFuture($query->executeInline()); } $authors = array(); diff --git a/src/applications/diffusion/conduit/DiffusionDiffQueryConduitAPIMethod.php b/src/applications/diffusion/conduit/DiffusionDiffQueryConduitAPIMethod.php index 19295f2b20..d8ce38b5d5 100644 --- a/src/applications/diffusion/conduit/DiffusionDiffQueryConduitAPIMethod.php +++ b/src/applications/diffusion/conduit/DiffusionDiffQueryConduitAPIMethod.php @@ -207,7 +207,7 @@ final class DiffusionDiffQueryConduitAPIMethod $raw_query = DiffusionRawDiffQuery::newFromDiffusionRequest($drequest) ->setAnchorCommit($effective_commit); - $raw_diff = $raw_query->loadRawDiff(); + $raw_diff = $raw_query->executeInline(); if (!$raw_diff) { return $this->getEmptyResult(2); } diff --git a/src/applications/diffusion/conduit/DiffusionRawDiffQueryConduitAPIMethod.php b/src/applications/diffusion/conduit/DiffusionRawDiffQueryConduitAPIMethod.php index 282dc7eb9b..4fab6baae1 100644 --- a/src/applications/diffusion/conduit/DiffusionRawDiffQueryConduitAPIMethod.php +++ b/src/applications/diffusion/conduit/DiffusionRawDiffQueryConduitAPIMethod.php @@ -21,39 +21,27 @@ final class DiffusionRawDiffQueryConduitAPIMethod return array( 'commit' => 'required string', 'path' => 'optional string', - 'timeout' => 'optional int', - 'byteLimit' => 'optional int', 'linesOfContext' => 'optional int', 'againstCommit' => 'optional string', - ); + ) + DiffusionFileFutureQuery::getConduitParameters(); } protected function getResult(ConduitAPIRequest $request) { $drequest = $this->getDiffusionRequest(); - $raw_query = DiffusionRawDiffQuery::newFromDiffusionRequest($drequest); - - $timeout = $request->getValue('timeout'); - if ($timeout !== null) { - $raw_query->setTimeout($timeout); - } + $query = DiffusionRawDiffQuery::newFromDiffusionRequest($drequest); $lines_of_context = $request->getValue('linesOfContext'); if ($lines_of_context !== null) { - $raw_query->setLinesOfContext($lines_of_context); + $query->setLinesOfContext($lines_of_context); } $against_commit = $request->getValue('againstCommit'); if ($against_commit !== null) { - $raw_query->setAgainstCommit($against_commit); + $query->setAgainstCommit($against_commit); } - $byte_limit = $request->getValue('byteLimit'); - if ($byte_limit !== null) { - $raw_query->setByteLimit($byte_limit); - } - - return $raw_query->loadRawDiff(); + return $query->respondToConduitRequest($request); } } diff --git a/src/applications/diffusion/controller/DiffusionBrowseController.php b/src/applications/diffusion/controller/DiffusionBrowseController.php index 3ae076a5d0..9d51146534 100644 --- a/src/applications/diffusion/controller/DiffusionBrowseController.php +++ b/src/applications/diffusion/controller/DiffusionBrowseController.php @@ -1527,19 +1527,36 @@ final class DiffusionBrowseController extends DiffusionController { private function getBeforeLineNumber($target_commit) { $drequest = $this->getDiffusionRequest(); + $viewer = $this->getViewer(); $line = $drequest->getLine(); if (!$line) { return null; } - $raw_diff = $this->callConduitWithDiffusionRequest( + $diff_info = $this->callConduitWithDiffusionRequest( 'diffusion.rawdiffquery', array( 'commit' => $drequest->getCommit(), 'path' => $drequest->getPath(), 'againstCommit' => $target_commit, )); + + $file_phid = $diff_info['filePHID']; + $file = id(new PhabricatorFileQuery()) + ->setViewer($viewer) + ->withPHIDs(array($file_phid)) + ->executeOne(); + if (!$file) { + throw new Exception( + pht( + 'Failed to load file ("%s") returned by "%s".', + $file_phid, + 'diffusion.rawdiffquery.')); + } + + $raw_diff = $file->loadFileData(); + $old_line = 0; $new_line = 0; diff --git a/src/applications/diffusion/controller/DiffusionCommitController.php b/src/applications/diffusion/controller/DiffusionCommitController.php index c27006350f..3ec28d31a5 100644 --- a/src/applications/diffusion/controller/DiffusionCommitController.php +++ b/src/applications/diffusion/controller/DiffusionCommitController.php @@ -1027,24 +1027,26 @@ final class DiffusionCommitController extends DiffusionController { } private function buildRawDiffResponse(DiffusionRequest $drequest) { - $raw_diff = $this->callConduitWithDiffusionRequest( + $diff_info = $this->callConduitWithDiffusionRequest( 'diffusion.rawdiffquery', array( 'commit' => $drequest->getCommit(), 'path' => $drequest->getPath(), )); - $file = PhabricatorFile::buildFromFileDataOrHash( - $raw_diff, - array( - 'name' => $drequest->getCommit().'.diff', - 'ttl' => (60 * 60 * 24), - 'viewPolicy' => PhabricatorPolicies::POLICY_NOONE, - )); + $file_phid = $diff_info['filePHID']; - $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); - $file->attachToObject($drequest->getRepository()->getPHID()); - unset($unguarded); + $file = id(new PhabricatorFileQuery()) + ->setViewer($this->getViewer()) + ->withPHIDs(array($file_phid)) + ->executeOne(); + if (!$file) { + throw new Exception( + pht( + 'Failed to load file ("%s") returned by "%s".', + $file_phid, + 'diffusion.rawdiffquery')); + } return $file->getRedirectResponse(); } diff --git a/src/applications/diffusion/engine/DiffusionCommitHookEngine.php b/src/applications/diffusion/engine/DiffusionCommitHookEngine.php index 50fc828364..2813927e40 100644 --- a/src/applications/diffusion/engine/DiffusionCommitHookEngine.php +++ b/src/applications/diffusion/engine/DiffusionCommitHookEngine.php @@ -1095,7 +1095,7 @@ final class DiffusionCommitHookEngine extends Phobject { ->setTimeout($time_limit) ->setByteLimit($byte_limit) ->setLinesOfContext(0) - ->loadRawDiff(); + ->executeInline(); break; case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: // TODO: This diff has 3 lines of context, which produces slightly diff --git a/src/applications/diffusion/herald/HeraldCommitAdapter.php b/src/applications/diffusion/herald/HeraldCommitAdapter.php index bd34fe23cc..759b8afa6f 100644 --- a/src/applications/diffusion/herald/HeraldCommitAdapter.php +++ b/src/applications/diffusion/herald/HeraldCommitAdapter.php @@ -204,25 +204,50 @@ final class HeraldCommitAdapter } private function loadCommitDiff() { - $byte_limit = self::getEnormousByteLimit(); + $viewer = PhabricatorUser::getOmnipotentUser(); - $raw = $this->callConduit( + $byte_limit = self::getEnormousByteLimit(); + $time_limit = self::getEnormousTimeLimit(); + + $diff_info = $this->callConduit( 'diffusion.rawdiffquery', array( 'commit' => $this->commit->getCommitIdentifier(), - 'timeout' => self::getEnormousTimeLimit(), + 'timeout' => $time_limit, 'byteLimit' => $byte_limit, 'linesOfContext' => 0, )); - if (strlen($raw) >= $byte_limit) { + if ($diff_info['tooHuge']) { throw new Exception( pht( - 'The raw text of this change is enormous (larger than %d bytes). '. + 'The raw text of this change is enormous (larger than %s byte(s)). '. 'Herald can not process it.', - $byte_limit)); + new PhutilNumber($byte_limit))); } + if ($diff_info['tooSlow']) { + throw new Exception( + pht( + 'The raw text of this change took too long to process (longer '. + 'than %s second(s)). Herald can not process it.', + new PhutilNumber($time_limit))); + } + + $file_phid = $diff_info['filePHID']; + $diff_file = id(new PhabricatorFileQuery()) + ->setViewer($viewer) + ->withPHIDs(array($file_phid)) + ->executeOne(); + if (!$diff_file) { + throw new Exception( + pht( + 'Failed to load diff ("%s") for this change.', + $file_phid)); + } + + $raw = $diff_file->loadFileData(); + $parser = new ArcanistDiffParser(); $changes = $parser->parseDiff($raw); diff --git a/src/applications/diffusion/query/DiffusionFileFutureQuery.php b/src/applications/diffusion/query/DiffusionFileFutureQuery.php index 595b9fe5ae..8ce59028e2 100644 --- a/src/applications/diffusion/query/DiffusionFileFutureQuery.php +++ b/src/applications/diffusion/query/DiffusionFileFutureQuery.php @@ -42,7 +42,7 @@ abstract class DiffusionFileFutureQuery return $this->didHitTimeLimit; } - abstract protected function getFileContentFuture(); + abstract protected function newQueryFuture(); final public function respondToConduitRequest(ConduitAPIRequest $request) { $drequest = $this->getRequest(); @@ -82,13 +82,13 @@ abstract class DiffusionFileFutureQuery } final public function executeInline() { - $future = $this->getFileContentFuture(); + $future = $this->newConfiguredQueryFuture(); list($stdout) = $future->resolvex(); - return $future; + return $stdout; } final protected function executeQuery() { - $future = $this->newConfiguredFileContentFuture(); + $future = $this->newQueryFuture(); $drequest = $this->getRequest(); @@ -134,8 +134,8 @@ abstract class DiffusionFileFutureQuery return $file; } - private function newConfiguredFileContentFuture() { - $future = $this->getFileContentFuture(); + private function newConfiguredQueryFuture() { + $future = $this->newQueryFuture(); if ($this->getTimeout()) { $future->setTimeout($this->getTimeout()); @@ -149,5 +149,4 @@ abstract class DiffusionFileFutureQuery return $future; } - } diff --git a/src/applications/diffusion/query/filecontent/DiffusionGitFileContentQuery.php b/src/applications/diffusion/query/filecontent/DiffusionGitFileContentQuery.php index 279abe7cce..e0fb8bd9ee 100644 --- a/src/applications/diffusion/query/filecontent/DiffusionGitFileContentQuery.php +++ b/src/applications/diffusion/query/filecontent/DiffusionGitFileContentQuery.php @@ -2,7 +2,7 @@ final class DiffusionGitFileContentQuery extends DiffusionFileContentQuery { - protected function getFileContentFuture() { + protected function newQueryFuture() { $drequest = $this->getRequest(); $repository = $drequest->getRepository(); diff --git a/src/applications/diffusion/query/filecontent/DiffusionMercurialFileContentQuery.php b/src/applications/diffusion/query/filecontent/DiffusionMercurialFileContentQuery.php index e88bf82e63..f47f0936d9 100644 --- a/src/applications/diffusion/query/filecontent/DiffusionMercurialFileContentQuery.php +++ b/src/applications/diffusion/query/filecontent/DiffusionMercurialFileContentQuery.php @@ -3,7 +3,7 @@ final class DiffusionMercurialFileContentQuery extends DiffusionFileContentQuery { - protected function getFileContentFuture() { + protected function newQueryFuture() { $drequest = $this->getRequest(); $repository = $drequest->getRepository(); diff --git a/src/applications/diffusion/query/filecontent/DiffusionSvnFileContentQuery.php b/src/applications/diffusion/query/filecontent/DiffusionSvnFileContentQuery.php index 35f002297c..8060dd5dfd 100644 --- a/src/applications/diffusion/query/filecontent/DiffusionSvnFileContentQuery.php +++ b/src/applications/diffusion/query/filecontent/DiffusionSvnFileContentQuery.php @@ -2,7 +2,7 @@ final class DiffusionSvnFileContentQuery extends DiffusionFileContentQuery { - protected function getFileContentFuture() { + protected function newQueryFuture() { $drequest = $this->getRequest(); $repository = $drequest->getRepository(); diff --git a/src/applications/diffusion/query/rawdiff/DiffusionGitRawDiffQuery.php b/src/applications/diffusion/query/rawdiff/DiffusionGitRawDiffQuery.php index c7fdeb0e38..18e5a9ec9a 100644 --- a/src/applications/diffusion/query/rawdiff/DiffusionGitRawDiffQuery.php +++ b/src/applications/diffusion/query/rawdiff/DiffusionGitRawDiffQuery.php @@ -2,7 +2,7 @@ final class DiffusionGitRawDiffQuery extends DiffusionRawDiffQuery { - protected function executeQuery() { + protected function newQueryFuture() { $drequest = $this->getRequest(); $repository = $drequest->getRepository(); @@ -17,54 +17,34 @@ final class DiffusionGitRawDiffQuery extends DiffusionRawDiffQuery { '--dst-prefix=b/', '-U'.(int)$this->getLinesOfContext(), ); - $options = implode(' ', $options); $against = $this->getAgainstCommit(); if ($against === null) { - $against = $commit.'^'; + // Check if this is the root commit by seeing if it has parents, since + // `git diff X^ X` does not work if "X" is the initial commit. + list($parents) = $repository->execxLocalCommand( + 'log --format=%s %s --', + '%P', + $commit); + + if (strlen(trim($parents))) { + $against = $commit.'^'; + } else { + $against = ArcanistGitAPI::GIT_MAGIC_ROOT_COMMIT; + } } - // If there's no path, get the entire raw diff. - $path = nonempty($drequest->getPath(), '.'); + $path = $drequest->getPath(); + if (!strlen($path)) { + $path = '.'; + } - $future = $repository->getLocalCommandFuture( - 'diff %C %s %s -- %s', + return $repository->getLocalCommandFuture( + 'diff %Ls %s %s -- %s', $options, $against, $commit, $path); - - $this->configureFuture($future); - - try { - list($raw_diff) = $future->resolvex(); - } catch (CommandException $ex) { - // Check if this is the root commit by seeing if it has parents. - list($parents) = $repository->execxLocalCommand( - 'log --format=%s %s --', - '%P', // "parents" - $commit); - - if (strlen(trim($parents))) { - throw $ex; - } - - // No parents means we're looking at the root revision. Diff against - // the empty tree hash instead, since there is no parent so "^" does - // not work. See ArcanistGitAPI for more discussion. - $future = $repository->getLocalCommandFuture( - 'diff %C %s %s -- %s', - $options, - ArcanistGitAPI::GIT_MAGIC_ROOT_COMMIT, - $commit, - $drequest->getPath()); - - $this->configureFuture($future); - - list($raw_diff) = $future->resolvex(); - } - - return $raw_diff; } } diff --git a/src/applications/diffusion/query/rawdiff/DiffusionMercurialRawDiffQuery.php b/src/applications/diffusion/query/rawdiff/DiffusionMercurialRawDiffQuery.php index 37aeed045e..39eed01226 100644 --- a/src/applications/diffusion/query/rawdiff/DiffusionMercurialRawDiffQuery.php +++ b/src/applications/diffusion/query/rawdiff/DiffusionMercurialRawDiffQuery.php @@ -2,11 +2,7 @@ final class DiffusionMercurialRawDiffQuery extends DiffusionRawDiffQuery { - protected function executeQuery() { - return $this->executeRawDiffCommand(); - } - - protected function executeRawDiffCommand() { + protected function newQueryFuture() { $drequest = $this->getRequest(); $repository = $drequest->getRepository(); @@ -30,11 +26,7 @@ final class DiffusionMercurialRawDiffQuery extends DiffusionRawDiffQuery { $commit, $path); - $this->configureFuture($future); - - list($raw_diff) = $future->resolvex(); - - return $raw_diff; + return $future; } } diff --git a/src/applications/diffusion/query/rawdiff/DiffusionRawDiffQuery.php b/src/applications/diffusion/query/rawdiff/DiffusionRawDiffQuery.php index da16b9e609..37d8a68068 100644 --- a/src/applications/diffusion/query/rawdiff/DiffusionRawDiffQuery.php +++ b/src/applications/diffusion/query/rawdiff/DiffusionRawDiffQuery.php @@ -1,40 +1,17 @@ executeQuery(); - } - - final public function setTimeout($timeout) { - $this->timeout = $timeout; - return $this; - } - - final public function getTimeout() { - return $this->timeout; - } - - public function setByteLimit($byte_limit) { - $this->byteLimit = $byte_limit; - return $this; - } - - public function getByteLimit() { - return $this->byteLimit; - } - final public function setLinesOfContext($lines_of_context) { $this->linesOfContext = $lines_of_context; return $this; @@ -66,15 +43,4 @@ abstract class DiffusionRawDiffQuery extends DiffusionQuery { return $this->getRequest()->getStableCommit(); } - protected function configureFuture(ExecFuture $future) { - if ($this->getTimeout()) { - $future->setTimeout($this->getTimeout()); - } - - if ($this->getByteLimit()) { - $future->setStdoutSizeLimit($this->getByteLimit()); - $future->setStderrSizeLimit($this->getByteLimit()); - } - } - } diff --git a/src/applications/diffusion/query/rawdiff/DiffusionSvnRawDiffQuery.php b/src/applications/diffusion/query/rawdiff/DiffusionSvnRawDiffQuery.php index bc8384cb75..e492016fe3 100644 --- a/src/applications/diffusion/query/rawdiff/DiffusionSvnRawDiffQuery.php +++ b/src/applications/diffusion/query/rawdiff/DiffusionSvnRawDiffQuery.php @@ -2,7 +2,7 @@ final class DiffusionSvnRawDiffQuery extends DiffusionRawDiffQuery { - protected function executeQuery() { + protected function newQueryFuture() { $drequest = $this->getRequest(); $repository = $drequest->getRepository(); @@ -22,10 +22,7 @@ final class DiffusionSvnRawDiffQuery extends DiffusionRawDiffQuery { $commit, $repository->getSubversionPathURI($drequest->getPath())); - $this->configureFuture($future); - - list($raw_diff) = $future->resolvex(); - return $raw_diff; + return $future; } } diff --git a/src/applications/repository/worker/PhabricatorRepositoryCommitHeraldWorker.php b/src/applications/repository/worker/PhabricatorRepositoryCommitHeraldWorker.php index 4bd9344409..9fb6667924 100644 --- a/src/applications/repository/worker/PhabricatorRepositoryCommitHeraldWorker.php +++ b/src/applications/repository/worker/PhabricatorRepositoryCommitHeraldWorker.php @@ -105,40 +105,64 @@ final class PhabricatorRepositoryCommitHeraldWorker private function loadRawPatchText( PhabricatorRepository $repository, PhabricatorRepositoryCommit $commit) { + $viewer = PhabricatorUser::getOmnipotentUser(); + + $identifier = $commit->getCommitIdentifier(); $drequest = DiffusionRequest::newFromDictionary( array( - 'user' => PhabricatorUser::getOmnipotentUser(), + 'user' => $viewer, 'repository' => $repository, - 'commit' => $commit->getCommitIdentifier(), )); - $raw_query = DiffusionRawDiffQuery::newFromDiffusionRequest($drequest); - $raw_query->setLinesOfContext(3); - $time_key = 'metamta.diffusion.time-limit'; $byte_key = 'metamta.diffusion.byte-limit'; $time_limit = PhabricatorEnv::getEnvConfig($time_key); $byte_limit = PhabricatorEnv::getEnvConfig($byte_key); - if ($time_limit) { - $raw_query->setTimeout($time_limit); + $diff_info = DiffusionQuery::callConduitWithDiffusionRequest( + $viewer, + $drequest, + 'diffusion.rawdiffquery', + array( + 'commit' => $identifier, + 'linesOfContext' => 3, + 'timeout' => $time_limit, + 'byteLimit' => $byte_limit, + )); + + if ($diff_info['tooSlow']) { + throw new Exception( + pht( + 'Patch generation took longer than configured limit ("%s") of '. + '%s second(s).', + $time_key, + new PhutilNumber($time_limit))); } - $raw_diff = $raw_query->loadRawDiff(); - - $size = strlen($raw_diff); - if ($byte_limit && $size > $byte_limit) { - $pretty_size = phutil_format_bytes($size); + if ($diff_info['tooHuge']) { $pretty_limit = phutil_format_bytes($byte_limit); - throw new Exception(pht( - 'Patch size of %s exceeds configured byte size limit (%s) of %s.', - $pretty_size, - $byte_key, - $pretty_limit)); + throw new Exception( + pht( + 'Patch size exceeds configured byte size limit ("%s") of %s.', + $byte_key, + $pretty_limit)); } - return $raw_diff; + $file_phid = $diff_info['filePHID']; + $file = id(new PhabricatorFileQuery()) + ->setViewer($viewer) + ->withPHIDs(array($file_phid)) + ->executeOne(); + if (!$file) { + throw new Exception( + pht( + 'Failed to load file ("%s") returned by "%s".', + $file_phid, + 'diffusion.rawdiffquery')); + } + + return $file->loadFileData(); } } From 86231a9d6db584dffa59eae81ca27260f29f8e13 Mon Sep 17 00:00:00 2001 From: Chad Little Date: Mon, 29 Aug 2016 08:47:31 -0700 Subject: [PATCH 03/25] Move Guides ObjectList styles to PHUIObjectItemListView Summary: I plan to reuse these styles with Config, maybe also Almanac, etc. Test Plan: Review /guides/, see same styles. Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D16467 --- resources/celerity/map.php | 8 ++--- .../PhabricatorGuideInstallController.php | 1 - .../PhabricatorGuideQuickStartController.php | 1 - .../PhabricatorGuideWelcomeController.php | 1 - .../guides/view/PhabricatorGuideListView.php | 4 +-- src/view/phui/PHUIObjectItemListView.php | 9 +++++ .../rsrc/css/application/guides/guides.css | 34 ------------------- .../css/phui/phui-object-item-list-view.css | 33 ++++++++++++++++++ 8 files changed, 46 insertions(+), 45 deletions(-) delete mode 100644 webroot/rsrc/css/application/guides/guides.css diff --git a/resources/celerity/map.php b/resources/celerity/map.php index 9fd15abad3..4317015ce9 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -7,7 +7,7 @@ */ return array( 'names' => array( - 'core.pkg.css' => 'ed7ae7bb', + 'core.pkg.css' => '25e4069a', 'core.pkg.js' => 'b562c3db', 'darkconsole.pkg.js' => 'e7393ebb', 'differential.pkg.css' => '3fb7f532', @@ -70,7 +70,6 @@ return array( 'rsrc/css/application/feed/feed.css' => 'ecd4ec57', 'rsrc/css/application/files/global-drag-and-drop.css' => '5c1b47c2', 'rsrc/css/application/flag/flag.css' => '5337623f', - 'rsrc/css/application/guides/guides.css' => '1d5414e5', 'rsrc/css/application/harbormaster/harbormaster.css' => 'f491c9f4', 'rsrc/css/application/herald/herald-test.css' => 'a52e323e', 'rsrc/css/application/herald/herald.css' => 'dc31f6e9', @@ -148,7 +147,7 @@ return array( 'rsrc/css/phui/phui-info-view.css' => '28efab79', 'rsrc/css/phui/phui-list.css' => '9da2aa00', 'rsrc/css/phui/phui-object-box.css' => '6b487c57', - 'rsrc/css/phui/phui-object-item-list-view.css' => '40010767', + 'rsrc/css/phui/phui-object-item-list-view.css' => '985e9d54', 'rsrc/css/phui/phui-pager.css' => 'bea33d23', 'rsrc/css/phui/phui-pinboard-view.css' => '2495140e', 'rsrc/css/phui/phui-profile-menu.css' => '8a3fc181', @@ -574,7 +573,6 @@ return array( 'font-fontawesome' => '2b7ebbcc', 'font-lato' => 'c7ccd872', 'global-drag-and-drop-css' => '5c1b47c2', - 'guides-app-css' => '1d5414e5', 'harbormaster-css' => 'f491c9f4', 'herald-css' => 'dc31f6e9', 'herald-rule-editor' => 'd6a7e717', @@ -858,7 +856,7 @@ return array( 'phui-inline-comment-view-css' => '5953c28e', 'phui-list-view-css' => '9da2aa00', 'phui-object-box-css' => '6b487c57', - 'phui-object-item-list-view-css' => '40010767', + 'phui-object-item-list-view-css' => '985e9d54', 'phui-pager-css' => 'bea33d23', 'phui-pinboard-view-css' => '2495140e', 'phui-profile-menu-css' => '8a3fc181', diff --git a/src/applications/guides/controller/PhabricatorGuideInstallController.php b/src/applications/guides/controller/PhabricatorGuideInstallController.php index 46e992b438..f72cb51a67 100644 --- a/src/applications/guides/controller/PhabricatorGuideInstallController.php +++ b/src/applications/guides/controller/PhabricatorGuideInstallController.php @@ -8,7 +8,6 @@ final class PhabricatorGuideInstallController } public function handleRequest(AphrontRequest $request) { - require_celerity_resource('guides-app-css'); $viewer = $request->getViewer(); $title = pht('Installation Guide'); diff --git a/src/applications/guides/controller/PhabricatorGuideQuickStartController.php b/src/applications/guides/controller/PhabricatorGuideQuickStartController.php index 36ad87b869..128556b7ae 100644 --- a/src/applications/guides/controller/PhabricatorGuideQuickStartController.php +++ b/src/applications/guides/controller/PhabricatorGuideQuickStartController.php @@ -8,7 +8,6 @@ final class PhabricatorGuideQuickStartController } public function handleRequest(AphrontRequest $request) { - require_celerity_resource('guides-app-css'); $viewer = $request->getViewer(); $title = pht('Quick Start Guide'); diff --git a/src/applications/guides/controller/PhabricatorGuideWelcomeController.php b/src/applications/guides/controller/PhabricatorGuideWelcomeController.php index 065504bacb..e5453c8c76 100644 --- a/src/applications/guides/controller/PhabricatorGuideWelcomeController.php +++ b/src/applications/guides/controller/PhabricatorGuideWelcomeController.php @@ -8,7 +8,6 @@ final class PhabricatorGuideWelcomeController } public function handleRequest(AphrontRequest $request) { - require_celerity_resource('guides-app-css'); $viewer = $request->getViewer(); $title = pht('Welcome to Phabricator'); diff --git a/src/applications/guides/view/PhabricatorGuideListView.php b/src/applications/guides/view/PhabricatorGuideListView.php index 4f65a021ba..384caf15ee 100644 --- a/src/applications/guides/view/PhabricatorGuideListView.php +++ b/src/applications/guides/view/PhabricatorGuideListView.php @@ -10,10 +10,8 @@ final class PhabricatorGuideListView extends AphrontView { } public function render() { - require_celerity_resource('guides-app-css'); - $list = id(new PHUIObjectItemListView()) - ->addClass('guides-app'); + ->setBig(true); foreach ($this->items as $item) { $icon = id(new PHUIIconView()) diff --git a/src/view/phui/PHUIObjectItemListView.php b/src/view/phui/PHUIObjectItemListView.php index 0e5747cf48..6c81053f0a 100644 --- a/src/view/phui/PHUIObjectItemListView.php +++ b/src/view/phui/PHUIObjectItemListView.php @@ -8,6 +8,7 @@ final class PHUIObjectItemListView extends AphrontTagView { private $noDataString; private $flush; private $simple; + private $big; private $allowEmptyList; private $itemClass = 'phui-object-item-standard'; @@ -40,6 +41,11 @@ final class PHUIObjectItemListView extends AphrontTagView { return $this; } + public function setBig($big) { + $this->big = $big; + return $this; + } + public function setNoDataString($no_data_string) { $this->noDataString = $no_data_string; return $this; @@ -69,6 +75,9 @@ final class PHUIObjectItemListView extends AphrontTagView { if ($this->simple) { $classes[] = 'phui-object-list-simple'; } + if ($this->big) { + $classes[] = 'phui-object-list-big'; + } return array( 'class' => $classes, diff --git a/webroot/rsrc/css/application/guides/guides.css b/webroot/rsrc/css/application/guides/guides.css deleted file mode 100644 index 8a871758c8..0000000000 --- a/webroot/rsrc/css/application/guides/guides.css +++ /dev/null @@ -1,34 +0,0 @@ -/** - * @provides guides-app-css - */ - -.guides-app ul.phui-object-item-list-view { - margin: 0; - padding: 20px; -} - -.guides-app .phui-object-item-no-bar .phui-object-item-frame { - border: 0; -} - -.guides-app .phui-object-item-image-icon { - margin: 8px 2px 12px; -} - -.guides-app a.phui-object-item-link { - color: #000; - font-size: {$biggestfontsize}; -} - -.guides-app .phui-object-item-name { - padding-top: 6px; -} - -.guides-app .phui-object-item-launch-button a.button { - font-size: {$normalfontsize}; - padding: 3px 12px 4px; -} - -.device-desktop .guides-app .phui-object-item { - margin-bottom: 8px; -} diff --git a/webroot/rsrc/css/phui/phui-object-item-list-view.css b/webroot/rsrc/css/phui/phui-object-item-list-view.css index 506ffc7985..b0d95286f7 100644 --- a/webroot/rsrc/css/phui/phui-object-item-list-view.css +++ b/webroot/rsrc/css/phui/phui-object-item-list-view.css @@ -738,3 +738,36 @@ ul.phui-object-item-list-view .phui-object-item-selected bottom: 2px; right: 2px; } + +/* - Big List---------------------------------------------------------------- */ + +.phui-object-list-big ul.phui-object-item-list-view { + margin: 0; + padding: 20px; +} + +.phui-object-list-big .phui-object-item-no-bar .phui-object-item-frame { + border: 0; +} + +.phui-object-list-big .phui-object-item-image-icon { + margin: 8px 2px 12px; +} + +.phui-object-list-big a.phui-object-item-link { + color: #000; + font-size: {$biggestfontsize}; +} + +.phui-object-list-big .phui-object-item-name { + padding-top: 6px; +} + +.phui-object-list-big .phui-object-item-launch-button a.button { + font-size: {$normalfontsize}; + padding: 3px 12px 4px; +} + +.device-desktop .phui-object-list-big .phui-object-item { + margin-bottom: 8px; +} From 00796e592b69aec1e2c41eff5814e8067ff1afca Mon Sep 17 00:00:00 2001 From: Chad Little Date: Sat, 27 Aug 2016 19:00:35 -0700 Subject: [PATCH 04/25] Move Setup Issues into it's own notification style menu Summary: Ref T11132. This gets rid of the red bar for admins and instead shows a new menu item next to notifications/chat if there are unresolved configuration issues. Menu goes away if there are no issues. May move this later into the bell icon, but think think might be the right place to start especially for NUX and updates. Maybe limit the number of items? Test Plan: Tested with some, lots, and no config issues. {F1790156} Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Maniphest Tasks: T11132 Differential Revision: https://secure.phabricator.com/D16461 --- resources/celerity/map.php | 66 +++++++------- src/__phutil_library_map__.php | 2 + .../PhabricatorConfigApplication.php | 1 + .../PhabricatorConfigIssuePanelController.php | 68 +++++++++++++++ .../PhabricatorUSEnglishTranslation.php | 5 -- src/view/page/PhabricatorStandardPageView.php | 19 ----- .../page/menu/PhabricatorMainMenuView.php | 85 +++++++++++++++++++ .../css/application/base/main-menu-view.css | 31 +++++-- .../application/base/notification-menu.css | 5 +- .../application/base/standard-page-view.css | 11 --- .../rsrc/css/application/conpherence/menu.css | 4 - .../application/conpherence/message-pane.css | 4 - .../application/conpherence/widget-pane.css | 10 --- webroot/rsrc/css/core/z-index.css | 4 - .../css/phui/workboards/phui-workboard.css | 4 - .../aphlict/behavior-aphlict-dropdown.js | 10 ++- 16 files changed, 227 insertions(+), 102 deletions(-) create mode 100644 src/applications/config/controller/PhabricatorConfigIssuePanelController.php diff --git a/resources/celerity/map.php b/resources/celerity/map.php index 4317015ce9..83a4949a80 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -7,8 +7,8 @@ */ return array( 'names' => array( - 'core.pkg.css' => '25e4069a', - 'core.pkg.js' => 'b562c3db', + 'core.pkg.css' => '7d178771', + 'core.pkg.js' => '2b8af4e4', 'darkconsole.pkg.js' => 'e7393ebb', 'differential.pkg.css' => '3fb7f532', 'differential.pkg.js' => '634399e9', @@ -32,11 +32,11 @@ return array( 'rsrc/css/aphront/typeahead.css' => 'd4f16145', 'rsrc/css/application/almanac/almanac.css' => 'dbb9b3af', 'rsrc/css/application/auth/auth.css' => '0877ed6e', - 'rsrc/css/application/base/main-menu-view.css' => '3b0d39f7', - 'rsrc/css/application/base/notification-menu.css' => 'f31c0bde', + 'rsrc/css/application/base/main-menu-view.css' => 'e862571a', + 'rsrc/css/application/base/notification-menu.css' => 'b3ab500d', 'rsrc/css/application/base/phabricator-application-launch-view.css' => '95351601', 'rsrc/css/application/base/phui-theme.css' => '027ba77e', - 'rsrc/css/application/base/standard-page-view.css' => 'e709f6d0', + 'rsrc/css/application/base/standard-page-view.css' => '99a7d403', 'rsrc/css/application/chatlog/chatlog.css' => 'd295b020', 'rsrc/css/application/conduit/conduit-api.css' => '7bc725c4', 'rsrc/css/application/config/config-options.css' => '0ede4c9b', @@ -45,12 +45,12 @@ return array( 'rsrc/css/application/config/setup-issue.css' => 'f794cfc3', 'rsrc/css/application/config/unhandled-exception.css' => '4c96257a', 'rsrc/css/application/conpherence/durable-column.css' => '86396117', - 'rsrc/css/application/conpherence/menu.css' => 'f99fee4c', - 'rsrc/css/application/conpherence/message-pane.css' => '5897d3ac', + 'rsrc/css/application/conpherence/menu.css' => '90bdf85c', + 'rsrc/css/application/conpherence/message-pane.css' => '5c7b7b17', 'rsrc/css/application/conpherence/notification.css' => '6cdcc253', 'rsrc/css/application/conpherence/transaction.css' => '85d0974c', 'rsrc/css/application/conpherence/update.css' => 'faf6be09', - 'rsrc/css/application/conpherence/widget-pane.css' => '775eaaba', + 'rsrc/css/application/conpherence/widget-pane.css' => 'c5b74f9e', 'rsrc/css/application/contentsource/content-source-view.css' => '4b8b05d4', 'rsrc/css/application/countdown/timer.css' => '16c52f5c', 'rsrc/css/application/daemon/bulk-job.css' => 'df9c1d4a', @@ -107,7 +107,7 @@ return array( 'rsrc/css/core/core.css' => 'd0801452', 'rsrc/css/core/remarkup.css' => '5ed06ed8', 'rsrc/css/core/syntax.css' => '769d3498', - 'rsrc/css/core/z-index.css' => '5b6fcf3f', + 'rsrc/css/core/z-index.css' => '2b01a823', 'rsrc/css/diviner/diviner-shared.css' => 'aa3656aa', 'rsrc/css/font/font-aleo.css' => '8bdb2835', 'rsrc/css/font/font-awesome.css' => '2b7ebbcc', @@ -160,7 +160,7 @@ return array( 'rsrc/css/phui/phui-timeline-view.css' => 'bc523970', 'rsrc/css/phui/phui-two-column-view.css' => '5afdf637', 'rsrc/css/phui/workboards/phui-workboard-color.css' => 'ac6fe6a7', - 'rsrc/css/phui/workboards/phui-workboard.css' => 'e6d89647', + 'rsrc/css/phui/workboards/phui-workboard.css' => 'bda3ef58', 'rsrc/css/phui/workboards/phui-workcard.css' => '0c62d7c5', 'rsrc/css/phui/workboards/phui-workpanel.css' => '92197373', 'rsrc/css/sprite-login.css' => '60e8560e', @@ -357,7 +357,7 @@ return array( 'rsrc/image/texture/table_header_hover.png' => '038ec3b9', 'rsrc/image/texture/table_header_tall.png' => 'd56b434f', 'rsrc/js/application/aphlict/Aphlict.js' => '5359e785', - 'rsrc/js/application/aphlict/behavior-aphlict-dropdown.js' => '031cee25', + 'rsrc/js/application/aphlict/behavior-aphlict-dropdown.js' => '49e20786', 'rsrc/js/application/aphlict/behavior-aphlict-listen.js' => 'fb20ac8d', 'rsrc/js/application/aphlict/behavior-aphlict-status.js' => 'ea681761', 'rsrc/js/application/aphlict/behavior-desktop-notifications-control.js' => 'edd1ba66', @@ -549,13 +549,13 @@ return array( 'config-options-css' => '0ede4c9b', 'config-welcome-css' => '035aa483', 'conpherence-durable-column-view' => '86396117', - 'conpherence-menu-css' => 'f99fee4c', - 'conpherence-message-pane-css' => '5897d3ac', + 'conpherence-menu-css' => '90bdf85c', + 'conpherence-message-pane-css' => '5c7b7b17', 'conpherence-notification-css' => '6cdcc253', 'conpherence-thread-manager' => '01774ab2', 'conpherence-transaction-css' => '85d0974c', 'conpherence-update-css' => 'faf6be09', - 'conpherence-widget-pane-css' => '775eaaba', + 'conpherence-widget-pane-css' => 'c5b74f9e', 'd3' => 'a11a5ff2', 'differential-changeset-view-css' => '9ef7d354', 'differential-core-view-css' => '5b7b8ff4', @@ -580,7 +580,7 @@ return array( 'inline-comment-summary-css' => '51efda3a', 'javelin-aphlict' => '5359e785', 'javelin-behavior' => '61cbc29a', - 'javelin-behavior-aphlict-dropdown' => '031cee25', + 'javelin-behavior-aphlict-dropdown' => '49e20786', 'javelin-behavior-aphlict-listen' => 'fb20ac8d', 'javelin-behavior-aphlict-status' => 'ea681761', 'javelin-behavior-aphront-basic-tokenizer' => 'b3a4b884', @@ -784,11 +784,11 @@ return array( 'phabricator-flag-css' => '5337623f', 'phabricator-keyboard-shortcut' => '1ae869f2', 'phabricator-keyboard-shortcut-manager' => '4a021c10', - 'phabricator-main-menu-view' => '3b0d39f7', + 'phabricator-main-menu-view' => 'e862571a', 'phabricator-nav-view-css' => 'b29426e9', 'phabricator-notification' => 'ccf1cbf8', 'phabricator-notification-css' => '3f6c89c9', - 'phabricator-notification-menu-css' => 'f31c0bde', + 'phabricator-notification-menu-css' => 'b3ab500d', 'phabricator-object-selector-css' => '85ee8ce6', 'phabricator-phtize' => 'd254d646', 'phabricator-prefab' => 'cfd23f37', @@ -797,7 +797,7 @@ return array( 'phabricator-shaped-request' => '7cbe244b', 'phabricator-slowvote-css' => 'a94b7230', 'phabricator-source-code-view-css' => 'cbeef983', - 'phabricator-standard-page-view' => 'e709f6d0', + 'phabricator-standard-page-view' => '99a7d403', 'phabricator-textareautils' => '320810c8', 'phabricator-title' => 'df5e11d2', 'phabricator-tooltip' => '6323f942', @@ -812,7 +812,7 @@ return array( 'phabricator-uiexample-reactor-select' => 'a155550f', 'phabricator-uiexample-reactor-sendclass' => '1def2711', 'phabricator-uiexample-reactor-sendproperties' => 'b1f0ccee', - 'phabricator-zindex-css' => '5b6fcf3f', + 'phabricator-zindex-css' => '2b01a823', 'phame-css' => '8efb0729', 'pholio-css' => 'ca89d380', 'pholio-edit-css' => '07676f51', @@ -870,7 +870,7 @@ return array( 'phui-timeline-view-css' => 'bc523970', 'phui-two-column-view-css' => '5afdf637', 'phui-workboard-color-css' => 'ac6fe6a7', - 'phui-workboard-view-css' => 'e6d89647', + 'phui-workboard-view-css' => 'bda3ef58', 'phui-workcard-view-css' => '0c62d7c5', 'phui-workpanel-view-css' => '92197373', 'phuix-action-list-view' => 'b5c256b8', @@ -931,16 +931,6 @@ return array( 'javelin-dom', 'phabricator-keyboard-shortcut', ), - '031cee25' => array( - 'javelin-behavior', - 'javelin-request', - 'javelin-stratcom', - 'javelin-vector', - 'javelin-dom', - 'javelin-uri', - 'javelin-behavior-device', - 'phabricator-title', - ), '05270951' => array( 'javelin-util', 'javelin-magical-init', @@ -1164,9 +1154,6 @@ return array( 'javelin-dom', 'javelin-magical-init', ), - '3b0d39f7' => array( - 'phui-theme-css', - ), '3cb0b2fc' => array( 'javelin-behavior', 'javelin-dom', @@ -1242,6 +1229,16 @@ return array( 'javelin-dom', 'javelin-stratcom', ), + '49e20786' => array( + 'javelin-behavior', + 'javelin-request', + 'javelin-stratcom', + 'javelin-vector', + 'javelin-dom', + 'javelin-uri', + 'javelin-behavior-device', + 'phabricator-title', + ), '4a021c10' => array( 'javelin-install', 'javelin-util', @@ -2097,6 +2094,9 @@ return array( 'e6e25838' => array( 'javelin-install', ), + 'e862571a' => array( + 'phui-theme-css', + ), 'e9581f08' => array( 'javelin-behavior', 'javelin-stratcom', diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 60852bface..13ae2af39c 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -2170,6 +2170,7 @@ phutil_register_library_map(array( 'PhabricatorConfigHistoryController' => 'applications/config/controller/PhabricatorConfigHistoryController.php', 'PhabricatorConfigIgnoreController' => 'applications/config/controller/PhabricatorConfigIgnoreController.php', 'PhabricatorConfigIssueListController' => 'applications/config/controller/PhabricatorConfigIssueListController.php', + 'PhabricatorConfigIssuePanelController' => 'applications/config/controller/PhabricatorConfigIssuePanelController.php', 'PhabricatorConfigIssueViewController' => 'applications/config/controller/PhabricatorConfigIssueViewController.php', 'PhabricatorConfigJSON' => 'applications/config/json/PhabricatorConfigJSON.php', 'PhabricatorConfigJSONOptionType' => 'applications/config/custom/PhabricatorConfigJSONOptionType.php', @@ -6915,6 +6916,7 @@ phutil_register_library_map(array( 'PhabricatorConfigHistoryController' => 'PhabricatorConfigController', 'PhabricatorConfigIgnoreController' => 'PhabricatorConfigController', 'PhabricatorConfigIssueListController' => 'PhabricatorConfigController', + 'PhabricatorConfigIssuePanelController' => 'PhabricatorConfigController', 'PhabricatorConfigIssueViewController' => 'PhabricatorConfigController', 'PhabricatorConfigJSON' => 'Phobject', 'PhabricatorConfigJSONOptionType' => 'PhabricatorConfigOptionType', diff --git a/src/applications/config/application/PhabricatorConfigApplication.php b/src/applications/config/application/PhabricatorConfigApplication.php index c9b1c5c345..869170ccbb 100644 --- a/src/applications/config/application/PhabricatorConfigApplication.php +++ b/src/applications/config/application/PhabricatorConfigApplication.php @@ -55,6 +55,7 @@ final class PhabricatorConfigApplication extends PhabricatorApplication { => 'PhabricatorConfigIgnoreController', 'issue/' => array( '' => 'PhabricatorConfigIssueListController', + 'panel/' => 'PhabricatorConfigIssuePanelController', '(?P[^/]+)/' => 'PhabricatorConfigIssueViewController', ), 'cache/' => array( diff --git a/src/applications/config/controller/PhabricatorConfigIssuePanelController.php b/src/applications/config/controller/PhabricatorConfigIssuePanelController.php new file mode 100644 index 0000000000..16541d184b --- /dev/null +++ b/src/applications/config/controller/PhabricatorConfigIssuePanelController.php @@ -0,0 +1,68 @@ +getViewer(); + $open_items = PhabricatorSetupCheck::getOpenSetupIssueKeys(); + $issues = PhabricatorSetupCheck::runAllChecks(); + PhabricatorSetupCheck::setOpenSetupIssueKeys( + PhabricatorSetupCheck::getUnignoredIssueKeys($issues), + $update_database = true); + + if ($issues) { + require_celerity_resource('phabricator-notification-menu-css'); + + $items = array(); + foreach ($issues as $issue) { + $classes = array(); + $classes[] = 'phabricator-notification'; + if ($issue->getIsIgnored()) { + $classes[] = 'phabricator-notification-read'; + } else { + $classes[] = 'phabricator-notification-unread'; + } + $uri = '/config/issue/'.$issue->getIssueKey().'/'; + $title = $issue->getName(); + $summary = $issue->getSummary(); + $items[] = javelin_tag( + 'div', + array( + 'class' => implode(' ', $classes), + 'sigil' => 'notification', + 'meta' => array( + 'href' => $uri, + ), + ), + $title); + } + $content = phutil_tag_div('setup-issue-menu', $items); + } else { + $content = phutil_tag_div( + 'phabricator-notification no-notifications', + pht('You have no unresolved setup issues.')); + } + + $content = hsprintf( + '
%s
'. + '%s', + phutil_tag( + 'a', + array( + 'href' => '/config/issue/', + ), + pht('Unresolved Setup Issues')), + $content); + + $unresolved_count = count($open_items); + + $json = array( + 'content' => $content, + 'number' => (int)$unresolved_count, + ); + + return id(new AphrontAjaxResponse())->setContent($json); + } + +} diff --git a/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php b/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php index 3b4cf6abc7..c65103d4ef 100644 --- a/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php +++ b/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php @@ -538,11 +538,6 @@ final class PhabricatorUSEnglishTranslation 'PHP also loaded these configuration files:', ), - 'You have %d unresolved setup issue(s)...' => array( - 'You have an unresolved setup issue...', - 'You have %d unresolved setup issues...', - ), - '%s added %d inline comment(s).' => array( array( '%s added an inline comment.', diff --git a/src/view/page/PhabricatorStandardPageView.php b/src/view/page/PhabricatorStandardPageView.php index b668a4883b..d7e3a643d5 100644 --- a/src/view/page/PhabricatorStandardPageView.php +++ b/src/view/page/PhabricatorStandardPageView.php @@ -459,24 +459,6 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView 'or the error log.')); } - // Render the "you have unresolved setup issues..." warning. - $setup_warning = null; - if ($user && $user->getIsAdmin()) { - $open = PhabricatorSetupCheck::getOpenSetupIssueKeys(); - if ($open) { - $classes[] = 'page-has-warning'; - $setup_warning = phutil_tag_div( - 'setup-warning-callout', - phutil_tag( - 'a', - array( - 'href' => '/config/issue/', - 'title' => implode(', ', $open), - ), - pht('You have %d unresolved setup issue(s)...', count($open)))); - } - } - $main_page = phutil_tag( 'div', array( @@ -486,7 +468,6 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView array( $developer_warning, $header_chrome, - $setup_warning, phutil_tag( 'div', array( diff --git a/src/view/page/menu/PhabricatorMainMenuView.php b/src/view/page/menu/PhabricatorMainMenuView.php index c0ebe680dc..7d9fccde5b 100644 --- a/src/view/page/menu/PhabricatorMainMenuView.php +++ b/src/view/page/menu/PhabricatorMainMenuView.php @@ -531,15 +531,100 @@ final class PhabricatorMainMenuView extends AphrontView { ''); } + // Admin Level Urgent Notification Channel + $setup_tag = ''; + $setup_notification_dropdown = ''; + if ($viewer && $viewer->getIsAdmin()) { + $open = PhabricatorSetupCheck::getOpenSetupIssueKeys(); + if ($open) { + $setup_id = celerity_generate_unique_node_id(); + $setup_count_id = celerity_generate_unique_node_id(); + $setup_dropdown_id = celerity_generate_unique_node_id(); + + $setup_count_number = count($open); + + if ($setup_count_number) { + $aural[] = phutil_tag( + 'a', + array( + 'href' => '/config/issue/', + ), + pht( + '%s unresolved issues.', + new PhutilNumber($setup_count_number))); + } else { + $aural[] = pht('No issues.'); + } + + $setup_count_tag = phutil_tag( + 'span', + array( + 'id' => $setup_count_id, + 'class' => 'phabricator-main-menu-setup-count', + ), + $setup_count_number); + + $setup_icon_tag = javelin_tag( + 'span', + array( + 'class' => 'phabricator-main-menu-setup-icon phui-icon-view '. + 'phui-font-fa fa-exclamation-circle', + 'sigil' => 'menu-icon', + ), + ''); + + if ($setup_count_number) { + $container_classes[] = 'setup-unread'; + } + + $setup_tag = phutil_tag( + 'a', + array( + 'href' => '/config/issue/', + 'class' => implode(' ', $container_classes), + 'id' => $setup_id, + ), + array( + $setup_icon_tag, + $setup_count_tag, + )); + + Javelin::initBehavior( + 'aphlict-dropdown', + array( + 'bubbleID' => $setup_id, + 'countID' => $setup_count_id, + 'dropdownID' => $setup_dropdown_id, + 'loadingText' => pht('Loading...'), + 'uri' => '/config/issue/panel/', + 'countType' => null, + 'countNumber' => null, + 'unreadClass' => 'setup-unread', + )); + + $setup_notification_dropdown = javelin_tag( + 'div', + array( + 'id' => $setup_dropdown_id, + 'class' => 'phabricator-notification-menu', + 'sigil' => 'phabricator-notification-menu', + 'style' => 'display: none;', + ), + ''); + } + } + $dropdowns = array( $notification_dropdown, $message_notification_dropdown, + $setup_notification_dropdown, ); return array( array( $bubble_tag, $message_tag, + $setup_tag, ), $dropdowns, $aural, diff --git a/webroot/rsrc/css/application/base/main-menu-view.css b/webroot/rsrc/css/application/base/main-menu-view.css index 4ee1372c16..b5a11d7ba5 100644 --- a/webroot/rsrc/css/application/base/main-menu-view.css +++ b/webroot/rsrc/css/application/base/main-menu-view.css @@ -376,7 +376,8 @@ button.phabricator-main-menu-search-dropdown .caret:before { } .phabricator-main-menu-alert-icon, -.phabricator-main-menu-message-icon { +.phabricator-main-menu-message-icon, +.phabricator-main-menu-setup-icon { width: 18px; height: 18px; float: left; @@ -396,8 +397,25 @@ button.phabricator-main-menu-search-dropdown .caret:before { margin-top: 2px; } +.setup-unread .phui-icon-view.phabricator-main-menu-setup-icon { + color: #ecf36c; + font-size: 16px; + margin-top: 2px; + width: 15px; +} + +.setup-unread .phabricator-main-menu-setup-count { + color: #ecf36c; + margin-top: 10px; +} + +.device-desktop .alert-notifications.setup-unread:hover .phui-icon-view { + color: #ecf36c; +} + .phabricator-main-menu-alert-count, -.phabricator-main-menu-message-count { +.phabricator-main-menu-message-count, +.phabricator-main-menu-setup-count { color: #fff; text-align: center; display: none; @@ -407,17 +425,20 @@ button.phabricator-main-menu-search-dropdown .caret:before { } .device-phone .alert-unread .phabricator-main-menu-alert-count, -.device-phone .message-unread .phabricator-main-menu-message-count { +.device-phone .message-unread .phabricator-main-menu-message-count, +.device-phone .setup-unread .phabricator-main-menu-setup-count { display: none; } .alert-unread .phabricator-main-menu-alert-icon, -.message-unread .phabricator-main-menu-message-icon { +.message-unread .phabricator-main-menu-message-icon, +.setup-unread .phabricator-main-menu-setup-icon { color: #fff; } .alert-unread .phabricator-main-menu-alert-count, -.message-unread .phabricator-main-menu-message-count { +.message-unread .phabricator-main-menu-message-count, +.setup-unread .phabricator-main-menu-setup-count { display: block; } diff --git a/webroot/rsrc/css/application/base/notification-menu.css b/webroot/rsrc/css/application/base/notification-menu.css index 198f7b0fa1..84569c7d6b 100644 --- a/webroot/rsrc/css/application/base/notification-menu.css +++ b/webroot/rsrc/css/application/base/notification-menu.css @@ -37,7 +37,6 @@ top: 42px !important; left: 3% !important; position: absolute; - } .phabricator-notification-list.pm { @@ -78,6 +77,10 @@ background: {$hoverblue}; } +.phabricator-notification-read { + color: {$lightgreytext}; +} + .phabricator-notification-header { font-weight: bold; padding: 10px 8px; diff --git a/webroot/rsrc/css/application/base/standard-page-view.css b/webroot/rsrc/css/application/base/standard-page-view.css index 05686898b6..d9f6cb8ea3 100644 --- a/webroot/rsrc/css/application/base/standard-page-view.css +++ b/webroot/rsrc/css/application/base/standard-page-view.css @@ -105,17 +105,6 @@ a.handle-availability-disabled { font-size: {$smallerfontsize}; } -.setup-warning-callout { - padding: 8px 16px; - background: {$lightred}; - border-bottom: 1px solid {$sh-redborder}; - position: relative; -} - -.setup-warning-callout a { - color: {$red}; -} - .phui-handle .phui-icon-view { display: inline-block; margin: 2px 2px -2px 0; diff --git a/webroot/rsrc/css/application/conpherence/menu.css b/webroot/rsrc/css/application/conpherence/menu.css index 49549c5738..d786848837 100644 --- a/webroot/rsrc/css/application/conpherence/menu.css +++ b/webroot/rsrc/css/application/conpherence/menu.css @@ -11,10 +11,6 @@ background: #fff; } -.page-has-warning .conpherence-layout { - top: 76px; -} - .conpherence-layout .conpherence-no-threads { text-align: center; position: fixed; diff --git a/webroot/rsrc/css/application/conpherence/message-pane.css b/webroot/rsrc/css/application/conpherence/message-pane.css index c4b0bf6208..ea26d3cbe6 100644 --- a/webroot/rsrc/css/application/conpherence/message-pane.css +++ b/webroot/rsrc/css/application/conpherence/message-pane.css @@ -65,10 +65,6 @@ bottom: 42px; } -.page-has-warning .conpherence-message-pane .conpherence-messages { - top: 110px; -} - .conpherence-messages.jx-scrollbar-frame { overflow-y: hidden; } diff --git a/webroot/rsrc/css/application/conpherence/widget-pane.css b/webroot/rsrc/css/application/conpherence/widget-pane.css index 6b5401b2a9..6b8e97e359 100644 --- a/webroot/rsrc/css/application/conpherence/widget-pane.css +++ b/webroot/rsrc/css/application/conpherence/widget-pane.css @@ -15,12 +15,6 @@ overflow-y: auto; -webkit-overflow-scrolling: touch; } - -.page-has-warning .conpherence-widget-pane, -.page-had-warning .loading .widgets-loading-mask { - top: 110px; -} - .device .conpherence-widget-pane, .device .loading .widgets-loading-mask { top: 44px; @@ -91,10 +85,6 @@ width: 240px; } -.device-desktop .page-has-warning .conpherence-widget-pane .widgets-body { - top: 142px; -} - .conpherence-widget-pane .widget-icon { display: block; height: 14px; diff --git a/webroot/rsrc/css/core/z-index.css b/webroot/rsrc/css/core/z-index.css index 23c6c59bf7..5d787b694d 100644 --- a/webroot/rsrc/css/core/z-index.css +++ b/webroot/rsrc/css/core/z-index.css @@ -68,10 +68,6 @@ div.phui-calendar-day-event { z-index: 4; } -.setup-warning-callout { - z-index: 5; -} - .loading .messages-loading-mask, .loading .widgets-loading-mask { z-index: 5; diff --git a/webroot/rsrc/css/phui/workboards/phui-workboard.css b/webroot/rsrc/css/phui/workboards/phui-workboard.css index 9ba75661d1..089fbcf0a5 100644 --- a/webroot/rsrc/css/phui/workboards/phui-workboard.css +++ b/webroot/rsrc/css/phui/workboards/phui-workboard.css @@ -22,10 +22,6 @@ background-color: #fff; } -.device-desktop .page-has-warning .phui-workboard-view-shadow { - top: 113px; -} - .device-desktop.with-durable-column .phui-workboard-view-shadow { right: 300px; } diff --git a/webroot/rsrc/js/application/aphlict/behavior-aphlict-dropdown.js b/webroot/rsrc/js/application/aphlict/behavior-aphlict-dropdown.js index 733088693e..b564350ff2 100644 --- a/webroot/rsrc/js/application/aphlict/behavior-aphlict-dropdown.js +++ b/webroot/rsrc/js/application/aphlict/behavior-aphlict-dropdown.js @@ -26,10 +26,16 @@ JX.behavior('aphlict-dropdown', function(config, statics) { var request = null; var dirty = config.local ? false : true; - JX.Title.setCount(config.countType, config.countNumber); + if (config.countType) { + JX.Title.setCount(config.countType, config.countNumber); + } function _updateCount(number) { - JX.Title.setCount(config.countType, number); + if (config.countType) { + JX.Title.setCount(config.countType, number); + } else { + return; + } JX.DOM.setContent(count, number); if (number === 0) { From 60d1762a85ced8ed828256b7379975b5195d7e2e Mon Sep 17 00:00:00 2001 From: Chad Little Date: Mon, 29 Aug 2016 15:36:13 -0700 Subject: [PATCH 05/25] Redesign Config Application Summary: Ref T11132, significantly cleans up the Config app, new layout, icons, spacing, etc. Some minor todos around re-designing "issues", mobile support, and maybe another pass at actual Group pages. Test Plan: Visit and test every page in the config app, set new items, resolve setup issues, etc. Reviewers: epriestley Reviewed By: epriestley Subscribers: PHID-OPKG-gm6ozazyms6q6i22gyam, Korvin Maniphest Tasks: T11132 Differential Revision: https://secure.phabricator.com/D16468 --- resources/celerity/map.php | 16 ++-- src/__phutil_library_map__.php | 10 +- ...icatorAuthSessionEngineExtensionModule.php | 6 +- ...habricatorAuthTemporaryTokenTypeModule.php | 8 +- .../check/PhabricatorCacheSetupCheck.php | 2 +- .../check/PhabricatorMySQLSetupCheck.php | 6 +- .../constants/PhabricatorConfigConstants.php | 3 + .../PhabricatorConfigGroupConstants.php | 37 ++++++++ .../PhabricatorConfigAllController.php | 23 +++-- ...PhabricatorConfigApplicationController.php | 31 ++++--- .../PhabricatorConfigCacheController.php | 25 +++-- ...icatorConfigClusterDatabasesController.php | 42 ++++----- ...orConfigClusterNotificationsController.php | 40 ++++---- ...torConfigClusterRepositoriesController.php | 46 +++++----- .../PhabricatorConfigDatabaseController.php | 14 --- ...abricatorConfigDatabaseIssueController.php | 23 ++--- ...bricatorConfigDatabaseStatusController.php | 87 ++++++------------ .../PhabricatorConfigGroupController.php | 33 ++++--- .../PhabricatorConfigHistoryController.php | 20 ++-- .../PhabricatorConfigIssueListController.php | 91 +++++++++---------- .../PhabricatorConfigIssueViewController.php | 10 +- .../PhabricatorConfigListController.php | 31 ++++--- .../PhabricatorConfigModuleController.php | 17 ++-- .../PhabricatorConfigVersionController.php | 27 +++--- .../PhabricatorConfigWelcomeController.php | 27 +++--- .../PhabricatorConfigCollectorsModule.php | 21 ++--- .../module/PhabricatorConfigEdgeModule.php | 7 +- ...bricatorConfigHTTPParameterTypesModule.php | 7 +- .../module/PhabricatorConfigPHIDModule.php | 7 +- ...torConfigRequestExceptionHandlerModule.php | 7 +- .../module/PhabricatorConfigSiteModule.php | 7 +- .../config/view/PhabricatorConfigPageView.php | 60 ++++++++++++ .../PhabricatorHarbormasterConfigOptions.php | 26 ------ .../PhabricatorPhrequentConfigOptions.php | 26 ------ ...bricatorHovercardEngineExtensionModule.php | 7 +- ...PhabricatorSearchEngineExtensionModule.php | 7 +- ...abricatorFulltextEngineExtensionModule.php | 6 +- .../PhabricatorIndexEngineExtensionModule.php | 6 +- ...icatorDestructionEngineExtensionModule.php | 6 +- .../PhabricatorEditEngineExtensionModule.php | 6 +- .../PhabricatorContentSourceModule.php | 6 +- .../application/base/standard-page-view.css | 4 + .../css/application/config/config-page.css | 59 ++++++++++++ webroot/rsrc/css/font/phui-font-icon-base.css | 3 + .../css/phui/phui-object-item-list-view.css | 12 ++- 45 files changed, 505 insertions(+), 460 deletions(-) create mode 100644 src/applications/config/constants/PhabricatorConfigConstants.php create mode 100644 src/applications/config/constants/PhabricatorConfigGroupConstants.php create mode 100644 src/applications/config/view/PhabricatorConfigPageView.php delete mode 100644 src/applications/harbormaster/config/PhabricatorHarbormasterConfigOptions.php delete mode 100644 src/applications/phrequent/config/PhabricatorPhrequentConfigOptions.php create mode 100644 webroot/rsrc/css/application/config/config-page.css diff --git a/resources/celerity/map.php b/resources/celerity/map.php index 83a4949a80..5597ea303d 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -7,7 +7,7 @@ */ return array( 'names' => array( - 'core.pkg.css' => '7d178771', + 'core.pkg.css' => 'ffbade6c', 'core.pkg.js' => '2b8af4e4', 'darkconsole.pkg.js' => 'e7393ebb', 'differential.pkg.css' => '3fb7f532', @@ -36,10 +36,11 @@ return array( 'rsrc/css/application/base/notification-menu.css' => 'b3ab500d', 'rsrc/css/application/base/phabricator-application-launch-view.css' => '95351601', 'rsrc/css/application/base/phui-theme.css' => '027ba77e', - 'rsrc/css/application/base/standard-page-view.css' => '99a7d403', + 'rsrc/css/application/base/standard-page-view.css' => '2b592894', 'rsrc/css/application/chatlog/chatlog.css' => 'd295b020', 'rsrc/css/application/conduit/conduit-api.css' => '7bc725c4', 'rsrc/css/application/config/config-options.css' => '0ede4c9b', + 'rsrc/css/application/config/config-page.css' => '8798e14f', 'rsrc/css/application/config/config-template.css' => '8e6c6fcd', 'rsrc/css/application/config/config-welcome.css' => '035aa483', 'rsrc/css/application/config/setup-issue.css' => 'f794cfc3', @@ -112,7 +113,7 @@ return array( 'rsrc/css/font/font-aleo.css' => '8bdb2835', 'rsrc/css/font/font-awesome.css' => '2b7ebbcc', 'rsrc/css/font/font-lato.css' => 'c7ccd872', - 'rsrc/css/font/phui-font-icon-base.css' => '4e8274c4', + 'rsrc/css/font/phui-font-icon-base.css' => '870a7360', 'rsrc/css/layout/phabricator-filetree-view.css' => 'fccf9f82', 'rsrc/css/layout/phabricator-source-code-view.css' => 'cbeef983', 'rsrc/css/phui/calendar/phui-calendar-day.css' => '572b1893', @@ -147,7 +148,7 @@ return array( 'rsrc/css/phui/phui-info-view.css' => '28efab79', 'rsrc/css/phui/phui-list.css' => '9da2aa00', 'rsrc/css/phui/phui-object-box.css' => '6b487c57', - 'rsrc/css/phui/phui-object-item-list-view.css' => '985e9d54', + 'rsrc/css/phui/phui-object-item-list-view.css' => '987db9bf', 'rsrc/css/phui/phui-pager.css' => 'bea33d23', 'rsrc/css/phui/phui-pinboard-view.css' => '2495140e', 'rsrc/css/phui/phui-profile-menu.css' => '8a3fc181', @@ -547,6 +548,7 @@ return array( 'changeset-view-manager' => 'a2828756', 'conduit-api-css' => '7bc725c4', 'config-options-css' => '0ede4c9b', + 'config-page-css' => '8798e14f', 'config-welcome-css' => '035aa483', 'conpherence-durable-column-view' => '86396117', 'conpherence-menu-css' => '90bdf85c', @@ -797,7 +799,7 @@ return array( 'phabricator-shaped-request' => '7cbe244b', 'phabricator-slowvote-css' => 'a94b7230', 'phabricator-source-code-view-css' => 'cbeef983', - 'phabricator-standard-page-view' => '99a7d403', + 'phabricator-standard-page-view' => '2b592894', 'phabricator-textareautils' => '320810c8', 'phabricator-title' => 'df5e11d2', 'phabricator-tooltip' => '6323f942', @@ -840,7 +842,7 @@ return array( 'phui-document-view-css' => 'c32e8dec', 'phui-document-view-pro-css' => 'dc3d46ed', 'phui-feed-story-css' => 'aa49845d', - 'phui-font-icon-base-css' => '4e8274c4', + 'phui-font-icon-base-css' => '870a7360', 'phui-fontkit-css' => '9cda225e', 'phui-form-css' => 'aac1d51d', 'phui-form-view-css' => '76b4a46c', @@ -856,7 +858,7 @@ return array( 'phui-inline-comment-view-css' => '5953c28e', 'phui-list-view-css' => '9da2aa00', 'phui-object-box-css' => '6b487c57', - 'phui-object-item-list-view-css' => '985e9d54', + 'phui-object-item-list-view-css' => '987db9bf', 'phui-pager-css' => 'bea33d23', 'phui-pinboard-view-css' => '2495140e', 'phui-profile-menu-css' => '8a3fc181', diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 13ae2af39c..ac0a35e75e 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -2149,6 +2149,7 @@ phutil_register_library_map(array( 'PhabricatorConfigCollectorsModule' => 'applications/config/module/PhabricatorConfigCollectorsModule.php', 'PhabricatorConfigColumnSchema' => 'applications/config/schema/PhabricatorConfigColumnSchema.php', 'PhabricatorConfigConfigPHIDType' => 'applications/config/phid/PhabricatorConfigConfigPHIDType.php', + 'PhabricatorConfigConstants' => 'applications/config/constants/PhabricatorConfigConstants.php', 'PhabricatorConfigController' => 'applications/config/controller/PhabricatorConfigController.php', 'PhabricatorConfigCoreSchemaSpec' => 'applications/config/schema/PhabricatorConfigCoreSchemaSpec.php', 'PhabricatorConfigDatabaseController' => 'applications/config/controller/PhabricatorConfigDatabaseController.php', @@ -2165,6 +2166,7 @@ phutil_register_library_map(array( 'PhabricatorConfigEntryDAO' => 'applications/config/storage/PhabricatorConfigEntryDAO.php', 'PhabricatorConfigEntryQuery' => 'applications/config/query/PhabricatorConfigEntryQuery.php', 'PhabricatorConfigFileSource' => 'infrastructure/env/PhabricatorConfigFileSource.php', + 'PhabricatorConfigGroupConstants' => 'applications/config/constants/PhabricatorConfigGroupConstants.php', 'PhabricatorConfigGroupController' => 'applications/config/controller/PhabricatorConfigGroupController.php', 'PhabricatorConfigHTTPParameterTypesModule' => 'applications/config/module/PhabricatorConfigHTTPParameterTypesModule.php', 'PhabricatorConfigHistoryController' => 'applications/config/controller/PhabricatorConfigHistoryController.php', @@ -2188,6 +2190,7 @@ phutil_register_library_map(array( 'PhabricatorConfigOption' => 'applications/config/option/PhabricatorConfigOption.php', 'PhabricatorConfigOptionType' => 'applications/config/custom/PhabricatorConfigOptionType.php', 'PhabricatorConfigPHIDModule' => 'applications/config/module/PhabricatorConfigPHIDModule.php', + 'PhabricatorConfigPageView' => 'applications/config/view/PhabricatorConfigPageView.php', 'PhabricatorConfigProxySource' => 'infrastructure/env/PhabricatorConfigProxySource.php', 'PhabricatorConfigPurgeCacheController' => 'applications/config/controller/PhabricatorConfigPurgeCacheController.php', 'PhabricatorConfigRequestExceptionHandlerModule' => 'applications/config/module/PhabricatorConfigRequestExceptionHandlerModule.php', @@ -2649,7 +2652,6 @@ phutil_register_library_map(array( 'PhabricatorHandleRemarkupRule' => 'applications/phid/remarkup/PhabricatorHandleRemarkupRule.php', 'PhabricatorHandlesEditField' => 'applications/transactions/editfield/PhabricatorHandlesEditField.php', 'PhabricatorHarbormasterApplication' => 'applications/harbormaster/application/PhabricatorHarbormasterApplication.php', - 'PhabricatorHarbormasterConfigOptions' => 'applications/harbormaster/config/PhabricatorHarbormasterConfigOptions.php', 'PhabricatorHash' => 'infrastructure/util/PhabricatorHash.php', 'PhabricatorHashTestCase' => 'infrastructure/util/__tests__/PhabricatorHashTestCase.php', 'PhabricatorHelpApplication' => 'applications/help/application/PhabricatorHelpApplication.php', @@ -3158,7 +3160,6 @@ phutil_register_library_map(array( 'PhabricatorPhortuneManagementWorkflow' => 'applications/phortune/management/PhabricatorPhortuneManagementWorkflow.php', 'PhabricatorPhragmentApplication' => 'applications/phragment/application/PhabricatorPhragmentApplication.php', 'PhabricatorPhrequentApplication' => 'applications/phrequent/application/PhabricatorPhrequentApplication.php', - 'PhabricatorPhrequentConfigOptions' => 'applications/phrequent/config/PhabricatorPhrequentConfigOptions.php', 'PhabricatorPhrictionApplication' => 'applications/phriction/application/PhabricatorPhrictionApplication.php', 'PhabricatorPhrictionConfigOptions' => 'applications/phriction/config/PhabricatorPhrictionConfigOptions.php', 'PhabricatorPhurlApplication' => 'applications/phurl/application/PhabricatorPhurlApplication.php', @@ -6891,6 +6892,7 @@ phutil_register_library_map(array( 'PhabricatorConfigCollectorsModule' => 'PhabricatorConfigModule', 'PhabricatorConfigColumnSchema' => 'PhabricatorConfigStorageSchema', 'PhabricatorConfigConfigPHIDType' => 'PhabricatorPHIDType', + 'PhabricatorConfigConstants' => 'Phobject', 'PhabricatorConfigController' => 'PhabricatorController', 'PhabricatorConfigCoreSchemaSpec' => 'PhabricatorConfigSchemaSpec', 'PhabricatorConfigDatabaseController' => 'PhabricatorConfigController', @@ -6911,6 +6913,7 @@ phutil_register_library_map(array( 'PhabricatorConfigEntryDAO' => 'PhabricatorLiskDAO', 'PhabricatorConfigEntryQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhabricatorConfigFileSource' => 'PhabricatorConfigProxySource', + 'PhabricatorConfigGroupConstants' => 'PhabricatorConfigConstants', 'PhabricatorConfigGroupController' => 'PhabricatorConfigController', 'PhabricatorConfigHTTPParameterTypesModule' => 'PhabricatorConfigModule', 'PhabricatorConfigHistoryController' => 'PhabricatorConfigController', @@ -6937,6 +6940,7 @@ phutil_register_library_map(array( ), 'PhabricatorConfigOptionType' => 'Phobject', 'PhabricatorConfigPHIDModule' => 'PhabricatorConfigModule', + 'PhabricatorConfigPageView' => 'AphrontTagView', 'PhabricatorConfigProxySource' => 'PhabricatorConfigSource', 'PhabricatorConfigPurgeCacheController' => 'PhabricatorConfigController', 'PhabricatorConfigRequestExceptionHandlerModule' => 'PhabricatorConfigModule', @@ -7467,7 +7471,6 @@ phutil_register_library_map(array( 'PhabricatorHandleRemarkupRule' => 'PhutilRemarkupRule', 'PhabricatorHandlesEditField' => 'PhabricatorPHIDListEditField', 'PhabricatorHarbormasterApplication' => 'PhabricatorApplication', - 'PhabricatorHarbormasterConfigOptions' => 'PhabricatorApplicationConfigOptions', 'PhabricatorHash' => 'Phobject', 'PhabricatorHashTestCase' => 'PhabricatorTestCase', 'PhabricatorHelpApplication' => 'PhabricatorApplication', @@ -8050,7 +8053,6 @@ phutil_register_library_map(array( 'PhabricatorPhortuneManagementWorkflow' => 'PhabricatorManagementWorkflow', 'PhabricatorPhragmentApplication' => 'PhabricatorApplication', 'PhabricatorPhrequentApplication' => 'PhabricatorApplication', - 'PhabricatorPhrequentConfigOptions' => 'PhabricatorApplicationConfigOptions', 'PhabricatorPhrictionApplication' => 'PhabricatorApplication', 'PhabricatorPhrictionConfigOptions' => 'PhabricatorApplicationConfigOptions', 'PhabricatorPhurlApplication' => 'PhabricatorApplication', diff --git a/src/applications/auth/engine/PhabricatorAuthSessionEngineExtensionModule.php b/src/applications/auth/engine/PhabricatorAuthSessionEngineExtensionModule.php index 0f8c9fef8c..7e776ab7bc 100644 --- a/src/applications/auth/engine/PhabricatorAuthSessionEngineExtensionModule.php +++ b/src/applications/auth/engine/PhabricatorAuthSessionEngineExtensionModule.php @@ -25,7 +25,7 @@ final class PhabricatorAuthSessionEngineExtensionModule ); } - $table = id(new AphrontTableView($rows)) + return id(new AphrontTableView($rows)) ->setNoDataString( pht('There are no registered session engine extensions.')) ->setHeaders( @@ -41,10 +41,6 @@ final class PhabricatorAuthSessionEngineExtensionModule 'wide pri', )); - return id(new PHUIObjectBoxView()) - ->setHeaderText(pht('SessionEngine Extensions')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setTable($table); } } diff --git a/src/applications/auth/tokentype/PhabricatorAuthTemporaryTokenTypeModule.php b/src/applications/auth/tokentype/PhabricatorAuthTemporaryTokenTypeModule.php index 3c44ef01b2..fc6358f8e8 100644 --- a/src/applications/auth/tokentype/PhabricatorAuthTemporaryTokenTypeModule.php +++ b/src/applications/auth/tokentype/PhabricatorAuthTemporaryTokenTypeModule.php @@ -8,7 +8,7 @@ final class PhabricatorAuthTemporaryTokenTypeModule } public function getModuleName() { - return pht('Temporary Tokens'); + return pht('Temporary Token Types'); } public function renderModuleStatus(AphrontRequest $request) { @@ -25,7 +25,7 @@ final class PhabricatorAuthTemporaryTokenTypeModule ); } - $table = id(new AphrontTableView($rows)) + return id(new AphrontTableView($rows)) ->setHeaders( array( pht('Class'), @@ -39,10 +39,6 @@ final class PhabricatorAuthTemporaryTokenTypeModule 'wide pri', )); - return id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Temporary Token Types')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setTable($table); } } diff --git a/src/applications/config/check/PhabricatorCacheSetupCheck.php b/src/applications/config/check/PhabricatorCacheSetupCheck.php index fba241150e..04d3dccb61 100644 --- a/src/applications/config/check/PhabricatorCacheSetupCheck.php +++ b/src/applications/config/check/PhabricatorCacheSetupCheck.php @@ -3,7 +3,7 @@ final class PhabricatorCacheSetupCheck extends PhabricatorSetupCheck { public function getDefaultGroup() { - return self::GROUP_OTHER; + return self::GROUP_PHP; } protected function executeChecks() { diff --git a/src/applications/config/check/PhabricatorMySQLSetupCheck.php b/src/applications/config/check/PhabricatorMySQLSetupCheck.php index 3303f29e89..1990e7f09f 100644 --- a/src/applications/config/check/PhabricatorMySQLSetupCheck.php +++ b/src/applications/config/check/PhabricatorMySQLSetupCheck.php @@ -34,11 +34,9 @@ final class PhabricatorMySQLSetupCheck extends PhabricatorSetupCheck { if ($max_allowed_packet < $recommended_minimum) { $message = pht( "MySQL is configured with a small '%s' (%d), ". - "which may cause some large writes to fail. Strongly consider raising ". - "this to at least %d in your MySQL configuration.", + "which may cause some large writes to fail.", 'max_allowed_packet', - $max_allowed_packet, - $recommended_minimum); + $max_allowed_packet); $this->newIssue('mysql.max_allowed_packet') ->setName(pht('Small MySQL "%s"', 'max_allowed_packet')) diff --git a/src/applications/config/constants/PhabricatorConfigConstants.php b/src/applications/config/constants/PhabricatorConfigConstants.php new file mode 100644 index 0000000000..36eab2c607 --- /dev/null +++ b/src/applications/config/constants/PhabricatorConfigConstants.php @@ -0,0 +1,3 @@ + pht('Core Settings'), + self::GROUP_APPLICATION => pht('Application Settings'), + self::GROUP_DEVELOPER => pht('Developer Settings'), + ); + return idx($map, $group, pht('Unknown')); + } + + public static function getGroupShortName($group) { + $map = array( + self::GROUP_CORE => pht('Core'), + self::GROUP_APPLICATION => pht('Application'), + self::GROUP_DEVELOPER => pht('Developer'), + ); + return idx($map, $group, pht('Unknown')); + } + + public static function getGroupURI($group) { + $map = array( + self::GROUP_CORE => '/', + self::GROUP_APPLICATION => pht('application/'), + self::GROUP_DEVELOPER => pht('developer/'), + ); + return idx($map, $group, '#'); + } + +} diff --git a/src/applications/config/controller/PhabricatorConfigAllController.php b/src/applications/config/controller/PhabricatorConfigAllController.php index 6d661479aa..421e0078cf 100644 --- a/src/applications/config/controller/PhabricatorConfigAllController.php +++ b/src/applications/config/controller/PhabricatorConfigAllController.php @@ -52,27 +52,26 @@ final class PhabricatorConfigAllController $crumbs = $this ->buildApplicationCrumbs() - ->addTextCrumb(pht('Configuration'), $this->getApplicationURI()) - ->addTextCrumb($title); + ->addTextCrumb($title) + ->setBorder(true); - $panel = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Current Settings')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setTable($table); + $header = id(new PHUIHeaderView()) + ->setHeader($title) + ->setProfileHeader(true); $nav = $this->buildSideNavView(); $nav->selectFilter('all/'); - $view = id(new PHUITwoColumnView()) - ->setNavigation($nav) - ->setMainColumn(array( - $panel, - )); + $content = id(new PhabricatorConfigPageView()) + ->setHeader($header) + ->setContent($table); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) - ->appendChild($view); + ->setNavigation($nav) + ->appendChild($content) + ->addClass('white-background'); } diff --git a/src/applications/config/controller/PhabricatorConfigApplicationController.php b/src/applications/config/controller/PhabricatorConfigApplicationController.php index 4a7bccf739..10f639adc7 100644 --- a/src/applications/config/controller/PhabricatorConfigApplicationController.php +++ b/src/applications/config/controller/PhabricatorConfigApplicationController.php @@ -12,42 +12,45 @@ final class PhabricatorConfigApplicationController $groups = PhabricatorApplicationConfigOptions::loadAll(); $apps_list = $this->buildConfigOptionsList($groups, 'apps'); - $title = pht('Application Configuration'); + $title = pht('Application Settings'); - $apps = id(new PHUIObjectBoxView()) - ->setHeaderText($title) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setObjectList($apps_list); + $header = id(new PHUIHeaderView()) + ->setHeader($title) + ->setProfileHeader(true); $crumbs = $this ->buildApplicationCrumbs() - ->addTextCrumb(pht('Configuration'), $this->getApplicationURI()) - ->addTextCrumb(pht('Applications')); + ->addTextCrumb(pht('Applications')) + ->setBorder(true); - $view = id(new PHUITwoColumnView()) - ->setNavigation($nav) - ->setMainColumn(array( - $apps, - )); + $content = id(new PhabricatorConfigPageView()) + ->setHeader($header) + ->setContent($apps_list); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) - ->appendChild($view); + ->setNavigation($nav) + ->appendChild($content) + ->addClass('white-background'); } private function buildConfigOptionsList(array $groups, $type) { assert_instances_of($groups, 'PhabricatorApplicationConfigOptions'); $list = new PHUIObjectItemListView(); + $list->setBig(true); $groups = msort($groups, 'getName'); foreach ($groups as $group) { if ($group->getGroup() == $type) { + $icon = id(new PHUIIconView()) + ->setIcon($group->getIcon()) + ->setBackground('bg-violet'); $item = id(new PHUIObjectItemView()) ->setHeader($group->getName()) ->setHref('/config/group/'.$group->getKey().'/') ->addAttribute($group->getDescription()) - ->setImageIcon($group->getIcon()); + ->setImageIcon($icon); $list->addItem($item); } } diff --git a/src/applications/config/controller/PhabricatorConfigCacheController.php b/src/applications/config/controller/PhabricatorConfigCacheController.php index 0f6ee83089..91b0be27cf 100644 --- a/src/applications/config/controller/PhabricatorConfigCacheController.php +++ b/src/applications/config/controller/PhabricatorConfigCacheController.php @@ -11,24 +11,33 @@ final class PhabricatorConfigCacheController $title = pht('Cache Status'); + $header = id(new PHUIHeaderView()) + ->setHeader($title) + ->setProfileHeader(true); + $crumbs = $this ->buildApplicationCrumbs() - ->addTextCrumb(pht('Cache Status')); + ->addTextCrumb(pht('Cache Status')) + ->setBorder(true); $code_box = $this->renderCodeBox(); $data_box = $this->renderDataBox(); - $view = id(new PHUITwoColumnView()) - ->setNavigation($nav) - ->setMainColumn(array( - $code_box, - $data_box, - )); + $page = array( + $code_box, + $data_box, + ); + + $content = id(new PhabricatorConfigPageView()) + ->setHeader($header) + ->setContent($page); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) - ->appendChild($view); + ->setNavigation($nav) + ->appendChild($content) + ->addClass('white-background'); } private function renderCodeBox() { diff --git a/src/applications/config/controller/PhabricatorConfigClusterDatabasesController.php b/src/applications/config/controller/PhabricatorConfigClusterDatabasesController.php index 33f7f1331e..44659ab24e 100644 --- a/src/applications/config/controller/PhabricatorConfigClusterDatabasesController.php +++ b/src/applications/config/controller/PhabricatorConfigClusterDatabasesController.php @@ -7,22 +7,36 @@ final class PhabricatorConfigClusterDatabasesController $nav = $this->buildSideNavView(); $nav->selectFilter('cluster/databases/'); - $title = pht('Database Servers'); + $title = pht('Cluster Database Status'); + $doc_href = PhabricatorEnv::getDoclink('Cluster: Databases'); + + $header = id(new PHUIHeaderView()) + ->setHeader($title) + ->setProfileHeader(true) + ->addActionLink( + id(new PHUIButtonView()) + ->setIcon('fa-book') + ->setHref($doc_href) + ->setTag('a') + ->setText(pht('Documentation'))); $crumbs = $this ->buildApplicationCrumbs($nav) - ->addTextCrumb(pht('Database Servers')); + ->addTextCrumb($title) + ->setBorder(true); $database_status = $this->buildClusterDatabaseStatus(); - $view = id(new PHUITwoColumnView()) - ->setNavigation($nav) - ->setMainColumn($database_status); + $content = id(new PhabricatorConfigPageView()) + ->setHeader($header) + ->setContent($database_status); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) - ->appendChild($view); + ->setNavigation($nav) + ->appendChild($content) + ->addClass('white-background'); } private function buildClusterDatabaseStatus() { @@ -194,21 +208,7 @@ final class PhabricatorConfigClusterDatabasesController 'wide', )); - $doc_href = PhabricatorEnv::getDoclink('Cluster: Databases'); - - $header = id(new PHUIHeaderView()) - ->setHeader(pht('Cluster Database Status')) - ->addActionLink( - id(new PHUIButtonView()) - ->setIcon('fa-book') - ->setHref($doc_href) - ->setTag('a') - ->setText(pht('Documentation'))); - - return id(new PHUIObjectBoxView()) - ->setHeader($header) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setTable($table); + return $table; } } diff --git a/src/applications/config/controller/PhabricatorConfigClusterNotificationsController.php b/src/applications/config/controller/PhabricatorConfigClusterNotificationsController.php index 576d6841d0..d0d26d0613 100644 --- a/src/applications/config/controller/PhabricatorConfigClusterNotificationsController.php +++ b/src/applications/config/controller/PhabricatorConfigClusterNotificationsController.php @@ -8,21 +8,35 @@ final class PhabricatorConfigClusterNotificationsController $nav->selectFilter('cluster/notifications/'); $title = pht('Cluster Notifications'); + $doc_href = PhabricatorEnv::getDoclink('Cluster: Notifications'); + + $header = id(new PHUIHeaderView()) + ->setHeader($title) + ->setProfileHeader(true) + ->addActionLink( + id(new PHUIButtonView()) + ->setIcon('fa-book') + ->setHref($doc_href) + ->setTag('a') + ->setText(pht('Documentation'))); $crumbs = $this ->buildApplicationCrumbs($nav) - ->addTextCrumb(pht('Cluster Notifications')); + ->addTextCrumb($title) + ->setBorder(true); $notification_status = $this->buildClusterNotificationStatus(); - $view = id(new PHUITwoColumnView()) - ->setNavigation($nav) - ->setMainColumn($notification_status); + $content = id(new PhabricatorConfigPageView()) + ->setHeader($header) + ->setContent($notification_status); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) - ->appendChild($view); + ->setNavigation($nav) + ->appendChild($content) + ->addClass('white-background'); } private function buildClusterNotificationStatus() { @@ -144,21 +158,7 @@ final class PhabricatorConfigClusterNotificationsController 'wide', )); - $doc_href = PhabricatorEnv::getDoclink('Cluster: Notifications'); - - $header = id(new PHUIHeaderView()) - ->setHeader(pht('Cluster Notification Status')) - ->addActionLink( - id(new PHUIButtonView()) - ->setIcon('fa-book') - ->setHref($doc_href) - ->setTag('a') - ->setText(pht('Documentation'))); - - return id(new PHUIObjectBoxView()) - ->setHeader($header) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setTable($table); + return $table; } } diff --git a/src/applications/config/controller/PhabricatorConfigClusterRepositoriesController.php b/src/applications/config/controller/PhabricatorConfigClusterRepositoriesController.php index c0fafc2c58..2486712022 100644 --- a/src/applications/config/controller/PhabricatorConfigClusterRepositoriesController.php +++ b/src/applications/config/controller/PhabricatorConfigClusterRepositoriesController.php @@ -7,22 +7,37 @@ final class PhabricatorConfigClusterRepositoriesController $nav = $this->buildSideNavView(); $nav->selectFilter('cluster/repositories/'); - $title = pht('Repository Servers'); + $title = pht('Cluster Repository Status'); + + $doc_href = PhabricatorEnv::getDoclink('Cluster: Repositories'); + + $header = id(new PHUIHeaderView()) + ->setHeader($title) + ->setProfileHeader(true) + ->addActionLink( + id(new PHUIButtonView()) + ->setIcon('fa-book') + ->setHref($doc_href) + ->setTag('a') + ->setText(pht('Documentation'))); $crumbs = $this ->buildApplicationCrumbs($nav) - ->addTextCrumb(pht('Repository Servers')); + ->addTextCrumb(pht('Repository Servers')) + ->setBorder(true); $repository_status = $this->buildClusterRepositoryStatus(); - $view = id(new PHUITwoColumnView()) - ->setNavigation($nav) - ->setMainColumn($repository_status); + $content = id(new PhabricatorConfigPageView()) + ->setHeader($header) + ->setContent($repository_status); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) - ->appendChild($view); + ->setNavigation($nav) + ->appendChild($content) + ->addClass('white-background'); } private function buildClusterRepositoryStatus() { @@ -217,8 +232,7 @@ final class PhabricatorConfigClusterRepositoriesController ); } - - $table = id(new AphrontTableView($rows)) + return id(new AphrontTableView($rows)) ->setNoDataString( pht('No repository cluster services are configured.')) ->setHeaders( @@ -239,22 +253,6 @@ final class PhabricatorConfigClusterRepositoriesController null, 'wide', )); - - $doc_href = PhabricatorEnv::getDoclink('Cluster: Repositories'); - - $header = id(new PHUIHeaderView()) - ->setHeader(pht('Cluster Repository Status')) - ->addActionLink( - id(new PHUIButtonView()) - ->setIcon('fa-book') - ->setHref($doc_href) - ->setTag('a') - ->setText(pht('Documentation'))); - - return id(new PHUIObjectBoxView()) - ->setHeader($header) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setTable($table); } private function getDevices( diff --git a/src/applications/config/controller/PhabricatorConfigDatabaseController.php b/src/applications/config/controller/PhabricatorConfigDatabaseController.php index 0619a4a3a1..c9f2aa6a3c 100644 --- a/src/applications/config/controller/PhabricatorConfigDatabaseController.php +++ b/src/applications/config/controller/PhabricatorConfigDatabaseController.php @@ -60,18 +60,4 @@ abstract class PhabricatorConfigDatabaseController } } - protected function buildHeaderWithDocumentationLink($title) { - - $doc_link = PhabricatorEnv::getDoclink('Managing Storage Adjustments'); - - return id(new PHUIHeaderView()) - ->setHeader($title) - ->addActionLink( - id(new PHUIButtonView()) - ->setTag('a') - ->setIcon('fa-book') - ->setHref($doc_link) - ->setText(pht('Learn More'))); - } - } diff --git a/src/applications/config/controller/PhabricatorConfigDatabaseIssueController.php b/src/applications/config/controller/PhabricatorConfigDatabaseIssueController.php index 775a765d92..f1a91d4d5b 100644 --- a/src/applications/config/controller/PhabricatorConfigDatabaseIssueController.php +++ b/src/applications/config/controller/PhabricatorConfigDatabaseIssueController.php @@ -14,6 +14,7 @@ final class PhabricatorConfigDatabaseIssueController $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb(pht('Database Issues')); + $crumbs->setBorder(true); // Collect all open issues. $issues = array(); @@ -111,6 +112,8 @@ final class PhabricatorConfigDatabaseIssueController } $table = id(new AphrontTableView($rows)) + ->setNoDataString( + pht('No databases have any issues.')) ->setHeaders( array( null, @@ -146,25 +149,23 @@ final class PhabricatorConfigDatabaseIssueController $title = pht('Database Issues'); - $table_box = id(new PHUIObjectBoxView()) - ->setHeader($this->buildHeaderWithDocumentationLink($title)) - ->setFormErrors($errors) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setTable($table); + $header = id(new PHUIHeaderView()) + ->setHeader($title) + ->setProfileHeader(true); $nav = $this->buildSideNavView(); $nav->selectFilter('dbissue/'); - $view = id(new PHUITwoColumnView()) - ->setNavigation($nav) - ->setMainColumn(array( - $table_box, - )); + $content = id(new PhabricatorConfigPageView()) + ->setHeader($header) + ->setContent($table); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) - ->appendChild($view); + ->setNavigation($nav) + ->appendChild($content) + ->addClass('white-background'); } } diff --git a/src/applications/config/controller/PhabricatorConfigDatabaseStatusController.php b/src/applications/config/controller/PhabricatorConfigDatabaseStatusController.php index 3e6e9af298..bdeb254437 100644 --- a/src/applications/config/controller/PhabricatorConfigDatabaseStatusController.php +++ b/src/applications/config/controller/PhabricatorConfigDatabaseStatusController.php @@ -62,7 +62,12 @@ final class PhabricatorConfigDatabaseStatusController $nav = $this->buildSideNavView(); $nav->selectFilter('database/'); + if (!$title) { + $title = pht('Database Status'); + } + $crumbs = $this->buildApplicationCrumbs(); + $crumbs->setBorder(true); if ($this->database) { $crumbs->addTextCrumb( pht('Database Status'), @@ -91,16 +96,28 @@ final class PhabricatorConfigDatabaseStatusController $crumbs->addTextCrumb(pht('Database Status')); } - $view = id(new PHUITwoColumnView()) - ->setNavigation($nav) - ->setMainColumn(array( - $body, - )); + $doc_link = PhabricatorEnv::getDoclink('Managing Storage Adjustments'); + + $header = id(new PHUIHeaderView()) + ->setHeader($title) + ->setProfileHeader(true) + ->addActionLink( + id(new PHUIButtonView()) + ->setTag('a') + ->setIcon('fa-book') + ->setHref($doc_link) + ->setText(pht('Learn More'))); + + $content = id(new PhabricatorConfigPageView()) + ->setHeader($header) + ->setContent($body); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) - ->appendChild($view); + ->setNavigation($nav) + ->appendChild($content) + ->addClass('white-background'); } @@ -163,17 +180,7 @@ final class PhabricatorConfigDatabaseStatusController ), $comp->getIssues()); - $prop_box = id(new PHUIObjectBoxView()) - ->setHeader($this->buildHeaderWithDocumentationLink($title)) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->addPropertyList($properties); - - $table_box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Databases')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setTable($table); - - return $this->buildResponse($title, array($prop_box, $table_box)); + return $this->buildResponse($title, array($properties, $table)); } private function renderDatabase( @@ -263,17 +270,7 @@ final class PhabricatorConfigDatabaseStatusController ), $database->getIssues()); - $prop_box = id(new PHUIObjectBoxView()) - ->setHeader($this->buildHeaderWithDocumentationLink($title)) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->addPropertyList($properties); - - $table_box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Database Status')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setTable($table); - - return $this->buildResponse($title, array($prop_box, $table_box)); + return $this->buildResponse($title, array($properties, $table)); } private function renderTable( @@ -478,22 +475,8 @@ final class PhabricatorConfigDatabaseStatusController ), $table->getIssues()); - $prop_box = id(new PHUIObjectBoxView()) - ->setHeader($this->buildHeaderWithDocumentationLink($title)) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->addPropertyList($properties); - - $table_box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Database')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setTable($table_view); - - $key_box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Keys')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setTable($keys_view); - - return $this->buildResponse($title, array($prop_box, $table_box, $key_box)); + return $this->buildResponse( + $title, array($properties, $table_view, $keys_view)); } private function renderColumn( @@ -625,12 +608,7 @@ final class PhabricatorConfigDatabaseStatusController ), $column->getIssues()); - $box = id(new PHUIObjectBoxView()) - ->setHeader($this->buildHeaderWithDocumentationLink($title)) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->addPropertyList($properties); - - return $this->buildResponse($title, $box); + return $this->buildResponse($title, $properties); } private function renderKey( @@ -719,12 +697,7 @@ final class PhabricatorConfigDatabaseStatusController ), $key->getIssues()); - $box = id(new PHUIObjectBoxView()) - ->setHeader($this->buildHeaderWithDocumentationLink($title)) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->addPropertyList($properties); - - return $this->buildResponse($title, $box); + return $this->buildResponse($title, $properties); } private function buildProperties(array $properties, array $issues) { @@ -769,7 +742,7 @@ final class PhabricatorConfigDatabaseStatusController } $view->addProperty(pht('Schema Status'), $status_view); - return $view; + return phutil_tag_div('config-page-property', $view); } } diff --git a/src/applications/config/controller/PhabricatorConfigGroupController.php b/src/applications/config/controller/PhabricatorConfigGroupController.php index c1d46906bc..9ff9311c63 100644 --- a/src/applications/config/controller/PhabricatorConfigGroupController.php +++ b/src/applications/config/controller/PhabricatorConfigGroupController.php @@ -13,31 +13,37 @@ final class PhabricatorConfigGroupController return new Aphront404Response(); } + $group_uri = PhabricatorConfigGroupConstants::getGroupURI( + $options->getGroup()); + $group_name = PhabricatorConfigGroupConstants::getGroupShortName( + $options->getGroup()); + + $nav = $this->buildSideNavView(); + $nav->selectFilter($group_uri); + $title = pht('%s Configuration', $options->getName()); $list = $this->buildOptionList($options->getOptions()); - $box = id(new PHUIObjectBoxView()) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setObjectList($list); - $crumbs = $this ->buildApplicationCrumbs() - ->addTextCrumb(pht('Config'), $this->getApplicationURI()) - ->addTextCrumb($options->getName(), $this->getApplicationURI()) + ->addTextCrumb($group_name, $this->getApplicationURI($group_uri)) + ->addTextCrumb($options->getName()) ->setBorder(true); $header = id(new PHUIHeaderView()) ->setHeader($title) - ->setHeaderIcon('fa-sliders'); + ->setProfileHeader(true); - $view = id(new PHUITwoColumnView()) + $content = id(new PhabricatorConfigPageView()) ->setHeader($header) - ->setFooter($box); + ->setContent($list); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) - ->appendChild($view); + ->setNavigation($nav) + ->appendChild($content) + ->addClass('white-background'); } private function buildOptionList(array $options) { @@ -62,6 +68,7 @@ final class PhabricatorConfigGroupController $engine->process(); $list = new PHUIObjectItemListView(); + $list->setBig(true); foreach ($options as $option) { $summary = $engine->getOutput($option, 'summary'); @@ -89,13 +96,13 @@ final class PhabricatorConfigGroupController $db_value = idx($db_values, $option->getKey()); if ($db_value && !$db_value->getIsDeleted()) { - $item->addIcon('edit', pht('Customized')); + $item->addIcon('fa-edit', pht('Customized')); } if ($option->getHidden()) { - $item->addIcon('unpublish', pht('Hidden')); + $item->addIcon('fa-eye-slash', pht('Hidden')); } else if ($option->getLocked()) { - $item->addIcon('lock', pht('Locked')); + $item->addIcon('fa-lock', pht('Locked')); } $list->addItem($item); diff --git a/src/applications/config/controller/PhabricatorConfigHistoryController.php b/src/applications/config/controller/PhabricatorConfigHistoryController.php index 6599c2d233..eb7fbf607b 100644 --- a/src/applications/config/controller/PhabricatorConfigHistoryController.php +++ b/src/applications/config/controller/PhabricatorConfigHistoryController.php @@ -31,22 +31,26 @@ final class PhabricatorConfigHistoryController $title = pht('Settings History'); $crumbs = $this->buildApplicationCrumbs(); - $crumbs->addTextCrumb('Configuration', $this->getApplicationURI()); - $crumbs->addTextCrumb($title, '/config/history/'); + $crumbs->addTextCrumb($title); + $crumbs->setBorder(true); $nav = $this->buildSideNavView(); $nav->selectFilter('history/'); - $view = id(new PHUITwoColumnView()) - ->setNavigation($nav) - ->setMainColumn(array( - $timeline, - )); + $header = id(new PHUIHeaderView()) + ->setHeader($title) + ->setProfileHeader(true); + + $content = id(new PhabricatorConfigPageView()) + ->setHeader($header) + ->setContent($timeline); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) - ->appendChild($view); + ->setNavigation($nav) + ->appendChild($content) + ->addClass('white-background'); } } diff --git a/src/applications/config/controller/PhabricatorConfigIssueListController.php b/src/applications/config/controller/PhabricatorConfigIssueListController.php index 7eac4c10ee..7f0b19af69 100644 --- a/src/applications/config/controller/PhabricatorConfigIssueListController.php +++ b/src/applications/config/controller/PhabricatorConfigIssueListController.php @@ -15,45 +15,25 @@ final class PhabricatorConfigIssueListController $update_database = true); $important = $this->buildIssueList( - $issues, PhabricatorSetupCheck::GROUP_IMPORTANT); + $issues, + PhabricatorSetupCheck::GROUP_IMPORTANT, + 'fa-warning'); $php = $this->buildIssueList( - $issues, PhabricatorSetupCheck::GROUP_PHP); + $issues, + PhabricatorSetupCheck::GROUP_PHP, + 'fa-code'); $mysql = $this->buildIssueList( - $issues, PhabricatorSetupCheck::GROUP_MYSQL); + $issues, + PhabricatorSetupCheck::GROUP_MYSQL, + 'fa-database'); $other = $this->buildIssueList( - $issues, PhabricatorSetupCheck::GROUP_OTHER); + $issues, + PhabricatorSetupCheck::GROUP_OTHER, + 'fa-question-circle'); - $setup_issues = array(); - if ($important) { - $setup_issues[] = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Important Setup Issues')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setObjectList($important); - } - - if ($php) { - $setup_issues[] = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('PHP Setup Issues')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setObjectList($php); - } - - if ($mysql) { - $setup_issues[] = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('MySQL Setup Issues')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setObjectList($mysql); - } - - if ($other) { - $setup_issues[] = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Other Setup Issues')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setObjectList($other); - } - - if (empty($setup_issues)) { - $setup_issues[] = id(new PHUIInfoView()) + $no_issues = null; + if (empty($issues)) { + $no_issues = id(new PHUIInfoView()) ->setTitle(pht('No Issues')) ->appendChild( pht('Your install has no current setup issues to resolve.')) @@ -62,25 +42,39 @@ final class PhabricatorConfigIssueListController $title = pht('Setup Issues'); + $header = id(new PHUIHeaderView()) + ->setHeader($title) + ->setProfileHeader(true); + $crumbs = $this ->buildApplicationCrumbs($nav) - ->addTextCrumb(pht('Setup'), $this->getApplicationURI('issue/')); + ->addTextCrumb(pht('Setup Issues')) + ->setBorder(true); - $view = id(new PHUITwoColumnView()) - ->setNavigation($nav) - ->setMainColumn(array( - $setup_issues, - )); + $page = array( + $no_issues, + $important, + $php, + $mysql, + $other, + ); + + $content = id(new PhabricatorConfigPageView()) + ->setHeader($header) + ->setContent($page); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) - ->appendChild($view); + ->setNavigation($nav) + ->appendChild($content) + ->addClass('white-background'); } - private function buildIssueList(array $issues, $group) { + private function buildIssueList(array $issues, $group, $fonticon) { assert_instances_of($issues, 'PhabricatorSetupIssue'); $list = new PHUIObjectItemListView(); + $list->setBig(true); $ignored_items = array(); $items = 0; @@ -93,12 +87,17 @@ final class PhabricatorConfigIssueListController ->setHref($href) ->addAttribute($issue->getSummary()); if (!$issue->getIsIgnored()) { - $item->setStatusIcon('fa-warning yellow'); + $icon = id(new PHUIIconView()) + ->setIcon($fonticon) + ->setBackground('bg-sky'); + $item->setImageIcon($icon); $list->addItem($item); } else { - $item->addIcon('fa-eye-slash', pht('Ignored')); + $icon = id(new PHUIIconView()) + ->setIcon('fa-eye-slash') + ->setBackground('bg-grey'); $item->setDisabled(true); - $item->setStatusIcon('fa-warning grey'); + $item->setImageIcon($icon); $ignored_items[] = $item; } } diff --git a/src/applications/config/controller/PhabricatorConfigIssueViewController.php b/src/applications/config/controller/PhabricatorConfigIssueViewController.php index 36fb77ce74..4700e6315e 100644 --- a/src/applications/config/controller/PhabricatorConfigIssueViewController.php +++ b/src/applications/config/controller/PhabricatorConfigIssueViewController.php @@ -12,6 +12,9 @@ final class PhabricatorConfigIssueViewController PhabricatorSetupCheck::getUnignoredIssueKeys($issues), $update_database = true); + $nav = $this->buildSideNavView(); + $nav->selectFilter('issue/'); + if (empty($issues[$issue_key])) { $content = id(new PHUIInfoView()) ->setSeverity(PHUIInfoView::SEVERITY_NOTICE) @@ -35,12 +38,15 @@ final class PhabricatorConfigIssueViewController ->buildApplicationCrumbs() ->setBorder(true) ->addTextCrumb(pht('Setup Issues'), $this->getApplicationURI('issue/')) - ->addTextCrumb($title, $request->getRequestURI()); + ->addTextCrumb($title, $request->getRequestURI()) + ->setBorder(true); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) - ->appendChild($content); + ->setNavigation($nav) + ->appendChild($content) + ->addClass('white-background'); } private function renderIssue(PhabricatorSetupIssue $issue) { diff --git a/src/applications/config/controller/PhabricatorConfigListController.php b/src/applications/config/controller/PhabricatorConfigListController.php index ed8301ff2f..517fe014a9 100644 --- a/src/applications/config/controller/PhabricatorConfigListController.php +++ b/src/applications/config/controller/PhabricatorConfigListController.php @@ -12,42 +12,45 @@ final class PhabricatorConfigListController $groups = PhabricatorApplicationConfigOptions::loadAll(); $core_list = $this->buildConfigOptionsList($groups, 'core'); - $title = pht('Core Configuration'); + $title = pht('Core Settings'); - $core = id(new PHUIObjectBoxView()) - ->setHeaderText($title) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setObjectList($core_list); + $header = id(new PHUIHeaderView()) + ->setHeader($title) + ->setProfileHeader(true); $crumbs = $this ->buildApplicationCrumbs() - ->addTextCrumb(pht('Configuration'), $this->getApplicationURI()) - ->addTextCrumb($title); + ->addTextCrumb(pht('Core')) + ->setBorder(true); - $view = id(new PHUITwoColumnView()) - ->setNavigation($nav) - ->setMainColumn(array( - $core, - )); + $content = id(new PhabricatorConfigPageView()) + ->setHeader($header) + ->setContent($core_list); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) - ->appendChild($view); + ->setNavigation($nav) + ->appendChild($content) + ->addClass('white-background'); } private function buildConfigOptionsList(array $groups, $type) { assert_instances_of($groups, 'PhabricatorApplicationConfigOptions'); $list = new PHUIObjectItemListView(); + $list->setBig(true); $groups = msort($groups, 'getName'); foreach ($groups as $group) { if ($group->getGroup() == $type) { + $icon = id(new PHUIIconView()) + ->setIcon($group->getIcon()) + ->setBackground('bg-blue'); $item = id(new PHUIObjectItemView()) ->setHeader($group->getName()) ->setHref('/config/group/'.$group->getKey().'/') ->addAttribute($group->getDescription()) - ->setImageIcon($group->getIcon()); + ->setImageIcon($icon); $list->addItem($item); } } diff --git a/src/applications/config/controller/PhabricatorConfigModuleController.php b/src/applications/config/controller/PhabricatorConfigModuleController.php index 3a67a8cdb4..e10d70561b 100644 --- a/src/applications/config/controller/PhabricatorConfigModuleController.php +++ b/src/applications/config/controller/PhabricatorConfigModuleController.php @@ -18,20 +18,25 @@ final class PhabricatorConfigModuleController $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb($title); + $crumbs->setBorder(true); $nav = $this->buildSideNavView(); $nav->selectFilter('module/'.$key.'/'); - $view = id(new PHUITwoColumnView()) - ->setNavigation($nav) - ->setMainColumn(array( - $content, - )); + $header = id(new PHUIHeaderView()) + ->setHeader($title) + ->setProfileHeader(true); + + $content = id(new PhabricatorConfigPageView()) + ->setHeader($header) + ->setContent($content); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) - ->appendChild($view); + ->setNavigation($nav) + ->appendChild($content) + ->addClass('white-background'); } } diff --git a/src/applications/config/controller/PhabricatorConfigVersionController.php b/src/applications/config/controller/PhabricatorConfigVersionController.php index f7c2b7898f..15877ddbd7 100644 --- a/src/applications/config/controller/PhabricatorConfigVersionController.php +++ b/src/applications/config/controller/PhabricatorConfigVersionController.php @@ -10,24 +10,28 @@ final class PhabricatorConfigVersionController $crumbs = $this ->buildApplicationCrumbs() - ->addTextCrumb(pht('Configuration'), $this->getApplicationURI()) - ->addTextCrumb($title); + ->addTextCrumb($title) + ->setBorder(true); $versions = $this->renderModuleStatus($viewer); $nav = $this->buildSideNavView(); $nav->selectFilter('version/'); - $view = id(new PHUITwoColumnView()) - ->setNavigation($nav) - ->setMainColumn(array( - $versions, - )); + $header = id(new PHUIHeaderView()) + ->setHeader($title) + ->setProfileHeader(true); + + $content = id(new PhabricatorConfigPageView()) + ->setHeader($header) + ->setContent($versions); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) - ->appendChild($view); + ->setNavigation($nav) + ->appendChild($content) + ->addClass('white-background'); } @@ -39,11 +43,6 @@ final class PhabricatorConfigVersionController $version_property_list->addProperty($name, $version); } - $object_box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Version Information')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->addPropertyList($version_property_list); - $phabricator_root = dirname(phutil_get_library_root('phabricator')); $version_path = $phabricator_root.'/conf/local/VERSION'; if (Filesystem::pathExists($version_path)) { @@ -53,7 +52,7 @@ final class PhabricatorConfigVersionController $version_from_file); } - return $object_box; + return $version_property_list; } private function loadVersions(PhabricatorUser $viewer) { diff --git a/src/applications/config/controller/PhabricatorConfigWelcomeController.php b/src/applications/config/controller/PhabricatorConfigWelcomeController.php index 5fa4c65495..357f6f129a 100644 --- a/src/applications/config/controller/PhabricatorConfigWelcomeController.php +++ b/src/applications/config/controller/PhabricatorConfigWelcomeController.php @@ -11,20 +11,25 @@ final class PhabricatorConfigWelcomeController $title = pht('Installation Guide'); + $header = id(new PHUIHeaderView()) + ->setHeader($title) + ->setProfileHeader(true); + $crumbs = $this ->buildApplicationCrumbs() - ->addTextCrumb($title); + ->addTextCrumb($title) + ->setBorder(true); - $view = id(new PHUITwoColumnView()) - ->setNavigation($nav) - ->setMainColumn(array( - $this->buildWelcomeScreen($request), - )); + $content = id(new PhabricatorConfigPageView()) + ->setHeader($header) + ->setContent($this->buildWelcomeScreen($request)); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) - ->appendChild($view); + ->setNavigation($nav) + ->appendChild($content) + ->addClass('white-background'); } public function buildWelcomeScreen(AphrontRequest $request) { @@ -346,9 +351,6 @@ final class PhabricatorConfigWelcomeController $diffusion_user_guide, $diffusion_setup_guide)); - $header = id(new PHUIHeaderView()) - ->setHeader(pht('Welcome to Phabricator')); - $setup_header = new PHUIRemarkupView( $viewer, pht('=Setup and Configuration')); @@ -359,7 +361,6 @@ final class PhabricatorConfigWelcomeController $viewer, pht('=Quick Start Guide')); $document = id(new PHUIDocumentViewPro()) - ->setHeader($header) ->setFluid(true) ->appendChild($setup_header) ->appendChild($setup) @@ -369,9 +370,7 @@ final class PhabricatorConfigWelcomeController ->appendChild($quick); return id(new PHUIBoxView()) - ->setBorder(true) - ->appendChild($document) - ->addClass('mlb'); + ->appendChild($document); } private function newItem(AphrontRequest $request, $icon, $content) { diff --git a/src/applications/config/module/PhabricatorConfigCollectorsModule.php b/src/applications/config/module/PhabricatorConfigCollectorsModule.php index 4a121f483d..f865643e8e 100644 --- a/src/applications/config/module/PhabricatorConfigCollectorsModule.php +++ b/src/applications/config/module/PhabricatorConfigCollectorsModule.php @@ -48,7 +48,15 @@ final class PhabricatorConfigCollectorsModule extends PhabricatorConfigModule { ); } + $info = id(new PHUIInfoView()) + ->setSeverity(PHUIInfoView::SEVERITY_NOTICE) + ->appendChild(pht( + 'Collectors with custom policies are highlighted. Use '. + '%s to change retention policies.', + phutil_tag('tt', array(), 'bin/garbage set-policy'))); + $table = id(new AphrontTableView($rows)) + ->setNotice($info) ->setRowClasses($rowc) ->setHeaders( array( @@ -63,18 +71,7 @@ final class PhabricatorConfigCollectorsModule extends PhabricatorConfigModule { null, )); - $header = id(new PHUIHeaderView()) - ->setHeader(pht('Garbage Collectors')) - ->setSubheader( - pht( - 'Collectors with custom policies are highlighted. Use '. - '%s to change retention policies.', - phutil_tag('tt', array(), 'bin/garbage set-policy'))); - - return id(new PHUIObjectBoxView()) - ->setHeader($header) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setTable($table); + return $table; } } diff --git a/src/applications/config/module/PhabricatorConfigEdgeModule.php b/src/applications/config/module/PhabricatorConfigEdgeModule.php index 2791269811..f748fd5b0d 100644 --- a/src/applications/config/module/PhabricatorConfigEdgeModule.php +++ b/src/applications/config/module/PhabricatorConfigEdgeModule.php @@ -25,7 +25,7 @@ final class PhabricatorConfigEdgeModule extends PhabricatorConfigModule { ); } - $table = id(new AphrontTableView($rows)) + return id(new AphrontTableView($rows)) ->setHeaders( array( pht('Constant'), @@ -38,11 +38,6 @@ final class PhabricatorConfigEdgeModule extends PhabricatorConfigModule { null, 'pri wide', )); - - return id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Edge Types')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setTable($table); } } diff --git a/src/applications/config/module/PhabricatorConfigHTTPParameterTypesModule.php b/src/applications/config/module/PhabricatorConfigHTTPParameterTypesModule.php index 8ea911570b..1ef55e9620 100644 --- a/src/applications/config/module/PhabricatorConfigHTTPParameterTypesModule.php +++ b/src/applications/config/module/PhabricatorConfigHTTPParameterTypesModule.php @@ -16,13 +16,8 @@ final class PhabricatorConfigHTTPParameterTypesModule $types = AphrontHTTPParameterType::getAllTypes(); - $table = id(new PhabricatorHTTPParameterTypeTableView()) + return id(new PhabricatorHTTPParameterTypeTableView()) ->setHTTPParameterTypes($types); - - return id(new PHUIObjectBoxView()) - ->setHeaderText(pht('HTTP Parameter Types')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setTable($table); } } diff --git a/src/applications/config/module/PhabricatorConfigPHIDModule.php b/src/applications/config/module/PhabricatorConfigPHIDModule.php index 772ad3ecd5..f237cad2e7 100644 --- a/src/applications/config/module/PhabricatorConfigPHIDModule.php +++ b/src/applications/config/module/PhabricatorConfigPHIDModule.php @@ -51,7 +51,7 @@ final class PhabricatorConfigPHIDModule extends PhabricatorConfigModule { ); } - $table = id(new AphrontTableView($rows)) + return id(new AphrontTableView($rows)) ->setHeaders( array( pht('Constant'), @@ -70,11 +70,6 @@ final class PhabricatorConfigPHIDModule extends PhabricatorConfigModule { 'icon', 'wide', )); - - return id(new PHUIObjectBoxView()) - ->setHeaderText(pht('PHID Types')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setTable($table); } } diff --git a/src/applications/config/module/PhabricatorConfigRequestExceptionHandlerModule.php b/src/applications/config/module/PhabricatorConfigRequestExceptionHandlerModule.php index 27b338de6d..6ba08ea7a3 100644 --- a/src/applications/config/module/PhabricatorConfigRequestExceptionHandlerModule.php +++ b/src/applications/config/module/PhabricatorConfigRequestExceptionHandlerModule.php @@ -25,7 +25,7 @@ final class PhabricatorConfigRequestExceptionHandlerModule ); } - $table = id(new AphrontTableView($rows)) + return id(new AphrontTableView($rows)) ->setHeaders( array( pht('Priority'), @@ -38,11 +38,6 @@ final class PhabricatorConfigRequestExceptionHandlerModule 'pri', 'wide', )); - - return id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Exception Handlers')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setTable($table); } } diff --git a/src/applications/config/module/PhabricatorConfigSiteModule.php b/src/applications/config/module/PhabricatorConfigSiteModule.php index a1a7bab9d0..e8c0988826 100644 --- a/src/applications/config/module/PhabricatorConfigSiteModule.php +++ b/src/applications/config/module/PhabricatorConfigSiteModule.php @@ -24,7 +24,7 @@ final class PhabricatorConfigSiteModule extends PhabricatorConfigModule { ); } - $table = id(new AphrontTableView($rows)) + return id(new AphrontTableView($rows)) ->setHeaders( array( pht('Priority'), @@ -37,11 +37,6 @@ final class PhabricatorConfigSiteModule extends PhabricatorConfigModule { 'pri', 'wide', )); - - return id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Sites')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setTable($table); } } diff --git a/src/applications/config/view/PhabricatorConfigPageView.php b/src/applications/config/view/PhabricatorConfigPageView.php new file mode 100644 index 0000000000..9fed2d4f47 --- /dev/null +++ b/src/applications/config/view/PhabricatorConfigPageView.php @@ -0,0 +1,60 @@ +header = $header; + return $this; + } + + public function setContent($content) { + $this->content = $content; + return $this; + } + + public function setFooter($footer) { + $this->footer = $footer; + return $this; + } + + protected function getTagName() { + return 'div'; + } + + protected function getTagAttributes() { + require_celerity_resource('config-page-css'); + + $classes = array(); + $classes[] = 'config-page'; + + return array( + 'class' => implode(' ', $classes), + ); + } + + protected function getTagContent() { + + $header = null; + if ($this->header) { + $header = phutil_tag_div('config-page-header', $this->header); + } + + $content = null; + if ($this->content) { + $content = phutil_tag_div('config-page-content', $this->content); + } + + $footer = null; + if ($this->footer) { + $footer = phutil_tag_div('config-page-footer', $this->footer); + } + + return array($header, $content, $footer); + + } + +} diff --git a/src/applications/harbormaster/config/PhabricatorHarbormasterConfigOptions.php b/src/applications/harbormaster/config/PhabricatorHarbormasterConfigOptions.php deleted file mode 100644 index bab1e6de85..0000000000 --- a/src/applications/harbormaster/config/PhabricatorHarbormasterConfigOptions.php +++ /dev/null @@ -1,26 +0,0 @@ -setHeaders( array( pht('Order'), @@ -46,11 +46,6 @@ final class PhabricatorHovercardEngineExtensionModule 'wide pri', null, )); - - return id(new PHUIObjectBoxView()) - ->setHeaderText(pht('HovercardEngine Extensions')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setTable($table); } } diff --git a/src/applications/search/engineextension/PhabricatorSearchEngineExtensionModule.php b/src/applications/search/engineextension/PhabricatorSearchEngineExtensionModule.php index 45879edcb4..728ab1fc3a 100644 --- a/src/applications/search/engineextension/PhabricatorSearchEngineExtensionModule.php +++ b/src/applications/search/engineextension/PhabricatorSearchEngineExtensionModule.php @@ -29,7 +29,7 @@ final class PhabricatorSearchEngineExtensionModule ); } - $table = id(new AphrontTableView($rows)) + return id(new AphrontTableView($rows)) ->setHeaders( array( pht('Order'), @@ -46,11 +46,6 @@ final class PhabricatorSearchEngineExtensionModule 'wide pri', null, )); - - return id(new PHUIObjectBoxView()) - ->setHeaderText(pht('SearchEngine Extensions')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setTable($table); } } diff --git a/src/applications/search/index/PhabricatorFulltextEngineExtensionModule.php b/src/applications/search/index/PhabricatorFulltextEngineExtensionModule.php index c0061e9293..7b3c5b6cad 100644 --- a/src/applications/search/index/PhabricatorFulltextEngineExtensionModule.php +++ b/src/applications/search/index/PhabricatorFulltextEngineExtensionModule.php @@ -24,7 +24,7 @@ final class PhabricatorFulltextEngineExtensionModule ); } - $table = id(new AphrontTableView($rows)) + return id(new AphrontTableView($rows)) ->setHeaders( array( pht('Class'), @@ -36,10 +36,6 @@ final class PhabricatorFulltextEngineExtensionModule 'wide pri', )); - return id(new PHUIObjectBoxView()) - ->setHeaderText(pht('FulltextEngine Extensions')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setTable($table); } } diff --git a/src/applications/search/index/PhabricatorIndexEngineExtensionModule.php b/src/applications/search/index/PhabricatorIndexEngineExtensionModule.php index 712deef5ff..57ca63bc52 100644 --- a/src/applications/search/index/PhabricatorIndexEngineExtensionModule.php +++ b/src/applications/search/index/PhabricatorIndexEngineExtensionModule.php @@ -24,7 +24,7 @@ final class PhabricatorIndexEngineExtensionModule ); } - $table = id(new AphrontTableView($rows)) + return id(new AphrontTableView($rows)) ->setHeaders( array( pht('Class'), @@ -36,10 +36,6 @@ final class PhabricatorIndexEngineExtensionModule 'wide pri', )); - return id(new PHUIObjectBoxView()) - ->setHeaderText(pht('IndexEngine Extensions')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setTable($table); } } diff --git a/src/applications/system/engine/PhabricatorDestructionEngineExtensionModule.php b/src/applications/system/engine/PhabricatorDestructionEngineExtensionModule.php index a201e3da54..d7eb47a4bd 100644 --- a/src/applications/system/engine/PhabricatorDestructionEngineExtensionModule.php +++ b/src/applications/system/engine/PhabricatorDestructionEngineExtensionModule.php @@ -24,7 +24,7 @@ final class PhabricatorDestructionEngineExtensionModule ); } - $table = id(new AphrontTableView($rows)) + return id(new AphrontTableView($rows)) ->setHeaders( array( pht('Class'), @@ -36,10 +36,6 @@ final class PhabricatorDestructionEngineExtensionModule 'wide pri', )); - return id(new PHUIObjectBoxView()) - ->setHeaderText(pht('DestructionEngine Extensions')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setTable($table); } } diff --git a/src/applications/transactions/engineextension/PhabricatorEditEngineExtensionModule.php b/src/applications/transactions/engineextension/PhabricatorEditEngineExtensionModule.php index 67bcfae6d9..a7211989ef 100644 --- a/src/applications/transactions/engineextension/PhabricatorEditEngineExtensionModule.php +++ b/src/applications/transactions/engineextension/PhabricatorEditEngineExtensionModule.php @@ -28,7 +28,7 @@ final class PhabricatorEditEngineExtensionModule ); } - $table = id(new AphrontTableView($rows)) + return id(new AphrontTableView($rows)) ->setHeaders( array( pht('Priority'), @@ -44,10 +44,6 @@ final class PhabricatorEditEngineExtensionModule null, )); - return id(new PHUIObjectBoxView()) - ->setHeaderText(pht('EditEngine Extensions')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setTable($table); } } diff --git a/src/infrastructure/contentsource/PhabricatorContentSourceModule.php b/src/infrastructure/contentsource/PhabricatorContentSourceModule.php index 2eed665eac..54e9dbe736 100644 --- a/src/infrastructure/contentsource/PhabricatorContentSourceModule.php +++ b/src/infrastructure/contentsource/PhabricatorContentSourceModule.php @@ -27,7 +27,7 @@ final class PhabricatorContentSourceModule ); } - $table = id(new AphrontTableView($rows)) + return id(new AphrontTableView($rows)) ->setHeaders( array( pht('Key'), @@ -43,10 +43,6 @@ final class PhabricatorContentSourceModule 'wide', )); - return id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Content Sources')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setTable($table); } } diff --git a/webroot/rsrc/css/application/base/standard-page-view.css b/webroot/rsrc/css/application/base/standard-page-view.css index d9f6cb8ea3..e5d50dc825 100644 --- a/webroot/rsrc/css/application/base/standard-page-view.css +++ b/webroot/rsrc/css/application/base/standard-page-view.css @@ -17,6 +17,10 @@ clear: both; } +body.white-background { + background: #fff; +} + .phabricator-standard-page-footer { text-align: right; margin: 44px 16px 16px; diff --git a/webroot/rsrc/css/application/config/config-page.css b/webroot/rsrc/css/application/config/config-page.css new file mode 100644 index 0000000000..a46ead7a2c --- /dev/null +++ b/webroot/rsrc/css/application/config/config-page.css @@ -0,0 +1,59 @@ +/** + * @provides config-page-css + */ + +.config-page-header { + margin: 28px 24px 0; + padding-bottom: 28px; + border-bottom: 1px solid {$thinblueborder}; +} + +.config-page-header .phui-profile-header { + padding: 0; +} + +.config-page-header .phui-profile-header.phui-header-shell .phui-header-header { + font-size: 20px; +} + + +.config-page-content { + margin: 0 24px; +} + +.device-desktop .config-page-content .phui-object-item-list-view { + padding-left: 0; + padding-right: 0; +} + +.device-desktop .config-page-content .phui-document-fluid .phui-document-view { + padding: 16px 0; + margin: 0; +} + +.config-page-content .aphront-table-view { + border: none; +} + +.config-page-property { + padding-top: 4px; + border-bottom: 1px solid {$thinblueborder}; +} + +.config-page-content .aphront-table-notice { + padding: 0; +} + +.config-page-content .aphront-table-notice .phui-info-view { + margin-left: 0; + margin-right: 0; +} + +.config-page-content .aphront-table-wrap + .aphront-table-wrap { + margin-top: 20px; + border-top: 1px solid {$thinblueborder}; +} + +.config-page-content .phui-box.phui-box-blue-property { + margin-top: 16px; +} diff --git a/webroot/rsrc/css/font/phui-font-icon-base.css b/webroot/rsrc/css/font/phui-font-icon-base.css index a1b0d61d0d..60c323d69d 100644 --- a/webroot/rsrc/css/font/phui-font-icon-base.css +++ b/webroot/rsrc/css/font/phui-font-icon-base.css @@ -159,6 +159,9 @@ .phui-icon-view.bg-bluegrey { background-color: {$bluetext}; } +.phui-icon-view.bg-grey { + background-color: {$lightgreytext}; +} .phui-icon-view.bg-red { background-color: {$red}; } diff --git a/webroot/rsrc/css/phui/phui-object-item-list-view.css b/webroot/rsrc/css/phui/phui-object-item-list-view.css index b0d95286f7..ef5fab6c3d 100644 --- a/webroot/rsrc/css/phui/phui-object-item-list-view.css +++ b/webroot/rsrc/css/phui/phui-object-item-list-view.css @@ -447,16 +447,16 @@ ul.phui-object-item-icons { */ -.phui-object-item-disabled .phui-object-item-link, -.phui-object-item-disabled .phui-object-item-link a { +.phui-object-item.phui-object-item-disabled .phui-object-item-link, +.phui-object-item.phui-object-item-disabled .phui-object-item-link a { color: {$lightgreytext}; } -.phui-object-item-disabled .phui-object-item-frame { +.phui-object-item.phui-object-item-disabled .phui-object-item-frame { border-color: #d7d7d7; } -.phui-object-item-disabled .phui-object-item-objname { +.phui-object-item.phui-object-item-disabled .phui-object-item-objname { color: {$greytext}; text-decoration: line-through; } @@ -771,3 +771,7 @@ ul.phui-object-item-list-view .phui-object-item-selected .device-desktop .phui-object-list-big .phui-object-item { margin-bottom: 8px; } + +.device-desktop .phui-object-list-big .phui-object-item-frame:hover { + +} From 9422596ebf2fca0495a60288af5ac3d8f097a982 Mon Sep 17 00:00:00 2001 From: Josh Cox Date: Tue, 30 Aug 2016 00:41:47 +0000 Subject: [PATCH 06/25] Converted Paste language selection to a typeahead Summary: Fixes T11532. The language selection for pastes is now a typeahead that is backed by `pygments.dropdown-choices`. There is still a bit of weirdness around making "auto-detection" the default state. To actually select a different language, you first need to remove the "auto detect" option that is pre-populated in a new paste. Other than that, it works as intended. Test Plan: Create a new paste with a file extension that can be auto-detected. Created a new paste and manually selected the language Edited a paste and changed the language. Reviewers: #blessed_reviewers, epriestley Reviewed By: #blessed_reviewers, epriestley Subscribers: Korvin, epriestley, yelirekim Maniphest Tasks: T11532 Differential Revision: https://secure.phabricator.com/D16463 --- .../20160829.pastebin.01.language.sql | 3 ++ .../20160829.pastebin.02.language.sql | 2 + src/__phutil_library_map__.php | 2 + .../editor/PhabricatorPasteEditEngine.php | 10 ++--- .../paste/storage/PhabricatorPaste.php | 3 +- .../PasteLanguageSelectDatasource.php | 42 +++++++++++++++++++ 6 files changed, 53 insertions(+), 9 deletions(-) create mode 100644 resources/sql/autopatches/20160829.pastebin.01.language.sql create mode 100644 resources/sql/autopatches/20160829.pastebin.02.language.sql create mode 100644 src/applications/paste/typeahead/PasteLanguageSelectDatasource.php diff --git a/resources/sql/autopatches/20160829.pastebin.01.language.sql b/resources/sql/autopatches/20160829.pastebin.01.language.sql new file mode 100644 index 0000000000..b29a9d0bc5 --- /dev/null +++ b/resources/sql/autopatches/20160829.pastebin.01.language.sql @@ -0,0 +1,3 @@ +/* Allow this column to be nullable (null means we'll try to autodetect) */ +ALTER TABLE {$NAMESPACE}_pastebin.pastebin_paste MODIFY language VARCHAR(64) + COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20160829.pastebin.02.language.sql b/resources/sql/autopatches/20160829.pastebin.02.language.sql new file mode 100644 index 0000000000..b6876c6c69 --- /dev/null +++ b/resources/sql/autopatches/20160829.pastebin.02.language.sql @@ -0,0 +1,2 @@ +UPDATE {$NAMESPACE}_pastebin.pastebin_paste SET language = NULL + WHERE language = ''; diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index ac0a35e75e..831d22a1a5 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1732,6 +1732,7 @@ phutil_register_library_map(array( 'PasteEditConduitAPIMethod' => 'applications/paste/conduit/PasteEditConduitAPIMethod.php', 'PasteEmbedView' => 'applications/paste/view/PasteEmbedView.php', 'PasteInfoConduitAPIMethod' => 'applications/paste/conduit/PasteInfoConduitAPIMethod.php', + 'PasteLanguageSelectDatasource' => 'applications/paste/typeahead/PasteLanguageSelectDatasource.php', 'PasteMailReceiver' => 'applications/paste/mail/PasteMailReceiver.php', 'PasteQueryConduitAPIMethod' => 'applications/paste/conduit/PasteQueryConduitAPIMethod.php', 'PasteReplyHandler' => 'applications/paste/mail/PasteReplyHandler.php', @@ -6401,6 +6402,7 @@ phutil_register_library_map(array( 'PasteEditConduitAPIMethod' => 'PhabricatorEditEngineAPIMethod', 'PasteEmbedView' => 'AphrontView', 'PasteInfoConduitAPIMethod' => 'PasteConduitAPIMethod', + 'PasteLanguageSelectDatasource' => 'PhabricatorTypeaheadDatasource', 'PasteMailReceiver' => 'PhabricatorObjectMailReceiver', 'PasteQueryConduitAPIMethod' => 'PasteConduitAPIMethod', 'PasteReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler', diff --git a/src/applications/paste/editor/PhabricatorPasteEditEngine.php b/src/applications/paste/editor/PhabricatorPasteEditEngine.php index 1bad86da15..5578a7c9f6 100644 --- a/src/applications/paste/editor/PhabricatorPasteEditEngine.php +++ b/src/applications/paste/editor/PhabricatorPasteEditEngine.php @@ -63,10 +63,6 @@ final class PhabricatorPasteEditEngine } protected function buildCustomEditFields($object) { - $langs = array( - '' => pht('(Detect From Filename in Title)'), - ) + PhabricatorEnv::getEnvConfig('pygments.dropdown-choices'); - return array( id(new PhabricatorTextEditField()) ->setKey('title') @@ -76,14 +72,14 @@ final class PhabricatorPasteEditEngine ->setConduitDescription(pht('Retitle the paste.')) ->setConduitTypeDescription(pht('New paste title.')) ->setValue($object->getTitle()), - id(new PhabricatorSelectEditField()) + id(new PhabricatorDatasourceEditField()) ->setKey('language') ->setLabel(pht('Language')) ->setTransactionType( PhabricatorPasteLanguageTransaction::TRANSACTIONTYPE) ->setAliases(array('lang')) ->setIsCopyable(true) - ->setOptions($langs) + ->setDatasource(new PasteLanguageSelectDatasource()) ->setDescription( pht( 'Language used for syntax highlighting. By default, inferred '. @@ -91,7 +87,7 @@ final class PhabricatorPasteEditEngine ->setConduitDescription( pht('Change language used for syntax highlighting.')) ->setConduitTypeDescription(pht('New highlighting language.')) - ->setValue($object->getLanguage()), + ->setSingleValue($object->getLanguage()), id(new PhabricatorTextAreaEditField()) ->setKey('text') ->setLabel(pht('Text')) diff --git a/src/applications/paste/storage/PhabricatorPaste.php b/src/applications/paste/storage/PhabricatorPaste.php index 0e8f497936..19aabcf8e0 100644 --- a/src/applications/paste/storage/PhabricatorPaste.php +++ b/src/applications/paste/storage/PhabricatorPaste.php @@ -42,7 +42,6 @@ final class PhabricatorPaste extends PhabricatorPasteDAO return id(new PhabricatorPaste()) ->setTitle('') - ->setLanguage('') ->setStatus(self::STATUS_ACTIVE) ->setAuthorPHID($actor->getPHID()) ->setViewPolicy($view_policy) @@ -72,7 +71,7 @@ final class PhabricatorPaste extends PhabricatorPasteDAO self::CONFIG_COLUMN_SCHEMA => array( 'status' => 'text32', 'title' => 'text255', - 'language' => 'text64', + 'language' => 'text64?', 'mailKey' => 'bytes20', 'parentPHID' => 'phid?', diff --git a/src/applications/paste/typeahead/PasteLanguageSelectDatasource.php b/src/applications/paste/typeahead/PasteLanguageSelectDatasource.php new file mode 100644 index 0000000000..45c36db968 --- /dev/null +++ b/src/applications/paste/typeahead/PasteLanguageSelectDatasource.php @@ -0,0 +1,42 @@ +buildResults(); + return $this->filterResultsAgainstTokens($results); + } + + + protected function renderSpecialTokens(array $values) { + return $this->renderTokensFromResults($this->buildResults(), $values); + } + + private function buildResults() { + $results = array(); + $languages = PhabricatorEnv::getEnvConfig('pygments.dropdown-choices'); + + foreach ($languages as $value => $name) { + $result = id(new PhabricatorTypeaheadResult()) + ->setPHID($value) + ->setName($name); + + $results[$value] = $result; + } + return $results; + } + +} From b75cea55a782d6a9d9969c82027731f7fe88b1b9 Mon Sep 17 00:00:00 2001 From: Chad Little Date: Mon, 29 Aug 2016 20:09:43 -0700 Subject: [PATCH 07/25] Fix search results with tables, fatals in Phortune Summary: Previously we collapsed all table search results, but the new UI doesn't need it. Remove unused methods and fix CSS. Test Plan: Legalpad Signatures, Phortune Accounts. Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D16469 --- resources/celerity/map.php | 4 ++-- .../controller/PhortuneAccountListController.php | 4 ++-- .../controller/PhortuneProductListController.php | 2 +- .../phortune/query/PhortuneMerchantSearchEngine.php | 2 +- .../PhabricatorApplicationSearchController.php | 3 --- .../view/PhabricatorApplicationSearchResultView.php | 10 ---------- .../css/application/search/application-search-view.css | 5 +++++ 7 files changed, 11 insertions(+), 19 deletions(-) diff --git a/resources/celerity/map.php b/resources/celerity/map.php index 5597ea303d..98cf103b11 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -100,7 +100,7 @@ return array( 'rsrc/css/application/releeph/releeph-preview-branch.css' => 'b7a6f4a5', 'rsrc/css/application/releeph/releeph-request-differential-create-dialog.css' => '8d8b92cd', 'rsrc/css/application/releeph/releeph-request-typeahead.css' => '667a48ae', - 'rsrc/css/application/search/application-search-view.css' => 'b3e0e5ef', + 'rsrc/css/application/search/application-search-view.css' => 'be6454ec', 'rsrc/css/application/search/search-results.css' => '7dea472c', 'rsrc/css/application/slowvote/slowvote.css' => 'a94b7230', 'rsrc/css/application/tokens/tokens.css' => '3d0f239e', @@ -542,7 +542,7 @@ return array( 'aphront-tokenizer-control-css' => '056da01b', 'aphront-tooltip-css' => '1a07aea8', 'aphront-typeahead-control-css' => 'd4f16145', - 'application-search-view-css' => 'b3e0e5ef', + 'application-search-view-css' => 'be6454ec', 'auth-css' => '0877ed6e', 'bulk-job-css' => 'df9c1d4a', 'changeset-view-manager' => 'a2828756', diff --git a/src/applications/phortune/controller/PhortuneAccountListController.php b/src/applications/phortune/controller/PhortuneAccountListController.php index 4b7521ceaa..d95fd709d5 100644 --- a/src/applications/phortune/controller/PhortuneAccountListController.php +++ b/src/applications/phortune/controller/PhortuneAccountListController.php @@ -39,7 +39,7 @@ final class PhortuneAccountListController extends PhortuneController { ->setHeader($account->getName()) ->setHref($this->getApplicationURI($account->getID().'/')) ->setObject($account) - ->setIcon('fa-credit-card'); + ->setImageIcon('fa-credit-card'); $payment_list->addItem($item); } @@ -71,7 +71,7 @@ final class PhortuneAccountListController extends PhortuneController { ->setHeader($merchant->getName()) ->setHref($this->getApplicationURI('/merchant/'.$merchant->getID().'/')) ->setObject($merchant) - ->setIcon('fa-bank'); + ->setImageIcon('fa-bank'); $merchant_list->addItem($item); } diff --git a/src/applications/phortune/controller/PhortuneProductListController.php b/src/applications/phortune/controller/PhortuneProductListController.php index eeb594d650..ee84581ae1 100644 --- a/src/applications/phortune/controller/PhortuneProductListController.php +++ b/src/applications/phortune/controller/PhortuneProductListController.php @@ -41,7 +41,7 @@ final class PhortuneProductListController extends PhabricatorController { ->setHeader($product->getProductName()) ->setHref($view_uri) ->addAttribute($price->formatForDisplay()) - ->setIcon('fa-gift'); + ->setImageIcon('fa-gift'); $product_list->addItem($item); } diff --git a/src/applications/phortune/query/PhortuneMerchantSearchEngine.php b/src/applications/phortune/query/PhortuneMerchantSearchEngine.php index 1806af371e..d37c1455b3 100644 --- a/src/applications/phortune/query/PhortuneMerchantSearchEngine.php +++ b/src/applications/phortune/query/PhortuneMerchantSearchEngine.php @@ -74,7 +74,7 @@ final class PhortuneMerchantSearchEngine ->setHeader($merchant->getName()) ->setHref('/phortune/merchant/'.$merchant->getID().'/') ->setObject($merchant) - ->setIcon('fa-bank'); + ->setImageIcon('fa-bank'); $list->addItem($item); } diff --git a/src/applications/search/controller/PhabricatorApplicationSearchController.php b/src/applications/search/controller/PhabricatorApplicationSearchController.php index 164e9aabbc..a463e50471 100644 --- a/src/applications/search/controller/PhabricatorApplicationSearchController.php +++ b/src/applications/search/controller/PhabricatorApplicationSearchController.php @@ -270,9 +270,6 @@ final class PhabricatorApplicationSearchController if ($list->getContent()) { $box->appendChild($list->getContent()); } - if ($list->getCollapsed()) { - $box->setCollapsed(true); - } $result_header = $list->getHeader(); if ($result_header) { diff --git a/src/applications/search/view/PhabricatorApplicationSearchResultView.php b/src/applications/search/view/PhabricatorApplicationSearchResultView.php index 5bcfdcf675..1c3f4aad65 100644 --- a/src/applications/search/view/PhabricatorApplicationSearchResultView.php +++ b/src/applications/search/view/PhabricatorApplicationSearchResultView.php @@ -12,7 +12,6 @@ final class PhabricatorApplicationSearchResultView extends Phobject { private $content = null; private $infoView = null; private $actions = array(); - private $collapsed = null; private $noDataString; private $crumbs = array(); private $header; @@ -70,15 +69,6 @@ final class PhabricatorApplicationSearchResultView extends Phobject { return $this->actions; } - public function setCollapsed($collapsed) { - $this->collapsed = $collapsed; - return $this; - } - - public function getCollapsed() { - return $this->collapsed; - } - public function setNoDataString($nodata) { $this->noDataString = $nodata; return $this; diff --git a/webroot/rsrc/css/application/search/application-search-view.css b/webroot/rsrc/css/application/search/application-search-view.css index 24ee18c847..4a573f5111 100644 --- a/webroot/rsrc/css/application/search/application-search-view.css +++ b/webroot/rsrc/css/application/search/application-search-view.css @@ -16,6 +16,11 @@ border-bottom: 1px solid {$thinblueborder}; } +.application-search-view .phui-object-box.phui-object-box-collapsed + .phui-header-shell { + padding: 20px 8px; +} + .application-search-results .phui-profile-header.phui-header-shell .phui-header-header { font-size: 20px; From f2f896c761a2415607e45b6d5524ae40d125f652 Mon Sep 17 00:00:00 2001 From: Josh Cox Date: Mon, 29 Aug 2016 17:58:49 -0400 Subject: [PATCH 08/25] Removed all instances of getIconURI Summary: Fixes T11541. `PhabricatorApplication::getIconURI()` has been returning only null for a while (I assume in preparation to remove it). I removed the method and all the remaining call sites. Test Plan: Removed the method and then clicked around. Things didn't explode! Reviewers: #blessed_reviewers, epriestley Reviewed By: #blessed_reviewers, epriestley Subscribers: epriestley, yelirekim Maniphest Tasks: T11541 Differential Revision: https://secure.phabricator.com/D16470 --- src/applications/base/PhabricatorApplication.php | 4 ---- .../typeahead/PhabricatorApplicationDatasource.php | 1 - .../meta/view/PhabricatorApplicationLaunchView.php | 11 +++-------- 3 files changed, 3 insertions(+), 13 deletions(-) diff --git a/src/applications/base/PhabricatorApplication.php b/src/applications/base/PhabricatorApplication.php index 82b094c311..b45b1be102 100644 --- a/src/applications/base/PhabricatorApplication.php +++ b/src/applications/base/PhabricatorApplication.php @@ -151,10 +151,6 @@ abstract class PhabricatorApplication return $this->getBaseURI().ltrim($path, '/'); } - public function getIconURI() { - return null; - } - public function getIcon() { return 'fa-puzzle-piece'; } diff --git a/src/applications/meta/typeahead/PhabricatorApplicationDatasource.php b/src/applications/meta/typeahead/PhabricatorApplicationDatasource.php index 7dddeda53b..2a78afa655 100644 --- a/src/applications/meta/typeahead/PhabricatorApplicationDatasource.php +++ b/src/applications/meta/typeahead/PhabricatorApplicationDatasource.php @@ -36,7 +36,6 @@ final class PhabricatorApplicationDatasource ->setPriorityString($application->getName()) ->setDisplayName($application->getName()) ->setDisplayType($application->getShortDescription()) - ->setImageuRI($application->getIconURI()) ->setPriorityType('apps') ->setImageSprite('phabricator-search-icon '.$img) ->setIcon($application->getIcon()) diff --git a/src/applications/meta/view/PhabricatorApplicationLaunchView.php b/src/applications/meta/view/PhabricatorApplicationLaunchView.php index 95c3777d4e..4f337f013c 100644 --- a/src/applications/meta/view/PhabricatorApplicationLaunchView.php +++ b/src/applications/meta/view/PhabricatorApplicationLaunchView.php @@ -109,14 +109,9 @@ final class PhabricatorApplicationLaunchView extends AphrontTagView { $classes = array(); $classes[] = 'phabricator-application-launch-icon'; $styles = array(); - - if ($application->getIconURI()) { - $styles[] = 'background-image: url('.$application->getIconURI().')'; - } else { - $classes[] = $application->getIcon(); - $classes[] = 'phui-icon-view'; - $classes[] = 'phui-font-fa'; - } + $classes[] = $application->getIcon(); + $classes[] = 'phui-icon-view'; + $classes[] = 'phui-font-fa'; $icon = phutil_tag( 'span', From 024a6693d3b9af9396364045aaa5d777d9a0924f Mon Sep 17 00:00:00 2001 From: epriestley Date: Tue, 30 Aug 2016 07:11:07 -0700 Subject: [PATCH 09/25] Implement PhabricatorApplicationTransactionInterface on PhortunePaymentProviderConfig Summary: Fixes T11556. This was just missing an `implements ...`, which became necessary at some point even for classes that don't use much of the beahvior (ModularTransactions?). Test Plan: Created a new test payment provider on a Phortune merchant. Reviewers: chad Reviewed By: chad Maniphest Tasks: T11556 Differential Revision: https://secure.phabricator.com/D16471 --- src/__phutil_library_map__.php | 1 + .../storage/PhortunePaymentProviderConfig.php | 27 ++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 831d22a1a5..0712bb72da 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -9219,6 +9219,7 @@ phutil_register_library_map(array( 'PhortunePaymentProviderConfig' => array( 'PhortuneDAO', 'PhabricatorPolicyInterface', + 'PhabricatorApplicationTransactionInterface', ), 'PhortunePaymentProviderConfigEditor' => 'PhabricatorApplicationTransactionEditor', 'PhortunePaymentProviderConfigQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', diff --git a/src/applications/phortune/storage/PhortunePaymentProviderConfig.php b/src/applications/phortune/storage/PhortunePaymentProviderConfig.php index 1b516cadb4..b358b51d0b 100644 --- a/src/applications/phortune/storage/PhortunePaymentProviderConfig.php +++ b/src/applications/phortune/storage/PhortunePaymentProviderConfig.php @@ -1,7 +1,9 @@ Date: Tue, 30 Aug 2016 08:52:46 -0700 Subject: [PATCH 10/25] Add a summary view of all repository errors to the repository cluster screen Summary: Ref T11559. This makes managing large numbers of repositories slightly easier. Test Plan: {F1796119} Reviewers: chad Reviewed By: chad Maniphest Tasks: T11559 Differential Revision: https://secure.phabricator.com/D16472 --- ...torConfigClusterRepositoriesController.php | 73 ++++++++++++++++++- .../PhabricatorRepositoryStatusMessage.php | 11 +++ 2 files changed, 83 insertions(+), 1 deletion(-) diff --git a/src/applications/config/controller/PhabricatorConfigClusterRepositoriesController.php b/src/applications/config/controller/PhabricatorConfigClusterRepositoriesController.php index 2486712022..a61f0e3535 100644 --- a/src/applications/config/controller/PhabricatorConfigClusterRepositoriesController.php +++ b/src/applications/config/controller/PhabricatorConfigClusterRepositoriesController.php @@ -27,10 +27,15 @@ final class PhabricatorConfigClusterRepositoriesController ->setBorder(true); $repository_status = $this->buildClusterRepositoryStatus(); + $repository_errors = $this->buildClusterRepositoryErrors(); $content = id(new PhabricatorConfigPageView()) ->setHeader($header) - ->setContent($repository_status); + ->setContent( + array( + $repository_status, + $repository_errors, + )); return $this->newPage() ->setTitle($title) @@ -338,4 +343,70 @@ final class PhabricatorConfigClusterRepositoriesController } + private function buildClusterRepositoryErrors() { + $viewer = $this->getViewer(); + + $messages = id(new PhabricatorRepositoryStatusMessage())->loadAllWhere( + 'statusCode IN (%Ls)', + array( + PhabricatorRepositoryStatusMessage::CODE_ERROR, + )); + + $repository_ids = mpull($messages, 'getRepositoryID'); + if ($repository_ids) { + // NOTE: We're bypassing policies when loading repositories because we + // want to show errors exist even if the viewer can't see the repository. + // We use handles to describe the repository below, so the viewer won't + // actually be able to see any particulars if they can't see the + // repository. + $repositories = id(new PhabricatorRepositoryQuery()) + ->setViewer(PhabricatorUser::getOmnipotentUser()) + ->withIDs($repository_ids) + ->execute(); + $repositories = mpull($repositories, null, 'getID'); + } + + $rows = array(); + foreach ($messages as $message) { + $repository = idx($repositories, $message->getRepositoryID()); + if (!$repository) { + continue; + } + + if (!$repository->isTracked()) { + continue; + } + + $icon = id(new PHUIIconView()) + ->setIcon('fa-exclamation-triangle red'); + + $rows[] = array( + $icon, + $viewer->renderHandle($repository->getPHID()), + phutil_tag( + 'a', + array( + 'href' => $repository->getPathURI('manage/status/'), + ), + $message->getStatusTypeName()), + ); + } + + return id(new AphrontTableView($rows)) + ->setNoDataString( + pht('No active repositories have outstanding errors.')) + ->setHeaders( + array( + null, + pht('Repository'), + pht('Error'), + )) + ->setColumnClasses( + array( + null, + 'pri', + 'wide', + )); + } + } diff --git a/src/applications/repository/storage/PhabricatorRepositoryStatusMessage.php b/src/applications/repository/storage/PhabricatorRepositoryStatusMessage.php index eb5bb9688c..79d75cc50c 100644 --- a/src/applications/repository/storage/PhabricatorRepositoryStatusMessage.php +++ b/src/applications/repository/storage/PhabricatorRepositoryStatusMessage.php @@ -40,4 +40,15 @@ final class PhabricatorRepositoryStatusMessage return idx($this->parameters, $key, $default); } + public function getStatusTypeName() { + $names = array( + self::TYPE_INIT => pht('Error While Initializing Repository'), + self::TYPE_FETCH => pht('Error While Fetching Changes'), + self::TYPE_NEEDS_UPDATE => pht('Repository Needs Update'), + ); + + $type = $this->getStatusType(); + return idx($names, $type, $type); + } + } From f5537fdff69fab977b1e5d296ea5941381cd9362 Mon Sep 17 00:00:00 2001 From: Josh Cox Date: Mon, 29 Aug 2016 22:00:27 -0400 Subject: [PATCH 11/25] Fix the feed line items for autodetect paste languages Summary: Fixes T11555. Previously changing the extension of a paste wouldn't change the syntax highlight language. Now it does. Also, feed items involving autodetect weren't rendering in a readable way. Test Plan: Created a paste named `paste.php` and let it autodetect language. Then edited the paste to be named paste.rainbow. It should now be highlighted in raiinnboow Reviewers: #blessed_reviewers, epriestley Reviewed By: #blessed_reviewers, epriestley Subscribers: Korvin, epriestley, yelirekim Maniphest Tasks: T11555 Differential Revision: https://secure.phabricator.com/D16474 --- .../paste/query/PhabricatorPasteQuery.php | 2 ++ .../PhabricatorPasteLanguageTransaction.php | 16 ++++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/applications/paste/query/PhabricatorPasteQuery.php b/src/applications/paste/query/PhabricatorPasteQuery.php index 2bc9b35168..0d8b1542b7 100644 --- a/src/applications/paste/query/PhabricatorPasteQuery.php +++ b/src/applications/paste/query/PhabricatorPasteQuery.php @@ -173,6 +173,7 @@ final class PhabricatorPasteQuery 'P'.$paste->getID(), $paste->getFilePHID(), $paste->getLanguage(), + PhabricatorHash::digestForIndex($paste->getTitle()), )); } @@ -184,6 +185,7 @@ final class PhabricatorPasteQuery $paste->getFilePHID(), $paste->getLanguage(), 'snippet', + PhabricatorHash::digestForIndex($paste->getTitle()), )); } diff --git a/src/applications/paste/xaction/PhabricatorPasteLanguageTransaction.php b/src/applications/paste/xaction/PhabricatorPasteLanguageTransaction.php index 3497288b74..a0c060d430 100644 --- a/src/applications/paste/xaction/PhabricatorPasteLanguageTransaction.php +++ b/src/applications/paste/xaction/PhabricatorPasteLanguageTransaction.php @@ -13,12 +13,20 @@ final class PhabricatorPasteLanguageTransaction $object->setLanguage($value); } + private function renderLanguageValue($value) { + if (!strlen($value)) { + return $this->renderValue(pht('autodetect')); + } else { + return $this->renderValue($value); + } + } + public function getTitle() { return pht( "%s updated the paste's language from %s to %s.", $this->renderAuthor(), - $this->renderOldValue(), - $this->renderNewValue()); + $this->renderLanguageValue($this->getOldValue()), + $this->renderLanguageValue($this->getNewValue())); } public function getTitleForFeed() { @@ -26,8 +34,8 @@ final class PhabricatorPasteLanguageTransaction '%s updated the language for %s from %s to %s.', $this->renderAuthor(), $this->renderObject(), - $this->renderOldValue(), - $this->renderNewValue()); + $this->renderLanguageValue($this->getOldValue()), + $this->renderLanguageValue($this->getNewValue())); } } From 7ce58539368524f11fa4bbf29cdd20a366d942a8 Mon Sep 17 00:00:00 2001 From: Josh Cox Date: Mon, 29 Aug 2016 20:41:14 -0400 Subject: [PATCH 12/25] Start actually showing the phurl urls to users Summary: Fixes T10679. Added a 'short url' field to the phurl link page and changed the "view url" button to link to the shortened version Test Plan: Create a phurl link (or navigate to an existing one) and note that there is now a field for "Short URL". Also verified that the "Visit URL" button in the top right still works as intended Reviewers: epriestley, #blessed_reviewers Reviewed By: epriestley, #blessed_reviewers Subscribers: Korvin, epriestley, yelirekim Maniphest Tasks: T10679 Differential Revision: https://secure.phabricator.com/D16473 --- .../controller/PhabricatorPhurlURLViewController.php | 6 +++++- .../phurl/storage/PhabricatorPhurlURL.php | 12 ++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/applications/phurl/controller/PhabricatorPhurlURLViewController.php b/src/applications/phurl/controller/PhabricatorPhurlURLViewController.php index 1c9a66f237..4e79670143 100644 --- a/src/applications/phurl/controller/PhabricatorPhurlURLViewController.php +++ b/src/applications/phurl/controller/PhabricatorPhurlURLViewController.php @@ -86,7 +86,7 @@ final class PhabricatorPhurlURLViewController ->setTag('a') ->setText(pht('Visit URL')) ->setIcon('fa-external-link') - ->setHref("u/{$id}") + ->setHref($url->getRedirectURI()) ->setDisabled(!$url->isValid()); $header = id(new PHUIHeaderView()) @@ -129,6 +129,10 @@ final class PhabricatorPhurlURLViewController $properties = id(new PHUIPropertyListView()) ->setUser($viewer); + $properties->addProperty( + pht('Short URL'), + $url->getRedirectURI()); + $properties->addProperty( pht('Original URL'), $url->getLongURL()); diff --git a/src/applications/phurl/storage/PhabricatorPhurlURL.php b/src/applications/phurl/storage/PhabricatorPhurlURL.php index 19d5968b0c..db82e20baf 100644 --- a/src/applications/phurl/storage/PhabricatorPhurlURL.php +++ b/src/applications/phurl/storage/PhabricatorPhurlURL.php @@ -99,10 +99,18 @@ final class PhabricatorPhurlURL extends PhabricatorPhurlDAO public function getRedirectURI() { if (strlen($this->getAlias())) { - return '/u/'.$this->getAlias(); + $path = '/u/'.$this->getAlias(); } else { - return '/u/'.$this->getID(); + $path = '/u/'.$this->getID(); } + $short_domain = PhabricatorEnv::getEnvConfig('phurl.short-uri'); + if (!$short_domain) { + return $path; + } + + $uri = new PhutilURI($short_domain); + $uri->setPath($path); + return (string)$uri; } /* -( PhabricatorPolicyInterface )----------------------------------------- */ From eac8171a63dfe3d34bfba74e2c55f8f3b40e0b84 Mon Sep 17 00:00:00 2001 From: Chad Little Date: Tue, 30 Aug 2016 12:53:09 -0700 Subject: [PATCH 13/25] Add some icons/color to Config Settings UI Summary: This adds status icons, locked, hidden, editable, customized, to the list of options in config. Makes it easier to read and assertain state. Test Plan: View a hidden, customized, editable, and locked. {F1796320} Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D16475 --- resources/celerity/map.php | 6 ++-- .../PhabricatorConfigGroupController.php | 31 ++++++++++++------- src/view/phui/PHUIObjectItemView.php | 3 ++ .../css/phui/phui-object-item-list-view.css | 13 ++++++++ 4 files changed, 38 insertions(+), 15 deletions(-) diff --git a/resources/celerity/map.php b/resources/celerity/map.php index 98cf103b11..9cdac5d965 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -7,7 +7,7 @@ */ return array( 'names' => array( - 'core.pkg.css' => 'ffbade6c', + 'core.pkg.css' => 'ad6a3591', 'core.pkg.js' => '2b8af4e4', 'darkconsole.pkg.js' => 'e7393ebb', 'differential.pkg.css' => '3fb7f532', @@ -148,7 +148,7 @@ return array( 'rsrc/css/phui/phui-info-view.css' => '28efab79', 'rsrc/css/phui/phui-list.css' => '9da2aa00', 'rsrc/css/phui/phui-object-box.css' => '6b487c57', - 'rsrc/css/phui/phui-object-item-list-view.css' => '987db9bf', + 'rsrc/css/phui/phui-object-item-list-view.css' => '87278fa0', 'rsrc/css/phui/phui-pager.css' => 'bea33d23', 'rsrc/css/phui/phui-pinboard-view.css' => '2495140e', 'rsrc/css/phui/phui-profile-menu.css' => '8a3fc181', @@ -858,7 +858,7 @@ return array( 'phui-inline-comment-view-css' => '5953c28e', 'phui-list-view-css' => '9da2aa00', 'phui-object-box-css' => '6b487c57', - 'phui-object-item-list-view-css' => '987db9bf', + 'phui-object-item-list-view-css' => '87278fa0', 'phui-pager-css' => 'bea33d23', 'phui-pinboard-view-css' => '2495140e', 'phui-profile-menu-css' => '8a3fc181', diff --git a/src/applications/config/controller/PhabricatorConfigGroupController.php b/src/applications/config/controller/PhabricatorConfigGroupController.php index 9ff9311c63..6e713f7eab 100644 --- a/src/applications/config/controller/PhabricatorConfigGroupController.php +++ b/src/applications/config/controller/PhabricatorConfigGroupController.php @@ -77,6 +77,24 @@ final class PhabricatorConfigGroupController ->setHref('/config/edit/'.$option->getKey().'/') ->addAttribute($summary); + $label = pht('Current Value:'); + $color = null; + $db_value = idx($db_values, $option->getKey()); + if ($db_value && !$db_value->getIsDeleted()) { + $item->setEffect('visited'); + $color = 'violet'; + $label = pht('Customized Value:'); + } + + if ($option->getHidden()) { + $item->setStatusIcon('fa-eye-slash grey', pht('Hidden')); + $item->setDisabled(true); + } else if ($option->getLocked()) { + $item->setStatusIcon('fa-lock '.$color, pht('Locked')); + } else { + $item->setStatusIcon('fa-pencil-square-o '.$color, pht('Editable')); + } + if (!$option->getHidden()) { $current_value = PhabricatorEnv::getEnvConfig($option->getKey()); $current_value = PhabricatorConfigJSON::prettyPrintJSON( @@ -87,24 +105,13 @@ final class PhabricatorConfigGroupController 'class' => 'config-options-current-value', ), array( - phutil_tag('span', array(), pht('Current Value:')), + phutil_tag('span', array(), $label), ' '.$current_value, )); $item->appendChild($current_value); } - $db_value = idx($db_values, $option->getKey()); - if ($db_value && !$db_value->getIsDeleted()) { - $item->addIcon('fa-edit', pht('Customized')); - } - - if ($option->getHidden()) { - $item->addIcon('fa-eye-slash', pht('Hidden')); - } else if ($option->getLocked()) { - $item->addIcon('fa-lock', pht('Locked')); - } - $list->addItem($item); } diff --git a/src/view/phui/PHUIObjectItemView.php b/src/view/phui/PHUIObjectItemView.php index 28d683e4d3..a5b24ed81e 100644 --- a/src/view/phui/PHUIObjectItemView.php +++ b/src/view/phui/PHUIObjectItemView.php @@ -254,6 +254,9 @@ final class PHUIObjectItemView extends AphrontTagView { case 'selected': $item_classes[] = 'phui-object-item-selected'; break; + case 'visited': + $item_classes[] = 'phui-object-item-visited'; + break; case null: break; default: diff --git a/webroot/rsrc/css/phui/phui-object-item-list-view.css b/webroot/rsrc/css/phui/phui-object-item-list-view.css index ef5fab6c3d..2f77102f42 100644 --- a/webroot/rsrc/css/phui/phui-object-item-list-view.css +++ b/webroot/rsrc/css/phui/phui-object-item-list-view.css @@ -772,6 +772,19 @@ ul.phui-object-item-list-view .phui-object-item-selected margin-bottom: 8px; } +.phui-object-list-big .phui-object-item-col0 { + vertical-align: top; + padding: 0; +} + +.phui-object-list-big .phui-object-item-status-icon { + padding: 5px; +} + +.phui-object-list-big .phui-object-item-visited a.phui-object-item-link { + color: {$violet}; +} + .device-desktop .phui-object-list-big .phui-object-item-frame:hover { } From 991e49b7114eeee61bc918363fa23e16fe004ab3 Mon Sep 17 00:00:00 2001 From: epriestley Date: Tue, 30 Aug 2016 13:56:25 -0700 Subject: [PATCH 14/25] Correct spelling of "therefore" Summary: Fixes T11565. Test Plan: `git grep -i therefor | grep -vi therefore` Reviewers: chad Reviewed By: chad Maniphest Tasks: T11565 Differential Revision: https://secure.phabricator.com/D16476 --- src/applications/owners/storage/PhabricatorOwnersPath.php | 2 +- src/docs/user/userguide/harbormaster.diviner | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/applications/owners/storage/PhabricatorOwnersPath.php b/src/applications/owners/storage/PhabricatorOwnersPath.php index 33ab109719..b552a7fb0d 100644 --- a/src/applications/owners/storage/PhabricatorOwnersPath.php +++ b/src/applications/owners/storage/PhabricatorOwnersPath.php @@ -88,7 +88,7 @@ final class PhabricatorOwnersPath extends PhabricatorOwnersDAO { $self_count = count($self_fragments); $path_count = count($path_fragments); if ($self_count > $path_count) { - // If this path is longer (and therefor more specific) than the target + // If this path is longer (and therefore more specific) than the target // path, we don't match it at all. return 0; } diff --git a/src/docs/user/userguide/harbormaster.diviner b/src/docs/user/userguide/harbormaster.diviner index 23ed15d5e4..a6f2047fdd 100644 --- a/src/docs/user/userguide/harbormaster.diviner +++ b/src/docs/user/userguide/harbormaster.diviner @@ -88,7 +88,7 @@ with {nav Add Build Step}. Currently, the only useful type of build step is "Make HTTP Request", which you can use to make a call to an external build system like Jenkins. Today, most -plans should therefor look something like this: +plans should therefore look something like this: - Use a "Make HTTP Request" step to tell Jenkins or some other similar external build system about the code. From 29957d196bb186259a662268dd6c5000f9273724 Mon Sep 17 00:00:00 2001 From: epriestley Date: Wed, 31 Aug 2016 09:47:22 -0700 Subject: [PATCH 15/25] Fix some more setIcon() issues Summary: Fixes T11569. This fixes a known bad `setIcon()`. I also looked for more calls to `setIcon()` without success, and stubbed `setIcon()` so we're in good shape even if more exist. Test Plan: - Grepped for `setIcon(` and manually inspect all 1,004 callsites to look for calls on `PHUIObjectItemView` objects. - Grepped for "high risk" callsites (`setIcon` in file after `PHUIObjectItemView`) and re-examined them. I identified these files with this command: ``` git ls-tree -r --name-only HEAD | xargs pcregrep -i -M -H -c --files-with-matches -o 'PHUIObjectItemView(.|\n)*setIcon' ``` There might be some more clever way to do that. - Since this only identified the callsites I already knew about and I don't have a ton of confidence that I didn't miss any, I put a stub in place that logs a deprecation warning. I'll file a followup to go clean these up in a month or so if the logs are clean. - Loaded Nuance, saw it work but warn. - Changed Nuance to use `setStatusIcon()`, loaded Nuance, no more fatal. Reviewers: chad Reviewed By: chad Maniphest Tasks: T11569 Differential Revision: https://secure.phabricator.com/D16477 --- .../nuance/controller/NuanceConsoleController.php | 6 +++--- src/view/phui/PHUIObjectItemView.php | 12 ++++++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/applications/nuance/controller/NuanceConsoleController.php b/src/applications/nuance/controller/NuanceConsoleController.php index d4a8f6c9ff..5daade874d 100644 --- a/src/applications/nuance/controller/NuanceConsoleController.php +++ b/src/applications/nuance/controller/NuanceConsoleController.php @@ -16,21 +16,21 @@ final class NuanceConsoleController extends NuanceController { id(new PHUIObjectItemView()) ->setHeader(pht('Queues')) ->setHref($this->getApplicationURI('queue/')) - ->setIcon('fa-align-left') + ->setImageIcon('fa-align-left') ->addAttribute(pht('Manage Nuance queues.'))); $menu->addItem( id(new PHUIObjectItemView()) ->setHeader(pht('Sources')) ->setHref($this->getApplicationURI('source/')) - ->setIcon('fa-filter') + ->setImageIcon('fa-filter') ->addAttribute(pht('Manage Nuance sources.'))); $menu->addItem( id(new PHUIObjectItemView()) ->setHeader(pht('Items')) ->setHref($this->getApplicationURI('item/')) - ->setIcon('fa-clone') + ->setImageIcon('fa-clone') ->addAttribute(pht('Manage Nuance items.'))); $crumbs = $this->buildApplicationCrumbs(); diff --git a/src/view/phui/PHUIObjectItemView.php b/src/view/phui/PHUIObjectItemView.php index a5b24ed81e..80fe6fb4d0 100644 --- a/src/view/phui/PHUIObjectItemView.php +++ b/src/view/phui/PHUIObjectItemView.php @@ -171,6 +171,18 @@ final class PHUIObjectItemView extends AphrontTagView { return $this; } + /** + * This method has been deprecated, use @{method:setImageIcon} instead. + * + * @deprecated + */ + public function setIcon($icon) { + phlog( + pht('Deprecated call to setIcon(), use setImageIcon() instead.')); + + return $this->setImageIcon($icon); + } + public function setStatusIcon($icon, $label = null) { $this->statusIcon = array( 'icon' => $icon, From b5c9c64b0f2e8dc8a46c6b6b62fcaaaecb432b13 Mon Sep 17 00:00:00 2001 From: Chad Little Date: Wed, 31 Aug 2016 12:14:05 -0700 Subject: [PATCH 16/25] Convert Guides to Modules Summary: Splitting these up to re-use in Config as a stop gap. Test Plan: Visit welcome, install, and quick start on guides app Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D16478 --- src/__phutil_library_map__.php | 16 +++--- .../PhabricatorGuideApplication.php | 7 +-- .../controller/PhabricatorGuideController.php | 8 +-- .../PhabricatorGuideModuleController.php | 42 +++++++++++++++ .../PhabricatorGuideWelcomeController.php | 52 ------------------- .../PhabricatorGuideInstallModule.php} | 47 +++++------------ .../guides/module/PhabricatorGuideModule.php | 18 +++++++ .../PhabricatorGuideQuickStartModule.php} | 47 +++++------------ .../module/PhabricatorGuideWelcomeModule.php | 34 ++++++++++++ 9 files changed, 139 insertions(+), 132 deletions(-) create mode 100644 src/applications/guides/controller/PhabricatorGuideModuleController.php delete mode 100644 src/applications/guides/controller/PhabricatorGuideWelcomeController.php rename src/applications/guides/{controller/PhabricatorGuideInstallController.php => module/PhabricatorGuideInstallModule.php} (84%) create mode 100644 src/applications/guides/module/PhabricatorGuideModule.php rename src/applications/guides/{controller/PhabricatorGuideQuickStartController.php => module/PhabricatorGuideQuickStartModule.php} (84%) create mode 100644 src/applications/guides/module/PhabricatorGuideWelcomeModule.php diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 0712bb72da..81ca752943 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -2639,11 +2639,13 @@ phutil_register_library_map(array( 'PhabricatorGoogleAuthProvider' => 'applications/auth/provider/PhabricatorGoogleAuthProvider.php', 'PhabricatorGuideApplication' => 'applications/guides/application/PhabricatorGuideApplication.php', 'PhabricatorGuideController' => 'applications/guides/controller/PhabricatorGuideController.php', - 'PhabricatorGuideInstallController' => 'applications/guides/controller/PhabricatorGuideInstallController.php', + 'PhabricatorGuideInstallModule' => 'applications/guides/module/PhabricatorGuideInstallModule.php', 'PhabricatorGuideItemView' => 'applications/guides/view/PhabricatorGuideItemView.php', 'PhabricatorGuideListView' => 'applications/guides/view/PhabricatorGuideListView.php', - 'PhabricatorGuideQuickStartController' => 'applications/guides/controller/PhabricatorGuideQuickStartController.php', - 'PhabricatorGuideWelcomeController' => 'applications/guides/controller/PhabricatorGuideWelcomeController.php', + 'PhabricatorGuideModule' => 'applications/guides/module/PhabricatorGuideModule.php', + 'PhabricatorGuideModuleController' => 'applications/guides/controller/PhabricatorGuideModuleController.php', + 'PhabricatorGuideQuickStartModule' => 'applications/guides/module/PhabricatorGuideQuickStartModule.php', + 'PhabricatorGuideWelcomeModule' => 'applications/guides/module/PhabricatorGuideWelcomeModule.php', 'PhabricatorHTTPParameterTypeTableView' => 'applications/config/view/PhabricatorHTTPParameterTypeTableView.php', 'PhabricatorHandleList' => 'applications/phid/handle/pool/PhabricatorHandleList.php', 'PhabricatorHandleObjectSelectorDataView' => 'applications/phid/handle/view/PhabricatorHandleObjectSelectorDataView.php', @@ -7454,11 +7456,13 @@ phutil_register_library_map(array( 'PhabricatorGoogleAuthProvider' => 'PhabricatorOAuth2AuthProvider', 'PhabricatorGuideApplication' => 'PhabricatorApplication', 'PhabricatorGuideController' => 'PhabricatorController', - 'PhabricatorGuideInstallController' => 'PhabricatorGuideController', + 'PhabricatorGuideInstallModule' => 'PhabricatorGuideModule', 'PhabricatorGuideItemView' => 'Phobject', 'PhabricatorGuideListView' => 'AphrontView', - 'PhabricatorGuideQuickStartController' => 'PhabricatorGuideController', - 'PhabricatorGuideWelcomeController' => 'PhabricatorGuideController', + 'PhabricatorGuideModule' => 'Phobject', + 'PhabricatorGuideModuleController' => 'PhabricatorGuideController', + 'PhabricatorGuideQuickStartModule' => 'PhabricatorGuideModule', + 'PhabricatorGuideWelcomeModule' => 'PhabricatorGuideModule', 'PhabricatorHTTPParameterTypeTableView' => 'AphrontView', 'PhabricatorHandleList' => array( 'Phobject', diff --git a/src/applications/guides/application/PhabricatorGuideApplication.php b/src/applications/guides/application/PhabricatorGuideApplication.php index 66f678489a..f60b66bfb2 100644 --- a/src/applications/guides/application/PhabricatorGuideApplication.php +++ b/src/applications/guides/application/PhabricatorGuideApplication.php @@ -29,11 +29,8 @@ final class PhabricatorGuideApplication extends PhabricatorApplication { public function getRoutes() { return array( '/guides/' => array( - '' => 'PhabricatorGuideWelcomeController', - 'install/' - => 'PhabricatorGuideInstallController', - 'quickstart/' - => 'PhabricatorGuideQuickStartController', + '' => 'PhabricatorGuideModuleController', + '(?P[^/]+)/' => 'PhabricatorGuideModuleController', ), ); } diff --git a/src/applications/guides/controller/PhabricatorGuideController.php b/src/applications/guides/controller/PhabricatorGuideController.php index 5aac89ba00..e7584cea00 100644 --- a/src/applications/guides/controller/PhabricatorGuideController.php +++ b/src/applications/guides/controller/PhabricatorGuideController.php @@ -7,9 +7,11 @@ abstract class PhabricatorGuideController extends PhabricatorController { $nav = new AphrontSideNavFilterView(); $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); $nav->addLabel(pht('Guides')); - $nav->addFilter('/', pht('Welcome')); - $nav->addFilter('install/', pht('Installation Guide')); - $nav->addFilter('quickstart/', pht('Quick Start Guide')); + + $modules = PhabricatorGuideModule::getAllModules(); + foreach ($modules as $key => $module) { + $nav->addFilter($key.'/', $module->getModuleName()); + } return $nav; } diff --git a/src/applications/guides/controller/PhabricatorGuideModuleController.php b/src/applications/guides/controller/PhabricatorGuideModuleController.php new file mode 100644 index 0000000000..c971195e60 --- /dev/null +++ b/src/applications/guides/controller/PhabricatorGuideModuleController.php @@ -0,0 +1,42 @@ +getViewer(); + $key = $request->getURIData('module'); + + if (!$key) { + $key = 'welcome'; + } + $all_modules = PhabricatorGuideModule::getAllModules(); + + $nav = $this->buildSideNavView(); + $nav->selectFilter($key.'/'); + + $module = $all_modules[$key]; + $content = $module->renderModuleStatus($request); + $title = $module->getModuleName(); + + $crumbs = $this->buildApplicationCrumbs(); + $crumbs->addTextCrumb($title); + $crumbs->setBorder(true); + + $header = id(new PHUIHeaderView()) + ->setHeader($title) + ->setProfileHeader(true); + + $view = id(new PHUICMSView()) + ->setCrumbs($crumbs) + ->setNavigation($nav) + ->setHeader($header) + ->setContent($content); + + return $this->newPage() + ->setTitle($title) + ->addClass('phui-cms-body') + ->appendChild($view); + } + +} diff --git a/src/applications/guides/controller/PhabricatorGuideWelcomeController.php b/src/applications/guides/controller/PhabricatorGuideWelcomeController.php deleted file mode 100644 index e5453c8c76..0000000000 --- a/src/applications/guides/controller/PhabricatorGuideWelcomeController.php +++ /dev/null @@ -1,52 +0,0 @@ -getViewer(); - - $title = pht('Welcome to Phabricator'); - - $nav = $this->buildSideNavView(); - $nav->selectFilter('/'); - - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setProfileHeader(true); - - $crumbs = $this->buildApplicationCrumbs() - ->addTextCrumb(pht('Welcome')); - - $content = id(new PHUIDocumentViewPro()) - ->appendChild($this->getGuideContent($viewer)); - - $view = id(new PHUICMSView()) - ->setCrumbs($crumbs) - ->setNavigation($nav) - ->setHeader($header) - ->setContent($content); - - return $this->newPage() - ->setTitle($title) - ->addClass('phui-cms-body') - ->appendChild($view); - - } - - private function getGuideContent($viewer) { - - $content = pht( - 'You have successfully installed Phabricator. These next guides will '. - 'take you through configuration and new user orientation. '. - 'These steps are optional, and you can go through them in any order. '. - 'If you want to get back to this guide later on, you can find it in '. - 'the **Config** application under **Welcome Guide**.'); - - return new PHUIRemarkupView($viewer, $content); - } -} diff --git a/src/applications/guides/controller/PhabricatorGuideInstallController.php b/src/applications/guides/module/PhabricatorGuideInstallModule.php similarity index 84% rename from src/applications/guides/controller/PhabricatorGuideInstallController.php rename to src/applications/guides/module/PhabricatorGuideInstallModule.php index f72cb51a67..819cbf363e 100644 --- a/src/applications/guides/controller/PhabricatorGuideInstallController.php +++ b/src/applications/guides/module/PhabricatorGuideInstallModule.php @@ -1,43 +1,22 @@ getViewer(); - $title = pht('Installation Guide'); - - $nav = $this->buildSideNavView(); - $nav->selectFilter('install/'); - - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setProfileHeader(true); - - $crumbs = $this->buildApplicationCrumbs() - ->addTextCrumb(pht('Installation')); - - $content = $this->getGuideContent($viewer); - - $view = id(new PHUICMSView()) - ->setCrumbs($crumbs) - ->setNavigation($nav) - ->setHeader($header) - ->setContent($content); - - return $this->newPage() - ->setTitle($title) - ->addClass('phui-cms-body') - ->appendChild($view); - - } - - private function getGuideContent($viewer) { $guide_items = new PhabricatorGuideListView(); $title = pht('Resolve Setup Issues'); @@ -191,5 +170,7 @@ final class PhabricatorGuideInstallController $guide_items->addItem($item); return $guide_items; + } + } diff --git a/src/applications/guides/module/PhabricatorGuideModule.php b/src/applications/guides/module/PhabricatorGuideModule.php new file mode 100644 index 0000000000..5ae7b6bf16 --- /dev/null +++ b/src/applications/guides/module/PhabricatorGuideModule.php @@ -0,0 +1,18 @@ +setAncestorClass(__CLASS__) + ->setUniqueMethod('getModuleKey') + ->setSortMethod('getModulePosition') + ->execute(); + } + +} diff --git a/src/applications/guides/controller/PhabricatorGuideQuickStartController.php b/src/applications/guides/module/PhabricatorGuideQuickStartModule.php similarity index 84% rename from src/applications/guides/controller/PhabricatorGuideQuickStartController.php rename to src/applications/guides/module/PhabricatorGuideQuickStartModule.php index 128556b7ae..64ee4d8534 100644 --- a/src/applications/guides/controller/PhabricatorGuideQuickStartController.php +++ b/src/applications/guides/module/PhabricatorGuideQuickStartModule.php @@ -1,43 +1,22 @@ getViewer(); - $title = pht('Quick Start Guide'); - - $nav = $this->buildSideNavView(); - $nav->selectFilter('quickstart/'); - - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setProfileHeader(true); - - $crumbs = $this->buildApplicationCrumbs() - ->addTextCrumb(pht('Quick Start')); - - $content = $this->getGuideContent($viewer); - - $view = id(new PHUICMSView()) - ->setCrumbs($crumbs) - ->setNavigation($nav) - ->setHeader($header) - ->setContent($content); - - return $this->newPage() - ->setTitle($title) - ->addClass('phui-cms-body') - ->appendChild($view); - - } - - private function getGuideContent($viewer) { $guide_items = new PhabricatorGuideListView(); $title = pht('Configure Applications'); @@ -205,5 +184,7 @@ final class PhabricatorGuideQuickStartController $guide_items->addItem($item); return $guide_items; + } + } diff --git a/src/applications/guides/module/PhabricatorGuideWelcomeModule.php b/src/applications/guides/module/PhabricatorGuideWelcomeModule.php new file mode 100644 index 0000000000..2b2bb80184 --- /dev/null +++ b/src/applications/guides/module/PhabricatorGuideWelcomeModule.php @@ -0,0 +1,34 @@ +getViewer(); + + $content = pht( + 'You have successfully installed Phabricator. These next guides will '. + 'take you through configuration and new user orientation. '. + 'These steps are optional, and you can go through them in any order. '. + 'If you want to get back to this guide later on, you can find it in '. + 'the **Config** application under **Welcome Guide**.'); + + $content = new PHUIRemarkupView($viewer, $content); + + return id(new PHUIDocumentViewPro()) + ->appendChild($content); + + } + +} From 4dacf4d3ad4b1b2d9fa50b08ffa1c6e6bffb7574 Mon Sep 17 00:00:00 2001 From: Chad Little Date: Wed, 31 Aug 2016 13:53:27 -0700 Subject: [PATCH 17/25] Add a basic first feed story on /home/ Summary: Ref T11132. Adds a text panel to feed if no stories are present and the user is an admin. Seems ok-ish for 15 minutes. Happy to take content suggestions. Test Plan: Make a new install, see panel. Log in as new user, don't see panel. Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Maniphest Tasks: T11132 Differential Revision: https://secure.phabricator.com/D16479 --- .../PhabricatorConfigWelcomeController.php | 2 +- .../PhabricatorHomeMainController.php | 29 +++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/applications/config/controller/PhabricatorConfigWelcomeController.php b/src/applications/config/controller/PhabricatorConfigWelcomeController.php index 357f6f129a..010f3f7a5a 100644 --- a/src/applications/config/controller/PhabricatorConfigWelcomeController.php +++ b/src/applications/config/controller/PhabricatorConfigWelcomeController.php @@ -317,7 +317,7 @@ final class PhabricatorConfigWelcomeController $pholio_all_uri)); - $diffusion_uri = PhabricatorEnv::getURI('/diffusion/'); + $diffusion_uri = PhabricatorEnv::getURI('/diffusion/edit/'); $diffusion_create_uri = PhabricatorEnv::getURI('/diffusion/create/'); $diffusion_all_uri = PhabricatorEnv::getURI('/diffusion/query/all/'); diff --git a/src/applications/home/controller/PhabricatorHomeMainController.php b/src/applications/home/controller/PhabricatorHomeMainController.php index 592478c894..fce4729a6d 100644 --- a/src/applications/home/controller/PhabricatorHomeMainController.php +++ b/src/applications/home/controller/PhabricatorHomeMainController.php @@ -202,6 +202,35 @@ final class PhabricatorHomeMainController extends PhabricatorHomeController { $pager->setPageSize(40); $results = $engine->executeQuery($query, $pager); $view = $engine->renderResults($results, $saved); + // Low tech NUX. + if (!$results && ($viewer->getIsAdmin() == 1)) { + $instance = PhabricatorEnv::getEnvConfig('cluster.instance'); + if (!$instance) { + $content = pht(<<setObjectList($list); + $view->setNoDataString($welcome); + } $title = pht('Recent Activity'); $href = '/feed/'; From 25a7266d15dc9d6881687cec63f314b7e321594b Mon Sep 17 00:00:00 2001 From: Aviv Eyal Date: Wed, 31 Aug 2016 21:35:57 +0000 Subject: [PATCH 18/25] Correctly calculate "any_failed" Summary: See T10746. Test Plan: Fail one of several builds, run `./bin/harbormaster update`, see that Build Status is Failed. Reviewers: #blessed_reviewers, epriestley Reviewed By: #blessed_reviewers, epriestley Subscribers: epriestley, O14 ATC Monitoring, yelirekim Maniphest Tasks: T10746 Differential Revision: https://secure.phabricator.com/D16480 --- .../harbormaster/engine/HarbormasterBuildEngine.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/applications/harbormaster/engine/HarbormasterBuildEngine.php b/src/applications/harbormaster/engine/HarbormasterBuildEngine.php index 4cece6a69d..893f8fc546 100644 --- a/src/applications/harbormaster/engine/HarbormasterBuildEngine.php +++ b/src/applications/harbormaster/engine/HarbormasterBuildEngine.php @@ -446,11 +446,14 @@ final class HarbormasterBuildEngine extends Phobject { if ($build->getBuildStatus() != HarbormasterBuildStatus::STATUS_PASSED) { $all_pass = false; } - $any_fail = in_array($build->getBuildStatus(), array( + if (in_array($build->getBuildStatus(), array( HarbormasterBuildStatus::STATUS_FAILED, HarbormasterBuildStatus::STATUS_ERROR, HarbormasterBuildStatus::STATUS_DEADLOCKED, - )); + ))) { + + $any_fail = true; + } } if ($any_fail) { From 27cfd8d19e8369b6696d3a6b9ef50c8baff24ded Mon Sep 17 00:00:00 2001 From: epriestley Date: Wed, 31 Aug 2016 14:59:37 -0700 Subject: [PATCH 19/25] Support object mentions in Calendar Event descriptions Summary: Ref T7924. This: - Adds support for remarkup block changes to Modular Transactions. - Exposes remarkup changes from the Calendar event "Description" transaction. This makes stuff like mentions and file embeds work properly. Test Plan: Mentioned a task in an event description, saw a mention appear on the task. Uploaded a file to an event description, saw the file become "Attached" to the event. (Neither of these worked properly before.) Reviewers: chad Reviewed By: chad Maniphest Tasks: T7924 Differential Revision: https://secure.phabricator.com/D16481 --- ...PhabricatorCalendarEventDescriptionTransaction.php | 11 +++++++++++ .../storage/PhabricatorModularTransaction.php | 4 ++++ .../storage/PhabricatorModularTransactionType.php | 9 +++++++++ 3 files changed, 24 insertions(+) diff --git a/src/applications/calendar/xaction/PhabricatorCalendarEventDescriptionTransaction.php b/src/applications/calendar/xaction/PhabricatorCalendarEventDescriptionTransaction.php index 9c14f1ae80..343ffa2adf 100644 --- a/src/applications/calendar/xaction/PhabricatorCalendarEventDescriptionTransaction.php +++ b/src/applications/calendar/xaction/PhabricatorCalendarEventDescriptionTransaction.php @@ -39,4 +39,15 @@ final class PhabricatorCalendarEventDescriptionTransaction ->setNewText($this->getNewValue()); } + public function newRemarkupChanges() { + $changes = array(); + + $changes[] = $this->newRemarkupChange() + ->setOldValue($this->getOldValue()) + ->setNewValue($this->getNewValue()); + + return $changes; + } + + } diff --git a/src/applications/transactions/storage/PhabricatorModularTransaction.php b/src/applications/transactions/storage/PhabricatorModularTransaction.php index 8ea6248563..c93a559108 100644 --- a/src/applications/transactions/storage/PhabricatorModularTransaction.php +++ b/src/applications/transactions/storage/PhabricatorModularTransaction.php @@ -149,4 +149,8 @@ abstract class PhabricatorModularTransaction return parent::renderChangeDetails($viewer); } + final protected function newRemarkupChanges() { + return $this->getTransactionImplementation()->newRemarkupChanges(); + } + } diff --git a/src/applications/transactions/storage/PhabricatorModularTransactionType.php b/src/applications/transactions/storage/PhabricatorModularTransactionType.php index a35eb02cd3..a5ddcc3e94 100644 --- a/src/applications/transactions/storage/PhabricatorModularTransactionType.php +++ b/src/applications/transactions/storage/PhabricatorModularTransactionType.php @@ -67,6 +67,10 @@ abstract class PhabricatorModularTransactionType throw new PhutilMethodNotImplementedException(); } + public function newRemarkupChanges() { + return array(); + } + final public function setStorage( PhabricatorApplicationTransaction $xaction) { $this->storage = $xaction; @@ -253,4 +257,9 @@ abstract class PhabricatorModularTransactionType return ($target == PhabricatorApplicationTransaction::TARGET_TEXT); } + final protected function newRemarkupChange() { + return id(new PhabricatorTransactionRemarkupChange()) + ->setTransaction($this->getStorage()); + } + } From 1eee75496a5a08f7e2b04a2a50effb4ce7ce478c Mon Sep 17 00:00:00 2001 From: epriestley Date: Fri, 2 Sep 2016 04:51:40 -0700 Subject: [PATCH 20/25] Update Diviner for array-valued `@doc-stuff` return values from DocblockParser Summary: Ref T11575. After D16431, the parser may return arrays. Test Plan: Ran `bin/diviner generate --clean` in `phabricator/` without errors. Previously, this raised some parsing errors related to getting arrays where strings were expected. Reviewers: chad, yelirekim, joshuaspence Reviewed By: joshuaspence Maniphest Tasks: T11575 Differential Revision: https://secure.phabricator.com/D16487 --- .../diviner/atomizer/DivinerPHPAtomizer.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/applications/diviner/atomizer/DivinerPHPAtomizer.php b/src/applications/diviner/atomizer/DivinerPHPAtomizer.php index 36616897f2..201055a15c 100644 --- a/src/applications/diviner/atomizer/DivinerPHPAtomizer.php +++ b/src/applications/diviner/atomizer/DivinerPHPAtomizer.php @@ -141,7 +141,7 @@ final class DivinerPHPAtomizer extends DivinerAtomizer { $docs = idx($metadata, 'param'); if ($docs) { - $docs = explode("\n", $docs); + $docs = (array)$docs; $docs = array_filter($docs); } else { $docs = array(); @@ -283,6 +283,15 @@ final class DivinerPHPAtomizer extends DivinerAtomizer { } } + $return = (array)$return; + if (count($return) > 1) { + $atom->addWarning( + pht( + 'Documentation specifies `%s` multiple times.', + '@return')); + } + $return = head($return); + if ($atom->getName() == '__construct' && $atom->getType() == 'method') { $return_spec = array( 'doctype' => 'this', From 0eb5a80e7b689fa9261e3b6ee7640664bfe14a5f Mon Sep 17 00:00:00 2001 From: Luke081515 Date: Fri, 2 Sep 2016 06:18:17 -0700 Subject: [PATCH 21/25] Fix typo at calendar transaction Summary: * Fixed conveted => converted Ref T11576 Test Plan: * Looked at a page, where somebody converted an AllDay Event to a normal one Reviewers: #blessed_reviewers, epriestley Reviewed By: #blessed_reviewers, epriestley Subscribers: epriestley Tags: #calendar Maniphest Tasks: T11576 Differential Revision: https://secure.phabricator.com/D16488 --- .../xaction/PhabricatorCalendarEventAllDayTransaction.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/applications/calendar/xaction/PhabricatorCalendarEventAllDayTransaction.php b/src/applications/calendar/xaction/PhabricatorCalendarEventAllDayTransaction.php index 1fe9320d6f..1bcad16adf 100644 --- a/src/applications/calendar/xaction/PhabricatorCalendarEventAllDayTransaction.php +++ b/src/applications/calendar/xaction/PhabricatorCalendarEventAllDayTransaction.php @@ -24,7 +24,7 @@ final class PhabricatorCalendarEventAllDayTransaction $this->renderAuthor()); } else { return pht( - '%s conveted this from an all day event.', + '%s converted this from an all day event.', $this->renderAuthor()); } } From 403073c989b4979ebc89d682a6ee8d121f182075 Mon Sep 17 00:00:00 2001 From: Mike Riley Date: Fri, 2 Sep 2016 03:22:59 +0000 Subject: [PATCH 22/25] Provide a workflow to restart Harbormaster builds Summary: Ref T10867 for original use case. This workflow provides a plausible way for administrators to stop the daemons when performing upgrades or maintenance, then bring those daemons back up without resulting in the failure of builds that were running at the time. On our organization's phab install, builds are running 24/7. The majority of these builds last for at least several minutes, and contain build steps which fail if interrupted and then resumed, as happens when turning daemons on and off. Instead of allowing these build steps to resume execution as normal, this workflow will instruct active builds to restart their entire build process instead of just resuming whichever step they were on. Test Plan: contrived a build plan which would fail if resumed partway through: - lease a working copy - command `touch restart_{build.id}` - command `test -e restart_{build.id} && rm restart_{build.id} && sleep 60` followed old procedure: - run a few of these builds manually - `./bin/phd stop` - `./bin/phd start` - saw the builds fail followed new procedure: - run a few of these builds manually - `./bin/phd stop` - `./bin/harbormaster restart --active` - `./bin/phd start` - saw the builds pass Reviewers: epriestley, #blessed_reviewers Reviewed By: epriestley, #blessed_reviewers Subscribers: Korvin, epriestley Maniphest Tasks: T10867 Differential Revision: https://secure.phabricator.com/D16485 --- src/__phutil_library_map__.php | 2 + .../HarbormasterManagementRestartWorkflow.php | 100 ++++++++++++++++++ .../PhabricatorUSEnglishTranslation.php | 5 + 3 files changed, 107 insertions(+) create mode 100644 src/applications/harbormaster/management/HarbormasterManagementRestartWorkflow.php diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 81ca752943..f471313be8 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1190,6 +1190,7 @@ phutil_register_library_map(array( 'HarbormasterLintPropertyView' => 'applications/harbormaster/view/HarbormasterLintPropertyView.php', 'HarbormasterManagementArchiveLogsWorkflow' => 'applications/harbormaster/management/HarbormasterManagementArchiveLogsWorkflow.php', 'HarbormasterManagementBuildWorkflow' => 'applications/harbormaster/management/HarbormasterManagementBuildWorkflow.php', + 'HarbormasterManagementRestartWorkflow' => 'applications/harbormaster/management/HarbormasterManagementRestartWorkflow.php', 'HarbormasterManagementUpdateWorkflow' => 'applications/harbormaster/management/HarbormasterManagementUpdateWorkflow.php', 'HarbormasterManagementWorkflow' => 'applications/harbormaster/management/HarbormasterManagementWorkflow.php', 'HarbormasterMessageType' => 'applications/harbormaster/engine/HarbormasterMessageType.php', @@ -5785,6 +5786,7 @@ phutil_register_library_map(array( 'HarbormasterLintPropertyView' => 'AphrontView', 'HarbormasterManagementArchiveLogsWorkflow' => 'HarbormasterManagementWorkflow', 'HarbormasterManagementBuildWorkflow' => 'HarbormasterManagementWorkflow', + 'HarbormasterManagementRestartWorkflow' => 'HarbormasterManagementWorkflow', 'HarbormasterManagementUpdateWorkflow' => 'HarbormasterManagementWorkflow', 'HarbormasterManagementWorkflow' => 'PhabricatorManagementWorkflow', 'HarbormasterMessageType' => 'Phobject', diff --git a/src/applications/harbormaster/management/HarbormasterManagementRestartWorkflow.php b/src/applications/harbormaster/management/HarbormasterManagementRestartWorkflow.php new file mode 100644 index 0000000000..2a38e10409 --- /dev/null +++ b/src/applications/harbormaster/management/HarbormasterManagementRestartWorkflow.php @@ -0,0 +1,100 @@ +setName('restart') + ->setExamples( + "**restart** --active\n". + '**restart** --id id') + ->setSynopsis(pht('Restart Harbormaster builds.')) + ->setArguments( + array( + array( + 'name' => 'id', + 'param' => 'id', + 'repeat' => true, + 'help' => pht('Select one or more builds by ID.'), + ), + array( + 'name' => 'active', + 'help' => pht('Select all active builds.'), + ), + )); + } + + public function execute(PhutilArgumentParser $args) { + $viewer = $this->getViewer(); + $ids = $args->getArg('id'); + $active = $args->getArg('active'); + + if (!$ids && !$active) { + throw new PhutilArgumentUsageException( + pht('Use --id or --active to select builds.')); + } if ($ids && $active) { + throw new PhutilArgumentUsageException( + pht('Use one of --id or --active to select builds, but not both.')); + } + + $query = id(new HarbormasterBuildQuery()) + ->setViewer($viewer); + if ($ids) { + $query->withIDs($ids); + } else { + $query->withBuildStatuses( + HarbormasterBuildStatus::getActiveStatusConstants()); + } + $builds = $query->execute(); + + $console = PhutilConsole::getConsole(); + $count = count($builds); + if (!$count) { + $console->writeOut("%s\n", pht('No builds to restart.')); + return 0; + } + $prompt = pht('Restart %s build(s)?', new PhutilNumber($count)); + if (!phutil_console_confirm($prompt)) { + $console->writeOut("%s\n", pht('Cancelled.')); + return 1; + } + + $app_phid = id(new PhabricatorHarbormasterApplication())->getPHID(); + $editor = id(new HarbormasterBuildTransactionEditor()) + ->setActor($viewer) + ->setActingAsPHID($app_phid) + ->setContentSource($this->newContentSource()); + foreach ($builds as $build) { + $console->writeOut( + " %s %s\n", + pht('RESTARTING'), + pht('Build %d: %s', $build->getID(), $build->getName())); + if (!$build->canRestartBuild()) { + $console->writeOut( + " %s %s\n", + pht('INVALID'), + pht('Cannot be restarted.')); + continue; + } + $xactions = array(); + $xactions[] = id(new HarbormasterBuildTransaction()) + ->setTransactionType(HarbormasterBuildTransaction::TYPE_COMMAND) + ->setNewValue(HarbormasterBuildCommand::COMMAND_RESTART); + try { + $editor->applyTransactions($build, $xactions); + } catch (Exception $e) { + $message = phutil_console_wrap($e->getMessage(), 2); + $console->writeOut( + " %s \n%s\n", + pht('FAILED'), + $message); + continue; + } + $console->writeOut(" %s \n", pht('SUCCESS')); + } + + return 0; + } + +} diff --git a/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php b/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php index c65103d4ef..b11f67ceb4 100644 --- a/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php +++ b/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php @@ -1573,6 +1573,11 @@ final class PhabricatorUSEnglishTranslation '%s updated the invite list for %s, invited %s: %s; uninvinted %s: %s.' => '%s updated the invite list for %s, invited: %4$s; uninvited: %6$s.', + + 'Restart %s build(s)?' => array( + 'Restart %s build?', + 'Restart %s builds?', + ), ); } From 081081b20e973265b80540310f585ce222c7a7c4 Mon Sep 17 00:00:00 2001 From: epriestley Date: Thu, 1 Sep 2016 10:55:49 -0700 Subject: [PATCH 23/25] Fix a Repository doc spelling mistake Summary: Those letters don't go there! Test Plan: O__O Reviewers: chad Reviewed By: chad Differential Revision: https://secure.phabricator.com/D16486 --- src/docs/user/cluster/cluster_repositories.diviner | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/docs/user/cluster/cluster_repositories.diviner b/src/docs/user/cluster/cluster_repositories.diviner index 07203f03eb..e7e8031677 100644 --- a/src/docs/user/cluster/cluster_repositories.diviner +++ b/src/docs/user/cluster/cluster_repositories.diviner @@ -156,7 +156,7 @@ $ ./bin/repository clusterize --service To migrate a repository back off a service, use this command: ``` -$ ./bin/repoistory clusterize --remove-service +$ ./bin/repository clusterize --remove-service ``` This command only changes how Phabricator connects to the repository; it does From d0013d08983a0ceeaa37bde36f1983cefa78e8a8 Mon Sep 17 00:00:00 2001 From: epriestley Date: Fri, 2 Sep 2016 08:03:51 -0700 Subject: [PATCH 24/25] Distinguish between unreachable cluster database hosts and missing MySQL databases Summary: Fixes T11577. When we connect to a host and try to select a database which does not exist, we currently treat it as though the host wasn't reachable. This isn't correct, and prevents storage from being initialized while already in cluster mode, since the "config" database won't exist yet the first time we connect. Instead, distinguish between `AphrontSchemaQueryException` (thrown on connection if the requested database is not present) and other errors. Test Plan: - Put Phabricator into cluster database mode (`cluster.databases = ...`). - Swapped `storage.default-namespace` to force initialization of a new install. - Ran `bin/storage upgrade`. - Before patch: Immediate fatal about unreachablility. - After patch: Database initialized. - Also ran initialization steps in tranditional single-host mode (`cluster.databases` empty, `mysql.host` configured). Reviewers: chad Reviewed By: chad Maniphest Tasks: T11577 Differential Revision: https://secure.phabricator.com/D16489 --- src/infrastructure/cluster/PhabricatorDatabaseRef.php | 6 ++++++ src/infrastructure/env/PhabricatorEnv.php | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/infrastructure/cluster/PhabricatorDatabaseRef.php b/src/infrastructure/cluster/PhabricatorDatabaseRef.php index 02777fb7a7..c81de56823 100644 --- a/src/infrastructure/cluster/PhabricatorDatabaseRef.php +++ b/src/infrastructure/cluster/PhabricatorDatabaseRef.php @@ -405,6 +405,12 @@ final class PhabricatorDatabaseRef try { $connection->openConnection(); $reachable = true; + } catch (AphrontSchemaQueryException $ex) { + // We get one of these if the database we're trying to select does not + // exist. In this case, just re-throw the exception. This is expected + // during first-time setup, when databases like "config" will not exist + // yet. + throw $ex; } catch (Exception $ex) { $reachable = false; } diff --git a/src/infrastructure/env/PhabricatorEnv.php b/src/infrastructure/env/PhabricatorEnv.php index dd8c11e629..d66e022465 100644 --- a/src/infrastructure/env/PhabricatorEnv.php +++ b/src/infrastructure/env/PhabricatorEnv.php @@ -231,7 +231,7 @@ final class PhabricatorEnv extends Phobject { $stack->pushSource( id(new PhabricatorConfigDatabaseSource('default')) ->setName(pht('Database'))); - } catch (AphrontQueryException $exception) { + } catch (AphrontSchemaQueryException $exception) { // If the database is not available, just skip this configuration // source. This happens during `bin/storage upgrade`, `bin/conf` before // schema setup, etc. From 31c5f39506bd569709adb4effbc06176047822aa Mon Sep 17 00:00:00 2001 From: Aviv Eyal Date: Fri, 2 Sep 2016 10:16:14 -0700 Subject: [PATCH 25/25] Show broken units in revision history Summary: This is hacky, and I'm not sure I'm happy with it; Until T9365 is done, this will show up broken tests with an appropriate star in the Revision History. Test Plan: Created 1M messages in a couple of old diffs in a revision. The query took ~80us (On SSD drive). Reviewers: #blessed_reviewers, epriestley Reviewed By: #blessed_reviewers, epriestley Subscribers: epriestley Differential Revision: https://secure.phabricator.com/D16483 --- .../DifferentialRevisionViewController.php | 42 +++++++++++++++++++ .../customfield/DifferentialUnitField.php | 3 +- .../DifferentialRevisionUpdateHistoryView.php | 26 ++++++++---- 3 files changed, 62 insertions(+), 9 deletions(-) diff --git a/src/applications/differential/controller/DifferentialRevisionViewController.php b/src/applications/differential/controller/DifferentialRevisionViewController.php index e7fcdba377..390c90b2e9 100644 --- a/src/applications/differential/controller/DifferentialRevisionViewController.php +++ b/src/applications/differential/controller/DifferentialRevisionViewController.php @@ -292,9 +292,12 @@ final class DifferentialRevisionViewController extends DifferentialController { '/differential/comment/inline/edit/'.$revision->getID().'/'); } + $broken_diffs = $this->loadHistoryDiffStatus($diffs); + $history = id(new DifferentialRevisionUpdateHistoryView()) ->setUser($viewer) ->setDiffs($diffs) + ->setDiffUnitStatuses($broken_diffs) ->setSelectedVersusDiffID($diff_vs) ->setSelectedDiffID($target->getID()) ->setSelectedWhitespace($whitespace) @@ -776,6 +779,45 @@ final class DifferentialRevisionViewController extends DifferentialController { return $actions_dict; } + private function loadHistoryDiffStatus(array $diffs) { + assert_instances_of($diffs, 'DifferentialDiff'); + + $diff_phids = mpull($diffs, 'getPHID'); + $bad_unit_status = array( + ArcanistUnitTestResult::RESULT_FAIL, + ArcanistUnitTestResult::RESULT_BROKEN, + ); + + $message = new HarbormasterBuildUnitMessage(); + $target = new HarbormasterBuildTarget(); + $build = new HarbormasterBuild(); + $buildable = new HarbormasterBuildable(); + + $broken_diffs = queryfx_all( + $message->establishConnection('r'), + 'SELECT distinct a.buildablePHID + FROM %T m + JOIN %T t ON m.buildTargetPHID = t.phid + JOIN %T b ON t.buildPHID = b.phid + JOIN %T a ON b.buildablePHID = a.phid + WHERE a.buildablePHID IN (%Ls) + AND m.result in (%Ls)', + $message->getTableName(), + $target->getTableName(), + $build->getTableName(), + $buildable->getTableName(), + $diff_phids, + $bad_unit_status); + + $unit_status = array(); + foreach ($broken_diffs as $broken) { + $phid = $broken['buildablePHID']; + $unit_status[$phid] = DifferentialUnitStatus::UNIT_FAIL; + } + + return $unit_status; + } + private function loadChangesetsAndVsMap( DifferentialDiff $target, DifferentialDiff $diff_vs = null, diff --git a/src/applications/differential/customfield/DifferentialUnitField.php b/src/applications/differential/customfield/DifferentialUnitField.php index fa2016b106..c9b3998762 100644 --- a/src/applications/differential/customfield/DifferentialUnitField.php +++ b/src/applications/differential/customfield/DifferentialUnitField.php @@ -61,7 +61,8 @@ final class DifferentialUnitField ); $icon_color = idx($colors, $diff->getUnitStatus(), 'grey'); - $message = DifferentialRevisionUpdateHistoryView::getDiffUnitMessage($diff); + $message = DifferentialRevisionUpdateHistoryView::getDiffUnitMessage( + $diff->getUnitStatus()); $status = id(new PHUIStatusListView()) ->addItem( diff --git a/src/applications/differential/view/DifferentialRevisionUpdateHistoryView.php b/src/applications/differential/view/DifferentialRevisionUpdateHistoryView.php index 2d311fd0bd..bdac860674 100644 --- a/src/applications/differential/view/DifferentialRevisionUpdateHistoryView.php +++ b/src/applications/differential/view/DifferentialRevisionUpdateHistoryView.php @@ -7,6 +7,7 @@ final class DifferentialRevisionUpdateHistoryView extends AphrontView { private $selectedDiffID; private $selectedWhitespace; private $commitsForLinks = array(); + private $unitStatus = array(); public function setDiffs(array $diffs) { assert_instances_of($diffs, 'DifferentialDiff'); @@ -35,6 +36,11 @@ final class DifferentialRevisionUpdateHistoryView extends AphrontView { return $this; } + public function setDiffUnitStatuses(array $unit_status) { + $this->unitStatus = $unit_status; + return $this; + } + public function render() { $this->requireResource('differential-core-view-css'); $this->requireResource('differential-revision-history-css'); @@ -139,6 +145,11 @@ final class DifferentialRevisionUpdateHistoryView extends AphrontView { } if ($diff) { + $unit_status = idx( + $this->unitStatus, + $diff->getPHID(), + $diff->getUnitStatus()); + $lint = self::renderDiffLintStar($row['obj']); $lint = phutil_tag( 'div', @@ -148,12 +159,12 @@ final class DifferentialRevisionUpdateHistoryView extends AphrontView { ), $lint); - $unit = self::renderDiffUnitStar($row['obj']); + $unit = self::renderDiffUnitStar($unit_status); $unit = phutil_tag( 'div', array( 'class' => 'lintunit-star', - 'title' => self::getDiffUnitMessage($diff), + 'title' => self::getDiffUnitMessage($unit_status), ), $unit); @@ -312,7 +323,7 @@ final class DifferentialRevisionUpdateHistoryView extends AphrontView { const STAR_FAIL = 'fail'; const STAR_SKIP = 'skip'; - public static function renderDiffLintStar(DifferentialDiff $diff) { + private static function renderDiffLintStar(DifferentialDiff $diff) { static $map = array( DifferentialLintStatus::LINT_NONE => self::STAR_NONE, DifferentialLintStatus::LINT_OKAY => self::STAR_OKAY, @@ -327,7 +338,7 @@ final class DifferentialRevisionUpdateHistoryView extends AphrontView { return self::renderDiffStar($star); } - public static function renderDiffUnitStar(DifferentialDiff $diff) { + private static function renderDiffUnitStar($unit_status) { static $map = array( DifferentialUnitStatus::UNIT_NONE => self::STAR_NONE, DifferentialUnitStatus::UNIT_OKAY => self::STAR_OKAY, @@ -336,8 +347,7 @@ final class DifferentialRevisionUpdateHistoryView extends AphrontView { DifferentialUnitStatus::UNIT_SKIP => self::STAR_SKIP, DifferentialUnitStatus::UNIT_AUTO_SKIP => self::STAR_SKIP, ); - - $star = idx($map, $diff->getUnitStatus(), self::STAR_FAIL); + $star = idx($map, $unit_status, self::STAR_FAIL); return self::renderDiffStar($star); } @@ -360,8 +370,8 @@ final class DifferentialRevisionUpdateHistoryView extends AphrontView { return pht('Unknown'); } - public static function getDiffUnitMessage(DifferentialDiff $diff) { - switch ($diff->getUnitStatus()) { + public static function getDiffUnitMessage($unit_status) { + switch ($unit_status) { case DifferentialUnitStatus::UNIT_NONE: return pht('No Unit Test Coverage'); case DifferentialUnitStatus::UNIT_OKAY: