diff --git a/src/__celerity_resource_map__.php b/src/__celerity_resource_map__.php index ef74552bad..aca5273560 100644 --- a/src/__celerity_resource_map__.php +++ b/src/__celerity_resource_map__.php @@ -1,493 +1,530 @@ array( 'uri' => '/res/056b0c12/rsrc/css/aphront/dark-console.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/aphront/dark-console.css', ), 'aphront-dialog-view-css' => array( 'uri' => '/res/a05107ae/rsrc/css/aphront/dialog-view.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/aphront/dialog-view.css', ), 'aphront-error-view-css' => array( 'uri' => '/res/19b27527/rsrc/css/aphront/error-view.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/aphront/error-view.css', ), 'aphront-form-view-css' => array( 'uri' => '/res/8aaef437/rsrc/css/aphront/form-view.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/aphront/form-view.css', ), 'aphront-panel-view-css' => array( 'uri' => '/res/63672373/rsrc/css/aphront/panel-view.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/aphront/panel-view.css', ), 'aphront-request-failure-view-css' => array( 'uri' => '/res/97b8337a/rsrc/css/aphront/request-failure-view.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/aphront/request-failure-view.css', ), 'aphront-side-nav-view-css' => array( 'uri' => '/res/0fc0545c/rsrc/css/aphront/side-nav-view.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/aphront/side-nav-view.css', ), 'aphront-table-view-css' => array( 'uri' => '/res/6a70f0f0/rsrc/css/aphront/table-view.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/aphront/table-view.css', ), 'aphront-tokenizer-control-css' => array( 'uri' => '/res/a3d23074/rsrc/css/aphront/tokenizer.css', 'type' => 'css', 'requires' => array( 0 => 'aphront-typeahead-control-css', ), 'disk' => '/rsrc/css/aphront/tokenizer.css', ), 'aphront-typeahead-control-css' => array( 'uri' => '/res/928df9f0/rsrc/css/aphront/typeahead.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/aphront/typeahead.css', ), 'phabricator-standard-page-view' => array( 'uri' => '/res/4ebe4b10/rsrc/css/application/base/standard-page-view.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/application/base/standard-page-view.css', ), 'differential-revision-add-comment-css' => array( 'uri' => '/res/9be761de/rsrc/css/application/differential/add-comment.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/application/differential/add-comment.css', ), 'differential-changeset-view-css' => array( 'uri' => '/res/8b893b8e/rsrc/css/application/differential/changeset-view.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/application/differential/changeset-view.css', ), 'differential-core-view-css' => array( 'uri' => '/res/525d1a12/rsrc/css/application/differential/core.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/application/differential/core.css', ), 'differential-revision-comment-list-css' => array( 'uri' => '/res/10b9a829/rsrc/css/application/differential/revision-comment-list.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/application/differential/revision-comment-list.css', ), 'differential-revision-comment-css' => array( 'uri' => '/res/678be39a/rsrc/css/application/differential/revision-comment.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/application/differential/revision-comment.css', ), 'differential-revision-detail-css' => array( 'uri' => '/res/230a67c6/rsrc/css/application/differential/revision-detail.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/application/differential/revision-detail.css', ), 'differential-revision-history-css' => array( 'uri' => '/res/755f3da3/rsrc/css/application/differential/revision-history.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/application/differential/revision-history.css', ), 'differential-table-of-contents-css' => array( 'uri' => '/res/e68f6f05/rsrc/css/application/differential/table-of-contents.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/application/differential/table-of-contents.css', ), 'phabricator-directory-css' => array( 'uri' => '/res/6a000601/rsrc/css/application/directory/phabricator-directory.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/application/directory/phabricator-directory.css', ), + 'mainphest-task-detail-css' => + array( + 'uri' => '/res/e5f3beca/rsrc/css/application/maniphest/task-detail.css', + 'type' => 'css', + 'requires' => + array( + ), + 'disk' => '/rsrc/css/application/maniphest/task-detail.css', + ), + 'maniphest-task-summary-css' => + array( + 'uri' => '/res/bed1edf0/rsrc/css/application/maniphest/task-summary.css', + 'type' => 'css', + 'requires' => + array( + ), + 'disk' => '/rsrc/css/application/maniphest/task-summary.css', + ), + 'maniphest-transaction-detail-css' => + array( + 'uri' => '/res/436b83d7/rsrc/css/application/maniphest/transaction-detail.css', + 'type' => 'css', + 'requires' => + array( + ), + 'disk' => '/rsrc/css/application/maniphest/transaction-detail.css', + ), 'phabricator-core-buttons-css' => array( 'uri' => '/res/fe74ba44/rsrc/css/core/buttons.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/core/buttons.css', ), 'phabricator-core-css' => array( 'uri' => '/res/6eebb99b/rsrc/css/core/core.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/core/core.css', ), 'phabricator-core-dialog-css' => array( 'uri' => '/res/f66cec41/rsrc/css/core/dialog.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/core/dialog.css', ), 'phabricator-remarkup-css' => array( 'uri' => '/res/786989c3/rsrc/css/core/remarkup.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/core/remarkup.css', ), 'syntax-highlighting-css' => array( 'uri' => '/res/fb673ece/rsrc/css/core/syntax.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/core/syntax.css', ), 'javelin-behavior-dark-console' => array( 'uri' => '/res/020b0265/rsrc/js/application/core/behavior-dark-console.js', 'type' => 'js', 'requires' => array( ), 'disk' => '/rsrc/js/application/core/behavior-dark-console.js', ), 'javelin-behavior-aphront-basic-tokenizer' => array( 'uri' => '/res/8317d761/rsrc/js/application/core/behavior-tokenizer.js', 'type' => 'js', 'requires' => array( 0 => 'javelin-lib-dev', ), 'disk' => '/rsrc/js/application/core/behavior-tokenizer.js', ), 'javelin-behavior-workflow' => array( 'uri' => '/res/15446e7e/rsrc/js/application/core/behavior-workflow.js', 'type' => 'js', 'requires' => array( 0 => 'javelin-lib-dev', ), 'disk' => '/rsrc/js/application/core/behavior-workflow.js', ), 'javelin-behavior-differential-add-reviewers' => array( 'uri' => '/res/330154e4/rsrc/js/application/differential/behavior-add-reviewers.js', 'type' => 'js', 'requires' => array( 0 => 'javelin-lib-dev', ), 'disk' => '/rsrc/js/application/differential/behavior-add-reviewers.js', ), 'javelin-behavior-differential-feedback-preview' => array( 'uri' => '/res/8695d8b8/rsrc/js/application/differential/behavior-comment-preview.js', 'type' => 'js', 'requires' => array( 0 => 'javelin-lib-dev', ), 'disk' => '/rsrc/js/application/differential/behavior-comment-preview.js', ), 'javelin-behavior-differential-diff-radios' => array( 'uri' => '/res/fdeb3823/rsrc/js/application/differential/behavior-diff-radios.js', 'type' => 'js', 'requires' => array( 0 => 'javelin-lib-dev', ), 'disk' => '/rsrc/js/application/differential/behavior-diff-radios.js', ), 'javelin-behavior-differential-edit-inline-comments' => array( 'uri' => '/res/74747b2e/rsrc/js/application/differential/behavior-edit-inline-comments.js', 'type' => 'js', 'requires' => array( 0 => 'javelin-lib-dev', ), 'disk' => '/rsrc/js/application/differential/behavior-edit-inline-comments.js', ), 'javelin-behavior-differential-populate' => array( 'uri' => '/res/a13dcd7e/rsrc/js/application/differential/behavior-populate.js', 'type' => 'js', 'requires' => array( 0 => 'javelin-lib-dev', ), 'disk' => '/rsrc/js/application/differential/behavior-populate.js', ), 'javelin-behavior-differential-show-all-comments' => array( 'uri' => '/res/2a3592b8/rsrc/js/application/differential/behavior-show-all-comments.js', 'type' => 'js', 'requires' => array( 0 => 'javelin-lib-dev', ), 'disk' => '/rsrc/js/application/differential/behavior-show-all-comments.js', ), 'javelin-behavior-differential-show-more' => array( 'uri' => '/res/ea998002/rsrc/js/application/differential/behavior-show-more.js', 'type' => 'js', 'requires' => array( 0 => 'javelin-lib-dev', ), 'disk' => '/rsrc/js/application/differential/behavior-show-more.js', ), + 'javelin-behavior-maniphest-transaction-controls' => + array( + 'uri' => '/res/fc6a8722/rsrc/js/application/maniphest/behavior-transaction-controls.js', + 'type' => 'js', + 'requires' => + array( + 0 => 'javelin-lib-dev', + ), + 'disk' => '/rsrc/js/application/maniphest/behavior-transaction-controls.js', + ), 'javelin-magical-init' => array( 'uri' => '/res/76614f84/rsrc/js/javelin/init.dev.js', 'type' => 'js', 'requires' => array( ), 'disk' => '/rsrc/js/javelin/init.dev.js', ), 'javelin-init-prod' => array( 'uri' => '/res/1267c868/rsrc/js/javelin/init.min.js', 'type' => 'js', 'requires' => array( ), 'disk' => '/rsrc/js/javelin/init.min.js', ), 'javelin-lib-dev' => array( 'uri' => '/res/a0e7a5e9/rsrc/js/javelin/javelin.dev.js', 'type' => 'js', 'requires' => array( ), 'disk' => '/rsrc/js/javelin/javelin.dev.js', ), 'javelin-lib-prod' => array( 'uri' => '/res/2f2b3b2e/rsrc/js/javelin/javelin.min.js', 'type' => 'js', 'requires' => array( ), 'disk' => '/rsrc/js/javelin/javelin.min.js', ), 'javelin-typeahead-dev' => array( 'uri' => '/res/6de6ae59/rsrc/js/javelin/typeahead.dev.js', 'type' => 'js', 'requires' => array( ), 'disk' => '/rsrc/js/javelin/typeahead.dev.js', ), 'javelin-typeahead-prod' => array( 'uri' => '/res/69d5fad1/rsrc/js/javelin/typeahead.min.js', 'type' => 'js', 'requires' => array( ), 'disk' => '/rsrc/js/javelin/typeahead.min.js', ), 'javelin-workflow-dev' => array( 'uri' => '/res/c6b17f93/rsrc/js/javelin/workflow.dev.js', 'type' => 'js', 'requires' => array( ), 'disk' => '/rsrc/js/javelin/workflow.dev.js', ), 'javelin-workflow-prod' => array( 'uri' => '/res/b758e0a0/rsrc/js/javelin/workflow.min.js', 'type' => 'js', 'requires' => array( ), 'disk' => '/rsrc/js/javelin/workflow.min.js', ), ), array ( 'packages' => array ( '8cbb3650' => array ( 'name' => 'core.pkg.css', 'symbols' => array ( 0 => 'phabricator-core-css', 1 => 'phabricator-core-buttons-css', 2 => 'phabricator-standard-page-view', 3 => 'aphront-dialog-view-css', 4 => 'aphront-form-view-css', 5 => 'aphront-panel-view-css', 6 => 'aphront-side-nav-view-css', 7 => 'aphront-table-view-css', 8 => 'aphront-tokenizer-control-css', 9 => 'aphront-typeahead-control-css', 10 => 'phabricator-directory-css', 11 => 'phabricator-remarkup-css', 12 => 'syntax-highlighting-css', ), 'uri' => '/res/pkg/8cbb3650/core.pkg.css', 'type' => 'css', ), '4b8af7b5' => array ( 'name' => 'differential.pkg.css', 'symbols' => array ( 0 => 'differential-core-view-css', 1 => 'differential-changeset-view-css', 2 => 'differential-revision-detail-css', 3 => 'differential-revision-history-css', 4 => 'differential-table-of-contents-css', 5 => 'differential-revision-comment-css', 6 => 'differential-revision-add-comment-css', 7 => 'differential-revision-comment-list-css', ), 'uri' => '/res/pkg/4b8af7b5/differential.pkg.css', 'type' => 'css', ), '30d594cf' => array ( 'name' => 'differential.pkg.js', 'symbols' => array ( 0 => 'javelin-behavior-differential-feedback-preview', 1 => 'javelin-behavior-differential-edit-inline-comments', 2 => 'javelin-behavior-differential-populate', 3 => 'javelin-behavior-differential-show-more', 4 => 'javelin-behavior-differential-diff-radios', ), 'uri' => '/res/pkg/30d594cf/differential.pkg.js', 'type' => 'js', ), ), 'reverse' => array ( 'phabricator-core-css' => '8cbb3650', 'phabricator-core-buttons-css' => '8cbb3650', 'phabricator-standard-page-view' => '8cbb3650', 'aphront-dialog-view-css' => '8cbb3650', 'aphront-form-view-css' => '8cbb3650', 'aphront-panel-view-css' => '8cbb3650', 'aphront-side-nav-view-css' => '8cbb3650', 'aphront-table-view-css' => '8cbb3650', 'aphront-tokenizer-control-css' => '8cbb3650', 'aphront-typeahead-control-css' => '8cbb3650', 'phabricator-directory-css' => '8cbb3650', 'phabricator-remarkup-css' => '8cbb3650', 'syntax-highlighting-css' => '8cbb3650', 'differential-core-view-css' => '4b8af7b5', 'differential-changeset-view-css' => '4b8af7b5', 'differential-revision-detail-css' => '4b8af7b5', 'differential-revision-history-css' => '4b8af7b5', 'differential-table-of-contents-css' => '4b8af7b5', 'differential-revision-comment-css' => '4b8af7b5', 'differential-revision-add-comment-css' => '4b8af7b5', 'differential-revision-comment-list-css' => '4b8af7b5', 'javelin-behavior-differential-feedback-preview' => '30d594cf', 'javelin-behavior-differential-edit-inline-comments' => '30d594cf', 'javelin-behavior-differential-populate' => '30d594cf', 'javelin-behavior-differential-show-more' => '30d594cf', 'javelin-behavior-differential-diff-radios' => '30d594cf', ), )); diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 5f80b68b39..da9c0cc81c 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1,398 +1,426 @@ array( 'Aphront400Response' => 'aphront/response/400', 'Aphront404Response' => 'aphront/response/404', 'AphrontAjaxResponse' => 'aphront/response/ajax', 'AphrontApplicationConfiguration' => 'aphront/applicationconfiguration', 'AphrontController' => 'aphront/controller', 'AphrontDatabaseConnection' => 'storage/connection/base', 'AphrontDefaultApplicationConfiguration' => 'aphront/default/configuration', 'AphrontDefaultApplicationController' => 'aphront/default/controller', 'AphrontDialogResponse' => 'aphront/response/dialog', 'AphrontDialogView' => 'view/dialog', 'AphrontErrorView' => 'view/form/error', 'AphrontException' => 'aphront/exception/base', 'AphrontFileResponse' => 'aphront/response/file', 'AphrontFormCheckboxControl' => 'view/form/control/checkbox', 'AphrontFormControl' => 'view/form/control/base', 'AphrontFormDividerControl' => 'view/form/control/divider', 'AphrontFormFileControl' => 'view/form/control/file', 'AphrontFormMarkupControl' => 'view/form/control/markup', 'AphrontFormPasswordControl' => 'view/form/control/password', 'AphrontFormRecaptchaControl' => 'view/form/control/recaptcha', 'AphrontFormSelectControl' => 'view/form/control/select', 'AphrontFormStaticControl' => 'view/form/control/static', 'AphrontFormSubmitControl' => 'view/form/control/submit', 'AphrontFormTextAreaControl' => 'view/form/control/textarea', 'AphrontFormTextControl' => 'view/form/control/text', 'AphrontFormTokenizerControl' => 'view/form/control/tokenizer', 'AphrontFormView' => 'view/form/base', 'AphrontMySQLDatabaseConnection' => 'storage/connection/mysql', 'AphrontNullView' => 'view/null', 'AphrontPageView' => 'view/page/base', 'AphrontPanelView' => 'view/layout/panel', 'AphrontQueryConnectionException' => 'storage/exception/connection', 'AphrontQueryConnectionLostException' => 'storage/exception/connectionlost', 'AphrontQueryCountException' => 'storage/exception/count', 'AphrontQueryDuplicateKeyException' => 'storage/exception/duplicatekey', 'AphrontQueryException' => 'storage/exception/base', 'AphrontQueryObjectMissingException' => 'storage/exception/objectmissing', 'AphrontQueryParameterException' => 'storage/exception/parameter', 'AphrontQueryRecoverableException' => 'storage/exception/recoverable', 'AphrontRedirectException' => 'aphront/exception/redirect', 'AphrontRedirectResponse' => 'aphront/response/redirect', 'AphrontRequest' => 'aphront/request', 'AphrontRequestFailureView' => 'view/page/failure', 'AphrontResponse' => 'aphront/response/base', 'AphrontSideNavView' => 'view/layout/sidenav', 'AphrontTableView' => 'view/control/table', 'AphrontURIMapper' => 'aphront/mapper', 'AphrontView' => 'view/base', 'AphrontWebpageResponse' => 'aphront/response/webpage', 'CelerityAPI' => 'infrastructure/celerity/api', 'CelerityResourceController' => 'infrastructure/celerity/controller', 'CelerityResourceMap' => 'infrastructure/celerity/map', 'CelerityStaticResourceResponse' => 'infrastructure/celerity/response', 'ConduitAPIMethod' => 'applications/conduit/method/base', 'ConduitAPIRequest' => 'applications/conduit/protocol/request', 'ConduitAPI_conduit_connect_Method' => 'applications/conduit/method/conduit/connect', 'ConduitAPI_differential_creatediff_Method' => 'applications/conduit/method/differential/creatediff', 'ConduitAPI_differential_createrevision_Method' => 'applications/conduit/method/differential/createrevision', 'ConduitAPI_differential_find_Method' => 'applications/conduit/method/differential/find', 'ConduitAPI_differential_parsecommitmessage_Method' => 'applications/conduit/method/differential/parsecommitmessage', 'ConduitAPI_differential_setdiffproperty_Method' => 'applications/conduit/method/differential/setdiffproperty', 'ConduitAPI_differential_updaterevision_Method' => 'applications/conduit/method/differential/updaterevision', 'ConduitAPI_file_upload_Method' => 'applications/conduit/method/file/upload', 'ConduitAPI_user_find_Method' => 'applications/conduit/method/user/find', 'ConduitException' => 'applications/conduit/protocol/exception', 'DarkConsole' => 'aphront/console/api', 'DarkConsoleController' => 'aphront/console/controller', 'DarkConsoleCore' => 'aphront/console/core', 'DarkConsoleErrorLogPlugin' => 'aphront/console/plugin/errorlog', 'DarkConsoleErrorLogPluginAPI' => 'aphront/console/plugin/errorlog/api', 'DarkConsolePlugin' => 'aphront/console/plugin/base', 'DarkConsoleRequestPlugin' => 'aphront/console/plugin/request', 'DarkConsoleServicesPlugin' => 'aphront/console/plugin/services', 'DarkConsoleServicesPluginAPI' => 'aphront/console/plugin/services/api', 'DarkConsoleXHProfPlugin' => 'aphront/console/plugin/xhprof', 'DarkConsoleXHProfPluginAPI' => 'aphront/console/plugin/xhprof/api', 'DifferentialAction' => 'applications/differential/constants/action', 'DifferentialAddCommentView' => 'applications/differential/view/addcomment', 'DifferentialCCWelcomeMail' => 'applications/differential/mail/ccwelcome', 'DifferentialChangeType' => 'applications/differential/constants/changetype', 'DifferentialChangeset' => 'applications/differential/storage/changeset', 'DifferentialChangesetDetailView' => 'applications/differential/view/changesetdetailview', 'DifferentialChangesetListView' => 'applications/differential/view/changesetlistview', 'DifferentialChangesetParser' => 'applications/differential/parser/changeset', 'DifferentialChangesetViewController' => 'applications/differential/controller/changesetview', 'DifferentialComment' => 'applications/differential/storage/comment', 'DifferentialCommentEditor' => 'applications/differential/editor/comment', 'DifferentialCommentMail' => 'applications/differential/mail/comment', 'DifferentialCommentPreviewController' => 'applications/differential/controller/commentpreview', 'DifferentialCommentSaveController' => 'applications/differential/controller/commentsave', 'DifferentialCommitMessage' => 'applications/differential/parser/commitmessage', 'DifferentialCommitMessageParserException' => 'applications/differential/parser/commitmessage/exception', 'DifferentialController' => 'applications/differential/controller/base', 'DifferentialDAO' => 'applications/differential/storage/base', 'DifferentialDiff' => 'applications/differential/storage/diff', 'DifferentialDiffContentMail' => 'applications/differential/mail/diffcontent', 'DifferentialDiffCreateController' => 'applications/differential/controller/diffcreate', 'DifferentialDiffProperty' => 'applications/differential/storage/diffproperty', 'DifferentialDiffTableOfContentsView' => 'applications/differential/view/difftableofcontents', 'DifferentialDiffViewController' => 'applications/differential/controller/diffview', 'DifferentialHunk' => 'applications/differential/storage/hunk', 'DifferentialInlineComment' => 'applications/differential/storage/inlinecomment', 'DifferentialInlineCommentEditController' => 'applications/differential/controller/inlinecommentedit', 'DifferentialInlineCommentPreviewController' => 'applications/differential/controller/inlinecommentpreview', 'DifferentialInlineCommentView' => 'applications/differential/view/inlinecomment', 'DifferentialLintStatus' => 'applications/differential/constants/lintstatus', 'DifferentialMail' => 'applications/differential/mail/base', 'DifferentialMarkupEngineFactory' => 'applications/differential/parser/markup', 'DifferentialNewDiffMail' => 'applications/differential/mail/newdiff', 'DifferentialReviewRequestMail' => 'applications/differential/mail/reviewrequest', 'DifferentialRevision' => 'applications/differential/storage/revision', 'DifferentialRevisionCommentListView' => 'applications/differential/view/revisioncommentlist', 'DifferentialRevisionCommentView' => 'applications/differential/view/revisioncomment', 'DifferentialRevisionControlSystem' => 'applications/differential/constants/revisioncontrolsystem', 'DifferentialRevisionDetailView' => 'applications/differential/view/revisiondetail', 'DifferentialRevisionEditController' => 'applications/differential/controller/revisionedit', 'DifferentialRevisionEditor' => 'applications/differential/editor/revision', 'DifferentialRevisionListController' => 'applications/differential/controller/revisionlist', 'DifferentialRevisionListData' => 'applications/differential/data/revisionlist', 'DifferentialRevisionStatus' => 'applications/differential/constants/revisionstatus', 'DifferentialRevisionUpdateHistoryView' => 'applications/differential/view/revisionupdatehistory', 'DifferentialRevisionViewController' => 'applications/differential/controller/revisionview', 'DifferentialUnitStatus' => 'applications/differential/constants/unitstatus', 'Javelin' => 'infrastructure/javelin/api', 'LiskDAO' => 'storage/lisk/dao', + 'ManiphestController' => 'applications/maniphest/controller/base', + 'ManiphestDAO' => 'applications/maniphest/storage/base', + 'ManiphestTask' => 'applications/maniphest/storage/task', + 'ManiphestTaskCreateController' => 'applications/maniphest/controller/createtask', + 'ManiphestTaskDetailController' => 'applications/maniphest/controller/taskdetail', + 'ManiphestTaskListController' => 'applications/maniphest/controller/tasklist', + 'ManiphestTaskListView' => 'applications/maniphest/view/tasklist', + 'ManiphestTaskPriority' => 'applications/maniphest/constants/priority', + 'ManiphestTaskStatus' => 'applications/maniphest/constants/status', + 'ManiphestTaskSummaryView' => 'applications/maniphest/view/tasksummary', + 'ManiphestTransaction' => 'applications/maniphest/storage/transaction', + 'ManiphestTransactionDetailView' => 'applications/maniphest/view/transactiondetail', + 'ManiphestTransactionEditor' => 'applications/maniphest/editor/transaction', + 'ManiphestTransactionListView' => 'applications/maniphest/view/transactionlist', + 'ManiphestTransactionSaveController' => 'applications/maniphest/controller/transactionsave', + 'ManiphestTransactionType' => 'applications/maniphest/constants/transactiontype', 'Phabricator404Controller' => 'applications/base/controller/404', 'PhabricatorAuthController' => 'applications/auth/controller/base', 'PhabricatorConduitAPIController' => 'applications/conduit/controller/api', 'PhabricatorConduitConnectionLog' => 'applications/conduit/storage/connectionlog', 'PhabricatorConduitConsoleController' => 'applications/conduit/controller/console', 'PhabricatorConduitController' => 'applications/conduit/controller/base', 'PhabricatorConduitDAO' => 'applications/conduit/storage/base', 'PhabricatorConduitLogController' => 'applications/conduit/controller/log', 'PhabricatorConduitMethodCallLog' => 'applications/conduit/storage/methodcalllog', 'PhabricatorController' => 'applications/base/controller/base', 'PhabricatorDirectoryCategory' => 'applications/directory/storage/category', 'PhabricatorDirectoryCategoryDeleteController' => 'applications/directory/controller/categorydelete', 'PhabricatorDirectoryCategoryEditController' => 'applications/directory/controller/categoryedit', 'PhabricatorDirectoryCategoryListController' => 'applications/directory/controller/categorylist', 'PhabricatorDirectoryController' => 'applications/directory/controller/base', 'PhabricatorDirectoryDAO' => 'applications/directory/storage/base', 'PhabricatorDirectoryItem' => 'applications/directory/storage/item', 'PhabricatorDirectoryItemDeleteController' => 'applications/directory/controller/itemdelete', 'PhabricatorDirectoryItemEditController' => 'applications/directory/controller/itemedit', 'PhabricatorDirectoryItemListController' => 'applications/directory/controller/itemlist', 'PhabricatorDirectoryMainController' => 'applications/directory/controller/main', 'PhabricatorDraft' => 'applications/draft/storage/draft', 'PhabricatorDraftDAO' => 'applications/draft/storage/base', 'PhabricatorEmailLoginController' => 'applications/auth/controller/email', 'PhabricatorEmailTokenController' => 'applications/auth/controller/emailtoken', 'PhabricatorEnv' => 'infrastructure/env', 'PhabricatorFacebookAuthController' => 'applications/auth/controller/facebookauth', 'PhabricatorFacebookAuthDiagnosticsController' => 'applications/auth/controller/facebookauth/diagnostics', 'PhabricatorFile' => 'applications/files/storage/file', 'PhabricatorFileController' => 'applications/files/controller/base', 'PhabricatorFileDAO' => 'applications/files/storage/base', 'PhabricatorFileListController' => 'applications/files/controller/list', 'PhabricatorFileStorageBlob' => 'applications/files/storage/storageblob', 'PhabricatorFileURI' => 'applications/files/uri', 'PhabricatorFileUploadController' => 'applications/files/controller/upload', 'PhabricatorFileViewController' => 'applications/files/controller/view', 'PhabricatorLiskDAO' => 'applications/base/storage/lisk', 'PhabricatorLoginController' => 'applications/auth/controller/login', 'PhabricatorLogoutController' => 'applications/auth/controller/logout', 'PhabricatorMailImplementationAdapter' => 'applications/metamta/adapter/base', 'PhabricatorMailImplementationAmazonSESAdapter' => 'applications/metamta/adapter/amazonses', 'PhabricatorMailImplementationPHPMailerLiteAdapter' => 'applications/metamta/adapter/phpmailerlite', 'PhabricatorMetaMTAController' => 'applications/metamta/controller/base', 'PhabricatorMetaMTADAO' => 'applications/metamta/storage/base', 'PhabricatorMetaMTAListController' => 'applications/metamta/controller/list', 'PhabricatorMetaMTAMail' => 'applications/metamta/storage/mail', 'PhabricatorMetaMTAMailingList' => 'applications/metamta/storage/mailinglist', 'PhabricatorMetaMTAMailingListEditController' => 'applications/metamta/controller/mailinglistedit', 'PhabricatorMetaMTAMailingListsController' => 'applications/metamta/controller/mailinglists', 'PhabricatorMetaMTASendController' => 'applications/metamta/controller/send', 'PhabricatorMetaMTAViewController' => 'applications/metamta/controller/view', 'PhabricatorObjectHandle' => 'applications/phid/handle', 'PhabricatorObjectHandleData' => 'applications/phid/handle/data', 'PhabricatorPHID' => 'applications/phid/storage/phid', 'PhabricatorPHIDAllocateController' => 'applications/phid/controller/allocate', 'PhabricatorPHIDController' => 'applications/phid/controller/base', 'PhabricatorPHIDDAO' => 'applications/phid/storage/base', 'PhabricatorPHIDListController' => 'applications/phid/controller/list', 'PhabricatorPHIDLookupController' => 'applications/phid/controller/lookup', 'PhabricatorPHIDType' => 'applications/phid/storage/type', 'PhabricatorPHIDTypeEditController' => 'applications/phid/controller/typeedit', 'PhabricatorPHIDTypeListController' => 'applications/phid/controller/typelist', 'PhabricatorPeopleController' => 'applications/people/controller/base', 'PhabricatorPeopleEditController' => 'applications/people/controller/edit', 'PhabricatorPeopleListController' => 'applications/people/controller/list', 'PhabricatorPeopleProfileController' => 'applications/people/controller/profile', 'PhabricatorStandardPageView' => 'view/page/standard', 'PhabricatorTypeaheadCommonDatasourceController' => 'applications/typeahead/controller/common', 'PhabricatorTypeaheadDatasourceController' => 'applications/typeahead/controller/base', 'PhabricatorUser' => 'applications/people/storage/user', 'PhabricatorUserDAO' => 'applications/people/storage/base', 'PhabricatorUserSettingsController' => 'applications/people/controller/settings', 'PhabricatorXHProfController' => 'applications/xhprof/controller/base', 'PhabricatorXHProfProfileController' => 'applications/xhprof/controller/profile', 'PhabricatorXHProfProfileSymbolView' => 'applications/xhprof/view/symbol', 'PhabricatorXHProfProfileTopLevelView' => 'applications/xhprof/view/toplevel', ), 'function' => array( '_qsprintf_check_scalar_type' => 'storage/qsprintf', '_qsprintf_check_type' => 'storage/qsprintf', 'celerity_generate_unique_node_id' => 'infrastructure/celerity/api', 'celerity_register_resource_map' => 'infrastructure/celerity/map', 'javelin_render_tag' => 'infrastructure/javelin/markup', 'phabricator_format_relative_time' => 'view/utils', 'phabricator_format_timestamp' => 'view/utils', 'phabricator_format_units_generic' => 'view/utils', 'qsprintf' => 'storage/qsprintf', 'queryfx' => 'storage/queryfx', 'queryfx_all' => 'storage/queryfx', 'queryfx_one' => 'storage/queryfx', 'require_celerity_resource' => 'infrastructure/celerity/api', 'vqsprintf' => 'storage/qsprintf', 'vqueryfx' => 'storage/queryfx', 'vqueryfx_all' => 'storage/queryfx', 'xsprintf_query' => 'storage/qsprintf', ), 'requires_class' => array( 'Aphront400Response' => 'AphrontResponse', 'Aphront404Response' => 'AphrontResponse', 'AphrontAjaxResponse' => 'AphrontResponse', 'AphrontDefaultApplicationConfiguration' => 'AphrontApplicationConfiguration', 'AphrontDefaultApplicationController' => 'AphrontController', 'AphrontDialogResponse' => 'AphrontResponse', 'AphrontDialogView' => 'AphrontView', 'AphrontErrorView' => 'AphrontView', 'AphrontFileResponse' => 'AphrontResponse', 'AphrontFormCheckboxControl' => 'AphrontFormControl', 'AphrontFormControl' => 'AphrontView', 'AphrontFormDividerControl' => 'AphrontFormControl', 'AphrontFormFileControl' => 'AphrontFormControl', 'AphrontFormMarkupControl' => 'AphrontFormControl', 'AphrontFormPasswordControl' => 'AphrontFormControl', 'AphrontFormRecaptchaControl' => 'AphrontFormControl', 'AphrontFormSelectControl' => 'AphrontFormControl', 'AphrontFormStaticControl' => 'AphrontFormControl', 'AphrontFormSubmitControl' => 'AphrontFormControl', 'AphrontFormTextAreaControl' => 'AphrontFormControl', 'AphrontFormTextControl' => 'AphrontFormControl', 'AphrontFormTokenizerControl' => 'AphrontFormControl', 'AphrontFormView' => 'AphrontView', 'AphrontMySQLDatabaseConnection' => 'AphrontDatabaseConnection', 'AphrontNullView' => 'AphrontView', 'AphrontPageView' => 'AphrontView', 'AphrontPanelView' => 'AphrontView', 'AphrontQueryConnectionException' => 'AphrontQueryException', 'AphrontQueryConnectionLostException' => 'AphrontQueryRecoverableException', 'AphrontQueryCountException' => 'AphrontQueryException', 'AphrontQueryDuplicateKeyException' => 'AphrontQueryException', 'AphrontQueryObjectMissingException' => 'AphrontQueryException', 'AphrontQueryParameterException' => 'AphrontQueryException', 'AphrontQueryRecoverableException' => 'AphrontQueryException', 'AphrontRedirectException' => 'AphrontException', 'AphrontRedirectResponse' => 'AphrontResponse', 'AphrontRequestFailureView' => 'AphrontView', 'AphrontSideNavView' => 'AphrontView', 'AphrontTableView' => 'AphrontView', 'AphrontWebpageResponse' => 'AphrontResponse', 'CelerityResourceController' => 'AphrontController', 'ConduitAPI_conduit_connect_Method' => 'ConduitAPIMethod', 'ConduitAPI_differential_creatediff_Method' => 'ConduitAPIMethod', 'ConduitAPI_differential_createrevision_Method' => 'ConduitAPIMethod', 'ConduitAPI_differential_find_Method' => 'ConduitAPIMethod', 'ConduitAPI_differential_parsecommitmessage_Method' => 'ConduitAPIMethod', 'ConduitAPI_differential_setdiffproperty_Method' => 'ConduitAPIMethod', 'ConduitAPI_differential_updaterevision_Method' => 'ConduitAPIMethod', 'ConduitAPI_file_upload_Method' => 'ConduitAPIMethod', 'ConduitAPI_user_find_Method' => 'ConduitAPIMethod', 'DarkConsoleController' => 'PhabricatorController', 'DarkConsoleErrorLogPlugin' => 'DarkConsolePlugin', 'DarkConsoleRequestPlugin' => 'DarkConsolePlugin', 'DarkConsoleServicesPlugin' => 'DarkConsolePlugin', 'DarkConsoleXHProfPlugin' => 'DarkConsolePlugin', 'DifferentialAddCommentView' => 'AphrontView', 'DifferentialCCWelcomeMail' => 'DifferentialReviewRequestMail', 'DifferentialChangeset' => 'DifferentialDAO', 'DifferentialChangesetDetailView' => 'AphrontView', 'DifferentialChangesetListView' => 'AphrontView', 'DifferentialChangesetViewController' => 'DifferentialController', 'DifferentialComment' => 'DifferentialDAO', 'DifferentialCommentMail' => 'DifferentialMail', 'DifferentialCommentPreviewController' => 'DifferentialController', 'DifferentialCommentSaveController' => 'DifferentialController', 'DifferentialController' => 'PhabricatorController', 'DifferentialDAO' => 'PhabricatorLiskDAO', 'DifferentialDiff' => 'DifferentialDAO', 'DifferentialDiffContentMail' => 'DifferentialMail', 'DifferentialDiffCreateController' => 'DifferentialController', 'DifferentialDiffProperty' => 'DifferentialDAO', 'DifferentialDiffTableOfContentsView' => 'AphrontView', 'DifferentialDiffViewController' => 'DifferentialController', 'DifferentialHunk' => 'DifferentialDAO', 'DifferentialInlineComment' => 'DifferentialDAO', 'DifferentialInlineCommentEditController' => 'DifferentialController', 'DifferentialInlineCommentPreviewController' => 'DifferentialController', 'DifferentialInlineCommentView' => 'AphrontView', 'DifferentialNewDiffMail' => 'DifferentialReviewRequestMail', 'DifferentialReviewRequestMail' => 'DifferentialMail', 'DifferentialRevision' => 'DifferentialDAO', 'DifferentialRevisionCommentListView' => 'AphrontView', 'DifferentialRevisionCommentView' => 'AphrontView', 'DifferentialRevisionDetailView' => 'AphrontView', 'DifferentialRevisionEditController' => 'DifferentialController', 'DifferentialRevisionListController' => 'DifferentialController', 'DifferentialRevisionUpdateHistoryView' => 'AphrontView', 'DifferentialRevisionViewController' => 'DifferentialController', + 'ManiphestController' => 'PhabricatorController', + 'ManiphestDAO' => 'PhabricatorLiskDAO', + 'ManiphestTask' => 'ManiphestDAO', + 'ManiphestTaskCreateController' => 'ManiphestController', + 'ManiphestTaskDetailController' => 'ManiphestController', + 'ManiphestTaskListController' => 'ManiphestController', + 'ManiphestTaskListView' => 'AphrontView', + 'ManiphestTaskSummaryView' => 'AphrontView', + 'ManiphestTransaction' => 'ManiphestDAO', + 'ManiphestTransactionDetailView' => 'AphrontView', + 'ManiphestTransactionListView' => 'AphrontView', + 'ManiphestTransactionSaveController' => 'ManiphestController', 'Phabricator404Controller' => 'PhabricatorController', 'PhabricatorAuthController' => 'PhabricatorController', 'PhabricatorConduitAPIController' => 'PhabricatorConduitController', 'PhabricatorConduitConnectionLog' => 'PhabricatorConduitDAO', 'PhabricatorConduitConsoleController' => 'PhabricatorConduitController', 'PhabricatorConduitController' => 'PhabricatorController', 'PhabricatorConduitDAO' => 'PhabricatorLiskDAO', 'PhabricatorConduitLogController' => 'PhabricatorConduitController', 'PhabricatorConduitMethodCallLog' => 'PhabricatorConduitDAO', 'PhabricatorController' => 'AphrontController', 'PhabricatorDirectoryCategory' => 'PhabricatorDirectoryDAO', 'PhabricatorDirectoryCategoryDeleteController' => 'PhabricatorDirectoryController', 'PhabricatorDirectoryCategoryEditController' => 'PhabricatorDirectoryController', 'PhabricatorDirectoryCategoryListController' => 'PhabricatorDirectoryController', 'PhabricatorDirectoryController' => 'PhabricatorController', 'PhabricatorDirectoryDAO' => 'PhabricatorLiskDAO', 'PhabricatorDirectoryItem' => 'PhabricatorDirectoryDAO', 'PhabricatorDirectoryItemDeleteController' => 'PhabricatorDirectoryController', 'PhabricatorDirectoryItemEditController' => 'PhabricatorDirectoryController', 'PhabricatorDirectoryItemListController' => 'PhabricatorDirectoryController', 'PhabricatorDirectoryMainController' => 'PhabricatorDirectoryController', 'PhabricatorDraft' => 'PhabricatorDraftDAO', 'PhabricatorDraftDAO' => 'PhabricatorLiskDAO', 'PhabricatorEmailLoginController' => 'PhabricatorAuthController', 'PhabricatorEmailTokenController' => 'PhabricatorAuthController', 'PhabricatorFacebookAuthController' => 'PhabricatorAuthController', 'PhabricatorFacebookAuthDiagnosticsController' => 'PhabricatorAuthController', 'PhabricatorFile' => 'PhabricatorFileDAO', 'PhabricatorFileController' => 'PhabricatorController', 'PhabricatorFileDAO' => 'PhabricatorLiskDAO', 'PhabricatorFileListController' => 'PhabricatorFileController', 'PhabricatorFileStorageBlob' => 'PhabricatorFileDAO', 'PhabricatorFileUploadController' => 'PhabricatorFileController', 'PhabricatorFileViewController' => 'PhabricatorFileController', 'PhabricatorLiskDAO' => 'LiskDAO', 'PhabricatorLoginController' => 'PhabricatorAuthController', 'PhabricatorLogoutController' => 'PhabricatorAuthController', 'PhabricatorMailImplementationAmazonSESAdapter' => 'PhabricatorMailImplementationAdapter', 'PhabricatorMailImplementationPHPMailerLiteAdapter' => 'PhabricatorMailImplementationAdapter', 'PhabricatorMetaMTAController' => 'PhabricatorController', 'PhabricatorMetaMTADAO' => 'PhabricatorLiskDAO', 'PhabricatorMetaMTAListController' => 'PhabricatorMetaMTAController', 'PhabricatorMetaMTAMail' => 'PhabricatorMetaMTADAO', 'PhabricatorMetaMTAMailingList' => 'PhabricatorMetaMTADAO', 'PhabricatorMetaMTAMailingListEditController' => 'PhabricatorMetaMTAController', 'PhabricatorMetaMTAMailingListsController' => 'PhabricatorMetaMTAController', 'PhabricatorMetaMTASendController' => 'PhabricatorMetaMTAController', 'PhabricatorMetaMTAViewController' => 'PhabricatorMetaMTAController', 'PhabricatorPHID' => 'PhabricatorPHIDDAO', 'PhabricatorPHIDAllocateController' => 'PhabricatorPHIDController', 'PhabricatorPHIDController' => 'PhabricatorController', 'PhabricatorPHIDDAO' => 'PhabricatorLiskDAO', 'PhabricatorPHIDListController' => 'PhabricatorPHIDController', 'PhabricatorPHIDLookupController' => 'PhabricatorPHIDController', 'PhabricatorPHIDType' => 'PhabricatorPHIDDAO', 'PhabricatorPHIDTypeEditController' => 'PhabricatorPHIDController', 'PhabricatorPHIDTypeListController' => 'PhabricatorPHIDController', 'PhabricatorPeopleController' => 'PhabricatorController', 'PhabricatorPeopleEditController' => 'PhabricatorPeopleController', 'PhabricatorPeopleListController' => 'PhabricatorPeopleController', 'PhabricatorPeopleProfileController' => 'PhabricatorPeopleController', 'PhabricatorStandardPageView' => 'AphrontPageView', 'PhabricatorTypeaheadCommonDatasourceController' => 'PhabricatorTypeaheadDatasourceController', 'PhabricatorTypeaheadDatasourceController' => 'PhabricatorController', 'PhabricatorUser' => 'PhabricatorUserDAO', 'PhabricatorUserDAO' => 'PhabricatorLiskDAO', 'PhabricatorUserSettingsController' => 'PhabricatorPeopleController', 'PhabricatorXHProfController' => 'PhabricatorController', 'PhabricatorXHProfProfileController' => 'PhabricatorXHProfController', 'PhabricatorXHProfProfileSymbolView' => 'AphrontView', 'PhabricatorXHProfProfileTopLevelView' => 'AphrontView', ), 'requires_interface' => array( ), )); diff --git a/src/aphront/console/plugin/request/DarkConsoleRequestPlugin.php b/src/aphront/console/plugin/request/DarkConsoleRequestPlugin.php index 1c155eec4b..77dea1566c 100755 --- a/src/aphront/console/plugin/request/DarkConsoleRequestPlugin.php +++ b/src/aphront/console/plugin/request/DarkConsoleRequestPlugin.php @@ -1,76 +1,76 @@ $_REQUEST, 'Server' => $_SERVER, ); } public function render() { $data = $this->getData(); $sections = array( 'Basics' => array( 'Host' => $data['Server']['SERVER_ADDR'], 'Hostname' => gethostbyaddr($data['Server']['SERVER_ADDR']), 'Machine' => php_uname('n'), ), ); $sections = array_merge($sections, $data); $out = array(); foreach ($sections as $header => $map) { $rows = array(); foreach ($map as $key => $value) { $rows[] = array( phutil_escape_html($key), - phutil_escape_html($value), + phutil_escape_html(is_array($value) ? json_encode($value) : $value), ); } $table = new AphrontTableView($rows); $table->setHeaders( array( $header, null, )); $table->setColumnClasses( array( 'header', 'wide wrap', )); $out[] = $table->render(); } return implode("\n", $out); } } diff --git a/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php b/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php index 82240be5db..1d9a30a173 100644 --- a/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php +++ b/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php @@ -1,226 +1,239 @@ array( '$' => 'RepositoryListController', 'new/$' => 'RepositoryEditController', 'edit/(?P\d+)/$' => 'RepositoryEditController', 'delete/(?P\d+)/$' => 'RepositoryDeleteController', ), '/' => array( '$' => 'PhabricatorDirectoryMainController', ), '/directory/' => array( 'item/$' => 'PhabricatorDirectoryItemListController', 'item/edit/(?:(?P\d+)/)?$' => 'PhabricatorDirectoryItemEditController', 'item/delete/(?P\d+)/' => 'PhabricatorDirectoryItemDeleteController', 'category/$' => 'PhabricatorDirectoryCategoryListController', 'category/edit/(?:(?P\d+)/)?$' => 'PhabricatorDirectoryCategoryEditController', 'category/delete/(?P\d+)/' => 'PhabricatorDirectoryCategoryDeleteController', ), '/file/' => array( '$' => 'PhabricatorFileListController', 'upload/$' => 'PhabricatorFileUploadController', '(?Pinfo)/(?P[^/]+)/' => 'PhabricatorFileViewController', '(?Pview)/(?P[^/]+)/' => 'PhabricatorFileViewController', '(?Pdownload)/(?P[^/]+)/' => 'PhabricatorFileViewController', ), '/phid/' => array( '$' => 'PhabricatorPHIDLookupController', 'list/$' => 'PhabricatorPHIDListController', 'type/$' => 'PhabricatorPHIDTypeListController', 'type/edit/(?:(?P\d+)/)?$' => 'PhabricatorPHIDTypeEditController', 'new/$' => 'PhabricatorPHIDAllocateController', ), '/people/' => array( '$' => 'PhabricatorPeopleListController', 'edit/(?:(?P\w+)/)?$' => 'PhabricatorPeopleEditController', ), '/p/(?P\w+)/$' => 'PhabricatorPeopleProfileController', '/conduit/' => array( '$' => 'PhabricatorConduitConsoleController', 'method/(?P[^/]+)$' => 'PhabricatorConduitConsoleController', 'log/$' => 'PhabricatorConduitLogController', ), '/api/(?P[^/]+)$' => 'PhabricatorConduitAPIController', '/D(?P\d+)' => 'DifferentialRevisionViewController', '/differential/' => array( '$' => 'DifferentialRevisionListController', 'filter/(?P\w+)/$' => 'DifferentialRevisionListController', 'diff/' => array( '(?P\d+)/$' => 'DifferentialDiffViewController', 'create/$' => 'DifferentialDiffCreateController', ), 'changeset/$' => 'DifferentialChangesetViewController', 'revision/edit/(?:(?P\d+)/)?$' => 'DifferentialRevisionEditController', 'comment/' => array( 'preview/(?P\d+)/$' => 'DifferentialCommentPreviewController', 'save/$' => 'DifferentialCommentSaveController', 'inline/' => array( 'preview/(?P\d+)/$' => 'DifferentialInlineCommentPreviewController', 'edit/(?P\d+)/$' => 'DifferentialInlineCommentEditController', ), ), ), '/res/' => array( '(?Ppkg/)?(?P[a-f0-9]{8})/(?P.+\.(?:css|js))$' => 'CelerityResourceController', ), '/typeahead/' => array( 'common/(?P\w+)/$' => 'PhabricatorTypeaheadCommonDatasourceController', ), '/mail/' => array( '$' => 'PhabricatorMetaMTAListController', 'send/$' => 'PhabricatorMetaMTASendController', 'view/(?P\d+)/$' => 'PhabricatorMetaMTAViewController', 'lists/$' => 'PhabricatorMetaMTAMailingListsController', 'lists/edit/(?:(?P\d+)/)?$' => 'PhabricatorMetaMTAMailingListEditController', ), '/login/' => array( '$' => 'PhabricatorLoginController', 'email/$' => 'PhabricatorEmailLoginController', 'etoken/(?P\w+)/$' => 'PhabricatorEmailTokenController', ), '/logout/$' => 'PhabricatorLogoutController', '/facebook-auth/' => array( '$' => 'PhabricatorFacebookAuthController', 'diagnose/$' => 'PhabricatorFacebookAuthDiagnosticsController', ), '/xhprof/' => array( 'profile/(?P[^/]+)/$' => 'PhabricatorXHProfProfileController', ), '/~/' => 'DarkConsoleController', '/settings/' => array( '(?:page/(?P[^/]+)/)?$' => 'PhabricatorUserSettingsController', ), + + '/maniphest/' => array( + '$' => 'ManiphestTaskListController', + 'view/(?P\w+)/$' => 'ManiphestTaskListController', + 'task/' => array( + 'create/' => 'ManiphestTaskCreateController', + ), + 'transaction/' => array( + 'save/' => 'ManiphestTransactionSaveController', + ), + ), + + '/T(?P\d+)$' => 'ManiphestTaskDetailController', ); } public function buildRequest() { $request = new AphrontRequest($this->getHost(), $this->getPath()); $request->setRequestData($_GET + $_POST); $request->setApplicationConfiguration($this); return $request; } public function handleException(Exception $ex) { $class = phutil_escape_html(get_class($ex)); $message = phutil_escape_html($ex->getMessage()); $content = '
'. '

Unhandled Exception "'.$class.'": '.$message.'

'. ''.phutil_escape_html((string)$ex).''. '
'; $view = new PhabricatorStandardPageView(); $view->setRequest($this->getRequest()); $view->appendChild($content); $response = new AphrontWebpageResponse(); $response->setContent($view->render()); return $response; } public function willSendResponse(AphrontResponse $response) { $request = $this->getRequest(); if ($response instanceof AphrontDialogResponse) { if (!$request->isAjax()) { $view = new PhabricatorStandardPageView(); $view->setRequest($request); $view->appendChild( '
'. $response->buildResponseString(). '
'); $response = new AphrontWebpageResponse(); $response->setContent($view->render()); return $response; } else { return id(new AphrontAjaxResponse()) ->setContent(array( 'dialog' => $response->buildResponseString(), )); } } else if ($response instanceof AphrontRedirectResponse) { if ($request->isAjax()) { return id(new AphrontAjaxResponse()) ->setContent( array( 'redirect' => $response->getURI(), )); } } else if ($response instanceof Aphront404Response) { $failure = new AphrontRequestFailureView(); $failure->setHeader('404 Not Found'); $failure->appendChild( '

The page you requested was not found.

'); $view = new PhabricatorStandardPageView(); $view->setTitle('404 Not Found'); $view->setRequest($this->getRequest()); $view->appendChild($failure); $response = new AphrontWebpageResponse(); $response->setContent($view->render()); $response->setHTTPResponseCode(404); return $response; } return $response; } public function build404Controller() { return array(new Phabricator404Controller($this->getRequest()), array()); } } diff --git a/src/applications/maniphest/constants/priority/ManiphestTaskPriority.php b/src/applications/maniphest/constants/priority/ManiphestTaskPriority.php new file mode 100644 index 0000000000..fa52e3d9d6 --- /dev/null +++ b/src/applications/maniphest/constants/priority/ManiphestTaskPriority.php @@ -0,0 +1,42 @@ + 'Unbreak Now!', + self::PRIORITY_TRIAGE => 'Needs Triage', + self::PRIORITY_HIGH => 'High', + self::PRIORITY_NORMAL => 'Normal', + self::PRIORITY_LOW => 'Low', + self::PRIORITY_WISH => 'Wishlist', + ); + } + + public static function getTaskPriorityName($priority) { + return idx(self::getTaskPriorityMap(), $priority, '???'); + } +} diff --git a/src/applications/maniphest/constants/priority/__init__.php b/src/applications/maniphest/constants/priority/__init__.php new file mode 100644 index 0000000000..791832bac4 --- /dev/null +++ b/src/applications/maniphest/constants/priority/__init__.php @@ -0,0 +1,12 @@ + 'Open', + self::STATUS_CLOSED_RESOLVED => 'Resolved', + self::STATUS_CLOSED_WONTFIX => 'Wontfix', + self::STATUS_CLOSED_INVALID => 'Invalid', + self::STATUS_CLOSED_DUPLICATE => 'Duplicate', + self::STATUS_CLOSED_SPITE => 'Spite', + ); + } + + public static function getTaskStatusFullName($status) { + $map = array( + self::STATUS_OPEN => 'Open', + self::STATUS_CLOSED_RESOLVED => 'Closed, Resolved', + self::STATUS_CLOSED_WONTFIX => 'Closed, Wontfix', + self::STATUS_CLOSED_INVALID => 'Closed, Invalid', + self::STATUS_CLOSED_DUPLICATE => 'Closed, Duplicate', + self::STATUS_CLOSED_SPITE => 'Closed out of Spite', + ); + return idx($map, $status, '???'); + } + +} diff --git a/src/applications/maniphest/constants/status/__init__.php b/src/applications/maniphest/constants/status/__init__.php new file mode 100644 index 0000000000..0b7212d908 --- /dev/null +++ b/src/applications/maniphest/constants/status/__init__.php @@ -0,0 +1,12 @@ + 'Comment', + self::TYPE_STATUS => 'Close Task', + self::TYPE_OWNER => 'Reassign / Claim', + self::TYPE_CCS => 'Add CCs', + self::TYPE_PRIORITY => 'Change Priority', + ); + } + +} diff --git a/src/applications/maniphest/constants/transactiontype/__init__.php b/src/applications/maniphest/constants/transactiontype/__init__.php new file mode 100644 index 0000000000..2d1616cc7d --- /dev/null +++ b/src/applications/maniphest/constants/transactiontype/__init__.php @@ -0,0 +1,10 @@ +buildStandardPageView(); + + $page->setApplicationName('Maniphest'); + $page->setBaseURI('/maniphest/'); + $page->setTitle(idx($data, 'title')); + $page->setGlyph("\xE2\x9A\x93"); + $page->appendChild($view); + + $response = new AphrontWebpageResponse(); + return $response->setContent($page->render()); + } + +} diff --git a/src/applications/maniphest/controller/base/__init__.php b/src/applications/maniphest/controller/base/__init__.php new file mode 100644 index 0000000000..04b0fcd7dc --- /dev/null +++ b/src/applications/maniphest/controller/base/__init__.php @@ -0,0 +1,15 @@ +getRequest(); + $user = $request->getUser(); + + $task = new ManiphestTask(); + + $task->setPriority(ManiphestTaskPriority::PRIORITY_TRIAGE); + + $errors = array(); + $e_title = true; + + if ($request->isFormPost()) { + $task->setTitle($request->getStr('title')); + $task->setAuthorPHID($user->getPHID()); + $owner_tokenizer = $request->getArr('assigned_to'); + $task->setOwnerPHID(reset($owner_tokenizer)); + $task->setCCPHIDs($request->getArr('cc')); + $task->setPriority($request->getInt('priority')); + $task->setDescription($request->getStr('description')); + + if (!strlen($task->getTitle())) { + $e_title = 'Required'; + $errors[] = 'Title is required.'; + } + + if (!$errors) { + $transaction = new ManiphestTransaction(); + $transaction->setAuthorPHID($user->getPHID()); + $transaction->setTransactionType(ManiphestTransactionType::TYPE_STATUS); + $transaction->setNewValue(ManiphestTaskStatus::STATUS_OPEN); + + $editor = new ManiphestTransactionEditor(); + $editor->applyTransaction($task, $transaction); + + return id(new AphrontRedirectResponse()) + ->setURI('/T'.$task->getID()); + } + } + + $phids = array_merge( + array($task->getOwnerPHID()), + nonempty($task->getCCPHIDs(), array())); + $phids = array_filter($phids); + $phids = array_unique($phids); + + $handles = id(new PhabricatorObjectHandleData($phids)) + ->loadHandles($phids); + + $tvalues = mpull($handles, 'getFullName', 'getPHID'); + + $error_view = null; + if ($errors) { + $error_view = new AphrontErrorView(); + $error_view->setErrors($errors); + $error_view->setTitle('Form Errors'); + } + + $priority_map = ManiphestTaskPriority::getTaskPriorityMap(); + + if ($task->getOwnerPHID()) { + $assigned_value = array( + $task->getOwnerPHID() => $handles[$task->getOwnerPHID()]->getFullName(), + ); + } else { + $assigned_value = array(); + } + + if ($task->getCCPHIDs()) { + $cc_value = array_select_keys($tvalues, $task->getCCPHIDs()); + } else { + $cc_value = array(); + } + + $form = new AphrontFormView(); + $form + ->setUser($user) + ->appendChild( + id(new AphrontFormTextAreaControl()) + ->setLabel('Title') + ->setName('title') + ->setError($e_title) + ->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_SHORT) + ->setValue($task->getTitle())) + ->appendChild( + id(new AphrontFormTokenizerControl()) + ->setLabel('Assigned To') + ->setName('assigned_to') + ->setValue($assigned_value) + ->setDatasource('/typeahead/common/users/') + ->setLimit(1)) + ->appendChild( + id(new AphrontFormTokenizerControl()) + ->setLabel('CC') + ->setName('cc') + ->setValue($cc_value) + ->setDatasource('/typeahead/common/mailable/')) + ->appendChild( + id(new AphrontFormSelectControl()) + ->setLabel('Priority') + ->setName('priority') + ->setOptions($priority_map) + ->setValue($task->getPriority())) + ->appendChild( + id(new AphrontFormTextAreaControl()) + ->setLabel('Description') + ->setName('description') + ->setValue($task->getDescription())) + ->appendChild( + id(new AphrontFormSubmitControl()) + ->setValue('Create Task')); + + $panel = new AphrontPanelView(); + $panel->setWidth(AphrontPanelView::WIDTH_FULL); + $panel->setHeader('Create New Task'); + $panel->appendChild($form); + + return $this->buildStandardPageResponse( + array( + $error_view, + $panel, + ), + array( + 'title' => 'Create Task', + )); + } +} diff --git a/src/applications/maniphest/controller/createtask/__init__.php b/src/applications/maniphest/controller/createtask/__init__.php new file mode 100644 index 0000000000..580a9fec9a --- /dev/null +++ b/src/applications/maniphest/controller/createtask/__init__.php @@ -0,0 +1,26 @@ +id = $data['id']; + } + + public function processRequest() { + + $request = $this->getRequest(); + $user = $request->getUser(); + + $e_title = null; + + $priority_map = ManiphestTaskPriority::getTaskPriorityMap(); + + $task = id(new ManiphestTask())->load($this->id); + + $transactions = id(new ManiphestTransaction())->loadAllWhere( + 'taskID = %d', + $task->getID()); + + $phids = array(); + foreach ($transactions as $transaction) { + foreach ($transaction->extractPHIDs() as $phid) { + $phids[$phid] = true; + } + } + foreach ($task->getCCPHIDs() as $phid) { + $phids[$phid] = true; + } + if ($task->getOwnerPHID()) { + $phids[$task->getOwnerPHID()] = true; + } + $phids[$task->getAuthorPHID()] = true; + $phids = array_keys($phids); + + $handles = id(new PhabricatorObjectHandleData($phids)) + ->loadHandles(); + + $factory = new DifferentialMarkupEngineFactory(); + $engine = $factory->newDifferentialCommentMarkupEngine(); + + $dict = array(); + $dict['Status'] = + ''. + ManiphestTaskStatus::getTaskStatusFullName($task->getStatus()). + ''; + + $dict['Assigned To'] = $task->getOwnerPHID() + ? 'None' + : $handles[$task->getOwnerPHID()]->renderLink(); + + $dict['Priority'] = ManiphestTaskPriority::getTaskPriorityName( + $task->getPriority()); + + $cc = $task->getCCPHIDs(); + if ($cc) { + $cc_links = array(); + foreach ($cc as $phid) { + $cc_links[] = $handles[$phid]->renderLink(); + } + $dict['CC'] = implode(', ', $cc_links); + } else { + $dict['CC'] = 'None'; + } + + $dict['Author'] = $handles[$task->getAuthorPHID()]->renderLink(); + + $dict['Description'] = $engine->markupText($task->getDescription()); + + require_celerity_resource('mainphest-task-detail-css'); + + $table = array(); + foreach ($dict as $key => $value) { + $table[] = + ''. + ''.phutil_escape_html($key).':'. + ''.$value.''. + ''; + } + $table = + ''. + implode("\n", $table). + '
'; + + $panel = + '
'. + '
'. + '

'. + phutil_escape_html('T'.$task->getID().' '.$task->getTitle()). + '

'. + $table. + '
'. + '
'; + + $transaction_types = ManiphestTransactionType::getTransactionTypeMap(); + $resolution_types = ManiphestTaskStatus::getTaskStatusMap(); + + if ($task->getStatus() == ManiphestTaskStatus::STATUS_OPEN) { + $resolution_types = array_select_keys( + $resolution_types, + array( + ManiphestTaskStatus::STATUS_CLOSED_RESOLVED, + ManiphestTaskStatus::STATUS_CLOSED_WONTFIX, + ManiphestTaskStatus::STATUS_CLOSED_INVALID, + ManiphestTaskStatus::STATUS_CLOSED_SPITE, + )); + } else { + $resolution_types = array( + ManiphestTaskStatus::STATUS_OPEN => 'Reopened', + ); + $transaction_types[ManiphestTransactionType::TYPE_STATUS] = + 'Reopen Task'; + unset($transaction_types[ManiphestTransactionType::TYPE_PRIORITY]); + unset($transaction_types[ManiphestTransactionType::TYPE_OWNER]); + } + + $default_claim = array( + $user->getPHID() => $user->getUsername().' ('.$user->getRealName().')', + ); + + $comment_form = new AphrontFormView(); + $comment_form + ->setUser($user) + ->setAction('/maniphest/transaction/save/') + ->addHiddenInput('taskID', $task->getID()) + ->appendChild( + id(new AphrontFormSelectControl()) + ->setLabel('Action') + ->setName('action') + ->setOptions($transaction_types) + ->setID('transaction-action')) + ->appendChild( + id(new AphrontFormSelectControl()) + ->setLabel('Resolution') + ->setName('resolution') + ->setControlID('resolution') + ->setControlStyle('display: none') + ->setOptions($resolution_types)) + ->appendChild( + id(new AphrontFormTokenizerControl()) + ->setLabel('Assign To') + ->setName('assign_to') + ->setControlID('assign_to') + ->setControlStyle('display: none') + ->setID('assign-tokenizer') + ->setDisableBehavior(true)) + ->appendChild( + id(new AphrontFormTokenizerControl()) + ->setLabel('CCs') + ->setName('ccs') + ->setControlID('ccs') + ->setControlStyle('display: none') + ->setID('cc-tokenizer') + ->setDisableBehavior(true)) + ->appendChild( + id(new AphrontFormSelectControl()) + ->setLabel('Priority') + ->setName('priority') + ->setOptions($priority_map) + ->setControlID('priority') + ->setControlStyle('display: none') + ->setValue($task->getPriority())) + ->appendChild( + id(new AphrontFormTextAreaControl()) + ->setLabel('Comments') + ->setName('comments') + ->setValue('')) + ->appendChild( + id(new AphrontFormSubmitControl()) + ->setValue('Avast!')); + + Javelin::initBehavior('maniphest-transaction-controls', array( + 'select' => 'transaction-action', + 'controlMap' => array( + ManiphestTransactionType::TYPE_STATUS => 'resolution', + ManiphestTransactionType::TYPE_OWNER => 'assign_to', + ManiphestTransactionType::TYPE_CCS => 'ccs', + ManiphestTransactionType::TYPE_PRIORITY => 'priority', + ), + 'tokenizers' => array( + ManiphestTransactionType::TYPE_OWNER => array( + 'id' => 'assign-tokenizer', + 'src' => '/typeahead/common/users/', + 'value' => $default_claim, + 'limit' => 1, + ), + ManiphestTransactionType::TYPE_CCS => array( + 'id' => 'cc-tokenizer', + 'src' => '/typeahead/common/mailable/', + ), + ), + )); + + $comment_panel = new AphrontPanelView(); + $comment_panel->appendChild($comment_form); + $comment_panel->setHeader('Leap Into Action'); + + $transaction_view = new ManiphestTransactionListView(); + $transaction_view->setTransactions($transactions); + $transaction_view->setHandles($handles); + $transaction_view->setUser($user); + $transaction_view->setMarkupEngine($engine); + + return $this->buildStandardPageResponse( + array( + $panel, + $transaction_view, + $comment_panel, + ), + array( + 'title' => 'Create Task', + )); + } +} diff --git a/src/applications/maniphest/controller/taskdetail/__init__.php b/src/applications/maniphest/controller/taskdetail/__init__.php new file mode 100644 index 0000000000..98cc671b92 --- /dev/null +++ b/src/applications/maniphest/controller/taskdetail/__init__.php @@ -0,0 +1,28 @@ +view = idx($data, 'view'); + } + + public function processRequest() { + + $views = array( + 'action' => 'Action Required', +// 'activity' => 'Recently Active', +// 'closed' => 'Recently Closed', + 'created' => 'Created', + 'triage' => 'Need Triage', + ); + + if (empty($views[$this->view])) { + $this->view = key($views); + } + + $tasks = $this->loadTasks(); + + $nav = new AphrontSideNavView(); + foreach ($views as $view => $name) { + $nav->addNavItem( + phutil_render_tag( + 'a', + array( + 'href' => '/maniphest/view/'.$view.'/', + 'class' => ($this->view == $view) + ? 'aphront-side-nav-selected' + : null, + ), + phutil_escape_html($name))); + } + + $handle_phids = mpull($tasks, 'getOwnerPHID'); + $handles = id(new PhabricatorObjectHandleData($handle_phids)) + ->loadHandles(); + + $task_list = new ManiphestTaskListView(); + $task_list->setTasks($tasks); + $task_list->setHandles($handles); + + $nav->appendChild( + ''); + $nav->appendChild($task_list); + + return $this->buildStandardPageResponse( + $nav, + array( + 'title' => 'Task List', + )); + } + + private function loadTasks() { + $request = $this->getRequest(); + $user = $request->getUser(); + + $phids = array($user->getPHID()); + + switch ($this->view) { + case 'action': + return id(new ManiphestTask())->loadAllWhere( + 'ownerPHID in (%Ls) AND status = 0', + $phids); + case 'created': + return id(new ManiphestTask())->loadAllWhere( + 'authorPHID in (%Ls) AND status = 0', + $phids); + case 'triage': + return id(new ManiphestTask())->loadAllWhere( + 'status = %d', + ManiphestTaskPriority::PRIORITY_TRIAGE); + } + + return array(); + } + + +} diff --git a/src/applications/maniphest/controller/tasklist/__init__.php b/src/applications/maniphest/controller/tasklist/__init__.php new file mode 100644 index 0000000000..17b4309e18 --- /dev/null +++ b/src/applications/maniphest/controller/tasklist/__init__.php @@ -0,0 +1,20 @@ +getRequest(); + $user = $request->getUser(); + + $task = id(new ManiphestTask())->load($request->getStr('taskID')); + if (!$task) { + return new Aphront404Response(); + } + + $action = $request->getStr('action'); + + $transaction = new ManiphestTransaction(); + $transaction + ->setAuthorPHID($user->getPHID()) + ->setComments($request->getStr('comments')) + ->setTransactionType($action); + + switch ($action) { + case ManiphestTransactionType::TYPE_NONE: + break; + case ManiphestTransactionType::TYPE_STATUS: + $transaction->setNewValue($request->getStr('resolution')); + break; + case ManiphestTransactionType::TYPE_OWNER: + $assign_to = $request->getArr('assign_to'); + $assign_to = reset($assign_to); + $transaction->setNewValue($assign_to); + break; + case ManiphestTransactionType::TYPE_CCS: + $ccs = $request->getArr('ccs'); + $transaction->setNewValue($ccs); + break; + case ManiphestTransactionType::TYPE_PRIORITY: + $transaction->setNewValue($request->getInt('priority')); + break; + default: + throw new Exception('unknown action'); + } + + $editor = new ManiphestTransactionEditor(); + $editor->applyTransaction($task, $transaction); + + return id(new AphrontRedirectResponse()) + ->setURI('/T'.$task->getID()); + } + +} diff --git a/src/applications/maniphest/controller/transactionsave/__init__.php b/src/applications/maniphest/controller/transactionsave/__init__.php new file mode 100644 index 0000000000..abe8106998 --- /dev/null +++ b/src/applications/maniphest/controller/transactionsave/__init__.php @@ -0,0 +1,20 @@ +getTransactionType(); + + $new = $transaction->getNewValue(); + + $email_cc = $task->getCCPHIDs(); + + $email_to = array(); + $email_to[] = $task->getOwnerPHID(); + $email_to[] = $transaction->getAuthorPHID(); + + switch ($type) { + case ManiphestTransactionType::TYPE_NONE: + $old = null; + break; + case ManiphestTransactionType::TYPE_STATUS: + $old = $task->getStatus(); + break; + case ManiphestTransactionType::TYPE_OWNER: + $old = $task->getOwnerPHID(); + break; + case ManiphestTransactionType::TYPE_CCS: + $old = $task->getCCPHIDs(); + $new = array_unique(array_merge($old, $new)); + break; + case ManiphestTransactionType::TYPE_PRIORITY: + $old = $task->getPriority(); + break; + default: + throw new Exception('Unknown action type.'); + } + + if (($old !== null) && ($old == $new)) { + $transaction->setOldValue(null); + $transaction->setNewValue(null); + $transaction->setTransactionType(ManiphestTransactionType::TYPE_NONE); + } else { + switch ($type) { + case ManiphestTransactionType::TYPE_NONE: + break; + case ManiphestTransactionType::TYPE_STATUS: + $task->setStatus($new); + break; + case ManiphestTransactionType::TYPE_OWNER: + $task->setOwnerPHID($new); + break; + case ManiphestTransactionType::TYPE_CCS: + $task->setCCPHIDs($new); + break; + case ManiphestTransactionType::TYPE_PRIORITY: + $task->setPriority($new); + break; + default: + throw new Exception('Unknown action type.'); + } + + $transaction->setOldValue($old); + $transaction->setNewValue($new); + } + + $task->save(); + $transaction->setTaskID($task->getID()); + $transaction->save(); + + $email_to[] = $task->getOwnerPHID(); + $email_cc = array_merge($email_cc, $task->getCCPHIDs()); + + $this->sendEmail($task, $transaction, $email_to, $email_cc); + } + + private function sendEmail($task, $transaction, $email_to, $email_cc) { + $email_to = array_filter(array_unique($email_to)); + $email_cc = array_filter(array_unique($email_cc)); + + $transactions = array($transaction); + + $phids = array(); + foreach ($transactions as $transaction) { + foreach ($transaction->extractPHIDs() as $phid) { + $phids[$phid] = true; + } + } + $phids = array_keys($phids); + + $handles = id(new PhabricatorObjectHandleData($phids)) + ->loadHandles(); + + + $view = new ManiphestTransactionDetailView(); + $view->setTransaction($transaction); + $view->setHandles($handles); + + list($action, $body) = $view->renderForEmail($with_date = false); + + $task_uri = PhabricatorEnv::getURI('/T'.$task->getID()); + + $body .= + "\n\n". + "TASK DETAIL\n". + " ".$task_uri."\n"; + + id(new PhabricatorMetaMTAMail()) + ->setSubject( + '[Maniphest] '.$action.': T'.$task->getID().' '.$task->getTitle()) + ->setFrom($transaction->getAuthorPHID()) + ->addTos($email_to) + ->addCCs($email_cc) + ->setBody($body) + ->save(); + } +} diff --git a/src/applications/maniphest/editor/transaction/__init__.php b/src/applications/maniphest/editor/transaction/__init__.php new file mode 100644 index 0000000000..fd66574fbd --- /dev/null +++ b/src/applications/maniphest/editor/transaction/__init__.php @@ -0,0 +1,18 @@ + true, + self::CONFIG_SERIALIZATION => array( + 'ccPHIDs' => self::SERIALIZATION_JSON, + 'relatedPHIDs' => self::SERIALIZATION_JSON, + ), + ) + parent::getConfiguration(); + } + + public function generatePHID() { + return PhabricatorPHID::generateNewPHID('TASK'); + } + +} diff --git a/src/applications/maniphest/storage/task/__init__.php b/src/applications/maniphest/storage/task/__init__.php new file mode 100644 index 0000000000..2290666547 --- /dev/null +++ b/src/applications/maniphest/storage/task/__init__.php @@ -0,0 +1,13 @@ + array( + 'oldValue' => self::SERIALIZATION_JSON, + 'newValue' => self::SERIALIZATION_JSON, + ), + ) + parent::getConfiguration(); + } + + public function extractPHIDs() { + $phids = array(); + + switch ($this->getTransactionType()) { + case ManiphestTransactionType::TYPE_CCS: + foreach ($this->getOldValue() as $phid) { + $phids[] = $phid; + } + foreach ($this->getNewValue() as $phid) { + $phids[] = $phid; + } + break; + case ManiphestTransactionType::TYPE_OWNER: + $phids[] = $this->getOldValue(); + $phids[] = $this->getNewValue(); + break; + } + + $phids[] = $this->getAuthorPHID(); + + return $phids; + } + +} diff --git a/src/applications/maniphest/storage/transaction/__init__.php b/src/applications/maniphest/storage/transaction/__init__.php new file mode 100644 index 0000000000..c4e475868c --- /dev/null +++ b/src/applications/maniphest/storage/transaction/__init__.php @@ -0,0 +1,13 @@ +tasks = $tasks; + return $this; + } + + public function setHandles(array $handles) { + $this->handles = $handles; + return $this; + } + + public function render() { + + $views = array(); + foreach ($this->tasks as $task) { + $view = new ManiphestTaskSummaryView($task); + $view->setTask($task); + $view->setHandles($this->handles); + $views[] = $view->render(); + } + + return + '
'. + implode("\n", $views). + '
'; + } + +} diff --git a/src/applications/maniphest/view/tasklist/__init__.php b/src/applications/maniphest/view/tasklist/__init__.php new file mode 100644 index 0000000000..5a35a49ef4 --- /dev/null +++ b/src/applications/maniphest/view/tasklist/__init__.php @@ -0,0 +1,13 @@ +task = $task; + return $this; + } + + public function setHandles(array $handles) { + $this->handles = $handles; + return $this; + } + + public function render() { + $task = $this->task; + $handles = $this->handles; + + require_celerity_resource('maniphest-task-summary-css'); + + return + ''. + ''. + ''. + ''. + ''. + ''. + '
'. + 'T'.$task->getID(). + ''. + $handles[$task->getOwnerPHID()]->renderLink(). + ''. + phutil_render_tag( + 'a', + array( + 'href' => '/T'.$task->getID(), + ), + phutil_escape_html($task->getTitle())). + ''. + ManiphestTaskPriority::getTaskPriorityName($task->getPriority()). + ''. + phabricator_format_timestamp($task->getDateModified()). + '
'; + } + +} diff --git a/src/applications/maniphest/view/tasksummary/__init__.php b/src/applications/maniphest/view/tasksummary/__init__.php new file mode 100644 index 0000000000..8c6a3ec782 --- /dev/null +++ b/src/applications/maniphest/view/tasksummary/__init__.php @@ -0,0 +1,17 @@ +transaction = $transaction; + return $this; + } + + public function setHandles(array $handles) { + $this->handles = $handles; + return $this; + } + + public function setMarkupEngine(PhutilMarkupEngine $engine) { + $this->markupEngine = $engine; + return $this; + } + + public function renderForEmail($with_date) { + $this->forEmail = true; + list ($verb, $desc, $classes) = $this->describeAction(); + + $transaction = $this->transaction; + $author = $this->renderHandles(array($transaction->getAuthorPHID())); + + $desc = $author.' '.$desc; + if ($with_date) { + $desc = 'On '.date('M jS \a\t g:i A', $transaction->getDateCreated()). + ', '.$desc; + } + + $comments = $transaction->getComments(); + if (strlen(trim($comments))) { + $desc = $desc.":\n".$comments; + } else { + $desc = $desc."."; + } + + $this->forEmail = false; + return array($verb, $desc); + } + + public function render() { + $transaction = $this->transaction; + $handles = $this->handles; + + require_celerity_resource('maniphest-transaction-detail-css'); + + $author = $this->handles[$transaction->getAuthorPHID()]; + + $comments = $transaction->getCache(); + if (!strlen($comments)) { + $comments = $transaction->getComments(); + if (strlen($comments)) { + $comments = $this->markupEngine->markupText($comments); + $transaction->setCache($comments); + $transaction->save(); + } + } + + list($verb, $desc, $classes) = $this->describeAction( + $transaction->getComments()); + + $more_classes = implode(' ', $classes); + + if (strlen(trim($transaction->getComments()))) { + $punc = ':'; + } else { + $punc = '.'; + } + + return phutil_render_tag( + 'div', + array( + 'class' => "maniphest-transaction-detail-container", + 'style' => "background-image: url('".$author->getImageURI()."')", + ), + '
'. + '
'. + '
'. + phabricator_format_timestamp($transaction->getDateCreated()). + '
'. + ''. + $author->renderLink(). + ' '. + $desc. + $punc. + ''. + '
'. + '
'. + $comments. + '
'. + '
'); + } + + private function describeAction() { + $verb = null; + $desc = null; + $classes = array(); + + $handles = $this->handles; + + $transaction = $this->transaction; + $type = $transaction->getTransactionType(); + $author_phid = $transaction->getAuthorPHID(); + $new = $transaction->getNewValue(); + $old = $transaction->getOldValue(); + switch ($type) { + case ManiphestTransactionType::TYPE_NONE: + $verb = 'Commented On'; + $desc = 'added a comment'; + break; + case ManiphestTransactionType::TYPE_OWNER: + if ($transaction->getAuthorPHID() == $new) { + $verb = 'Claimed'; + $desc = 'claimed this task'; + } else if (!$new) { + $verb = 'Up For Grabs'; + $desc = 'placed this task up for grabs'; + } else if (!$old) { + $verb = 'Assigned'; + $desc = 'assigned this task to '.$this->renderHandles(array($new)); + } else { + $verb = 'Reassigned'; + $desc = 'reassigned this task from '. + $this->renderHandles(array($old)). + ' to '. + $this->renderHandles(array($new)); + } + break; + case ManiphestTransactionType::TYPE_CCS: + $added = array_diff($new, $old); + $removed = array_diff($old, $new); + if ($added && !$removed) { + $verb = 'Added CC'; + if (count($added) == 1) { + $desc = 'added '.$this->renderHandles($added).' to CC'; + } else { + $desc = 'added CCs: '.$this->renderHandles($added); + } + } else if ($removed && !$added) { + $verb = 'Removed CC'; + if (count($removed) == 1) { + $desc = 'removed '.$this->renderHandles($removed).' from CC'; + } else { + $desc = 'removed CCs: '.$this->renderHandles($removed); + } + } else { + $verb = 'Changed CC'; + $desc = 'changed CCs, added: '.$this->renderHandles($added).'; '. + 'removed: '.$this->renderHandles($removed); + } + break; + case ManiphestTransactionType::TYPE_STATUS: + if ($new == ManiphestTaskStatus::STATUS_OPEN) { + if ($old) { + $verb = 'Reopened'; + $desc = 'reopened this task'; + } else { + $verb = 'Created'; + $desc = 'created this task'; + } + } else if ($new == ManiphestTaskStatus::STATUS_CLOSED_SPITE) { + $verb = 'Spited'; + $desc = 'closed this task out of spite'; + } else { + $verb = 'Closed'; + $full = idx(ManiphestTaskStatus::getTaskStatusMap(), $new, '???'); + $desc = 'closed this task as "'.$full.'"'; + } + break; + case ManiphestTransactionType::TYPE_PRIORITY: + $old_name = ManiphestTaskPriority::getTaskPriorityName($old); + $new_name = ManiphestTaskPriority::getTaskPriorityName($new); + + if ($old == ManiphestTaskPriority::PRIORITY_TRIAGE) { + $verb = 'Triaged'; + $desc = 'triaged this task as "'.$new_name.'" priority'; + } else if ($old > $new) { + $verb = 'Lowered Priority'; + $desc = 'lowered the priority of this task from "'.$old_name.'" to '. + '"'.$new_name.'"'; + } else { + $verb = 'Raised Priority'; + $desc = 'raised the priority of this task from "'.$old_name.'" to '. + '"'.$new_name.'"'; + } + break; + default: + return ' brazenly '.$type."'d"; + } + + return array($verb, $desc, $classes); + } + + private function renderHandles($phids) { + $links = array(); + foreach ($phids as $phid) { + if ($this->forEmail) { + $links[] = $this->handles[$phid]->getName(); + } else { + $links[] = $this->handles[$phid]->renderLink(); + } + } + return implode(', ', $links); + } + +} diff --git a/src/applications/maniphest/view/transactiondetail/__init__.php b/src/applications/maniphest/view/transactiondetail/__init__.php new file mode 100644 index 0000000000..9f08794372 --- /dev/null +++ b/src/applications/maniphest/view/transactiondetail/__init__.php @@ -0,0 +1,20 @@ +transactions = $transactions; + return $this; + } + + public function setHandles(array $handles) { + $this->handles = $handles; + return $this; + } + + public function setUser(PhabricatorUser $user) { + $this->user = $user; + return $this; + } + + public function setMarkupEngine(PhutilMarkupEngine $engine) { + $this->markupEngine = $engine; + return $this; + } + + public function render() { + + $views = array(); + foreach ($this->transactions as $transaction) { + $view = new ManiphestTransactionDetailView($transaction); + $view->setTransaction($transaction); + $view->setHandles($this->handles); + $view->setMarkupEngine($this->markupEngine); + $views[] = $view->render(); + } + + return + '
'. + implode("\n", $views). + '
'; + } + +} diff --git a/src/applications/maniphest/view/transactionlist/__init__.php b/src/applications/maniphest/view/transactionlist/__init__.php new file mode 100644 index 0000000000..8c06249c94 --- /dev/null +++ b/src/applications/maniphest/view/transactionlist/__init__.php @@ -0,0 +1,13 @@ +datasource = $datasource; return $this; } public function setDisableBehavior($disable) { $this->disableBehavior = $disable; return $this; } protected function getCustomControlClass() { return 'aphront-form-control-tokenizer'; } + public function setLimit($limit) { + $this->limit = $limit; + return $this; + } + protected function renderInput() { require_celerity_resource('aphront-tokenizer-control-css'); require_celerity_resource('javelin-typeahead-dev'); $tokens = array(); $values = nonempty($this->getValue(), array()); foreach ($values as $key => $value) { $tokens[] = $this->renderToken($key, $value); } $name = $this->getName(); $input = javelin_render_tag( 'input', array( 'mustcapture' => true, 'name' => $name, 'class' => 'jx-tokenizer-input', 'sigil' => 'tokenizer', 'style' => 'width: 0px;', 'disabled' => 'disabled', 'type' => 'text', )); if ($this->getID()) { $id = $this->getID(); } else { $id = celerity_generate_unique_node_id(); } if (!$this->disableBehavior) { Javelin::initBehavior('aphront-basic-tokenizer', array( 'id' => $id, 'src' => $this->datasource, 'value' => $values, + 'limit' => $this->limit, )); } return phutil_render_tag( 'div', array( 'id' => $id, 'class' => 'jx-tokenizer-container', ), implode('', $tokens). $input. '
'); return phutil_render_tag( 'input', array( 'type' => 'text', 'name' => $this->getName(), - 'value' => $this->getValue(), 'disabled' => $this->getDisabled() ? 'disabled' : null, )); } private function renderToken($key, $value) { $input_name = $this->getName(); if ($input_name) { $input_name .= '[]'; } return phutil_render_tag( 'a', array( 'class' => 'jx-tokenizer-token', ), phutil_escape_html($value). phutil_render_tag( 'input', array( 'type' => 'hidden', 'name' => $input_name, 'value' => $key, )). ''); } } diff --git a/src/view/page/standard/PhabricatorStandardPageView.php b/src/view/page/standard/PhabricatorStandardPageView.php index d3732da0f9..ef0ab6fcc4 100755 --- a/src/view/page/standard/PhabricatorStandardPageView.php +++ b/src/view/page/standard/PhabricatorStandardPageView.php @@ -1,238 +1,237 @@ request = $request; return $this; } public function getRequest() { return $this->request; } public function setApplicationName($application_name) { $this->applicationName = $application_name; return $this; } public function getApplicationName() { return $this->applicationName; } public function setBaseURI($base_uri) { $this->baseURI = $base_uri; return $this; } public function getBaseURI() { return $this->baseURI; } public function setTabs(array $tabs, $selected_tab) { $this->tabs = $tabs; $this->selectedTab = $selected_tab; return $this; } public function getTitle() { return $this->getGlyph().' '.parent::getTitle(); } protected function willRenderPage() { if (!$this->getRequest()) { throw new Exception( "You must set the Request to render a PhabricatorStandardPageView."); } $console = $this->getRequest()->getApplicationConfiguration()->getConsole(); require_celerity_resource('phabricator-core-css'); require_celerity_resource('phabricator-core-buttons-css'); require_celerity_resource('phabricator-standard-page-view'); require_celerity_resource('javelin-lib-dev'); require_celerity_resource('javelin-workflow-dev'); Javelin::initBehavior('workflow', array()); if ($console) { require_celerity_resource('aphront-dark-console-css'); Javelin::initBehavior( 'dark-console', array( 'uri' => '/~/', )); } $this->bodyContent = $this->renderChildren(); } protected function getHead() { $response = CelerityAPI::getStaticResourceResponse(); return $response->renderResourcesOfType('css'). ''. ''; } public function setGlyph($glyph) { $this->glyph = $glyph; return $this; } public function getGlyph() { return $this->glyph; } protected function willSendResponse($response) { $console = $this->getRequest()->getApplicationConfiguration()->getConsole(); if ($console) { $response = str_replace( '', $console->render($this->getRequest()), $response); } return $response; } protected function getBody() { $console = $this->getRequest()->getApplicationConfiguration()->getConsole(); $tabs = array(); foreach ($this->tabs as $name => $tab) { $tabs[] = phutil_render_tag( 'a', array( 'href' => idx($tab, 'href'), 'class' => ($name == $this->selectedTab) ? 'phabricator-selected-tab' : null, ), phutil_escape_html(idx($tab, 'name'))); } $tabs = implode('', $tabs); if ($tabs) { $tabs = ''.$tabs.''; } $login_stuff = null; $request = $this->getRequest(); if ($request) { $user = $request->getUser(); if ($user->getPHID()) { $login_stuff = 'Logged in as '.phutil_escape_html($user->getUsername()). ' · '. 'Settings'. ' · '. '
'. phutil_render_tag( 'input', array( 'type' => 'hidden', 'name' => '__csrf__', 'value' => $user->getCSRFToken(), )). phutil_render_tag( 'input', array( 'type' => 'hidden', 'name' => '__form__', 'value' => true, )). ''. '
'; } } $foot_links = array(); $version = PhabricatorEnv::getEnvConfig('phabricator.version'); $foot_links[] = phutil_escape_html('Phabricator '.$version); if (PhabricatorEnv::getEnvConfig('darkconsole.enabled') && !PhabricatorEnv::getEnvConfig('darkconsole.always-on')) { if ($console) { $link = javelin_render_tag( 'a', array( 'href' => '/~/', 'sigil' => 'workflow', ), 'Disable DarkConsole'); } else { $link = javelin_render_tag( 'a', array( 'href' => '/~/', 'sigil' => 'workflow', ), 'Enable DarkConsole'); } $foot_links[] = $link; } $foot_links = implode(' · ', $foot_links); - return ($console ? '' : null). '
'. '
'. ''. 'Phabricator '. phutil_render_tag( 'a', array( 'href' => $this->getBaseURI(), 'class' => 'phabricator-head-appname', ), phutil_escape_html($this->getApplicationName())). $tabs. '
'. $this->bodyContent. '
'. '
'. '
'. $foot_links. '
'; } protected function getTail() { $response = CelerityAPI::getStaticResourceResponse(); return $response->renderResourcesOfType('js'). $response->renderHTMLFooter(); } } diff --git a/webroot/rsrc/css/application/maniphest/task-detail.css b/webroot/rsrc/css/application/maniphest/task-detail.css new file mode 100644 index 0000000000..602840d9e6 --- /dev/null +++ b/webroot/rsrc/css/application/maniphest/task-detail.css @@ -0,0 +1,44 @@ +/** + * @provides mainphest-task-detail-css + */ + +.maniphest-panel { + margin: .5em 2em .25em; + border: 1px solid #666622; + background: #efefdf; + padding: 15px 20px; + font-size: 13px; +} + +.maniphest-panel h1 { + border-bottom: 1px solid #aaaa99; + padding-bottom: 8px; + margin-bottom: 8px; +} + + +.maniphest-task-properties { + font-size: 12px; + width: 100%; +} + +.maniphest-task-properties tt { + letter-spacing: 1.1px; +} + +.maniphest-task-properties th { + font-weight: bold; + width: 100px; + text-align: right; + padding: 3px 4px 3px 3px; + color: #333333; + white-space: nowrap; +} + +.maniphest-task-properties td { + padding: 3px 2px; +} + +.maniphest-task-detail-core { + margin-right: 265px; +} diff --git a/webroot/rsrc/css/application/maniphest/task-summary.css b/webroot/rsrc/css/application/maniphest/task-summary.css new file mode 100644 index 0000000000..30630cfc5e --- /dev/null +++ b/webroot/rsrc/css/application/maniphest/task-summary.css @@ -0,0 +1,43 @@ +/** + * @provides maniphest-task-summary-css + */ + +.maniphest-task-summary { + border: 1px solid #aaaaaa; + width: 100%; + margin: 2px 0; + border-collapse: separate; + border-spacing: 1px; +} + +.maniphest-task-summary td { + padding: 4px 1%; + background: #dfdfdf; + white-space: nowrap; +} + +.maniphest-task-summary td.maniphest-task-number { + font-weight: bold; + color: #444444; + width: 8%; +} + +.maniphest-task-summary td.maniphest-task-owner { + width: 11%; +} + +.maniphest-task-summary td.maniphest-task-name { + overflow: hidden; + font-weight: bold; + width: 49%; +} + +.maniphest-task-summary td.maniphest-task-priority { + text-align: center; + width: 11%; +} + +.maniphest-task-summary td.maniphest-task-updated { + text-align: center; + width: 11%; +} diff --git a/webroot/rsrc/css/application/maniphest/transaction-detail.css b/webroot/rsrc/css/application/maniphest/transaction-detail.css new file mode 100644 index 0000000000..46a23e52ff --- /dev/null +++ b/webroot/rsrc/css/application/maniphest/transaction-detail.css @@ -0,0 +1,23 @@ +/** + * @provides maniphest-transaction-detail-css + */ + +.maniphest-transaction-detail-container { + margin: 2px 1em 3px; + background: 0px 0px no-repeat; + min-height: 50px; +} + +.maniphest-transaction-detail-view { + margin-left: 54px; + padding: 4px 1em; + border: 1px solid #dddddd; + background: #f6f6f6; + min-height: 40px; +} + +.maniphest-transaction-timestamp { + float: right; + font-size: 11px; + color: #666666; +} diff --git a/webroot/rsrc/js/application/maniphest/behavior-transaction-controls.js b/webroot/rsrc/js/application/maniphest/behavior-transaction-controls.js new file mode 100644 index 0000000000..f384c2aadb --- /dev/null +++ b/webroot/rsrc/js/application/maniphest/behavior-transaction-controls.js @@ -0,0 +1,81 @@ +/** + * @provides javelin-behavior-maniphest-transaction-controls + * @requires javelin-lib-dev + */ + +JX.behavior('maniphest-transaction-controls', function(config) { + + var tokenizers = {}; + + for (var k in config.tokenizers) { + var tconfig = config.tokenizers[k]; + var root = JX.$(tconfig.id); + var datasource = new JX.TypeaheadPreloadedSource(tconfig.src); + + var typeahead = new JX.Typeahead(root); + typeahead.setDatasource(datasource); + + var tokenizer = new JX.Tokenizer(root); + tokenizer.setTypeahead(typeahead); + + if (tconfig.limit) { + tokenizer.setLimit(tconfig.limit); + } + + tokenizer.start(); + + + if (tconfig.value) { + for (var jj in tconfig.value) { + tokenizer.addToken(jj, tconfig.value[jj]); + } + } + + tokenizers[k] = tokenizer; + } + + JX.DOM.listen( + JX.$(config.select), + 'change', + null, + function(e) { + for (var k in config.controlMap) { + if (k == JX.$(config.select).value) { + JX.DOM.show(JX.$(config.controlMap[k])); + if (tokenizers[k]) { + tokenizers[k].refresh(); + } + } else { + JX.DOM.hide(JX.$(config.controlMap[k])); + } + } + }); + +/* + + var root = JX.$(config.tokenizer); + var datasource = new JX.TypeaheadPreloadedSource(config.src); + + var typeahead = new JX.Typeahead(root); + typeahead.setDatasource(datasource); + + var tokenizer = new JX.Tokenizer(root); + tokenizer.setTypeahead(typeahead); + tokenizer.start(); + + JX.DOM.listen( + JX.$(config.select), + 'change', + null, + function(e) { + if (JX.$(config.select).value == 'add_reviewers') { + JX.DOM.show(JX.$(config.row)); + tokenizer.refresh(); + } else { + JX.DOM.hide(JX.$(config.row)); + } + }); + +*/ +}); +