mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-13 17:16:14 +01:00
(stable) Promote 2019 Week 16
This commit is contained in:
commit
f040a591e6
289 changed files with 7967 additions and 4389 deletions
|
@ -9,8 +9,8 @@ return array(
|
|||
'names' => array(
|
||||
'conpherence.pkg.css' => '3c8a0668',
|
||||
'conpherence.pkg.js' => '020aebcf',
|
||||
'core.pkg.css' => '7e6e954b',
|
||||
'core.pkg.js' => 'a747b035',
|
||||
'core.pkg.css' => '3dc188c0',
|
||||
'core.pkg.js' => '9ac8af68',
|
||||
'differential.pkg.css' => '8d8360fb',
|
||||
'differential.pkg.js' => '67e02996',
|
||||
'diffusion.pkg.css' => '42c75c37',
|
||||
|
@ -30,14 +30,14 @@ return array(
|
|||
'rsrc/css/aphront/notification.css' => '30240bd2',
|
||||
'rsrc/css/aphront/panel-view.css' => '46923d46',
|
||||
'rsrc/css/aphront/phabricator-nav-view.css' => 'f8a0c1bf',
|
||||
'rsrc/css/aphront/table-view.css' => '7dc3a9c2',
|
||||
'rsrc/css/aphront/table-view.css' => '5f13a9e4',
|
||||
'rsrc/css/aphront/tokenizer.css' => 'b52d0668',
|
||||
'rsrc/css/aphront/tooltip.css' => 'e3f2412f',
|
||||
'rsrc/css/aphront/typeahead-browse.css' => 'b7ed02d2',
|
||||
'rsrc/css/aphront/typeahead.css' => '8779483d',
|
||||
'rsrc/css/application/almanac/almanac.css' => '2e050f4f',
|
||||
'rsrc/css/application/auth/auth.css' => 'add92fd8',
|
||||
'rsrc/css/application/base/main-menu-view.css' => '8e2d9a28',
|
||||
'rsrc/css/application/base/main-menu-view.css' => '17b71bbc',
|
||||
'rsrc/css/application/base/notification-menu.css' => '4df1ee30',
|
||||
'rsrc/css/application/base/phui-theme.css' => '35883b37',
|
||||
'rsrc/css/application/base/standard-page-view.css' => '8a295cb9',
|
||||
|
@ -58,7 +58,7 @@ return array(
|
|||
'rsrc/css/application/contentsource/content-source-view.css' => 'cdf0d579',
|
||||
'rsrc/css/application/countdown/timer.css' => 'bff8012f',
|
||||
'rsrc/css/application/daemon/bulk-job.css' => '73af99f5',
|
||||
'rsrc/css/application/dashboard/dashboard.css' => '4267d6c6',
|
||||
'rsrc/css/application/dashboard/dashboard.css' => '5a205b9d',
|
||||
'rsrc/css/application/diff/inline-comment-summary.css' => '81eb368d',
|
||||
'rsrc/css/application/differential/add-comment.css' => '7e5900d9',
|
||||
'rsrc/css/application/differential/changeset-view.css' => 'bde53589',
|
||||
|
@ -86,7 +86,7 @@ return array(
|
|||
'rsrc/css/application/paste/paste.css' => 'b37bcd38',
|
||||
'rsrc/css/application/people/people-picture-menu-item.css' => 'fe8e07cf',
|
||||
'rsrc/css/application/people/people-profile.css' => '2ea2daa1',
|
||||
'rsrc/css/application/phame/phame.css' => '799febf9',
|
||||
'rsrc/css/application/phame/phame.css' => 'bb442327',
|
||||
'rsrc/css/application/pholio/pholio-edit.css' => '4df55b3b',
|
||||
'rsrc/css/application/pholio/pholio-inline-comments.css' => '722b48c2',
|
||||
'rsrc/css/application/pholio/pholio.css' => '88ef5ef1',
|
||||
|
@ -100,7 +100,7 @@ return array(
|
|||
'rsrc/css/application/policy/policy.css' => 'ceb56a08',
|
||||
'rsrc/css/application/ponder/ponder-view.css' => '05a09d0a',
|
||||
'rsrc/css/application/project/project-card-view.css' => '4e7371cd',
|
||||
'rsrc/css/application/project/project-triggers.css' => 'cb866c2d',
|
||||
'rsrc/css/application/project/project-triggers.css' => 'cd9c8bb9',
|
||||
'rsrc/css/application/project/project-view.css' => '567858b3',
|
||||
'rsrc/css/application/releeph/releeph-core.css' => 'f81ff2db',
|
||||
'rsrc/css/application/releeph/releeph-preview-branch.css' => '22db5c07',
|
||||
|
@ -128,13 +128,13 @@ return array(
|
|||
'rsrc/css/phui/calendar/phui-calendar-list.css' => 'ccd7e4e2',
|
||||
'rsrc/css/phui/calendar/phui-calendar-month.css' => 'cb758c42',
|
||||
'rsrc/css/phui/calendar/phui-calendar.css' => 'f11073aa',
|
||||
'rsrc/css/phui/object-item/phui-oi-big-ui.css' => '534f1757',
|
||||
'rsrc/css/phui/object-item/phui-oi-big-ui.css' => 'fa74cc35',
|
||||
'rsrc/css/phui/object-item/phui-oi-color.css' => 'b517bfa0',
|
||||
'rsrc/css/phui/object-item/phui-oi-drag-ui.css' => 'da15d3dc',
|
||||
'rsrc/css/phui/object-item/phui-oi-flush-ui.css' => '490e2e2e',
|
||||
'rsrc/css/phui/object-item/phui-oi-list-view.css' => 'a65865a7',
|
||||
'rsrc/css/phui/object-item/phui-oi-list-view.css' => 'd7723ecc',
|
||||
'rsrc/css/phui/object-item/phui-oi-simple-ui.css' => '6a30fa46',
|
||||
'rsrc/css/phui/phui-action-list.css' => 'c4972757',
|
||||
'rsrc/css/phui/phui-action-list.css' => 'e820263c',
|
||||
'rsrc/css/phui/phui-action-panel.css' => '6c386cbf',
|
||||
'rsrc/css/phui/phui-badge.css' => '666e25ad',
|
||||
'rsrc/css/phui/phui-basic-nav-view.css' => '56ebd66d',
|
||||
|
@ -160,11 +160,11 @@ return array(
|
|||
'rsrc/css/phui/phui-icon-set-selector.css' => '7aa5f3ec',
|
||||
'rsrc/css/phui/phui-icon.css' => '4cbc684a',
|
||||
'rsrc/css/phui/phui-image-mask.css' => '62c7f4d2',
|
||||
'rsrc/css/phui/phui-info-view.css' => '37b8d9ce',
|
||||
'rsrc/css/phui/phui-info-view.css' => 'a10a909b',
|
||||
'rsrc/css/phui/phui-invisible-character-view.css' => 'c694c4a4',
|
||||
'rsrc/css/phui/phui-left-right.css' => '68513c34',
|
||||
'rsrc/css/phui/phui-lightbox.css' => '4ebf22da',
|
||||
'rsrc/css/phui/phui-list.css' => '470b1adb',
|
||||
'rsrc/css/phui/phui-list.css' => 'b05144dd',
|
||||
'rsrc/css/phui/phui-object-box.css' => 'f434b6be',
|
||||
'rsrc/css/phui/phui-pager.css' => 'd022c7ad',
|
||||
'rsrc/css/phui/phui-pinboard-view.css' => '1f08f5d8',
|
||||
|
@ -173,7 +173,7 @@ return array(
|
|||
'rsrc/css/phui/phui-segment-bar-view.css' => '5166b370',
|
||||
'rsrc/css/phui/phui-spacing.css' => 'b05cadc3',
|
||||
'rsrc/css/phui/phui-status.css' => 'e5ff8be0',
|
||||
'rsrc/css/phui/phui-tag-view.css' => '29409667',
|
||||
'rsrc/css/phui/phui-tag-view.css' => '8519160a',
|
||||
'rsrc/css/phui/phui-timeline-view.css' => '1e348e4b',
|
||||
'rsrc/css/phui/phui-two-column-view.css' => '01e6991e',
|
||||
'rsrc/css/phui/workboards/phui-workboard-color.css' => 'e86de308',
|
||||
|
@ -217,7 +217,7 @@ return array(
|
|||
'rsrc/externals/javelin/core/init.js' => '98e6504a',
|
||||
'rsrc/externals/javelin/core/init_node.js' => '16961339',
|
||||
'rsrc/externals/javelin/core/install.js' => '5902260c',
|
||||
'rsrc/externals/javelin/core/util.js' => '22ae1776',
|
||||
'rsrc/externals/javelin/core/util.js' => 'edb4d8c9',
|
||||
'rsrc/externals/javelin/docs/Base.js' => '5a401d7d',
|
||||
'rsrc/externals/javelin/docs/onload.js' => 'ee58fb62',
|
||||
'rsrc/externals/javelin/ext/fx/Color.js' => '78f811c9',
|
||||
|
@ -259,7 +259,7 @@ return array(
|
|||
'rsrc/externals/javelin/lib/__tests__/JSON.js' => '710377ae',
|
||||
'rsrc/externals/javelin/lib/__tests__/URI.js' => '6fff0c2b',
|
||||
'rsrc/externals/javelin/lib/__tests__/behavior.js' => '8426ebeb',
|
||||
'rsrc/externals/javelin/lib/behavior.js' => 'fce5d170',
|
||||
'rsrc/externals/javelin/lib/behavior.js' => '1b6acc2a',
|
||||
'rsrc/externals/javelin/lib/control/tokenizer/Tokenizer.js' => '89a1ae3a',
|
||||
'rsrc/externals/javelin/lib/control/typeahead/Typeahead.js' => 'a4356cde',
|
||||
'rsrc/externals/javelin/lib/control/typeahead/normalizer/TypeaheadNormalizer.js' => 'a241536a',
|
||||
|
@ -371,10 +371,10 @@ return array(
|
|||
'rsrc/js/application/conpherence/behavior-toggle-widget.js' => '8f959ad0',
|
||||
'rsrc/js/application/countdown/timer.js' => '6a162524',
|
||||
'rsrc/js/application/daemon/behavior-bulk-job-reload.js' => '3829a3cf',
|
||||
'rsrc/js/application/dashboard/behavior-dashboard-async-panel.js' => '09ecf50c',
|
||||
'rsrc/js/application/dashboard/behavior-dashboard-move-panels.js' => '076bd092',
|
||||
'rsrc/js/application/dashboard/behavior-dashboard-async-panel.js' => '9c01e364',
|
||||
'rsrc/js/application/dashboard/behavior-dashboard-move-panels.js' => 'a2ab19be',
|
||||
'rsrc/js/application/dashboard/behavior-dashboard-query-panel-select.js' => '1e413dc9',
|
||||
'rsrc/js/application/dashboard/behavior-dashboard-tab-panel.js' => '9b1cbd76',
|
||||
'rsrc/js/application/dashboard/behavior-dashboard-tab-panel.js' => '0116d3e8',
|
||||
'rsrc/js/application/diff/DiffChangeset.js' => 'd0a85a85',
|
||||
'rsrc/js/application/diff/DiffChangesetList.js' => '04023d82',
|
||||
'rsrc/js/application/diff/DiffInline.js' => 'a4a14a94',
|
||||
|
@ -433,7 +433,7 @@ return array(
|
|||
'rsrc/js/application/transactions/behavior-show-older-transactions.js' => '600f440c',
|
||||
'rsrc/js/application/transactions/behavior-transaction-comment-form.js' => '2bdadf1a',
|
||||
'rsrc/js/application/transactions/behavior-transaction-list.js' => '9cec214e',
|
||||
'rsrc/js/application/trigger/TriggerRule.js' => '1c60c3fc',
|
||||
'rsrc/js/application/trigger/TriggerRule.js' => '41b7b4f6',
|
||||
'rsrc/js/application/trigger/TriggerRuleControl.js' => '5faf27b9',
|
||||
'rsrc/js/application/trigger/TriggerRuleEditor.js' => 'b49fd60c',
|
||||
'rsrc/js/application/trigger/TriggerRuleType.js' => '4feea7d3',
|
||||
|
@ -516,9 +516,9 @@ return array(
|
|||
'rsrc/js/phui/behavior-phui-timer-control.js' => 'f84bcbf4',
|
||||
'rsrc/js/phuix/PHUIXActionListView.js' => 'c68f183f',
|
||||
'rsrc/js/phuix/PHUIXActionView.js' => 'aaa08f3b',
|
||||
'rsrc/js/phuix/PHUIXAutocomplete.js' => '8f139ef0',
|
||||
'rsrc/js/phuix/PHUIXAutocomplete.js' => '2fbe234d',
|
||||
'rsrc/js/phuix/PHUIXButtonView.js' => '55a24e84',
|
||||
'rsrc/js/phuix/PHUIXDropdownMenu.js' => 'bdce4d78',
|
||||
'rsrc/js/phuix/PHUIXDropdownMenu.js' => '7acfd98b',
|
||||
'rsrc/js/phuix/PHUIXExample.js' => 'c2c500a7',
|
||||
'rsrc/js/phuix/PHUIXFormControl.js' => '38c1f3fb',
|
||||
'rsrc/js/phuix/PHUIXIconView.js' => 'a5257c4e',
|
||||
|
@ -531,7 +531,7 @@ return array(
|
|||
'aphront-list-filter-view-css' => 'feb64255',
|
||||
'aphront-multi-column-view-css' => 'fbc00ba3',
|
||||
'aphront-panel-view-css' => '46923d46',
|
||||
'aphront-table-view-css' => '7dc3a9c2',
|
||||
'aphront-table-view-css' => '5f13a9e4',
|
||||
'aphront-tokenizer-control-css' => 'b52d0668',
|
||||
'aphront-tooltip-css' => 'e3f2412f',
|
||||
'aphront-typeahead-control-css' => '8779483d',
|
||||
|
@ -571,7 +571,7 @@ return array(
|
|||
'herald-test-css' => 'e004176f',
|
||||
'inline-comment-summary-css' => '81eb368d',
|
||||
'javelin-aphlict' => '022516b4',
|
||||
'javelin-behavior' => 'fce5d170',
|
||||
'javelin-behavior' => '1b6acc2a',
|
||||
'javelin-behavior-aphlict-dropdown' => 'e9a2940f',
|
||||
'javelin-behavior-aphlict-listen' => '4e61fa88',
|
||||
'javelin-behavior-aphlict-status' => 'c3703a16',
|
||||
|
@ -594,10 +594,10 @@ return array(
|
|||
'javelin-behavior-conpherence-search' => '91befbcc',
|
||||
'javelin-behavior-countdown-timer' => '6a162524',
|
||||
'javelin-behavior-dark-console' => 'f39d968b',
|
||||
'javelin-behavior-dashboard-async-panel' => '09ecf50c',
|
||||
'javelin-behavior-dashboard-move-panels' => '076bd092',
|
||||
'javelin-behavior-dashboard-async-panel' => '9c01e364',
|
||||
'javelin-behavior-dashboard-move-panels' => 'a2ab19be',
|
||||
'javelin-behavior-dashboard-query-panel-select' => '1e413dc9',
|
||||
'javelin-behavior-dashboard-tab-panel' => '9b1cbd76',
|
||||
'javelin-behavior-dashboard-tab-panel' => '0116d3e8',
|
||||
'javelin-behavior-day-view' => '727a5a61',
|
||||
'javelin-behavior-desktop-notifications-control' => '070679fe',
|
||||
'javelin-behavior-detect-timezone' => '78bc5d94',
|
||||
|
@ -729,7 +729,7 @@ return array(
|
|||
'javelin-typeahead-source' => '8badee71',
|
||||
'javelin-typeahead-static-source' => '80bff3af',
|
||||
'javelin-uri' => '2e255291',
|
||||
'javelin-util' => '22ae1776',
|
||||
'javelin-util' => 'edb4d8c9',
|
||||
'javelin-vector' => 'e9c80beb',
|
||||
'javelin-view' => '289bf236',
|
||||
'javelin-view-html' => 'f8c4e135',
|
||||
|
@ -757,7 +757,7 @@ return array(
|
|||
'path-typeahead' => 'ad486db3',
|
||||
'people-picture-menu-item-css' => 'fe8e07cf',
|
||||
'people-profile-css' => '2ea2daa1',
|
||||
'phabricator-action-list-view-css' => 'c4972757',
|
||||
'phabricator-action-list-view-css' => 'e820263c',
|
||||
'phabricator-busy' => '5202e831',
|
||||
'phabricator-chatlog-css' => 'abdc76ee',
|
||||
'phabricator-content-source-view-css' => 'cdf0d579',
|
||||
|
@ -765,7 +765,7 @@ return array(
|
|||
'phabricator-countdown-css' => 'bff8012f',
|
||||
'phabricator-darklog' => '3b869402',
|
||||
'phabricator-darkmessage' => '26cd4b73',
|
||||
'phabricator-dashboard-css' => '4267d6c6',
|
||||
'phabricator-dashboard-css' => '5a205b9d',
|
||||
'phabricator-diff-changeset' => 'd0a85a85',
|
||||
'phabricator-diff-changeset-list' => '04023d82',
|
||||
'phabricator-diff-inline' => 'a4a14a94',
|
||||
|
@ -779,7 +779,7 @@ return array(
|
|||
'phabricator-flag-css' => '2b77be8d',
|
||||
'phabricator-keyboard-shortcut' => 'c9749dcd',
|
||||
'phabricator-keyboard-shortcut-manager' => '37b8a04a',
|
||||
'phabricator-main-menu-view' => '8e2d9a28',
|
||||
'phabricator-main-menu-view' => '17b71bbc',
|
||||
'phabricator-nav-view-css' => 'f8a0c1bf',
|
||||
'phabricator-notification' => 'a9b91e3f',
|
||||
'phabricator-notification-css' => '30240bd2',
|
||||
|
@ -798,7 +798,7 @@ return array(
|
|||
'phabricator-tooltip' => '83754533',
|
||||
'phabricator-ui-example-css' => 'b4795059',
|
||||
'phabricator-zindex-css' => '99c0f5eb',
|
||||
'phame-css' => '799febf9',
|
||||
'phame-css' => 'bb442327',
|
||||
'pholio-css' => '88ef5ef1',
|
||||
'pholio-edit-css' => '4df55b3b',
|
||||
'pholio-inline-comments-css' => '722b48c2',
|
||||
|
@ -842,18 +842,18 @@ return array(
|
|||
'phui-icon-set-selector-css' => '7aa5f3ec',
|
||||
'phui-icon-view-css' => '4cbc684a',
|
||||
'phui-image-mask-css' => '62c7f4d2',
|
||||
'phui-info-view-css' => '37b8d9ce',
|
||||
'phui-info-view-css' => 'a10a909b',
|
||||
'phui-inline-comment-view-css' => '48acce5b',
|
||||
'phui-invisible-character-view-css' => 'c694c4a4',
|
||||
'phui-left-right-css' => '68513c34',
|
||||
'phui-lightbox-css' => '4ebf22da',
|
||||
'phui-list-view-css' => '470b1adb',
|
||||
'phui-list-view-css' => 'b05144dd',
|
||||
'phui-object-box-css' => 'f434b6be',
|
||||
'phui-oi-big-ui-css' => '534f1757',
|
||||
'phui-oi-big-ui-css' => 'fa74cc35',
|
||||
'phui-oi-color-css' => 'b517bfa0',
|
||||
'phui-oi-drag-ui-css' => 'da15d3dc',
|
||||
'phui-oi-flush-ui-css' => '490e2e2e',
|
||||
'phui-oi-list-view-css' => 'a65865a7',
|
||||
'phui-oi-list-view-css' => 'd7723ecc',
|
||||
'phui-oi-simple-ui-css' => '6a30fa46',
|
||||
'phui-pager-css' => 'd022c7ad',
|
||||
'phui-pinboard-view-css' => '1f08f5d8',
|
||||
|
@ -862,7 +862,7 @@ return array(
|
|||
'phui-segment-bar-view-css' => '5166b370',
|
||||
'phui-spacing-css' => 'b05cadc3',
|
||||
'phui-status-list-view-css' => 'e5ff8be0',
|
||||
'phui-tag-view-css' => '29409667',
|
||||
'phui-tag-view-css' => '8519160a',
|
||||
'phui-theme-css' => '35883b37',
|
||||
'phui-timeline-view-css' => '1e348e4b',
|
||||
'phui-two-column-view-css' => '01e6991e',
|
||||
|
@ -872,9 +872,9 @@ return array(
|
|||
'phui-workpanel-view-css' => '3ae89b20',
|
||||
'phuix-action-list-view' => 'c68f183f',
|
||||
'phuix-action-view' => 'aaa08f3b',
|
||||
'phuix-autocomplete' => '8f139ef0',
|
||||
'phuix-autocomplete' => '2fbe234d',
|
||||
'phuix-button-view' => '55a24e84',
|
||||
'phuix-dropdown-menu' => 'bdce4d78',
|
||||
'phuix-dropdown-menu' => '7acfd98b',
|
||||
'phuix-form-control-view' => '38c1f3fb',
|
||||
'phuix-icon-view' => 'a5257c4e',
|
||||
'policy-css' => 'ceb56a08',
|
||||
|
@ -882,7 +882,7 @@ return array(
|
|||
'policy-transaction-detail-css' => 'c02b8384',
|
||||
'ponder-view-css' => '05a09d0a',
|
||||
'project-card-view-css' => '4e7371cd',
|
||||
'project-triggers-css' => 'cb866c2d',
|
||||
'project-triggers-css' => 'cd9c8bb9',
|
||||
'project-view-css' => '567858b3',
|
||||
'releeph-core' => 'f81ff2db',
|
||||
'releeph-preview-branch' => '22db5c07',
|
||||
|
@ -894,7 +894,7 @@ return array(
|
|||
'syntax-default-css' => '055fc231',
|
||||
'syntax-highlighting-css' => '4234f572',
|
||||
'tokens-css' => 'ce5a50bd',
|
||||
'trigger-rule' => '1c60c3fc',
|
||||
'trigger-rule' => '41b7b4f6',
|
||||
'trigger-rule-control' => '5faf27b9',
|
||||
'trigger-rule-editor' => 'b49fd60c',
|
||||
'trigger-rule-type' => '4feea7d3',
|
||||
|
@ -902,6 +902,11 @@ return array(
|
|||
'unhandled-exception-css' => '9ecfc00d',
|
||||
),
|
||||
'requires' => array(
|
||||
'0116d3e8' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-dom',
|
||||
'javelin-stratcom',
|
||||
),
|
||||
'01384686' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-uri',
|
||||
|
@ -959,14 +964,6 @@ return array(
|
|||
'javelin-request',
|
||||
'javelin-uri',
|
||||
),
|
||||
'076bd092' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-dom',
|
||||
'javelin-util',
|
||||
'javelin-stratcom',
|
||||
'javelin-workflow',
|
||||
'phabricator-draggable-list',
|
||||
),
|
||||
'0889b835' => array(
|
||||
'javelin-install',
|
||||
'javelin-event',
|
||||
|
@ -977,11 +974,6 @@ return array(
|
|||
'herald-rule-editor',
|
||||
'javelin-behavior',
|
||||
),
|
||||
'09ecf50c' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-dom',
|
||||
'javelin-workflow',
|
||||
),
|
||||
'0ad8d31f' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-stratcom',
|
||||
|
@ -1029,6 +1021,13 @@ return array(
|
|||
'javelin-stratcom',
|
||||
'javelin-util',
|
||||
),
|
||||
'17b71bbc' => array(
|
||||
'phui-theme-css',
|
||||
),
|
||||
'1b6acc2a' => array(
|
||||
'javelin-magical-init',
|
||||
'javelin-util',
|
||||
),
|
||||
'1c850a26' => array(
|
||||
'javelin-install',
|
||||
'javelin-util',
|
||||
|
@ -1173,6 +1172,12 @@ return array(
|
|||
'phuix-autocomplete',
|
||||
'javelin-mask',
|
||||
),
|
||||
'2fbe234d' => array(
|
||||
'javelin-install',
|
||||
'javelin-dom',
|
||||
'phuix-icon-view',
|
||||
'phabricator-prefab',
|
||||
),
|
||||
'308f9fe4' => array(
|
||||
'javelin-install',
|
||||
'javelin-util',
|
||||
|
@ -1369,9 +1374,6 @@ return array(
|
|||
'javelin-dom',
|
||||
'javelin-fx',
|
||||
),
|
||||
'534f1757' => array(
|
||||
'phui-oi-list-view-css',
|
||||
),
|
||||
'541f81c3' => array(
|
||||
'javelin-install',
|
||||
),
|
||||
|
@ -1556,6 +1558,13 @@ return array(
|
|||
'javelin-install',
|
||||
'javelin-dom',
|
||||
),
|
||||
'7acfd98b' => array(
|
||||
'javelin-install',
|
||||
'javelin-util',
|
||||
'javelin-dom',
|
||||
'javelin-vector',
|
||||
'javelin-stratcom',
|
||||
),
|
||||
'7ad020a5' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-dom',
|
||||
|
@ -1631,15 +1640,6 @@ return array(
|
|||
'javelin-install',
|
||||
'javelin-dom',
|
||||
),
|
||||
'8e2d9a28' => array(
|
||||
'phui-theme-css',
|
||||
),
|
||||
'8f139ef0' => array(
|
||||
'javelin-install',
|
||||
'javelin-dom',
|
||||
'phuix-icon-view',
|
||||
'phabricator-prefab',
|
||||
),
|
||||
'8f959ad0' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-dom',
|
||||
|
@ -1728,10 +1728,10 @@ return array(
|
|||
'javelin-install',
|
||||
'javelin-util',
|
||||
),
|
||||
'9b1cbd76' => array(
|
||||
'9c01e364' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-dom',
|
||||
'javelin-stratcom',
|
||||
'javelin-workflow',
|
||||
),
|
||||
'9cec214e' => array(
|
||||
'javelin-behavior',
|
||||
|
@ -1757,6 +1757,14 @@ return array(
|
|||
'a241536a' => array(
|
||||
'javelin-install',
|
||||
),
|
||||
'a2ab19be' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-dom',
|
||||
'javelin-util',
|
||||
'javelin-stratcom',
|
||||
'javelin-workflow',
|
||||
'phabricator-draggable-list',
|
||||
),
|
||||
'a4356cde' => array(
|
||||
'javelin-install',
|
||||
'javelin-dom',
|
||||
|
@ -1921,13 +1929,6 @@ return array(
|
|||
'javelin-uri',
|
||||
'phabricator-notification',
|
||||
),
|
||||
'bdce4d78' => array(
|
||||
'javelin-install',
|
||||
'javelin-util',
|
||||
'javelin-dom',
|
||||
'javelin-vector',
|
||||
'javelin-stratcom',
|
||||
),
|
||||
'bde53589' => array(
|
||||
'phui-inline-comment-view-css',
|
||||
),
|
||||
|
@ -2175,9 +2176,8 @@ return array(
|
|||
'phabricator-keyboard-shortcut',
|
||||
'conpherence-thread-manager',
|
||||
),
|
||||
'fce5d170' => array(
|
||||
'javelin-magical-init',
|
||||
'javelin-util',
|
||||
'fa74cc35' => array(
|
||||
'phui-oi-list-view-css',
|
||||
),
|
||||
'fdc13e4e' => array(
|
||||
'javelin-install',
|
||||
|
|
11
resources/sql/autopatches/20190329.portals.01.create.sql
Normal file
11
resources/sql/autopatches/20190329.portals.01.create.sql
Normal file
|
@ -0,0 +1,11 @@
|
|||
CREATE TABLE {$NAMESPACE}_dashboard.dashboard_portal (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
phid VARBINARY(64) NOT NULL,
|
||||
name VARCHAR(255) NOT NULL COLLATE {$COLLATE_TEXT},
|
||||
status VARCHAR(32) NOT NULL COLLATE {$COLLATE_TEXT},
|
||||
viewPolicy VARBINARY(64) NOT NULL,
|
||||
editPolicy VARBINARY(64) NOT NULL,
|
||||
properties LONGTEXT NOT NULL COLLATE {$COLLATE_TEXT},
|
||||
dateCreated INT UNSIGNED NOT NULL,
|
||||
dateModified INT UNSIGNED NOT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET={$CHARSET} COLLATE {$COLLATE_TEXT};
|
19
resources/sql/autopatches/20190329.portals.02.xaction.sql
Normal file
19
resources/sql/autopatches/20190329.portals.02.xaction.sql
Normal file
|
@ -0,0 +1,19 @@
|
|||
CREATE TABLE {$NAMESPACE}_dashboard.dashboard_portaltransaction (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
phid VARBINARY(64) NOT NULL,
|
||||
authorPHID VARBINARY(64) NOT NULL,
|
||||
objectPHID VARBINARY(64) NOT NULL,
|
||||
viewPolicy VARBINARY(64) NOT NULL,
|
||||
editPolicy VARBINARY(64) NOT NULL,
|
||||
commentPHID VARBINARY(64) DEFAULT NULL,
|
||||
commentVersion INT UNSIGNED NOT NULL,
|
||||
transactionType VARCHAR(32) NOT NULL,
|
||||
oldValue LONGTEXT NOT NULL,
|
||||
newValue LONGTEXT NOT NULL,
|
||||
contentSource LONGTEXT NOT NULL,
|
||||
metadata LONGTEXT NOT NULL,
|
||||
dateCreated INT UNSIGNED NOT NULL,
|
||||
dateModified INT UNSIGNED NOT NULL,
|
||||
UNIQUE KEY `key_phid` (`phid`),
|
||||
KEY `key_object` (`objectPHID`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET={$CHARSET} COLLATE {$COLLATE_TEXT};
|
|
@ -0,0 +1,9 @@
|
|||
CREATE TABLE {$NAMESPACE}_dashboard.dashboard_portal_fdocument (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
objectPHID VARBINARY(64) NOT NULL,
|
||||
isClosed BOOL NOT NULL,
|
||||
authorPHID VARBINARY(64),
|
||||
ownerPHID VARBINARY(64),
|
||||
epochCreated INT UNSIGNED NOT NULL,
|
||||
epochModified INT UNSIGNED NOT NULL
|
||||
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
|
@ -0,0 +1,8 @@
|
|||
CREATE TABLE {$NAMESPACE}_dashboard.dashboard_portal_ffield (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
documentID INT UNSIGNED NOT NULL,
|
||||
fieldKey VARCHAR(4) NOT NULL COLLATE {$COLLATE_TEXT},
|
||||
rawCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT},
|
||||
termCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT},
|
||||
normalCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT}
|
||||
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
|
@ -0,0 +1,5 @@
|
|||
CREATE TABLE {$NAMESPACE}_dashboard.dashboard_portal_fngrams (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
documentID INT UNSIGNED NOT NULL,
|
||||
ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT}
|
||||
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
|
@ -0,0 +1,7 @@
|
|||
CREATE TABLE {$NAMESPACE}_dashboard.dashboard_portal_fngrams_common (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT},
|
||||
needsCollection BOOL NOT NULL,
|
||||
UNIQUE KEY `key_ngram` (ngram),
|
||||
KEY `key_collect` (needsCollection)
|
||||
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
81
resources/sql/autopatches/20190412.dashboard.01.panels.php
Normal file
81
resources/sql/autopatches/20190412.dashboard.01.panels.php
Normal file
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
|
||||
// Convert dashboards to a new storage format. The old storage format looks
|
||||
// like this:
|
||||
|
||||
// {
|
||||
// "0": ["PHID-DSHP-A", ...],
|
||||
// "1": ["PHID-DSHP-B", ...]
|
||||
// }
|
||||
|
||||
// The new storage format looks like this:
|
||||
|
||||
// [
|
||||
// {
|
||||
// "panelKey": "abcdefgh",
|
||||
// "panelPHID": "PHID-DSHP-A",
|
||||
// "columnKey": "left"
|
||||
// },
|
||||
// ...
|
||||
// ]
|
||||
|
||||
// One major issue with the old storage format is that when multiple copies of
|
||||
// a single dashboard panel appeared on the same dashboard, the UI had a lot
|
||||
// of difficulty acting on a particular copy because copies were identified
|
||||
// only by PHID and all copies of the same panel have the same panel PHID.
|
||||
|
||||
$dashboard_table = new PhabricatorDashboard();
|
||||
$conn = $dashboard_table->establishConnection('r');
|
||||
$table_name = $dashboard_table->getTableName();
|
||||
|
||||
$rows = new LiskRawMigrationIterator($conn, $table_name);
|
||||
foreach ($rows as $row) {
|
||||
$config = $row['layoutConfig'];
|
||||
|
||||
try {
|
||||
$config = phutil_json_decode($config);
|
||||
} catch (Exception $ex) {
|
||||
$config = array();
|
||||
}
|
||||
|
||||
if (!is_array($config)) {
|
||||
$config = array();
|
||||
}
|
||||
|
||||
$panels = idx($config, 'panelLocations');
|
||||
if (!is_array($panels)) {
|
||||
$panels = array();
|
||||
}
|
||||
|
||||
if (idx($config, 'layoutMode') === 'layout-mode-full') {
|
||||
$column_map = array(
|
||||
0 => 'main',
|
||||
);
|
||||
} else {
|
||||
$column_map = array(
|
||||
0 => 'left',
|
||||
1 => 'right',
|
||||
);
|
||||
}
|
||||
|
||||
$panel_list = array();
|
||||
foreach ($panels as $column_idx => $panel_phids) {
|
||||
$column_key = idx($column_map, $column_idx, 'unknown');
|
||||
foreach ($panel_phids as $panel_phid) {
|
||||
$panel_list[] = array(
|
||||
'panelKey' => Filesystem::readRandomCharacters(8),
|
||||
'columnKey' => $column_key,
|
||||
'panelPHID' => $panel_phid,
|
||||
);
|
||||
}
|
||||
}
|
||||
unset($config['panelLocations']);
|
||||
$config['panels'] = $panel_list;
|
||||
|
||||
queryfx(
|
||||
$conn,
|
||||
'UPDATE %R SET layoutConfig = %s WHERE id = %d',
|
||||
$dashboard_table,
|
||||
phutil_json_encode($config),
|
||||
$row['id']);
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
DROP TABLE IF EXISTS {$NAMESPACE}_dashboard.dashboard_install;
|
|
@ -0,0 +1 @@
|
|||
DROP TABLE IF EXISTS {$NAMESPACE}_dashboard.dashboard_dashboard_ngrams;
|
|
@ -0,0 +1 @@
|
|||
DROP TABLE IF EXISTS {$NAMESPACE}_dashboard.dashboard_dashboardpanel_ngrams;
|
|
@ -0,0 +1,9 @@
|
|||
CREATE TABLE {$NAMESPACE}_dashboard.dashboard_dashboard_fdocument (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
objectPHID VARBINARY(64) NOT NULL,
|
||||
isClosed BOOL NOT NULL,
|
||||
authorPHID VARBINARY(64),
|
||||
ownerPHID VARBINARY(64),
|
||||
epochCreated INT UNSIGNED NOT NULL,
|
||||
epochModified INT UNSIGNED NOT NULL
|
||||
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
|
@ -0,0 +1,8 @@
|
|||
CREATE TABLE {$NAMESPACE}_dashboard.dashboard_dashboard_ffield (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
documentID INT UNSIGNED NOT NULL,
|
||||
fieldKey VARCHAR(4) NOT NULL COLLATE {$COLLATE_TEXT},
|
||||
rawCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT},
|
||||
termCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT},
|
||||
normalCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT}
|
||||
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
|
@ -0,0 +1,5 @@
|
|||
CREATE TABLE {$NAMESPACE}_dashboard.dashboard_dashboard_fngrams (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
documentID INT UNSIGNED NOT NULL,
|
||||
ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT}
|
||||
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
|
@ -0,0 +1,7 @@
|
|||
CREATE TABLE {$NAMESPACE}_dashboard.dashboard_dashboard_fngrams_common (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT},
|
||||
needsCollection BOOL NOT NULL,
|
||||
UNIQUE KEY `key_ngram` (ngram),
|
||||
KEY `key_collect` (needsCollection)
|
||||
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
|
@ -0,0 +1,9 @@
|
|||
CREATE TABLE {$NAMESPACE}_dashboard.dashboard_panel_fdocument (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
objectPHID VARBINARY(64) NOT NULL,
|
||||
isClosed BOOL NOT NULL,
|
||||
authorPHID VARBINARY(64),
|
||||
ownerPHID VARBINARY(64),
|
||||
epochCreated INT UNSIGNED NOT NULL,
|
||||
epochModified INT UNSIGNED NOT NULL
|
||||
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
|
@ -0,0 +1,8 @@
|
|||
CREATE TABLE {$NAMESPACE}_dashboard.dashboard_panel_ffield (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
documentID INT UNSIGNED NOT NULL,
|
||||
fieldKey VARCHAR(4) NOT NULL COLLATE {$COLLATE_TEXT},
|
||||
rawCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT},
|
||||
termCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT},
|
||||
normalCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT}
|
||||
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
|
@ -0,0 +1,5 @@
|
|||
CREATE TABLE {$NAMESPACE}_dashboard.dashboard_panel_fngrams (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
documentID INT UNSIGNED NOT NULL,
|
||||
ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT}
|
||||
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
|
@ -0,0 +1,7 @@
|
|||
CREATE TABLE {$NAMESPACE}_dashboard.dashboard_panel_fngrams_common (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT},
|
||||
needsCollection BOOL NOT NULL,
|
||||
UNIQUE KEY `key_ngram` (ngram),
|
||||
KEY `key_collect` (needsCollection)
|
||||
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
PhabricatorRebuildIndexesWorker::rebuildObjectsWithQuery(
|
||||
'PhabricatorDashboardQuery');
|
||||
|
||||
PhabricatorRebuildIndexesWorker::rebuildObjectsWithQuery(
|
||||
'PhabricatorDashboardPanelQuery');
|
3
resources/sql/autopatches/20190412.herald.01.rebuild.php
Normal file
3
resources/sql/autopatches/20190412.herald.01.rebuild.php
Normal file
|
@ -0,0 +1,3 @@
|
|||
<?php
|
||||
|
||||
PhabricatorRebuildIndexesWorker::rebuildObjectsWithQuery('HeraldRuleQuery');
|
|
@ -609,6 +609,7 @@ phutil_register_library_map(array(
|
|||
'DifferentialRevisionIDCommitMessageField' => 'applications/differential/field/DifferentialRevisionIDCommitMessageField.php',
|
||||
'DifferentialRevisionInlineTransaction' => 'applications/differential/xaction/DifferentialRevisionInlineTransaction.php',
|
||||
'DifferentialRevisionInlinesController' => 'applications/differential/controller/DifferentialRevisionInlinesController.php',
|
||||
'DifferentialRevisionJIRAIssueURIsHeraldField' => 'applications/differential/herald/DifferentialRevisionJIRAIssueURIsHeraldField.php',
|
||||
'DifferentialRevisionListController' => 'applications/differential/controller/DifferentialRevisionListController.php',
|
||||
'DifferentialRevisionListView' => 'applications/differential/view/DifferentialRevisionListView.php',
|
||||
'DifferentialRevisionMailReceiver' => 'applications/differential/mail/DifferentialRevisionMailReceiver.php',
|
||||
|
@ -2305,12 +2306,14 @@ phutil_register_library_map(array(
|
|||
'PhabricatorAuthManagementLDAPWorkflow' => 'applications/auth/management/PhabricatorAuthManagementLDAPWorkflow.php',
|
||||
'PhabricatorAuthManagementListFactorsWorkflow' => 'applications/auth/management/PhabricatorAuthManagementListFactorsWorkflow.php',
|
||||
'PhabricatorAuthManagementListMFAProvidersWorkflow' => 'applications/auth/management/PhabricatorAuthManagementListMFAProvidersWorkflow.php',
|
||||
'PhabricatorAuthManagementLockWorkflow' => 'applications/auth/management/PhabricatorAuthManagementLockWorkflow.php',
|
||||
'PhabricatorAuthManagementRecoverWorkflow' => 'applications/auth/management/PhabricatorAuthManagementRecoverWorkflow.php',
|
||||
'PhabricatorAuthManagementRefreshWorkflow' => 'applications/auth/management/PhabricatorAuthManagementRefreshWorkflow.php',
|
||||
'PhabricatorAuthManagementRevokeWorkflow' => 'applications/auth/management/PhabricatorAuthManagementRevokeWorkflow.php',
|
||||
'PhabricatorAuthManagementStripWorkflow' => 'applications/auth/management/PhabricatorAuthManagementStripWorkflow.php',
|
||||
'PhabricatorAuthManagementTrustOAuthClientWorkflow' => 'applications/auth/management/PhabricatorAuthManagementTrustOAuthClientWorkflow.php',
|
||||
'PhabricatorAuthManagementUnlimitWorkflow' => 'applications/auth/management/PhabricatorAuthManagementUnlimitWorkflow.php',
|
||||
'PhabricatorAuthManagementUnlockWorkflow' => 'applications/auth/management/PhabricatorAuthManagementUnlockWorkflow.php',
|
||||
'PhabricatorAuthManagementUntrustOAuthClientWorkflow' => 'applications/auth/management/PhabricatorAuthManagementUntrustOAuthClientWorkflow.php',
|
||||
'PhabricatorAuthManagementVerifyWorkflow' => 'applications/auth/management/PhabricatorAuthManagementVerifyWorkflow.php',
|
||||
'PhabricatorAuthManagementWorkflow' => 'applications/auth/management/PhabricatorAuthManagementWorkflow.php',
|
||||
|
@ -2903,65 +2906,112 @@ phutil_register_library_map(array(
|
|||
'PhabricatorDarkConsoleTabSetting' => 'applications/settings/setting/PhabricatorDarkConsoleTabSetting.php',
|
||||
'PhabricatorDarkConsoleVisibleSetting' => 'applications/settings/setting/PhabricatorDarkConsoleVisibleSetting.php',
|
||||
'PhabricatorDashboard' => 'applications/dashboard/storage/PhabricatorDashboard.php',
|
||||
'PhabricatorDashboardAddPanelController' => 'applications/dashboard/controller/PhabricatorDashboardAddPanelController.php',
|
||||
'PhabricatorDashboardAdjustController' => 'applications/dashboard/controller/dashboard/PhabricatorDashboardAdjustController.php',
|
||||
'PhabricatorDashboardApplication' => 'applications/dashboard/application/PhabricatorDashboardApplication.php',
|
||||
'PhabricatorDashboardArchiveController' => 'applications/dashboard/controller/PhabricatorDashboardArchiveController.php',
|
||||
'PhabricatorDashboardArrangeController' => 'applications/dashboard/controller/PhabricatorDashboardArrangeController.php',
|
||||
'PhabricatorDashboardApplicationInstallWorkflow' => 'applications/dashboard/install/PhabricatorDashboardApplicationInstallWorkflow.php',
|
||||
'PhabricatorDashboardArchiveController' => 'applications/dashboard/controller/dashboard/PhabricatorDashboardArchiveController.php',
|
||||
'PhabricatorDashboardColumn' => 'applications/dashboard/layoutconfig/PhabricatorDashboardColumn.php',
|
||||
'PhabricatorDashboardConsoleController' => 'applications/dashboard/controller/PhabricatorDashboardConsoleController.php',
|
||||
'PhabricatorDashboardController' => 'applications/dashboard/controller/PhabricatorDashboardController.php',
|
||||
'PhabricatorDashboardDAO' => 'applications/dashboard/storage/PhabricatorDashboardDAO.php',
|
||||
'PhabricatorDashboardDashboardHasPanelEdgeType' => 'applications/dashboard/edge/PhabricatorDashboardDashboardHasPanelEdgeType.php',
|
||||
'PhabricatorDashboardDashboardPHIDType' => 'applications/dashboard/phid/PhabricatorDashboardDashboardPHIDType.php',
|
||||
'PhabricatorDashboardDatasource' => 'applications/dashboard/typeahead/PhabricatorDashboardDatasource.php',
|
||||
'PhabricatorDashboardEditController' => 'applications/dashboard/controller/PhabricatorDashboardEditController.php',
|
||||
'PhabricatorDashboardEditController' => 'applications/dashboard/controller/dashboard/PhabricatorDashboardEditController.php',
|
||||
'PhabricatorDashboardEditEngine' => 'applications/dashboard/editor/PhabricatorDashboardEditEngine.php',
|
||||
'PhabricatorDashboardFavoritesInstallWorkflow' => 'applications/dashboard/install/PhabricatorDashboardFavoritesInstallWorkflow.php',
|
||||
'PhabricatorDashboardFerretEngine' => 'applications/dashboard/engine/PhabricatorDashboardFerretEngine.php',
|
||||
'PhabricatorDashboardFullLayoutMode' => 'applications/dashboard/layoutconfig/PhabricatorDashboardFullLayoutMode.php',
|
||||
'PhabricatorDashboardFulltextEngine' => 'applications/dashboard/engine/PhabricatorDashboardFulltextEngine.php',
|
||||
'PhabricatorDashboardHalfLayoutMode' => 'applications/dashboard/layoutconfig/PhabricatorDashboardHalfLayoutMode.php',
|
||||
'PhabricatorDashboardHomeInstallWorkflow' => 'applications/dashboard/install/PhabricatorDashboardHomeInstallWorkflow.php',
|
||||
'PhabricatorDashboardIconSet' => 'applications/dashboard/icon/PhabricatorDashboardIconSet.php',
|
||||
'PhabricatorDashboardInstall' => 'applications/dashboard/storage/PhabricatorDashboardInstall.php',
|
||||
'PhabricatorDashboardInstallController' => 'applications/dashboard/controller/PhabricatorDashboardInstallController.php',
|
||||
'PhabricatorDashboardLayoutConfig' => 'applications/dashboard/layoutconfig/PhabricatorDashboardLayoutConfig.php',
|
||||
'PhabricatorDashboardIconTransaction' => 'applications/dashboard/xaction/dashboard/PhabricatorDashboardIconTransaction.php',
|
||||
'PhabricatorDashboardInstallController' => 'applications/dashboard/controller/dashboard/PhabricatorDashboardInstallController.php',
|
||||
'PhabricatorDashboardInstallWorkflow' => 'applications/dashboard/install/PhabricatorDashboardInstallWorkflow.php',
|
||||
'PhabricatorDashboardLayoutMode' => 'applications/dashboard/layoutconfig/PhabricatorDashboardLayoutMode.php',
|
||||
'PhabricatorDashboardLayoutTransaction' => 'applications/dashboard/xaction/dashboard/PhabricatorDashboardLayoutTransaction.php',
|
||||
'PhabricatorDashboardListController' => 'applications/dashboard/controller/PhabricatorDashboardListController.php',
|
||||
'PhabricatorDashboardManageController' => 'applications/dashboard/controller/PhabricatorDashboardManageController.php',
|
||||
'PhabricatorDashboardMovePanelController' => 'applications/dashboard/controller/PhabricatorDashboardMovePanelController.php',
|
||||
'PhabricatorDashboardNgrams' => 'applications/dashboard/storage/PhabricatorDashboardNgrams.php',
|
||||
'PhabricatorDashboardNameTransaction' => 'applications/dashboard/xaction/dashboard/PhabricatorDashboardNameTransaction.php',
|
||||
'PhabricatorDashboardObjectInstallWorkflow' => 'applications/dashboard/install/PhabricatorDashboardObjectInstallWorkflow.php',
|
||||
'PhabricatorDashboardOneThirdLayoutMode' => 'applications/dashboard/layoutconfig/PhabricatorDashboardOneThirdLayoutMode.php',
|
||||
'PhabricatorDashboardPanel' => 'applications/dashboard/storage/PhabricatorDashboardPanel.php',
|
||||
'PhabricatorDashboardPanelArchiveController' => 'applications/dashboard/controller/PhabricatorDashboardPanelArchiveController.php',
|
||||
'PhabricatorDashboardPanelCoreCustomField' => 'applications/dashboard/customfield/PhabricatorDashboardPanelCoreCustomField.php',
|
||||
'PhabricatorDashboardPanelCustomField' => 'applications/dashboard/customfield/PhabricatorDashboardPanelCustomField.php',
|
||||
'PhabricatorDashboardPanelArchiveController' => 'applications/dashboard/controller/panel/PhabricatorDashboardPanelArchiveController.php',
|
||||
'PhabricatorDashboardPanelContainerIndexEngineExtension' => 'applications/dashboard/engineextension/PhabricatorDashboardPanelContainerIndexEngineExtension.php',
|
||||
'PhabricatorDashboardPanelContainerInterface' => 'applications/dashboard/interface/PhabricatorDashboardPanelContainerInterface.php',
|
||||
'PhabricatorDashboardPanelDatasource' => 'applications/dashboard/typeahead/PhabricatorDashboardPanelDatasource.php',
|
||||
'PhabricatorDashboardPanelEditConduitAPIMethod' => 'applications/dashboard/conduit/PhabricatorDashboardPanelEditConduitAPIMethod.php',
|
||||
'PhabricatorDashboardPanelEditController' => 'applications/dashboard/controller/PhabricatorDashboardPanelEditController.php',
|
||||
'PhabricatorDashboardPanelEditController' => 'applications/dashboard/controller/panel/PhabricatorDashboardPanelEditController.php',
|
||||
'PhabricatorDashboardPanelEditEngine' => 'applications/dashboard/editor/PhabricatorDashboardPanelEditEngine.php',
|
||||
'PhabricatorDashboardPanelEditproController' => 'applications/dashboard/controller/PhabricatorDashboardPanelEditproController.php',
|
||||
'PhabricatorDashboardPanelHasDashboardEdgeType' => 'applications/dashboard/edge/PhabricatorDashboardPanelHasDashboardEdgeType.php',
|
||||
'PhabricatorDashboardPanelListController' => 'applications/dashboard/controller/PhabricatorDashboardPanelListController.php',
|
||||
'PhabricatorDashboardPanelNgrams' => 'applications/dashboard/storage/PhabricatorDashboardPanelNgrams.php',
|
||||
'PhabricatorDashboardPanelFerretEngine' => 'applications/dashboard/engine/PhabricatorDashboardPanelFerretEngine.php',
|
||||
'PhabricatorDashboardPanelFulltextEngine' => 'applications/dashboard/engine/PhabricatorDashboardPanelFulltextEngine.php',
|
||||
'PhabricatorDashboardPanelListController' => 'applications/dashboard/controller/panel/PhabricatorDashboardPanelListController.php',
|
||||
'PhabricatorDashboardPanelNameTransaction' => 'applications/dashboard/xaction/panel/PhabricatorDashboardPanelNameTransaction.php',
|
||||
'PhabricatorDashboardPanelPHIDType' => 'applications/dashboard/phid/PhabricatorDashboardPanelPHIDType.php',
|
||||
'PhabricatorDashboardPanelPropertyTransaction' => 'applications/dashboard/xaction/panel/PhabricatorDashboardPanelPropertyTransaction.php',
|
||||
'PhabricatorDashboardPanelQuery' => 'applications/dashboard/query/PhabricatorDashboardPanelQuery.php',
|
||||
'PhabricatorDashboardPanelRenderController' => 'applications/dashboard/controller/PhabricatorDashboardPanelRenderController.php',
|
||||
'PhabricatorDashboardPanelRef' => 'applications/dashboard/layoutconfig/PhabricatorDashboardPanelRef.php',
|
||||
'PhabricatorDashboardPanelRefList' => 'applications/dashboard/layoutconfig/PhabricatorDashboardPanelRefList.php',
|
||||
'PhabricatorDashboardPanelRenderController' => 'applications/dashboard/controller/panel/PhabricatorDashboardPanelRenderController.php',
|
||||
'PhabricatorDashboardPanelRenderingEngine' => 'applications/dashboard/engine/PhabricatorDashboardPanelRenderingEngine.php',
|
||||
'PhabricatorDashboardPanelSearchApplicationCustomField' => 'applications/dashboard/customfield/PhabricatorDashboardPanelSearchApplicationCustomField.php',
|
||||
'PhabricatorDashboardPanelSearchEngine' => 'applications/dashboard/query/PhabricatorDashboardPanelSearchEngine.php',
|
||||
'PhabricatorDashboardPanelSearchQueryCustomField' => 'applications/dashboard/customfield/PhabricatorDashboardPanelSearchQueryCustomField.php',
|
||||
'PhabricatorDashboardPanelTabsCustomField' => 'applications/dashboard/customfield/PhabricatorDashboardPanelTabsCustomField.php',
|
||||
'PhabricatorDashboardPanelStatusTransaction' => 'applications/dashboard/xaction/panel/PhabricatorDashboardPanelStatusTransaction.php',
|
||||
'PhabricatorDashboardPanelTabsController' => 'applications/dashboard/controller/panel/PhabricatorDashboardPanelTabsController.php',
|
||||
'PhabricatorDashboardPanelTransaction' => 'applications/dashboard/storage/PhabricatorDashboardPanelTransaction.php',
|
||||
'PhabricatorDashboardPanelTransactionEditor' => 'applications/dashboard/editor/PhabricatorDashboardPanelTransactionEditor.php',
|
||||
'PhabricatorDashboardPanelTransactionQuery' => 'applications/dashboard/query/PhabricatorDashboardPanelTransactionQuery.php',
|
||||
'PhabricatorDashboardPanelTransactionType' => 'applications/dashboard/xaction/panel/PhabricatorDashboardPanelTransactionType.php',
|
||||
'PhabricatorDashboardPanelType' => 'applications/dashboard/paneltype/PhabricatorDashboardPanelType.php',
|
||||
'PhabricatorDashboardPanelViewController' => 'applications/dashboard/controller/PhabricatorDashboardPanelViewController.php',
|
||||
'PhabricatorDashboardPanelUsedByObjectEdgeType' => 'applications/search/edge/PhabricatorDashboardPanelUsedByObjectEdgeType.php',
|
||||
'PhabricatorDashboardPanelViewController' => 'applications/dashboard/controller/panel/PhabricatorDashboardPanelViewController.php',
|
||||
'PhabricatorDashboardPanelsTransaction' => 'applications/dashboard/xaction/dashboard/PhabricatorDashboardPanelsTransaction.php',
|
||||
'PhabricatorDashboardPortal' => 'applications/dashboard/storage/PhabricatorDashboardPortal.php',
|
||||
'PhabricatorDashboardPortalController' => 'applications/dashboard/controller/portal/PhabricatorDashboardPortalController.php',
|
||||
'PhabricatorDashboardPortalDatasource' => 'applications/dashboard/typeahead/PhabricatorDashboardPortalDatasource.php',
|
||||
'PhabricatorDashboardPortalEditConduitAPIMethod' => 'applications/dashboard/conduit/PhabricatorDashboardPortalEditConduitAPIMethod.php',
|
||||
'PhabricatorDashboardPortalEditController' => 'applications/dashboard/controller/portal/PhabricatorDashboardPortalEditController.php',
|
||||
'PhabricatorDashboardPortalEditEngine' => 'applications/dashboard/editor/PhabricatorDashboardPortalEditEngine.php',
|
||||
'PhabricatorDashboardPortalEditor' => 'applications/dashboard/editor/PhabricatorDashboardPortalEditor.php',
|
||||
'PhabricatorDashboardPortalFerretEngine' => 'applications/dashboard/engine/PhabricatorDashboardPortalFerretEngine.php',
|
||||
'PhabricatorDashboardPortalFulltextEngine' => 'applications/dashboard/engine/PhabricatorDashboardPortalFulltextEngine.php',
|
||||
'PhabricatorDashboardPortalInstallWorkflow' => 'applications/dashboard/install/PhabricatorDashboardPortalInstallWorkflow.php',
|
||||
'PhabricatorDashboardPortalListController' => 'applications/dashboard/controller/portal/PhabricatorDashboardPortalListController.php',
|
||||
'PhabricatorDashboardPortalMenuItem' => 'applications/dashboard/menuitem/PhabricatorDashboardPortalMenuItem.php',
|
||||
'PhabricatorDashboardPortalNameTransaction' => 'applications/dashboard/xaction/portal/PhabricatorDashboardPortalNameTransaction.php',
|
||||
'PhabricatorDashboardPortalPHIDType' => 'applications/dashboard/phid/PhabricatorDashboardPortalPHIDType.php',
|
||||
'PhabricatorDashboardPortalProfileMenuEngine' => 'applications/dashboard/engine/PhabricatorDashboardPortalProfileMenuEngine.php',
|
||||
'PhabricatorDashboardPortalQuery' => 'applications/dashboard/query/PhabricatorDashboardPortalQuery.php',
|
||||
'PhabricatorDashboardPortalSearchConduitAPIMethod' => 'applications/dashboard/conduit/PhabricatorDashboardPortalSearchConduitAPIMethod.php',
|
||||
'PhabricatorDashboardPortalSearchEngine' => 'applications/dashboard/query/PhabricatorDashboardPortalSearchEngine.php',
|
||||
'PhabricatorDashboardPortalStatus' => 'applications/dashboard/constants/PhabricatorDashboardPortalStatus.php',
|
||||
'PhabricatorDashboardPortalTransaction' => 'applications/dashboard/storage/PhabricatorDashboardPortalTransaction.php',
|
||||
'PhabricatorDashboardPortalTransactionQuery' => 'applications/dashboard/query/PhabricatorDashboardPortalTransactionQuery.php',
|
||||
'PhabricatorDashboardPortalTransactionType' => 'applications/dashboard/xaction/portal/PhabricatorDashboardPortalTransactionType.php',
|
||||
'PhabricatorDashboardPortalViewController' => 'applications/dashboard/controller/portal/PhabricatorDashboardPortalViewController.php',
|
||||
'PhabricatorDashboardProfileController' => 'applications/dashboard/controller/PhabricatorDashboardProfileController.php',
|
||||
'PhabricatorDashboardProfileMenuItem' => 'applications/search/menuitem/PhabricatorDashboardProfileMenuItem.php',
|
||||
'PhabricatorDashboardProjectInstallWorkflow' => 'applications/dashboard/install/PhabricatorDashboardProjectInstallWorkflow.php',
|
||||
'PhabricatorDashboardQuery' => 'applications/dashboard/query/PhabricatorDashboardQuery.php',
|
||||
'PhabricatorDashboardQueryPanelApplicationEditField' => 'applications/dashboard/editfield/PhabricatorDashboardQueryPanelApplicationEditField.php',
|
||||
'PhabricatorDashboardQueryPanelApplicationTransaction' => 'applications/dashboard/xaction/panel/PhabricatorDashboardQueryPanelApplicationTransaction.php',
|
||||
'PhabricatorDashboardQueryPanelInstallController' => 'applications/dashboard/controller/PhabricatorDashboardQueryPanelInstallController.php',
|
||||
'PhabricatorDashboardQueryPanelQueryEditField' => 'applications/dashboard/editfield/PhabricatorDashboardQueryPanelQueryEditField.php',
|
||||
'PhabricatorDashboardQueryPanelQueryTransaction' => 'applications/dashboard/xaction/panel/PhabricatorDashboardQueryPanelQueryTransaction.php',
|
||||
'PhabricatorDashboardQueryPanelType' => 'applications/dashboard/paneltype/PhabricatorDashboardQueryPanelType.php',
|
||||
'PhabricatorDashboardRemarkupRule' => 'applications/dashboard/remarkup/PhabricatorDashboardRemarkupRule.php',
|
||||
'PhabricatorDashboardRemovePanelController' => 'applications/dashboard/controller/PhabricatorDashboardRemovePanelController.php',
|
||||
'PhabricatorDashboardRenderingEngine' => 'applications/dashboard/engine/PhabricatorDashboardRenderingEngine.php',
|
||||
'PhabricatorDashboardSchemaSpec' => 'applications/dashboard/storage/PhabricatorDashboardSchemaSpec.php',
|
||||
'PhabricatorDashboardSearchEngine' => 'applications/dashboard/query/PhabricatorDashboardSearchEngine.php',
|
||||
'PhabricatorDashboardStatusTransaction' => 'applications/dashboard/xaction/dashboard/PhabricatorDashboardStatusTransaction.php',
|
||||
'PhabricatorDashboardTabsPanelTabsTransaction' => 'applications/dashboard/xaction/panel/PhabricatorDashboardTabsPanelTabsTransaction.php',
|
||||
'PhabricatorDashboardTabsPanelType' => 'applications/dashboard/paneltype/PhabricatorDashboardTabsPanelType.php',
|
||||
'PhabricatorDashboardTextPanelTextTransaction' => 'applications/dashboard/xaction/panel/PhabricatorDashboardTextPanelTextTransaction.php',
|
||||
'PhabricatorDashboardTextPanelType' => 'applications/dashboard/paneltype/PhabricatorDashboardTextPanelType.php',
|
||||
'PhabricatorDashboardTransaction' => 'applications/dashboard/storage/PhabricatorDashboardTransaction.php',
|
||||
'PhabricatorDashboardTransactionEditor' => 'applications/dashboard/editor/PhabricatorDashboardTransactionEditor.php',
|
||||
'PhabricatorDashboardTransactionQuery' => 'applications/dashboard/query/PhabricatorDashboardTransactionQuery.php',
|
||||
'PhabricatorDashboardViewController' => 'applications/dashboard/controller/PhabricatorDashboardViewController.php',
|
||||
'PhabricatorDashboardTransactionType' => 'applications/dashboard/xaction/dashboard/PhabricatorDashboardTransactionType.php',
|
||||
'PhabricatorDashboardTwoThirdsLayoutMode' => 'applications/dashboard/layoutconfig/PhabricatorDashboardTwoThirdsLayoutMode.php',
|
||||
'PhabricatorDashboardViewController' => 'applications/dashboard/controller/dashboard/PhabricatorDashboardViewController.php',
|
||||
'PhabricatorDataCacheSpec' => 'applications/cache/spec/PhabricatorDataCacheSpec.php',
|
||||
'PhabricatorDataNotAttachedException' => 'infrastructure/storage/lisk/PhabricatorDataNotAttachedException.php',
|
||||
'PhabricatorDatabaseRef' => 'infrastructure/cluster/PhabricatorDatabaseRef.php',
|
||||
|
@ -3028,6 +3078,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorEdgeEditType' => 'applications/transactions/edittype/PhabricatorEdgeEditType.php',
|
||||
'PhabricatorEdgeEditor' => 'infrastructure/edges/editor/PhabricatorEdgeEditor.php',
|
||||
'PhabricatorEdgeGraph' => 'infrastructure/edges/util/PhabricatorEdgeGraph.php',
|
||||
'PhabricatorEdgeIndexEngineExtension' => 'applications/search/engineextension/PhabricatorEdgeIndexEngineExtension.php',
|
||||
'PhabricatorEdgeObject' => 'infrastructure/edges/conduit/PhabricatorEdgeObject.php',
|
||||
'PhabricatorEdgeObjectQuery' => 'infrastructure/edges/query/PhabricatorEdgeObjectQuery.php',
|
||||
'PhabricatorEdgeQuery' => 'infrastructure/edges/query/PhabricatorEdgeQuery.php',
|
||||
|
@ -3687,6 +3738,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorObjectRemarkupRule' => 'infrastructure/markup/rule/PhabricatorObjectRemarkupRule.php',
|
||||
'PhabricatorObjectSelectorDialog' => 'view/control/PhabricatorObjectSelectorDialog.php',
|
||||
'PhabricatorObjectStatus' => 'infrastructure/status/PhabricatorObjectStatus.php',
|
||||
'PhabricatorObjectUsesDashboardPanelEdgeType' => 'applications/search/edge/PhabricatorObjectUsesDashboardPanelEdgeType.php',
|
||||
'PhabricatorOffsetPagedQuery' => 'infrastructure/query/PhabricatorOffsetPagedQuery.php',
|
||||
'PhabricatorOldWorldContentSource' => 'infrastructure/contentsource/PhabricatorOldWorldContentSource.php',
|
||||
'PhabricatorOlderInlinesSetting' => 'applications/settings/setting/PhabricatorOlderInlinesSetting.php',
|
||||
|
@ -4031,12 +4083,16 @@ phutil_register_library_map(array(
|
|||
'PhabricatorProfileMenuEditor' => 'applications/search/editor/PhabricatorProfileMenuEditor.php',
|
||||
'PhabricatorProfileMenuEngine' => 'applications/search/engine/PhabricatorProfileMenuEngine.php',
|
||||
'PhabricatorProfileMenuItem' => 'applications/search/menuitem/PhabricatorProfileMenuItem.php',
|
||||
'PhabricatorProfileMenuItemAffectsObjectEdgeType' => 'applications/search/edge/PhabricatorProfileMenuItemAffectsObjectEdgeType.php',
|
||||
'PhabricatorProfileMenuItemConfiguration' => 'applications/search/storage/PhabricatorProfileMenuItemConfiguration.php',
|
||||
'PhabricatorProfileMenuItemConfigurationQuery' => 'applications/search/query/PhabricatorProfileMenuItemConfigurationQuery.php',
|
||||
'PhabricatorProfileMenuItemConfigurationTransaction' => 'applications/search/storage/PhabricatorProfileMenuItemConfigurationTransaction.php',
|
||||
'PhabricatorProfileMenuItemConfigurationTransactionQuery' => 'applications/search/query/PhabricatorProfileMenuItemConfigurationTransactionQuery.php',
|
||||
'PhabricatorProfileMenuItemIconSet' => 'applications/search/menuitem/PhabricatorProfileMenuItemIconSet.php',
|
||||
'PhabricatorProfileMenuItemIndexEngineExtension' => 'applications/search/engineextension/PhabricatorProfileMenuItemIndexEngineExtension.php',
|
||||
'PhabricatorProfileMenuItemPHIDType' => 'applications/search/phidtype/PhabricatorProfileMenuItemPHIDType.php',
|
||||
'PhabricatorProfileMenuItemView' => 'applications/search/engine/PhabricatorProfileMenuItemView.php',
|
||||
'PhabricatorProfileMenuItemViewList' => 'applications/search/engine/PhabricatorProfileMenuItemViewList.php',
|
||||
'PhabricatorProject' => 'applications/project/storage/PhabricatorProject.php',
|
||||
'PhabricatorProjectAddHeraldAction' => 'applications/project/herald/PhabricatorProjectAddHeraldAction.php',
|
||||
'PhabricatorProjectApplication' => 'applications/project/application/PhabricatorProjectApplication.php',
|
||||
|
@ -4174,18 +4230,21 @@ phutil_register_library_map(array(
|
|||
'PhabricatorProjectTransactionQuery' => 'applications/project/query/PhabricatorProjectTransactionQuery.php',
|
||||
'PhabricatorProjectTransactionType' => 'applications/project/xaction/PhabricatorProjectTransactionType.php',
|
||||
'PhabricatorProjectTrigger' => 'applications/project/storage/PhabricatorProjectTrigger.php',
|
||||
'PhabricatorProjectTriggerAddProjectsRule' => 'applications/project/trigger/PhabricatorProjectTriggerAddProjectsRule.php',
|
||||
'PhabricatorProjectTriggerController' => 'applications/project/controller/trigger/PhabricatorProjectTriggerController.php',
|
||||
'PhabricatorProjectTriggerCorruptionException' => 'applications/project/exception/PhabricatorProjectTriggerCorruptionException.php',
|
||||
'PhabricatorProjectTriggerEditController' => 'applications/project/controller/trigger/PhabricatorProjectTriggerEditController.php',
|
||||
'PhabricatorProjectTriggerEditor' => 'applications/project/editor/PhabricatorProjectTriggerEditor.php',
|
||||
'PhabricatorProjectTriggerInvalidRule' => 'applications/project/trigger/PhabricatorProjectTriggerInvalidRule.php',
|
||||
'PhabricatorProjectTriggerListController' => 'applications/project/controller/trigger/PhabricatorProjectTriggerListController.php',
|
||||
'PhabricatorProjectTriggerManiphestOwnerRule' => 'applications/project/trigger/PhabricatorProjectTriggerManiphestOwnerRule.php',
|
||||
'PhabricatorProjectTriggerManiphestPriorityRule' => 'applications/project/trigger/PhabricatorProjectTriggerManiphestPriorityRule.php',
|
||||
'PhabricatorProjectTriggerManiphestStatusRule' => 'applications/project/trigger/PhabricatorProjectTriggerManiphestStatusRule.php',
|
||||
'PhabricatorProjectTriggerNameTransaction' => 'applications/project/xaction/trigger/PhabricatorProjectTriggerNameTransaction.php',
|
||||
'PhabricatorProjectTriggerPHIDType' => 'applications/project/phid/PhabricatorProjectTriggerPHIDType.php',
|
||||
'PhabricatorProjectTriggerPlaySoundRule' => 'applications/project/trigger/PhabricatorProjectTriggerPlaySoundRule.php',
|
||||
'PhabricatorProjectTriggerQuery' => 'applications/project/query/PhabricatorProjectTriggerQuery.php',
|
||||
'PhabricatorProjectTriggerRemoveProjectsRule' => 'applications/project/trigger/PhabricatorProjectTriggerRemoveProjectsRule.php',
|
||||
'PhabricatorProjectTriggerRule' => 'applications/project/trigger/PhabricatorProjectTriggerRule.php',
|
||||
'PhabricatorProjectTriggerRuleRecord' => 'applications/project/trigger/PhabricatorProjectTriggerRuleRecord.php',
|
||||
'PhabricatorProjectTriggerRulesetTransaction' => 'applications/project/xaction/trigger/PhabricatorProjectTriggerRulesetTransaction.php',
|
||||
|
@ -4235,6 +4294,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorQueryOrderVector' => 'infrastructure/query/order/PhabricatorQueryOrderVector.php',
|
||||
'PhabricatorQuickSearchEngineExtension' => 'applications/search/engineextension/PhabricatorQuickSearchEngineExtension.php',
|
||||
'PhabricatorRateLimitRequestExceptionHandler' => 'aphront/handler/PhabricatorRateLimitRequestExceptionHandler.php',
|
||||
'PhabricatorRebuildIndexesWorker' => 'applications/search/worker/PhabricatorRebuildIndexesWorker.php',
|
||||
'PhabricatorRecaptchaConfigOptions' => 'applications/config/option/PhabricatorRecaptchaConfigOptions.php',
|
||||
'PhabricatorRedirectController' => 'applications/base/controller/PhabricatorRedirectController.php',
|
||||
'PhabricatorRefreshCSRFController' => 'applications/auth/controller/PhabricatorRefreshCSRFController.php',
|
||||
|
@ -6192,6 +6252,7 @@ phutil_register_library_map(array(
|
|||
'DifferentialRevisionIDCommitMessageField' => 'DifferentialCommitMessageField',
|
||||
'DifferentialRevisionInlineTransaction' => 'PhabricatorModularTransactionType',
|
||||
'DifferentialRevisionInlinesController' => 'DifferentialController',
|
||||
'DifferentialRevisionJIRAIssueURIsHeraldField' => 'DifferentialRevisionHeraldField',
|
||||
'DifferentialRevisionListController' => 'DifferentialController',
|
||||
'DifferentialRevisionListView' => 'AphrontView',
|
||||
'DifferentialRevisionMailReceiver' => 'PhabricatorObjectMailReceiver',
|
||||
|
@ -7250,7 +7311,7 @@ phutil_register_library_map(array(
|
|||
'HeraldRuleEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
'HeraldRuleField' => 'HeraldField',
|
||||
'HeraldRuleFieldGroup' => 'HeraldFieldGroup',
|
||||
'HeraldRuleIndexEngineExtension' => 'PhabricatorIndexEngineExtension',
|
||||
'HeraldRuleIndexEngineExtension' => 'PhabricatorEdgeIndexEngineExtension',
|
||||
'HeraldRuleListController' => 'HeraldController',
|
||||
'HeraldRuleListView' => 'AphrontView',
|
||||
'HeraldRuleNameTransaction' => 'HeraldRuleTransactionType',
|
||||
|
@ -8134,12 +8195,14 @@ phutil_register_library_map(array(
|
|||
'PhabricatorAuthManagementLDAPWorkflow' => 'PhabricatorAuthManagementWorkflow',
|
||||
'PhabricatorAuthManagementListFactorsWorkflow' => 'PhabricatorAuthManagementWorkflow',
|
||||
'PhabricatorAuthManagementListMFAProvidersWorkflow' => 'PhabricatorAuthManagementWorkflow',
|
||||
'PhabricatorAuthManagementLockWorkflow' => 'PhabricatorAuthManagementWorkflow',
|
||||
'PhabricatorAuthManagementRecoverWorkflow' => 'PhabricatorAuthManagementWorkflow',
|
||||
'PhabricatorAuthManagementRefreshWorkflow' => 'PhabricatorAuthManagementWorkflow',
|
||||
'PhabricatorAuthManagementRevokeWorkflow' => 'PhabricatorAuthManagementWorkflow',
|
||||
'PhabricatorAuthManagementStripWorkflow' => 'PhabricatorAuthManagementWorkflow',
|
||||
'PhabricatorAuthManagementTrustOAuthClientWorkflow' => 'PhabricatorAuthManagementWorkflow',
|
||||
'PhabricatorAuthManagementUnlimitWorkflow' => 'PhabricatorAuthManagementWorkflow',
|
||||
'PhabricatorAuthManagementUnlockWorkflow' => 'PhabricatorAuthManagementWorkflow',
|
||||
'PhabricatorAuthManagementUntrustOAuthClientWorkflow' => 'PhabricatorAuthManagementWorkflow',
|
||||
'PhabricatorAuthManagementVerifyWorkflow' => 'PhabricatorAuthManagementWorkflow',
|
||||
'PhabricatorAuthManagementWorkflow' => 'PhabricatorManagementWorkflow',
|
||||
|
@ -8840,77 +8903,131 @@ phutil_register_library_map(array(
|
|||
'PhabricatorFlaggableInterface',
|
||||
'PhabricatorDestructibleInterface',
|
||||
'PhabricatorProjectInterface',
|
||||
'PhabricatorNgramsInterface',
|
||||
'PhabricatorFulltextInterface',
|
||||
'PhabricatorFerretInterface',
|
||||
'PhabricatorDashboardPanelContainerInterface',
|
||||
),
|
||||
'PhabricatorDashboardAddPanelController' => 'PhabricatorDashboardController',
|
||||
'PhabricatorDashboardAdjustController' => 'PhabricatorDashboardController',
|
||||
'PhabricatorDashboardApplication' => 'PhabricatorApplication',
|
||||
'PhabricatorDashboardApplicationInstallWorkflow' => 'PhabricatorDashboardInstallWorkflow',
|
||||
'PhabricatorDashboardArchiveController' => 'PhabricatorDashboardController',
|
||||
'PhabricatorDashboardArrangeController' => 'PhabricatorDashboardProfileController',
|
||||
'PhabricatorDashboardColumn' => 'Phobject',
|
||||
'PhabricatorDashboardConsoleController' => 'PhabricatorDashboardController',
|
||||
'PhabricatorDashboardController' => 'PhabricatorController',
|
||||
'PhabricatorDashboardDAO' => 'PhabricatorLiskDAO',
|
||||
'PhabricatorDashboardDashboardHasPanelEdgeType' => 'PhabricatorEdgeType',
|
||||
'PhabricatorDashboardDashboardPHIDType' => 'PhabricatorPHIDType',
|
||||
'PhabricatorDashboardDatasource' => 'PhabricatorTypeaheadDatasource',
|
||||
'PhabricatorDashboardEditController' => 'PhabricatorDashboardController',
|
||||
'PhabricatorDashboardEditEngine' => 'PhabricatorEditEngine',
|
||||
'PhabricatorDashboardFavoritesInstallWorkflow' => 'PhabricatorDashboardApplicationInstallWorkflow',
|
||||
'PhabricatorDashboardFerretEngine' => 'PhabricatorFerretEngine',
|
||||
'PhabricatorDashboardFullLayoutMode' => 'PhabricatorDashboardLayoutMode',
|
||||
'PhabricatorDashboardFulltextEngine' => 'PhabricatorFulltextEngine',
|
||||
'PhabricatorDashboardHalfLayoutMode' => 'PhabricatorDashboardLayoutMode',
|
||||
'PhabricatorDashboardHomeInstallWorkflow' => 'PhabricatorDashboardApplicationInstallWorkflow',
|
||||
'PhabricatorDashboardIconSet' => 'PhabricatorIconSet',
|
||||
'PhabricatorDashboardInstall' => 'PhabricatorDashboardDAO',
|
||||
'PhabricatorDashboardIconTransaction' => 'PhabricatorDashboardTransactionType',
|
||||
'PhabricatorDashboardInstallController' => 'PhabricatorDashboardController',
|
||||
'PhabricatorDashboardLayoutConfig' => 'Phobject',
|
||||
'PhabricatorDashboardInstallWorkflow' => 'Phobject',
|
||||
'PhabricatorDashboardLayoutMode' => 'Phobject',
|
||||
'PhabricatorDashboardLayoutTransaction' => 'PhabricatorDashboardTransactionType',
|
||||
'PhabricatorDashboardListController' => 'PhabricatorDashboardController',
|
||||
'PhabricatorDashboardManageController' => 'PhabricatorDashboardProfileController',
|
||||
'PhabricatorDashboardMovePanelController' => 'PhabricatorDashboardController',
|
||||
'PhabricatorDashboardNgrams' => 'PhabricatorSearchNgrams',
|
||||
'PhabricatorDashboardNameTransaction' => 'PhabricatorDashboardTransactionType',
|
||||
'PhabricatorDashboardObjectInstallWorkflow' => 'PhabricatorDashboardInstallWorkflow',
|
||||
'PhabricatorDashboardOneThirdLayoutMode' => 'PhabricatorDashboardLayoutMode',
|
||||
'PhabricatorDashboardPanel' => array(
|
||||
'PhabricatorDashboardDAO',
|
||||
'PhabricatorApplicationTransactionInterface',
|
||||
'PhabricatorPolicyInterface',
|
||||
'PhabricatorCustomFieldInterface',
|
||||
'PhabricatorFlaggableInterface',
|
||||
'PhabricatorDestructibleInterface',
|
||||
'PhabricatorNgramsInterface',
|
||||
'PhabricatorFulltextInterface',
|
||||
'PhabricatorFerretInterface',
|
||||
'PhabricatorDashboardPanelContainerInterface',
|
||||
),
|
||||
'PhabricatorDashboardPanelArchiveController' => 'PhabricatorDashboardController',
|
||||
'PhabricatorDashboardPanelCoreCustomField' => array(
|
||||
'PhabricatorDashboardPanelCustomField',
|
||||
'PhabricatorStandardCustomFieldInterface',
|
||||
),
|
||||
'PhabricatorDashboardPanelCustomField' => 'PhabricatorCustomField',
|
||||
'PhabricatorDashboardPanelContainerIndexEngineExtension' => 'PhabricatorEdgeIndexEngineExtension',
|
||||
'PhabricatorDashboardPanelDatasource' => 'PhabricatorTypeaheadDatasource',
|
||||
'PhabricatorDashboardPanelEditConduitAPIMethod' => 'PhabricatorEditEngineAPIMethod',
|
||||
'PhabricatorDashboardPanelEditController' => 'PhabricatorDashboardController',
|
||||
'PhabricatorDashboardPanelEditEngine' => 'PhabricatorEditEngine',
|
||||
'PhabricatorDashboardPanelEditproController' => 'PhabricatorDashboardController',
|
||||
'PhabricatorDashboardPanelHasDashboardEdgeType' => 'PhabricatorEdgeType',
|
||||
'PhabricatorDashboardPanelFerretEngine' => 'PhabricatorFerretEngine',
|
||||
'PhabricatorDashboardPanelFulltextEngine' => 'PhabricatorFulltextEngine',
|
||||
'PhabricatorDashboardPanelListController' => 'PhabricatorDashboardController',
|
||||
'PhabricatorDashboardPanelNgrams' => 'PhabricatorSearchNgrams',
|
||||
'PhabricatorDashboardPanelNameTransaction' => 'PhabricatorDashboardPanelTransactionType',
|
||||
'PhabricatorDashboardPanelPHIDType' => 'PhabricatorPHIDType',
|
||||
'PhabricatorDashboardPanelPropertyTransaction' => 'PhabricatorDashboardPanelTransactionType',
|
||||
'PhabricatorDashboardPanelQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhabricatorDashboardPanelRef' => 'Phobject',
|
||||
'PhabricatorDashboardPanelRefList' => 'Phobject',
|
||||
'PhabricatorDashboardPanelRenderController' => 'PhabricatorDashboardController',
|
||||
'PhabricatorDashboardPanelRenderingEngine' => 'Phobject',
|
||||
'PhabricatorDashboardPanelSearchApplicationCustomField' => 'PhabricatorStandardCustomField',
|
||||
'PhabricatorDashboardPanelSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||
'PhabricatorDashboardPanelSearchQueryCustomField' => 'PhabricatorStandardCustomField',
|
||||
'PhabricatorDashboardPanelTabsCustomField' => 'PhabricatorStandardCustomField',
|
||||
'PhabricatorDashboardPanelTransaction' => 'PhabricatorApplicationTransaction',
|
||||
'PhabricatorDashboardPanelStatusTransaction' => 'PhabricatorDashboardPanelTransactionType',
|
||||
'PhabricatorDashboardPanelTabsController' => 'PhabricatorDashboardController',
|
||||
'PhabricatorDashboardPanelTransaction' => 'PhabricatorModularTransaction',
|
||||
'PhabricatorDashboardPanelTransactionEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
'PhabricatorDashboardPanelTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||
'PhabricatorDashboardPanelTransactionType' => 'PhabricatorModularTransactionType',
|
||||
'PhabricatorDashboardPanelType' => 'Phobject',
|
||||
'PhabricatorDashboardPanelUsedByObjectEdgeType' => 'PhabricatorEdgeType',
|
||||
'PhabricatorDashboardPanelViewController' => 'PhabricatorDashboardController',
|
||||
'PhabricatorDashboardPanelsTransaction' => 'PhabricatorDashboardTransactionType',
|
||||
'PhabricatorDashboardPortal' => array(
|
||||
'PhabricatorDashboardDAO',
|
||||
'PhabricatorApplicationTransactionInterface',
|
||||
'PhabricatorPolicyInterface',
|
||||
'PhabricatorDestructibleInterface',
|
||||
'PhabricatorProjectInterface',
|
||||
'PhabricatorFulltextInterface',
|
||||
'PhabricatorFerretInterface',
|
||||
),
|
||||
'PhabricatorDashboardPortalController' => 'PhabricatorDashboardController',
|
||||
'PhabricatorDashboardPortalDatasource' => 'PhabricatorTypeaheadDatasource',
|
||||
'PhabricatorDashboardPortalEditConduitAPIMethod' => 'PhabricatorEditEngineAPIMethod',
|
||||
'PhabricatorDashboardPortalEditController' => 'PhabricatorDashboardPortalController',
|
||||
'PhabricatorDashboardPortalEditEngine' => 'PhabricatorEditEngine',
|
||||
'PhabricatorDashboardPortalEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
'PhabricatorDashboardPortalFerretEngine' => 'PhabricatorFerretEngine',
|
||||
'PhabricatorDashboardPortalFulltextEngine' => 'PhabricatorFulltextEngine',
|
||||
'PhabricatorDashboardPortalInstallWorkflow' => 'PhabricatorDashboardObjectInstallWorkflow',
|
||||
'PhabricatorDashboardPortalListController' => 'PhabricatorDashboardPortalController',
|
||||
'PhabricatorDashboardPortalMenuItem' => 'PhabricatorProfileMenuItem',
|
||||
'PhabricatorDashboardPortalNameTransaction' => 'PhabricatorDashboardPortalTransactionType',
|
||||
'PhabricatorDashboardPortalPHIDType' => 'PhabricatorPHIDType',
|
||||
'PhabricatorDashboardPortalProfileMenuEngine' => 'PhabricatorProfileMenuEngine',
|
||||
'PhabricatorDashboardPortalQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhabricatorDashboardPortalSearchConduitAPIMethod' => 'PhabricatorSearchEngineAPIMethod',
|
||||
'PhabricatorDashboardPortalSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||
'PhabricatorDashboardPortalStatus' => 'Phobject',
|
||||
'PhabricatorDashboardPortalTransaction' => 'PhabricatorModularTransaction',
|
||||
'PhabricatorDashboardPortalTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||
'PhabricatorDashboardPortalTransactionType' => 'PhabricatorModularTransactionType',
|
||||
'PhabricatorDashboardPortalViewController' => 'PhabricatorDashboardPortalController',
|
||||
'PhabricatorDashboardProfileController' => 'PhabricatorController',
|
||||
'PhabricatorDashboardProfileMenuItem' => 'PhabricatorProfileMenuItem',
|
||||
'PhabricatorDashboardProjectInstallWorkflow' => 'PhabricatorDashboardObjectInstallWorkflow',
|
||||
'PhabricatorDashboardQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhabricatorDashboardQueryPanelApplicationEditField' => 'PhabricatorEditField',
|
||||
'PhabricatorDashboardQueryPanelApplicationTransaction' => 'PhabricatorDashboardPanelPropertyTransaction',
|
||||
'PhabricatorDashboardQueryPanelInstallController' => 'PhabricatorDashboardController',
|
||||
'PhabricatorDashboardQueryPanelQueryEditField' => 'PhabricatorEditField',
|
||||
'PhabricatorDashboardQueryPanelQueryTransaction' => 'PhabricatorDashboardPanelPropertyTransaction',
|
||||
'PhabricatorDashboardQueryPanelType' => 'PhabricatorDashboardPanelType',
|
||||
'PhabricatorDashboardRemarkupRule' => 'PhabricatorObjectRemarkupRule',
|
||||
'PhabricatorDashboardRemovePanelController' => 'PhabricatorDashboardController',
|
||||
'PhabricatorDashboardRenderingEngine' => 'Phobject',
|
||||
'PhabricatorDashboardSchemaSpec' => 'PhabricatorConfigSchemaSpec',
|
||||
'PhabricatorDashboardSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||
'PhabricatorDashboardStatusTransaction' => 'PhabricatorDashboardTransactionType',
|
||||
'PhabricatorDashboardTabsPanelTabsTransaction' => 'PhabricatorDashboardPanelPropertyTransaction',
|
||||
'PhabricatorDashboardTabsPanelType' => 'PhabricatorDashboardPanelType',
|
||||
'PhabricatorDashboardTextPanelTextTransaction' => 'PhabricatorDashboardPanelPropertyTransaction',
|
||||
'PhabricatorDashboardTextPanelType' => 'PhabricatorDashboardPanelType',
|
||||
'PhabricatorDashboardTransaction' => 'PhabricatorApplicationTransaction',
|
||||
'PhabricatorDashboardTransaction' => 'PhabricatorModularTransaction',
|
||||
'PhabricatorDashboardTransactionEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
'PhabricatorDashboardTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||
'PhabricatorDashboardTransactionType' => 'PhabricatorModularTransactionType',
|
||||
'PhabricatorDashboardTwoThirdsLayoutMode' => 'PhabricatorDashboardLayoutMode',
|
||||
'PhabricatorDashboardViewController' => 'PhabricatorDashboardProfileController',
|
||||
'PhabricatorDataCacheSpec' => 'PhabricatorCacheSpec',
|
||||
'PhabricatorDataNotAttachedException' => 'Exception',
|
||||
|
@ -8975,6 +9092,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorEdgeEditType' => 'PhabricatorPHIDListEditType',
|
||||
'PhabricatorEdgeEditor' => 'Phobject',
|
||||
'PhabricatorEdgeGraph' => 'AbstractDirectedGraph',
|
||||
'PhabricatorEdgeIndexEngineExtension' => 'PhabricatorIndexEngineExtension',
|
||||
'PhabricatorEdgeObject' => array(
|
||||
'Phobject',
|
||||
'PhabricatorPolicyInterface',
|
||||
|
@ -9714,6 +9832,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorObjectRemarkupRule' => 'PhutilRemarkupRule',
|
||||
'PhabricatorObjectSelectorDialog' => 'Phobject',
|
||||
'PhabricatorObjectStatus' => 'Phobject',
|
||||
'PhabricatorObjectUsesDashboardPanelEdgeType' => 'PhabricatorEdgeType',
|
||||
'PhabricatorOffsetPagedQuery' => 'PhabricatorQuery',
|
||||
'PhabricatorOldWorldContentSource' => 'PhabricatorContentSource',
|
||||
'PhabricatorOlderInlinesSetting' => 'PhabricatorSelectSetting',
|
||||
|
@ -10130,17 +10249,22 @@ phutil_register_library_map(array(
|
|||
'PhabricatorProfileMenuEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
'PhabricatorProfileMenuEngine' => 'Phobject',
|
||||
'PhabricatorProfileMenuItem' => 'Phobject',
|
||||
'PhabricatorProfileMenuItemAffectsObjectEdgeType' => 'PhabricatorEdgeType',
|
||||
'PhabricatorProfileMenuItemConfiguration' => array(
|
||||
'PhabricatorSearchDAO',
|
||||
'PhabricatorPolicyInterface',
|
||||
'PhabricatorExtendedPolicyInterface',
|
||||
'PhabricatorApplicationTransactionInterface',
|
||||
'PhabricatorIndexableInterface',
|
||||
),
|
||||
'PhabricatorProfileMenuItemConfigurationQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhabricatorProfileMenuItemConfigurationTransaction' => 'PhabricatorApplicationTransaction',
|
||||
'PhabricatorProfileMenuItemConfigurationTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||
'PhabricatorProfileMenuItemIconSet' => 'PhabricatorIconSet',
|
||||
'PhabricatorProfileMenuItemIndexEngineExtension' => 'PhabricatorEdgeIndexEngineExtension',
|
||||
'PhabricatorProfileMenuItemPHIDType' => 'PhabricatorPHIDType',
|
||||
'PhabricatorProfileMenuItemView' => 'Phobject',
|
||||
'PhabricatorProfileMenuItemViewList' => 'Phobject',
|
||||
'PhabricatorProject' => array(
|
||||
'PhabricatorProjectDAO',
|
||||
'PhabricatorApplicationTransactionInterface',
|
||||
|
@ -10313,18 +10437,21 @@ phutil_register_library_map(array(
|
|||
'PhabricatorIndexableInterface',
|
||||
'PhabricatorDestructibleInterface',
|
||||
),
|
||||
'PhabricatorProjectTriggerAddProjectsRule' => 'PhabricatorProjectTriggerRule',
|
||||
'PhabricatorProjectTriggerController' => 'PhabricatorProjectController',
|
||||
'PhabricatorProjectTriggerCorruptionException' => 'Exception',
|
||||
'PhabricatorProjectTriggerEditController' => 'PhabricatorProjectTriggerController',
|
||||
'PhabricatorProjectTriggerEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
'PhabricatorProjectTriggerInvalidRule' => 'PhabricatorProjectTriggerRule',
|
||||
'PhabricatorProjectTriggerListController' => 'PhabricatorProjectTriggerController',
|
||||
'PhabricatorProjectTriggerManiphestOwnerRule' => 'PhabricatorProjectTriggerRule',
|
||||
'PhabricatorProjectTriggerManiphestPriorityRule' => 'PhabricatorProjectTriggerRule',
|
||||
'PhabricatorProjectTriggerManiphestStatusRule' => 'PhabricatorProjectTriggerRule',
|
||||
'PhabricatorProjectTriggerNameTransaction' => 'PhabricatorProjectTriggerTransactionType',
|
||||
'PhabricatorProjectTriggerPHIDType' => 'PhabricatorPHIDType',
|
||||
'PhabricatorProjectTriggerPlaySoundRule' => 'PhabricatorProjectTriggerRule',
|
||||
'PhabricatorProjectTriggerQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhabricatorProjectTriggerRemoveProjectsRule' => 'PhabricatorProjectTriggerRule',
|
||||
'PhabricatorProjectTriggerRule' => 'Phobject',
|
||||
'PhabricatorProjectTriggerRuleRecord' => 'Phobject',
|
||||
'PhabricatorProjectTriggerRulesetTransaction' => 'PhabricatorProjectTriggerTransactionType',
|
||||
|
@ -10377,6 +10504,7 @@ phutil_register_library_map(array(
|
|||
),
|
||||
'PhabricatorQuickSearchEngineExtension' => 'PhabricatorDatasourceEngineExtension',
|
||||
'PhabricatorRateLimitRequestExceptionHandler' => 'PhabricatorRequestExceptionHandler',
|
||||
'PhabricatorRebuildIndexesWorker' => 'PhabricatorWorker',
|
||||
'PhabricatorRecaptchaConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
||||
'PhabricatorRedirectController' => 'PhabricatorController',
|
||||
'PhabricatorRefreshCSRFController' => 'PhabricatorAuthController',
|
||||
|
|
|
@ -13,6 +13,7 @@ final class PhabricatorAuthListController
|
|||
$list = new PHUIObjectItemListView();
|
||||
$can_manage = $this->hasApplicationCapability(
|
||||
AuthManageProvidersCapability::CAPABILITY);
|
||||
$is_locked = PhabricatorEnv::getEnvConfig('auth.lock-config');
|
||||
|
||||
foreach ($configs as $config) {
|
||||
$item = new PHUIObjectItemView();
|
||||
|
@ -69,7 +70,8 @@ final class PhabricatorAuthListController
|
|||
$crumbs->addTextCrumb(pht('Login and Registration'));
|
||||
$crumbs->setBorder(true);
|
||||
|
||||
$guidance_context = new PhabricatorAuthProvidersGuidanceContext();
|
||||
$guidance_context = id(new PhabricatorAuthProvidersGuidanceContext())
|
||||
->setCanManage($can_manage);
|
||||
|
||||
$guidance = id(new PhabricatorGuidanceEngine())
|
||||
->setViewer($viewer)
|
||||
|
@ -81,7 +83,7 @@ final class PhabricatorAuthListController
|
|||
->setButtonType(PHUIButtonView::BUTTONTYPE_SIMPLE)
|
||||
->setHref($this->getApplicationURI('config/new/'))
|
||||
->setIcon('fa-plus')
|
||||
->setDisabled(!$can_manage)
|
||||
->setDisabled(!$can_manage || $is_locked)
|
||||
->setText(pht('Add Provider'));
|
||||
|
||||
$list->setFlush(true);
|
||||
|
|
|
@ -389,7 +389,7 @@ final class PhabricatorAuthSessionEngine extends Phobject {
|
|||
* appropriate for one-time checks.
|
||||
*
|
||||
* @param PhabricatorUser User whose session needs to be in high security.
|
||||
* @param AphrontReqeust Current request.
|
||||
* @param AphrontRequest Current request.
|
||||
* @param string URI to return the user to if they cancel.
|
||||
* @return PhabricatorAuthHighSecurityToken Security token.
|
||||
* @task hisec
|
||||
|
@ -421,7 +421,7 @@ final class PhabricatorAuthSessionEngine extends Phobject {
|
|||
* use @{method:requireHighSecurityToken}.
|
||||
*
|
||||
* @param PhabricatorUser User whose session needs to be in high security.
|
||||
* @param AphrontReqeust Current request.
|
||||
* @param AphrontRequest Current request.
|
||||
* @param string URI to return the user to if they cancel.
|
||||
* @param bool True to jump partial sessions directly into high
|
||||
* security instead of just upgrading them to full
|
||||
|
|
|
@ -1,4 +1,17 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorAuthProvidersGuidanceContext
|
||||
extends PhabricatorGuidanceContext {}
|
||||
extends PhabricatorGuidanceContext {
|
||||
|
||||
private $canManage = false;
|
||||
|
||||
public function setCanManage($can_manage) {
|
||||
$this->canManage = $can_manage;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCanManage() {
|
||||
return $this->canManage;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -92,6 +92,25 @@ final class PhabricatorAuthProvidersGuidanceEngineExtension
|
|||
->setMessage($message);
|
||||
}
|
||||
|
||||
$locked_config_key = 'auth.lock-config';
|
||||
$is_locked = PhabricatorEnv::getEnvConfig($locked_config_key);
|
||||
if ($is_locked) {
|
||||
$message = pht(
|
||||
'Authentication provider configuration is locked, and can not be '.
|
||||
'changed without being unlocked. See the configuration setting %s '.
|
||||
'for details.',
|
||||
phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => '/config/edit/'.$locked_config_key,
|
||||
),
|
||||
$locked_config_key));
|
||||
|
||||
$results[] = $this->newWarning('auth.locked-config')
|
||||
->setPriority(500)
|
||||
->setMessage($message);
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorAuthManagementLockWorkflow
|
||||
extends PhabricatorAuthManagementWorkflow {
|
||||
|
||||
protected function didConstruct() {
|
||||
$this
|
||||
->setName('lock')
|
||||
->setExamples('**lock**')
|
||||
->setSynopsis(
|
||||
pht(
|
||||
'Lock authentication provider config, to prevent changes to '.
|
||||
'the config without doing **bin/auth unlock**.'));
|
||||
}
|
||||
|
||||
public function execute(PhutilArgumentParser $args) {
|
||||
$console = PhutilConsole::getConsole();
|
||||
|
||||
$key = 'auth.lock-config';
|
||||
$config_entry = PhabricatorConfigEntry::loadConfigEntry($key);
|
||||
$config_entry->setValue(true);
|
||||
|
||||
// If the entry has been deleted, resurrect it.
|
||||
$config_entry->setIsDeleted(0);
|
||||
|
||||
$config_entry->save();
|
||||
|
||||
echo tsprintf(
|
||||
"%s\n",
|
||||
pht('Locked the authentication provider configuration.'));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorAuthManagementUnlockWorkflow
|
||||
extends PhabricatorAuthManagementWorkflow {
|
||||
|
||||
protected function didConstruct() {
|
||||
$this
|
||||
->setName('unlock')
|
||||
->setExamples('**unlock**')
|
||||
->setSynopsis(
|
||||
pht(
|
||||
'Unlock the authentication provider config, to make it possible '.
|
||||
'to edit the config using the web UI. Make sure to do '.
|
||||
'**bin/auth lock** when done editing the configuration.'));
|
||||
}
|
||||
|
||||
public function execute(PhutilArgumentParser $args) {
|
||||
$console = PhutilConsole::getConsole();
|
||||
|
||||
$key = 'auth.lock-config';
|
||||
$config_entry = PhabricatorConfigEntry::loadConfigEntry($key);
|
||||
$config_entry->setValue(false);
|
||||
|
||||
// If the entry has been deleted, resurrect it.
|
||||
$config_entry->setIsDeleted(0);
|
||||
|
||||
$config_entry->save();
|
||||
|
||||
echo tsprintf(
|
||||
"%s\n",
|
||||
pht('Unlocked the authentication provider configuration.'));
|
||||
}
|
||||
}
|
|
@ -238,6 +238,7 @@ final class CelerityDefaultPostprocessor
|
|||
'grey.button.gradient' => 'linear-gradient(to bottom, #ffffff, #f1f0f1)',
|
||||
'grey.button.hover' => 'linear-gradient(to bottom, #ffffff, #eeebec)',
|
||||
|
||||
'document.border' => '#dedee1',
|
||||
|
||||
);
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ final class PhabricatorAuthSetupCheck extends PhabricatorSetupCheck {
|
|||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||
->execute();
|
||||
|
||||
$did_warn = false;
|
||||
if (!$configs) {
|
||||
$message = pht(
|
||||
'You have not configured any authentication providers yet. You '.
|
||||
|
@ -35,6 +36,42 @@ final class PhabricatorAuthSetupCheck extends PhabricatorSetupCheck {
|
|||
->setName(pht('No Authentication Providers Configured'))
|
||||
->setMessage($message)
|
||||
->addLink('/auth/', pht('Auth Application'));
|
||||
|
||||
$did_warn = true;
|
||||
}
|
||||
|
||||
// This check is meant for new administrators, but we don't want to
|
||||
// show both this warning and the "No Auth Providers" warning. Also,
|
||||
// show this as a reminder to go back and do a `bin/auth lock` after
|
||||
// they make their desired changes.
|
||||
$is_locked = PhabricatorEnv::getEnvConfig('auth.lock-config');
|
||||
if (!$is_locked && !$did_warn) {
|
||||
$message = pht(
|
||||
'Your authentication provider configuration is unlocked. Once you '.
|
||||
'finish setting up or modifying authentication, you should lock the '.
|
||||
'configuration to prevent unauthorized changes.'.
|
||||
"\n\n".
|
||||
'Leaving your authentication provider configuration unlocked '.
|
||||
'increases the damage that a compromised administrator account can '.
|
||||
'do to your install, by, for example, changing the authentication '.
|
||||
'provider to a server they control and intercepting usernames and '.
|
||||
'passwords.'.
|
||||
"\n\n".
|
||||
'To prevent this attack, you should configure your authentication '.
|
||||
'providers, and then lock the configuration by doing `%s` '.
|
||||
'from the command line. This will prevent changing the '.
|
||||
'authentication provider config without first doing `%s`.',
|
||||
'bin/auth lock',
|
||||
'bin/auth unlock');
|
||||
$this
|
||||
->newIssue('auth.config-unlocked')
|
||||
->setShortName(pht('Auth Config Unlocked'))
|
||||
->setName(pht('Authenticaton Provider Configuration Unlocked'))
|
||||
->setMessage($message)
|
||||
->addRelatedPhabricatorConfig('auth.lock-config')
|
||||
->addCommand(
|
||||
hsprintf(
|
||||
'<tt>phabricator/ $</tt> ./bin/auth lock'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,6 +73,26 @@ final class PhabricatorAuthenticationConfigOptions
|
|||
->addExample(
|
||||
"yourcompany.com\nmail.yourcompany.com",
|
||||
pht('Valid Setting')),
|
||||
$this->newOption('auth.lock-config', 'bool', false)
|
||||
->setBoolOptions(
|
||||
array(
|
||||
pht('Auth provider config must be unlocked before editing'),
|
||||
pht('Auth provider config can be edited without unlocking'),
|
||||
))
|
||||
->setSummary(
|
||||
pht(
|
||||
'Require administrators to unlock the authentication provider '.
|
||||
'configuration from the CLI before it can be edited.'))
|
||||
->setDescription(
|
||||
pht(
|
||||
'When set to `true`, the authentication provider configuration '.
|
||||
'for this instance can not be modified without first running '.
|
||||
'`bin/auth unlock` from the command line. This is to reduce '.
|
||||
'the security impact of a compromised administrator account. '.
|
||||
"\n\n".
|
||||
'After running `bin/auth unlock` and making your changes to the '.
|
||||
'authentication provider config, you should run `bin/auth lock`.'))
|
||||
->setLocked(true),
|
||||
$this->newOption('account.editable', 'bool', true)
|
||||
->setBoolOptions(
|
||||
array(
|
||||
|
|
|
@ -163,14 +163,26 @@ EOTEXT
|
|||
'mailto' => true,
|
||||
))
|
||||
->setSummary(
|
||||
pht('Determines which URI protocols are auto-linked.'))
|
||||
pht(
|
||||
'Determines which URI protocols are valid for links and '.
|
||||
'redirects.'))
|
||||
->setDescription(
|
||||
pht(
|
||||
"When users write comments which have URIs, they'll be ".
|
||||
"automatically linked if the protocol appears in this set. This ".
|
||||
"whitelist is primarily to prevent security issues like ".
|
||||
"%s URIs.",
|
||||
'javascript://'))
|
||||
'When users write comments which have URIs, they will be '.
|
||||
'automatically turned into clickable links if the URI protocol '.
|
||||
'appears in this set.'.
|
||||
"\n\n".
|
||||
'This set of allowed protocols is primarily intended to prevent '.
|
||||
'security issues with "javascript:" and other potentially '.
|
||||
'dangerous URI handlers.'.
|
||||
"\n\n".
|
||||
'This set is also used to enforce valid redirect URIs. '.
|
||||
'Phabricator will refuse to issue a HTTP "Location" redirect to a '.
|
||||
'URI with a protocol not on this set.'.
|
||||
"\n\n".
|
||||
'Usually, "http" and "https" should be present in this set. If '.
|
||||
'you remove one or both protocols, some Phabricator features '.
|
||||
'which rely on links or redirects may not work.'))
|
||||
->addExample("http\nhttps", pht('Valid Setting'))
|
||||
->setLocked(true),
|
||||
$this->newOption(
|
||||
|
|
|
@ -136,7 +136,7 @@ final class ConpherenceThreadQuery
|
|||
|
||||
protected function buildGroupClause(AphrontDatabaseConnection $conn_r) {
|
||||
if ($this->participantPHIDs !== null || strlen($this->fulltext)) {
|
||||
return 'GROUP BY thread.id';
|
||||
return qsprintf($conn_r, 'GROUP BY thread.id');
|
||||
} else {
|
||||
return $this->buildApplicationSearchGroupClause($conn_r);
|
||||
}
|
||||
|
@ -192,18 +192,24 @@ final class ConpherenceThreadQuery
|
|||
if ($can_optimize) {
|
||||
$members_policy = id(new ConpherenceThreadMembersPolicyRule())
|
||||
->getObjectPolicyFullKey();
|
||||
$policies = array(
|
||||
$members_policy,
|
||||
PhabricatorPolicies::POLICY_USER,
|
||||
PhabricatorPolicies::POLICY_ADMIN,
|
||||
PhabricatorPolicies::POLICY_NOONE,
|
||||
);
|
||||
|
||||
if ($viewer->isLoggedIn()) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'thread.viewPolicy != %s OR vp.participantPHID = %s',
|
||||
$members_policy,
|
||||
'thread.viewPolicy NOT IN (%Ls) OR vp.participantPHID = %s',
|
||||
$policies,
|
||||
$viewer->getPHID());
|
||||
} else {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'thread.viewPolicy != %s',
|
||||
$members_policy);
|
||||
'thread.viewPolicy NOT IN (%Ls)',
|
||||
$policies);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -224,12 +224,12 @@ final class ConpherenceLayoutView extends AphrontTagView {
|
|||
private function buildNUXView() {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$engine = new ConpherenceThreadSearchEngine();
|
||||
$engine->setViewer($viewer);
|
||||
$engine = id(new ConpherenceThreadSearchEngine())
|
||||
->setViewer($viewer);
|
||||
$saved = $engine->buildSavedQueryFromBuiltin('all');
|
||||
$query = $engine->buildQueryFromSavedQuery($saved);
|
||||
$pager = $engine->newPagerForSavedQuery($saved);
|
||||
$pager->setPageSize(10);
|
||||
$pager = $engine->newPagerForSavedQuery($saved)
|
||||
->setPageSize(10);
|
||||
$results = $engine->executeQuery($query, $pager);
|
||||
$view = $engine->renderResults($results, $saved);
|
||||
|
||||
|
|
|
@ -10,6 +10,10 @@ final class PhabricatorDashboardApplication extends PhabricatorApplication {
|
|||
return '/dashboard/';
|
||||
}
|
||||
|
||||
public function getTypeaheadURI() {
|
||||
return '/dashboard/console/';
|
||||
}
|
||||
|
||||
public function getShortDescription() {
|
||||
return pht('Create Custom Pages');
|
||||
}
|
||||
|
@ -27,6 +31,9 @@ final class PhabricatorDashboardApplication extends PhabricatorApplication {
|
|||
}
|
||||
|
||||
public function getRoutes() {
|
||||
$menu_rules = $this->getProfileMenuRouting(
|
||||
'PhabricatorDashboardPortalViewController');
|
||||
|
||||
return array(
|
||||
'/W(?P<id>\d+)' => 'PhabricatorDashboardPanelViewController',
|
||||
'/dashboard/' => array(
|
||||
|
@ -34,29 +41,39 @@ final class PhabricatorDashboardApplication extends PhabricatorApplication {
|
|||
=> 'PhabricatorDashboardListController',
|
||||
'view/(?P<id>\d+)/' => 'PhabricatorDashboardViewController',
|
||||
'archive/(?P<id>\d+)/' => 'PhabricatorDashboardArchiveController',
|
||||
'manage/(?P<id>\d+)/' => 'PhabricatorDashboardManageController',
|
||||
'arrange/(?P<id>\d+)/' => 'PhabricatorDashboardArrangeController',
|
||||
'create/' => 'PhabricatorDashboardEditController',
|
||||
'edit/(?:(?P<id>\d+)/)?' => 'PhabricatorDashboardEditController',
|
||||
'install/(?:(?P<id>\d+)/)?' => 'PhabricatorDashboardInstallController',
|
||||
'addpanel/(?P<id>\d+)/' => 'PhabricatorDashboardAddPanelController',
|
||||
'movepanel/(?P<id>\d+)/' => 'PhabricatorDashboardMovePanelController',
|
||||
'removepanel/(?P<id>\d+)/'
|
||||
=> 'PhabricatorDashboardRemovePanelController',
|
||||
$this->getEditRoutePattern('edit/') =>
|
||||
'PhabricatorDashboardEditController',
|
||||
'install/(?P<id>\d+)/'.
|
||||
'(?:(?P<workflowKey>[^/]+)/'.
|
||||
'(?:(?P<modeKey>[^/]+)/)?)?' =>
|
||||
'PhabricatorDashboardInstallController',
|
||||
'console/' => 'PhabricatorDashboardConsoleController',
|
||||
'adjust/(?P<op>remove|add|move)/'
|
||||
=> 'PhabricatorDashboardAdjustController',
|
||||
'panel/' => array(
|
||||
'install/(?P<engineKey>[^/]+)/(?:(?P<queryKey>[^/]+)/)?' =>
|
||||
'PhabricatorDashboardQueryPanelInstallController',
|
||||
'(?:query/(?P<queryKey>[^/]+)/)?'
|
||||
=> 'PhabricatorDashboardPanelListController',
|
||||
'create/' => 'PhabricatorDashboardPanelEditController',
|
||||
$this->getEditRoutePattern('editpro/')
|
||||
=> 'PhabricatorDashboardPanelEditproController',
|
||||
'edit/(?:(?P<id>\d+)/)?' => 'PhabricatorDashboardPanelEditController',
|
||||
$this->getEditRoutePattern('edit/')
|
||||
=> 'PhabricatorDashboardPanelEditController',
|
||||
'render/(?P<id>\d+)/' => 'PhabricatorDashboardPanelRenderController',
|
||||
'archive/(?P<id>\d+)/'
|
||||
=> 'PhabricatorDashboardPanelArchiveController',
|
||||
'tabs/(?P<id>\d+)/(?P<op>add|move|remove|rename)/'
|
||||
=> 'PhabricatorDashboardPanelTabsController',
|
||||
),
|
||||
),
|
||||
'/portal/' => array(
|
||||
$this->getQueryRoutePattern() =>
|
||||
'PhabricatorDashboardPortalListController',
|
||||
$this->getEditRoutePattern('edit/') =>
|
||||
'PhabricatorDashboardPortalEditController',
|
||||
'view/(?P<portalID>\d)/' => array(
|
||||
'' => 'PhabricatorDashboardPortalViewController',
|
||||
) + $menu_rules,
|
||||
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardPortalEditConduitAPIMethod
|
||||
extends PhabricatorEditEngineAPIMethod {
|
||||
|
||||
public function getAPIMethodName() {
|
||||
return 'portal.edit';
|
||||
}
|
||||
|
||||
public function newEditEngine() {
|
||||
return new PhabricatorDashboardPortalEditEngine();
|
||||
}
|
||||
|
||||
public function getMethodSummary() {
|
||||
return pht(
|
||||
'Apply transactions to create a new portal or edit an existing one.');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardPortalSearchConduitAPIMethod
|
||||
extends PhabricatorSearchEngineAPIMethod {
|
||||
|
||||
public function getAPIMethodName() {
|
||||
return 'portal.search';
|
||||
}
|
||||
|
||||
public function newSearchEngine() {
|
||||
return new PhabricatorDashboardPortalSearchEngine();
|
||||
}
|
||||
|
||||
public function getMethodSummary() {
|
||||
return pht('Read information about portals.');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardPortalStatus
|
||||
extends Phobject {
|
||||
|
||||
const STATUS_ACTIVE = 'active';
|
||||
const STATUS_ARCHIVED = 'archived';
|
||||
|
||||
}
|
|
@ -1,104 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardAddPanelController
|
||||
extends PhabricatorDashboardController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
$dashboard = id(new PhabricatorDashboardQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->needPanels(true)
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->executeOne();
|
||||
if (!$dashboard) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$redirect_uri = $this->getApplicationURI(
|
||||
'arrange/'.$dashboard->getID().'/');
|
||||
|
||||
$v_panel = head($request->getArr('panel'));
|
||||
$e_panel = true;
|
||||
$errors = array();
|
||||
if ($request->isFormPost()) {
|
||||
if (strlen($v_panel)) {
|
||||
$panel = id(new PhabricatorDashboardPanelQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($v_panel))
|
||||
->executeOne();
|
||||
if (!$panel) {
|
||||
$errors[] = pht('Not a valid panel.');
|
||||
$e_panel = pht('Invalid');
|
||||
}
|
||||
|
||||
$on_dashboard = $dashboard->getPanels();
|
||||
$on_ids = mpull($on_dashboard, null, 'getID');
|
||||
if (array_key_exists($v_panel, $on_ids)) {
|
||||
$p_name = $panel->getName();
|
||||
$errors[] = pht('Panel "%s" already exists on dashboard.', $p_name);
|
||||
$e_panel = pht('Invalid');
|
||||
}
|
||||
|
||||
} else {
|
||||
$errors[] = pht('Select a panel to add.');
|
||||
$e_panel = pht('Required');
|
||||
}
|
||||
|
||||
if (!$errors) {
|
||||
PhabricatorDashboardTransactionEditor::addPanelToDashboard(
|
||||
$viewer,
|
||||
PhabricatorContentSource::newFromRequest($request),
|
||||
$panel,
|
||||
$dashboard,
|
||||
$request->getInt('column', 0));
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI($redirect_uri);
|
||||
}
|
||||
}
|
||||
|
||||
$panels = id(new PhabricatorDashboardPanelQuery())
|
||||
->setViewer($viewer)
|
||||
->withArchived(false)
|
||||
->execute();
|
||||
|
||||
if (!$panels) {
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('No Panels Exist Yet'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'You have not created any dashboard panels yet, so you can not '.
|
||||
'add an existing panel.'))
|
||||
->appendParagraph(
|
||||
pht('Instead, add a new panel.'))
|
||||
->addCancelButton($redirect_uri);
|
||||
}
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($viewer)
|
||||
->addHiddenInput('column', $request->getInt('column'))
|
||||
->appendRemarkupInstructions(
|
||||
pht('Choose a panel to add to this dashboard:'))
|
||||
->appendChild(
|
||||
id(new AphrontFormTokenizerControl())
|
||||
->setUser($this->getViewer())
|
||||
->setDatasource(new PhabricatorDashboardPanelDatasource())
|
||||
->setLimit(1)
|
||||
->setName('panel')
|
||||
->setLabel(pht('Panel')));
|
||||
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Add Panel'))
|
||||
->setErrors($errors)
|
||||
->appendChild($form->buildLayoutView())
|
||||
->addCancelButton($redirect_uri)
|
||||
->addSubmitButton(pht('Add Panel'));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardArrangeController
|
||||
extends PhabricatorDashboardProfileController {
|
||||
|
||||
public function shouldAllowPublic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
$dashboard = id(new PhabricatorDashboardQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->needPanels(true)
|
||||
->executeOne();
|
||||
if (!$dashboard) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
$this->setDashboard($dashboard);
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$dashboard,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$title = $dashboard->getName();
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb(pht('Arrange'));
|
||||
$header = $this->buildHeaderView();
|
||||
|
||||
$info_view = null;
|
||||
if (!$can_edit) {
|
||||
$no_edit = pht(
|
||||
'You do not have permission to edit this dashboard.');
|
||||
|
||||
$info_view = id(new PHUIInfoView())
|
||||
->setSeverity(PHUIInfoView::SEVERITY_NOTICE)
|
||||
->setErrors(array($no_edit));
|
||||
}
|
||||
|
||||
$rendered_dashboard = id(new PhabricatorDashboardRenderingEngine())
|
||||
->setViewer($viewer)
|
||||
->setDashboard($dashboard)
|
||||
->setArrangeMode($can_edit)
|
||||
->renderDashboard();
|
||||
|
||||
$dashboard_box = id(new PHUIBoxView())
|
||||
->addClass('dashboard-preview-box')
|
||||
->appendChild($rendered_dashboard);
|
||||
|
||||
$install_button = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setText('Install Dashboard')
|
||||
->setIcon('fa-plus')
|
||||
->setWorkflow(true)
|
||||
->setHref($this->getApplicationURI("/install/{$id}/"));
|
||||
$header->addActionLink($install_button);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setFooter(array(
|
||||
$info_view,
|
||||
$dashboard_box,
|
||||
));
|
||||
|
||||
$navigation = $this->buildSideNavView('arrange');
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->setNavigation($navigation)
|
||||
->appendChild($view);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardConsoleController
|
||||
extends PhabricatorDashboardController {
|
||||
|
||||
public function shouldAllowPublic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
|
||||
$menu = id(new PHUIObjectItemListView())
|
||||
->setUser($viewer)
|
||||
->setBig(true);
|
||||
|
||||
$menu->addItem(
|
||||
id(new PHUIObjectItemView())
|
||||
->setHeader(pht('Portals'))
|
||||
->setImageIcon('fa-compass')
|
||||
->setHref('/portal/')
|
||||
->setClickable(true)
|
||||
->addAttribute(
|
||||
pht(
|
||||
'Portals are collections of dashboards, links, and other '.
|
||||
'resources that can provide a high-level overview of a '.
|
||||
'project.')));
|
||||
|
||||
$menu->addItem(
|
||||
id(new PHUIObjectItemView())
|
||||
->setHeader(pht('Dashboards'))
|
||||
->setImageIcon('fa-dashboard')
|
||||
->setHref($this->getApplicationURI('/'))
|
||||
->setClickable(true)
|
||||
->addAttribute(
|
||||
pht(
|
||||
'Dashboards organize panels, creating a cohesive page for '.
|
||||
'analysis or action.')));
|
||||
|
||||
$menu->addItem(
|
||||
id(new PHUIObjectItemView())
|
||||
->setHeader(pht('Panels'))
|
||||
->setImageIcon('fa-line-chart')
|
||||
->setHref($this->getApplicationURI('panel/'))
|
||||
->setClickable(true)
|
||||
->addAttribute(
|
||||
pht(
|
||||
'Panels show queries, charts, and other information to provide '.
|
||||
'insight on a particular topic.')));
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb(pht('Console'));
|
||||
$crumbs->setBorder(true);
|
||||
|
||||
$title = pht('Dashboard Console');
|
||||
|
||||
$box = id(new PHUIObjectBoxView())
|
||||
->setHeaderText($title)
|
||||
->setBackground(PHUIObjectBoxView::WHITE_CONFIG)
|
||||
->setObjectList($menu);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setFixed(true)
|
||||
->setFooter($box);
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->appendChild($view);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,382 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardEditController
|
||||
extends PhabricatorDashboardController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
if ($id) {
|
||||
$dashboard = id(new PhabricatorDashboardQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->needPanels(true)
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->executeOne();
|
||||
if (!$dashboard) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
$v_projects = PhabricatorEdgeQuery::loadDestinationPHIDs(
|
||||
$dashboard->getPHID(),
|
||||
PhabricatorProjectObjectHasProjectEdgeType::EDGECONST);
|
||||
$v_projects = array_reverse($v_projects);
|
||||
$is_new = false;
|
||||
} else {
|
||||
if (!$request->getStr('edit')) {
|
||||
if ($request->isFormPost()) {
|
||||
switch ($request->getStr('template')) {
|
||||
case 'empty':
|
||||
break;
|
||||
default:
|
||||
return $this->processBuildTemplateRequest($request);
|
||||
}
|
||||
} else {
|
||||
return $this->processTemplateRequest($request);
|
||||
}
|
||||
}
|
||||
|
||||
$dashboard = PhabricatorDashboard::initializeNewDashboard($viewer);
|
||||
$v_projects = array();
|
||||
$is_new = true;
|
||||
}
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
|
||||
if ($is_new) {
|
||||
$title = pht('Create Dashboard');
|
||||
$header_icon = 'fa-plus-square';
|
||||
$button = pht('Create Dashboard');
|
||||
$cancel_uri = $this->getApplicationURI();
|
||||
|
||||
$crumbs->addTextCrumb(pht('Create Dashboard'));
|
||||
} else {
|
||||
$id = $dashboard->getID();
|
||||
$cancel_uri = $this->getApplicationURI('manage/'.$id.'/');
|
||||
|
||||
$title = pht('Edit Dashboard: %s', $dashboard->getName());
|
||||
$header_icon = 'fa-pencil';
|
||||
$button = pht('Save Changes');
|
||||
|
||||
$crumbs->addTextCrumb($dashboard->getName(), $cancel_uri);
|
||||
$crumbs->addTextCrumb(pht('Edit'));
|
||||
}
|
||||
|
||||
$v_name = $dashboard->getName();
|
||||
$v_icon = $dashboard->getIcon();
|
||||
$v_layout_mode = $dashboard->getLayoutConfigObject()->getLayoutMode();
|
||||
$e_name = true;
|
||||
|
||||
$validation_exception = null;
|
||||
if ($request->isFormPost() && $request->getStr('edit')) {
|
||||
$v_name = $request->getStr('name');
|
||||
$v_icon = $request->getStr('icon');
|
||||
$v_layout_mode = $request->getStr('layout_mode');
|
||||
$v_view_policy = $request->getStr('viewPolicy');
|
||||
$v_edit_policy = $request->getStr('editPolicy');
|
||||
$v_projects = $request->getArr('projects');
|
||||
|
||||
$xactions = array();
|
||||
|
||||
$type_name = PhabricatorDashboardTransaction::TYPE_NAME;
|
||||
$type_icon = PhabricatorDashboardTransaction::TYPE_ICON;
|
||||
$type_layout_mode = PhabricatorDashboardTransaction::TYPE_LAYOUT_MODE;
|
||||
$type_view_policy = PhabricatorTransactions::TYPE_VIEW_POLICY;
|
||||
$type_edit_policy = PhabricatorTransactions::TYPE_EDIT_POLICY;
|
||||
|
||||
$xactions[] = id(new PhabricatorDashboardTransaction())
|
||||
->setTransactionType($type_name)
|
||||
->setNewValue($v_name);
|
||||
$xactions[] = id(new PhabricatorDashboardTransaction())
|
||||
->setTransactionType($type_layout_mode)
|
||||
->setNewValue($v_layout_mode);
|
||||
$xactions[] = id(new PhabricatorDashboardTransaction())
|
||||
->setTransactionType($type_icon)
|
||||
->setNewValue($v_icon);
|
||||
$xactions[] = id(new PhabricatorDashboardTransaction())
|
||||
->setTransactionType($type_view_policy)
|
||||
->setNewValue($v_view_policy);
|
||||
$xactions[] = id(new PhabricatorDashboardTransaction())
|
||||
->setTransactionType($type_edit_policy)
|
||||
->setNewValue($v_edit_policy);
|
||||
|
||||
$proj_edge_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
|
||||
$xactions[] = id(new PhabricatorDashboardTransaction())
|
||||
->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
|
||||
->setMetadataValue('edge:type', $proj_edge_type)
|
||||
->setNewValue(array('=' => array_fuse($v_projects)));
|
||||
|
||||
try {
|
||||
$editor = id(new PhabricatorDashboardTransactionEditor())
|
||||
->setActor($viewer)
|
||||
->setContinueOnNoEffect(true)
|
||||
->setContentSourceFromRequest($request)
|
||||
->applyTransactions($dashboard, $xactions);
|
||||
|
||||
$uri = $this->getApplicationURI('arrange/'.$dashboard->getID().'/');
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI($uri);
|
||||
} catch (PhabricatorApplicationTransactionValidationException $ex) {
|
||||
$validation_exception = $ex;
|
||||
|
||||
$e_name = $validation_exception->getShortMessage($type_name);
|
||||
|
||||
$dashboard->setViewPolicy($v_view_policy);
|
||||
$dashboard->setEditPolicy($v_edit_policy);
|
||||
}
|
||||
}
|
||||
|
||||
$policies = id(new PhabricatorPolicyQuery())
|
||||
->setViewer($viewer)
|
||||
->setObject($dashboard)
|
||||
->execute();
|
||||
|
||||
$layout_mode_options =
|
||||
PhabricatorDashboardLayoutConfig::getLayoutModeSelectOptions();
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($viewer)
|
||||
->addHiddenInput('edit', true)
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setLabel(pht('Name'))
|
||||
->setName('name')
|
||||
->setValue($v_name)
|
||||
->setError($e_name))
|
||||
->appendChild(
|
||||
id(new AphrontFormSelectControl())
|
||||
->setLabel(pht('Layout Mode'))
|
||||
->setName('layout_mode')
|
||||
->setValue($v_layout_mode)
|
||||
->setOptions($layout_mode_options))
|
||||
->appendChild(
|
||||
id(new PHUIFormIconSetControl())
|
||||
->setLabel(pht('Icon'))
|
||||
->setName('icon')
|
||||
->setIconSet(new PhabricatorDashboardIconSet())
|
||||
->setValue($v_icon))
|
||||
->appendChild(
|
||||
id(new AphrontFormPolicyControl())
|
||||
->setName('viewPolicy')
|
||||
->setPolicyObject($dashboard)
|
||||
->setCapability(PhabricatorPolicyCapability::CAN_VIEW)
|
||||
->setPolicies($policies))
|
||||
->appendChild(
|
||||
id(new AphrontFormPolicyControl())
|
||||
->setName('editPolicy')
|
||||
->setPolicyObject($dashboard)
|
||||
->setCapability(PhabricatorPolicyCapability::CAN_EDIT)
|
||||
->setPolicies($policies));
|
||||
|
||||
$form->appendControl(
|
||||
id(new AphrontFormTokenizerControl())
|
||||
->setLabel(pht('Tags'))
|
||||
->setName('projects')
|
||||
->setValue($v_projects)
|
||||
->setDatasource(new PhabricatorProjectDatasource()));
|
||||
|
||||
$form->appendChild(
|
||||
id(new AphrontFormSubmitControl())
|
||||
->setValue($button)
|
||||
->addCancelButton($cancel_uri));
|
||||
|
||||
$box = id(new PHUIObjectBoxView())
|
||||
->setHeaderText($title)
|
||||
->setForm($form)
|
||||
->setBackground(PHUIObjectBoxView::WHITE_CONFIG)
|
||||
->setValidationException($validation_exception);
|
||||
|
||||
$crumbs->setBorder(true);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setFooter($box);
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->appendChild($view);
|
||||
}
|
||||
|
||||
private function processTemplateRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getUser();
|
||||
|
||||
$template_control = id(new AphrontFormRadioButtonControl())
|
||||
->setName(pht('template'))
|
||||
->setValue($request->getStr('template', 'empty'))
|
||||
->addButton(
|
||||
'empty',
|
||||
pht('Empty'),
|
||||
pht('Start with a blank canvas.'))
|
||||
->addButton(
|
||||
'simple',
|
||||
pht('Simple Template'),
|
||||
pht(
|
||||
'Start with a simple dashboard with a welcome message, a feed of '.
|
||||
'recent events, and a few starter panels.'));
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($viewer)
|
||||
->appendRemarkupInstructions(
|
||||
pht('Choose a dashboard template to start with.'))
|
||||
->appendChild($template_control);
|
||||
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Create Dashboard'))
|
||||
->setWidth(AphrontDialogView::WIDTH_FORM)
|
||||
->appendChild($form->buildLayoutView())
|
||||
->addCancelButton('/dashboard/')
|
||||
->addSubmitButton(pht('Continue'));
|
||||
}
|
||||
|
||||
private function processBuildTemplateRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getUser();
|
||||
$template = $request->getStr('template');
|
||||
|
||||
$bare_panel = PhabricatorDashboardPanel::initializeNewPanel($viewer);
|
||||
$panel_phids = array();
|
||||
|
||||
switch ($template) {
|
||||
case 'simple':
|
||||
$v_name = pht("%s's Dashboard", $viewer->getUsername());
|
||||
|
||||
$welcome_panel = $this->newPanel(
|
||||
$request,
|
||||
$viewer,
|
||||
'text',
|
||||
pht('Welcome'),
|
||||
array(
|
||||
'text' => pht(
|
||||
"This is a simple template dashboard. You can edit this panel ".
|
||||
"to change this text and replace it with a welcome message, or ".
|
||||
"leave this placeholder text as-is to give your dashboard a ".
|
||||
"rustic, authentic feel.\n\n".
|
||||
"You can drag, remove, add, and edit panels to customize the ".
|
||||
"rest of this dashboard to show the information you want.\n\n".
|
||||
"To install this dashboard on the home page, edit your personal ".
|
||||
"or global menu on the homepage and click Dashboard under ".
|
||||
"New Menu Item on the right."),
|
||||
));
|
||||
$panel_phids[] = $welcome_panel->getPHID();
|
||||
|
||||
$feed_panel = $this->newPanel(
|
||||
$request,
|
||||
$viewer,
|
||||
'query',
|
||||
pht('Recent Activity'),
|
||||
array(
|
||||
'class' => 'PhabricatorFeedSearchEngine',
|
||||
'key' => 'all',
|
||||
));
|
||||
$panel_phids[] = $feed_panel->getPHID();
|
||||
|
||||
$revision_panel = $this->newPanel(
|
||||
$request,
|
||||
$viewer,
|
||||
'query',
|
||||
pht('Active Revisions'),
|
||||
array(
|
||||
'class' => 'DifferentialRevisionSearchEngine',
|
||||
'key' => 'active',
|
||||
));
|
||||
$panel_phids[] = $revision_panel->getPHID();
|
||||
|
||||
$task_panel = $this->newPanel(
|
||||
$request,
|
||||
$viewer,
|
||||
'query',
|
||||
pht('Assigned Tasks'),
|
||||
array(
|
||||
'class' => 'ManiphestTaskSearchEngine',
|
||||
'key' => 'assigned',
|
||||
));
|
||||
$panel_phids[] = $task_panel->getPHID();
|
||||
|
||||
$commit_panel = $this->newPanel(
|
||||
$request,
|
||||
$viewer,
|
||||
'query',
|
||||
pht('Recent Commits'),
|
||||
array(
|
||||
'class' => 'PhabricatorCommitSearchEngine',
|
||||
'key' => 'all',
|
||||
));
|
||||
$panel_phids[] = $commit_panel->getPHID();
|
||||
|
||||
$mode_2_and_1 = PhabricatorDashboardLayoutConfig::MODE_THIRDS_AND_THIRD;
|
||||
$layout = id(new PhabricatorDashboardLayoutConfig())
|
||||
->setLayoutMode($mode_2_and_1)
|
||||
->setPanelLocation(0, $welcome_panel->getPHID())
|
||||
->setPanelLocation(0, $revision_panel->getPHID())
|
||||
->setPanelLocation(0, $task_panel->getPHID())
|
||||
->setPanelLocation(0, $commit_panel->getPHID())
|
||||
->setPanelLocation(1, $feed_panel->getPHID());
|
||||
|
||||
break;
|
||||
default:
|
||||
throw new Exception(pht('Unknown dashboard template %s!', $template));
|
||||
}
|
||||
|
||||
// Create the dashboard.
|
||||
|
||||
$dashboard = PhabricatorDashboard::initializeNewDashboard($viewer)
|
||||
->setLayoutConfigFromObject($layout);
|
||||
|
||||
$xactions = array();
|
||||
|
||||
$xactions[] = id(new PhabricatorDashboardTransaction())
|
||||
->setTransactionType(PhabricatorDashboardTransaction::TYPE_NAME)
|
||||
->setNewValue($v_name);
|
||||
|
||||
$xactions[] = id(new PhabricatorDashboardTransaction())
|
||||
->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
|
||||
->setMetadataValue(
|
||||
'edge:type',
|
||||
PhabricatorDashboardDashboardHasPanelEdgeType::EDGECONST)
|
||||
->setNewValue(
|
||||
array(
|
||||
'+' => array_fuse($panel_phids),
|
||||
));
|
||||
|
||||
$editor = id(new PhabricatorDashboardTransactionEditor())
|
||||
->setActor($viewer)
|
||||
->setContinueOnNoEffect(true)
|
||||
->setContentSourceFromRequest($request)
|
||||
->applyTransactions($dashboard, $xactions);
|
||||
|
||||
$manage_uri = $this->getApplicationURI('arrange/'.$dashboard->getID().'/');
|
||||
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI($manage_uri);
|
||||
}
|
||||
|
||||
private function newPanel(
|
||||
AphrontRequest $request,
|
||||
PhabricatorUser $viewer,
|
||||
$type,
|
||||
$name,
|
||||
array $properties) {
|
||||
|
||||
$panel = PhabricatorDashboardPanel::initializeNewPanel($viewer)
|
||||
->setPanelType($type)
|
||||
->setProperties($properties);
|
||||
|
||||
$xactions = array();
|
||||
|
||||
$xactions[] = id(new PhabricatorDashboardPanelTransaction())
|
||||
->setTransactionType(PhabricatorDashboardPanelTransaction::TYPE_NAME)
|
||||
->setNewValue($name);
|
||||
|
||||
$editor = id(new PhabricatorDashboardPanelTransactionEditor())
|
||||
->setActor($viewer)
|
||||
->setContinueOnNoEffect(true)
|
||||
->setContentSourceFromRequest($request)
|
||||
->applyTransactions($panel, $xactions);
|
||||
|
||||
return $panel;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,141 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardInstallController
|
||||
extends PhabricatorDashboardController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
$dashboard = id(new PhabricatorDashboardQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->executeOne();
|
||||
if (!$dashboard) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$cancel_uri = $this->getApplicationURI(
|
||||
'view/'.$dashboard->getID().'/');
|
||||
|
||||
$home_app = new PhabricatorHomeApplication();
|
||||
|
||||
$options = array();
|
||||
$options['home'] = array(
|
||||
'personal' =>
|
||||
array(
|
||||
'capability' => PhabricatorPolicyCapability::CAN_VIEW,
|
||||
'application' => $home_app,
|
||||
'name' => pht('Personal Dashboard'),
|
||||
'value' => 'personal',
|
||||
'description' => pht('Places this dashboard as a menu item on home '.
|
||||
'as a personal menu item. It will only be on your personal '.
|
||||
'home.'),
|
||||
),
|
||||
'global' =>
|
||||
array(
|
||||
'capability' => PhabricatorPolicyCapability::CAN_EDIT,
|
||||
'application' => $home_app,
|
||||
'name' => pht('Global Dashboard'),
|
||||
'value' => 'global',
|
||||
'description' => pht('Places this dashboard as a menu item on home '.
|
||||
'as a global menu item. It will be available to all users.'),
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
$errors = array();
|
||||
$v_name = null;
|
||||
if ($request->isFormPost()) {
|
||||
$menuitem = new PhabricatorDashboardProfileMenuItem();
|
||||
$dashboard_phid = $dashboard->getPHID();
|
||||
$home = new PhabricatorHomeApplication();
|
||||
$v_name = $request->getStr('name');
|
||||
$v_home = $request->getStr('home');
|
||||
|
||||
if ($v_home) {
|
||||
$application = $options['home'][$v_home]['application'];
|
||||
$capability = $options['home'][$v_home]['capability'];
|
||||
|
||||
$can_edit_home = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$application,
|
||||
$capability);
|
||||
|
||||
if (!$can_edit_home) {
|
||||
$errors[] = pht(
|
||||
'You do not have permission to install a dashboard on home.');
|
||||
}
|
||||
} else {
|
||||
$errors[] = pht(
|
||||
'You must select a destination to install this dashboard.');
|
||||
}
|
||||
|
||||
$v_phid = $viewer->getPHID();
|
||||
if ($v_home == 'global') {
|
||||
$v_phid = null;
|
||||
}
|
||||
|
||||
if (!$errors) {
|
||||
$install = PhabricatorProfileMenuItemConfiguration::initializeNewItem(
|
||||
$home,
|
||||
$menuitem,
|
||||
$v_phid);
|
||||
|
||||
$install->setMenuItemProperty('dashboardPHID', $dashboard_phid);
|
||||
$install->setMenuItemProperty('name', $v_name);
|
||||
$install->setMenuItemOrder(1);
|
||||
|
||||
$xactions = array();
|
||||
|
||||
$editor = id(new PhabricatorProfileMenuEditor())
|
||||
->setActor($viewer)
|
||||
->setContinueOnNoEffect(true)
|
||||
->setContinueOnMissingFields(true)
|
||||
->setContentSourceFromRequest($request);
|
||||
|
||||
$editor->applyTransactions($install, $xactions);
|
||||
|
||||
$view_uri = '/home/menu/view/'.$install->getID().'/';
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI($view_uri);
|
||||
}
|
||||
}
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($viewer)
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setLabel(pht('Menu Label'))
|
||||
->setName('name')
|
||||
->setValue($v_name));
|
||||
|
||||
$radio = id(new AphrontFormRadioButtonControl())
|
||||
->setLabel(pht('Home Menu'))
|
||||
->setName('home');
|
||||
|
||||
foreach ($options['home'] as $type => $option) {
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$option['application'],
|
||||
$option['capability']);
|
||||
if ($can_edit) {
|
||||
$radio->addButton(
|
||||
$option['value'],
|
||||
$option['name'],
|
||||
$option['description']);
|
||||
}
|
||||
}
|
||||
|
||||
$form->appendChild($radio);
|
||||
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Install Dashboard'))
|
||||
->setErrors($errors)
|
||||
->setWidth(AphrontDialogView::WIDTH_FORM)
|
||||
->appendChild($form->buildLayoutView())
|
||||
->addCancelButton($cancel_uri)
|
||||
->addSubmitButton(pht('Install Dashboard'));
|
||||
}
|
||||
|
||||
}
|
|
@ -28,9 +28,6 @@ final class PhabricatorDashboardListController
|
|||
->setViewer($user)
|
||||
->addNavigationItems($nav->getMenu());
|
||||
|
||||
$nav->addLabel(pht('Panels'));
|
||||
$nav->addFilter('panel/', pht('Manage Panels'));
|
||||
|
||||
$nav->selectFilter(null);
|
||||
|
||||
return $nav;
|
||||
|
@ -39,11 +36,9 @@ final class PhabricatorDashboardListController
|
|||
protected function buildApplicationCrumbs() {
|
||||
$crumbs = parent::buildApplicationCrumbs();
|
||||
|
||||
$crumbs->addAction(
|
||||
id(new PHUIListItemView())
|
||||
->setIcon('fa-plus-square')
|
||||
->setName(pht('Create Dashboard'))
|
||||
->setHref($this->getApplicationURI().'create/'));
|
||||
id(new PhabricatorDashboardEditEngine())
|
||||
->setViewer($this->getViewer())
|
||||
->addActionToCrumbs($crumbs);
|
||||
|
||||
return $crumbs;
|
||||
}
|
||||
|
|
|
@ -1,139 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardManageController
|
||||
extends PhabricatorDashboardProfileController {
|
||||
|
||||
public function shouldAllowPublic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
// TODO: This UI should drop a lot of capabilities if the user can't
|
||||
// edit the dashboard, but we should still let them in for "Install" and
|
||||
// "View History".
|
||||
|
||||
$dashboard = id(new PhabricatorDashboardQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->needPanels(true)
|
||||
->executeOne();
|
||||
if (!$dashboard) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
$this->setDashboard($dashboard);
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$dashboard,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$title = $dashboard->getName();
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb(pht('Manage'));
|
||||
|
||||
$header = $this->buildHeaderView();
|
||||
$curtain = $this->buildCurtainView($dashboard);
|
||||
$properties = $this->buildPropertyView($dashboard);
|
||||
|
||||
$timeline = $this->buildTransactionTimeline(
|
||||
$dashboard,
|
||||
new PhabricatorDashboardTransactionQuery());
|
||||
$timeline->setShouldTerminate(true);
|
||||
|
||||
$info_view = null;
|
||||
if (!$can_edit) {
|
||||
$no_edit = pht(
|
||||
'You do not have permission to edit this dashboard.');
|
||||
|
||||
$info_view = id(new PHUIInfoView())
|
||||
->setSeverity(PHUIInfoView::SEVERITY_NOTICE)
|
||||
->setErrors(array($no_edit));
|
||||
}
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setCurtain($curtain)
|
||||
->setMainColumn(array(
|
||||
$info_view,
|
||||
$properties,
|
||||
$timeline,
|
||||
));
|
||||
|
||||
$navigation = $this->buildSideNavView('manage');
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->setNavigation($navigation)
|
||||
->appendChild($view);
|
||||
|
||||
}
|
||||
|
||||
private function buildCurtainView(PhabricatorDashboard $dashboard) {
|
||||
$viewer = $this->getViewer();
|
||||
$id = $dashboard->getID();
|
||||
|
||||
$curtain = $this->newCurtainView($dashboard);
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$dashboard,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Edit Dashboard'))
|
||||
->setIcon('fa-pencil')
|
||||
->setHref($this->getApplicationURI("edit/{$id}/"))
|
||||
->setDisabled(!$can_edit));
|
||||
|
||||
if ($dashboard->isArchived()) {
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Activate Dashboard'))
|
||||
->setIcon('fa-check')
|
||||
->setHref($this->getApplicationURI("archive/{$id}/"))
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow($can_edit));
|
||||
} else {
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Archive Dashboard'))
|
||||
->setIcon('fa-ban')
|
||||
->setHref($this->getApplicationURI("archive/{$id}/"))
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow($can_edit));
|
||||
}
|
||||
|
||||
return $curtain;
|
||||
}
|
||||
|
||||
private function buildPropertyView(PhabricatorDashboard $dashboard) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$properties = id(new PHUIPropertyListView())
|
||||
->setUser($viewer);
|
||||
|
||||
$descriptions = PhabricatorPolicyQuery::renderPolicyDescriptions(
|
||||
$viewer,
|
||||
$dashboard);
|
||||
|
||||
$properties->addProperty(
|
||||
pht('Editable By'),
|
||||
$descriptions[PhabricatorPolicyCapability::CAN_EDIT]);
|
||||
|
||||
$properties->addProperty(
|
||||
pht('Panels'),
|
||||
$viewer->renderHandleList($dashboard->getPanelPHIDs()));
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Details'))
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->addPropertyList($properties);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardMovePanelController
|
||||
extends PhabricatorDashboardController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
$column_id = $request->getStr('columnID');
|
||||
$panel_phid = $request->getStr('objectPHID');
|
||||
$after_phid = $request->getStr('afterPHID');
|
||||
$before_phid = $request->getStr('beforePHID');
|
||||
|
||||
$dashboard = id(new PhabricatorDashboardQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->needPanels(true)
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->executeOne();
|
||||
if (!$dashboard) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
$panels = mpull($dashboard->getPanels(), null, 'getPHID');
|
||||
$panel = idx($panels, $panel_phid);
|
||||
if (!$panel) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$layout_config = $dashboard->getLayoutConfigObject();
|
||||
$layout_config->removePanel($panel_phid);
|
||||
$panel_location_grid = $layout_config->getPanelLocations();
|
||||
|
||||
$column_phids = idx($panel_location_grid, $column_id, array());
|
||||
$column_phids = array_values($column_phids);
|
||||
if ($column_phids) {
|
||||
$insert_at = 0;
|
||||
foreach ($column_phids as $index => $phid) {
|
||||
if ($phid === $before_phid) {
|
||||
$insert_at = $index;
|
||||
break;
|
||||
}
|
||||
if ($phid === $after_phid) {
|
||||
$insert_at = $index + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$new_column_phids = $column_phids;
|
||||
array_splice(
|
||||
$new_column_phids,
|
||||
$insert_at,
|
||||
0,
|
||||
array($panel_phid));
|
||||
} else {
|
||||
$new_column_phids = array(0 => $panel_phid);
|
||||
}
|
||||
|
||||
$panel_location_grid[$column_id] = $new_column_phids;
|
||||
$layout_config->setPanelLocations($panel_location_grid);
|
||||
$dashboard->setLayoutConfigFromObject($layout_config);
|
||||
$dashboard->save();
|
||||
|
||||
return id(new AphrontAjaxResponse())->setContent('');
|
||||
}
|
||||
|
||||
}
|
|
@ -1,354 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardPanelEditController
|
||||
extends PhabricatorDashboardController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
// If the user is trying to create a panel directly on a dashboard, make
|
||||
// sure they have permission to see and edit the dashboard.
|
||||
|
||||
$dashboard_id = $request->getInt('dashboardID');
|
||||
$dashboard = null;
|
||||
if ($dashboard_id) {
|
||||
$dashboard = id(new PhabricatorDashboardQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($dashboard_id))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->executeOne();
|
||||
if (!$dashboard) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$manage_uri = $this->getApplicationURI('arrange/'.$dashboard_id.'/');
|
||||
}
|
||||
|
||||
if ($id) {
|
||||
$is_create = false;
|
||||
|
||||
if ($dashboard) {
|
||||
$capabilities = array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
);
|
||||
} else {
|
||||
$capabilities = array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
);
|
||||
}
|
||||
|
||||
$panel = id(new PhabricatorDashboardPanelQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->requireCapabilities($capabilities)
|
||||
->executeOne();
|
||||
if (!$panel) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
} else {
|
||||
$is_create = true;
|
||||
|
||||
$panel = PhabricatorDashboardPanel::initializeNewPanel($viewer);
|
||||
$types = PhabricatorDashboardPanelType::getAllPanelTypes();
|
||||
$type = $request->getStr('type');
|
||||
if (empty($types[$type])) {
|
||||
return $this->processPanelTypeRequest($request);
|
||||
}
|
||||
|
||||
$panel->setPanelType($type);
|
||||
}
|
||||
|
||||
if ($is_create) {
|
||||
$title = pht('Create New Panel');
|
||||
$button = pht('Create Panel');
|
||||
$header_icon = 'fa-plus-square';
|
||||
if ($dashboard) {
|
||||
$cancel_uri = $manage_uri;
|
||||
} else {
|
||||
$cancel_uri = $this->getApplicationURI('panel/');
|
||||
}
|
||||
} else {
|
||||
$title = pht('Edit Panel: %s', $panel->getName());
|
||||
$button = pht('Save Panel');
|
||||
$header_icon = 'fa-pencil';
|
||||
if ($dashboard) {
|
||||
$cancel_uri = $manage_uri;
|
||||
} else {
|
||||
$cancel_uri = '/'.$panel->getMonogram();
|
||||
}
|
||||
}
|
||||
|
||||
$v_name = $panel->getName();
|
||||
$e_name = true;
|
||||
|
||||
$field_list = PhabricatorCustomField::getObjectFields(
|
||||
$panel,
|
||||
PhabricatorCustomField::ROLE_EDIT);
|
||||
$field_list
|
||||
->setViewer($viewer)
|
||||
->readFieldsFromStorage($panel);
|
||||
|
||||
if ($is_create && !$request->isFormPost()) {
|
||||
$panel->requireImplementation()->initializeFieldsFromRequest(
|
||||
$panel,
|
||||
$field_list,
|
||||
$request);
|
||||
}
|
||||
|
||||
$validation_exception = null;
|
||||
|
||||
// NOTE: We require 'edit' to distinguish between the "Choose a Type"
|
||||
// and "Create a Panel" dialogs.
|
||||
|
||||
if ($request->isFormPost() && $request->getBool('edit')) {
|
||||
$v_name = $request->getStr('name');
|
||||
$v_view_policy = $request->getStr('viewPolicy');
|
||||
$v_edit_policy = $request->getStr('editPolicy');
|
||||
|
||||
$type_name = PhabricatorDashboardPanelTransaction::TYPE_NAME;
|
||||
$type_view_policy = PhabricatorTransactions::TYPE_VIEW_POLICY;
|
||||
$type_edit_policy = PhabricatorTransactions::TYPE_EDIT_POLICY;
|
||||
|
||||
$xactions = array();
|
||||
|
||||
$xactions[] = id(new PhabricatorDashboardPanelTransaction())
|
||||
->setTransactionType($type_name)
|
||||
->setNewValue($v_name);
|
||||
|
||||
$xactions[] = id(new PhabricatorDashboardPanelTransaction())
|
||||
->setTransactionType($type_view_policy)
|
||||
->setNewValue($v_view_policy);
|
||||
|
||||
$xactions[] = id(new PhabricatorDashboardPanelTransaction())
|
||||
->setTransactionType($type_edit_policy)
|
||||
->setNewValue($v_edit_policy);
|
||||
|
||||
$field_xactions = $field_list->buildFieldTransactionsFromRequest(
|
||||
new PhabricatorDashboardPanelTransaction(),
|
||||
$request);
|
||||
$xactions = array_merge($xactions, $field_xactions);
|
||||
|
||||
try {
|
||||
$editor = id(new PhabricatorDashboardPanelTransactionEditor())
|
||||
->setActor($viewer)
|
||||
->setContinueOnNoEffect(true)
|
||||
->setContentSourceFromRequest($request)
|
||||
->applyTransactions($panel, $xactions);
|
||||
|
||||
// If we're creating a panel directly on a dashboard, add it now.
|
||||
if ($dashboard && $is_create) {
|
||||
PhabricatorDashboardTransactionEditor::addPanelToDashboard(
|
||||
$viewer,
|
||||
PhabricatorContentSource::newFromRequest($request),
|
||||
$panel,
|
||||
$dashboard,
|
||||
$request->getInt('column', 0));
|
||||
}
|
||||
|
||||
if ($dashboard) {
|
||||
$done_uri = $manage_uri;
|
||||
} else {
|
||||
$done_uri = '/'.$panel->getMonogram();
|
||||
}
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI($done_uri);
|
||||
} catch (PhabricatorApplicationTransactionValidationException $ex) {
|
||||
$validation_exception = $ex;
|
||||
|
||||
$e_name = $validation_exception->getShortMessage($type_name);
|
||||
|
||||
$panel->setViewPolicy($v_view_policy);
|
||||
$panel->setEditPolicy($v_edit_policy);
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: We're setting the submit URI explicitly because we need to edit
|
||||
// a different panel if we just cloned the original panel.
|
||||
if ($is_create) {
|
||||
$submit_uri = $this->getApplicationURI('panel/edit/');
|
||||
} else {
|
||||
$submit_uri = $this->getApplicationURI('panel/edit/'.$panel->getID().'/');
|
||||
}
|
||||
|
||||
$policies = id(new PhabricatorPolicyQuery())
|
||||
->setViewer($viewer)
|
||||
->setObject($panel)
|
||||
->execute();
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($viewer)
|
||||
->setAction($submit_uri)
|
||||
->addHiddenInput('edit', true)
|
||||
->addHiddenInput('dashboardID', $request->getInt('dashboardID'))
|
||||
->addHiddenInput('column', $request->getInt('column'))
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setLabel(pht('Name'))
|
||||
->setName('name')
|
||||
->setValue($v_name)
|
||||
->setError($e_name));
|
||||
|
||||
if (!$request->isAjax() || !$is_create) {
|
||||
$form
|
||||
->appendChild(
|
||||
id(new AphrontFormPolicyControl())
|
||||
->setName('viewPolicy')
|
||||
->setPolicyObject($panel)
|
||||
->setCapability(PhabricatorPolicyCapability::CAN_VIEW)
|
||||
->setPolicies($policies))
|
||||
->appendChild(
|
||||
id(new AphrontFormPolicyControl())
|
||||
->setName('editPolicy')
|
||||
->setPolicyObject($panel)
|
||||
->setCapability(PhabricatorPolicyCapability::CAN_EDIT)
|
||||
->setPolicies($policies));
|
||||
}
|
||||
|
||||
$field_list->appendFieldsToForm($form);
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb(
|
||||
pht('Panels'),
|
||||
$this->getApplicationURI('panel/'));
|
||||
if ($is_create) {
|
||||
$crumbs->addTextCrumb(pht('New Panel'));
|
||||
$form->addHiddenInput('type', $panel->getPanelType());
|
||||
} else {
|
||||
$crumbs->addTextCrumb(
|
||||
$panel->getMonogram(),
|
||||
'/'.$panel->getMonogram());
|
||||
$crumbs->addTextCrumb(pht('Edit'));
|
||||
}
|
||||
$crumbs->setBorder(true);
|
||||
|
||||
if ($request->isAjax()) {
|
||||
return $this->newDialog()
|
||||
->setTitle($title)
|
||||
->setSubmitURI($submit_uri)
|
||||
->setWidth(AphrontDialogView::WIDTH_FORM)
|
||||
->setValidationException($validation_exception)
|
||||
->appendChild($form->buildLayoutView())
|
||||
->addCancelButton($cancel_uri)
|
||||
->addSubmitButton($button);
|
||||
} else {
|
||||
$form
|
||||
->appendChild(
|
||||
id(new AphrontFormSubmitControl())
|
||||
->setValue($button)
|
||||
->addCancelButton($cancel_uri));
|
||||
}
|
||||
|
||||
$box = id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Panel'))
|
||||
->setValidationException($validation_exception)
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setForm($form);
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader($title)
|
||||
->setHeaderIcon($header_icon);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setFooter($box);
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->appendChild($view);
|
||||
}
|
||||
|
||||
private function processPanelTypeRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getUser();
|
||||
|
||||
$types = PhabricatorDashboardPanelType::getAllPanelTypes();
|
||||
|
||||
$v_type = null;
|
||||
$errors = array();
|
||||
if ($request->isFormPost()) {
|
||||
$v_type = $request->getStr('type');
|
||||
if (!isset($types[$v_type])) {
|
||||
$errors[] = pht('You must select a type of panel to create.');
|
||||
}
|
||||
}
|
||||
|
||||
$cancel_uri = $this->getApplicationURI('panel/');
|
||||
|
||||
if (!$v_type) {
|
||||
$v_type = key($types);
|
||||
}
|
||||
|
||||
$panel_types = id(new AphrontFormRadioButtonControl())
|
||||
->setName('type')
|
||||
->setValue($v_type);
|
||||
|
||||
foreach ($types as $key => $type) {
|
||||
$panel_types->addButton(
|
||||
$key,
|
||||
$type->getPanelTypeName(),
|
||||
$type->getPanelTypeDescription());
|
||||
}
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($viewer)
|
||||
->addHiddenInput('dashboardID', $request->getInt('dashboardID'))
|
||||
->addHiddenInput('column', $request->getInt('column'))
|
||||
->appendRemarkupInstructions(
|
||||
pht(
|
||||
'Choose the type of dashboard panel to create:'))
|
||||
->appendChild($panel_types);
|
||||
|
||||
if ($request->isAjax()) {
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Add New Panel'))
|
||||
->setWidth(AphrontDialogView::WIDTH_FORM)
|
||||
->setErrors($errors)
|
||||
->appendChild($form->buildLayoutView())
|
||||
->addCancelbutton($cancel_uri)
|
||||
->addSubmitButton(pht('Continue'));
|
||||
} else {
|
||||
$form->appendChild(
|
||||
id(new AphrontFormSubmitControl())
|
||||
->setValue(pht('Continue'))
|
||||
->addCancelButton($cancel_uri));
|
||||
}
|
||||
|
||||
$title = pht('Create Dashboard Panel');
|
||||
$header_icon = 'fa-plus-square';
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb(
|
||||
pht('Panels'),
|
||||
$this->getApplicationURI('panel/'));
|
||||
$crumbs->addTextCrumb(pht('New Panel'));
|
||||
$crumbs->setBorder(true);
|
||||
|
||||
$box = id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Panel'))
|
||||
->setFormErrors($errors)
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setForm($form);
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader($title)
|
||||
->setHeaderIcon($header_icon);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setFooter($box);
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->appendChild($view);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,105 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardPanelEditproController
|
||||
extends PhabricatorDashboardController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$engine = id(new PhabricatorDashboardPanelEditEngine())
|
||||
->setController($this);
|
||||
|
||||
$id = $request->getURIData('id');
|
||||
if (!$id) {
|
||||
$list_uri = $this->getApplicationURI('panel/');
|
||||
|
||||
$panel_type = $request->getStr('panelType');
|
||||
$panel_types = PhabricatorDashboardPanelType::getAllPanelTypes();
|
||||
if (empty($panel_types[$panel_type])) {
|
||||
return $this->buildPanelTypeResponse($list_uri);
|
||||
}
|
||||
|
||||
$engine
|
||||
->addContextParameter('panelType', $panel_type)
|
||||
->setPanelType($panel_type);
|
||||
}
|
||||
|
||||
return $engine->buildResponse();
|
||||
}
|
||||
|
||||
private function buildPanelTypeResponse($cancel_uri) {
|
||||
$panel_types = PhabricatorDashboardPanelType::getAllPanelTypes();
|
||||
|
||||
$viewer = $this->getViewer();
|
||||
$request = $this->getRequest();
|
||||
|
||||
$e_type = null;
|
||||
$errors = array();
|
||||
if ($request->isFormPost()) {
|
||||
$e_type = pht('Required');
|
||||
$errors[] = pht(
|
||||
'To create a new dashboard panel, you must select a panel type.');
|
||||
}
|
||||
|
||||
$type_control = id(new AphrontFormRadioButtonControl())
|
||||
->setLabel(pht('Panel Type'))
|
||||
->setName('panelType')
|
||||
->setError($e_type);
|
||||
|
||||
foreach ($panel_types as $key => $type) {
|
||||
$type_control->addButton(
|
||||
$key,
|
||||
$type->getPanelTypeName(),
|
||||
$type->getPanelTypeDescription());
|
||||
}
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($viewer)
|
||||
->appendRemarkupInstructions(
|
||||
pht('Choose the type of dashboard panel to create:'))
|
||||
->appendChild($type_control);
|
||||
|
||||
if ($request->isAjax()) {
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Add New Panel'))
|
||||
->setWidth(AphrontDialogView::WIDTH_FORM)
|
||||
->setErrors($errors)
|
||||
->appendForm($form)
|
||||
->addCancelButton($cancel_uri)
|
||||
->addSubmitButton(pht('Continue'));
|
||||
}
|
||||
|
||||
$form->appendChild(
|
||||
id(new AphrontFormSubmitControl())
|
||||
->setValue(pht('Continue'))
|
||||
->addCancelButton($cancel_uri));
|
||||
|
||||
$title = pht('Create Dashboard Panel');
|
||||
$header_icon = 'fa-plus-square';
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb(
|
||||
pht('Panels'),
|
||||
$this->getApplicationURI('panel/'));
|
||||
$crumbs->addTextCrumb(pht('New Panel'));
|
||||
$crumbs->setBorder(true);
|
||||
|
||||
$box = id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Panel'))
|
||||
->setFormErrors($errors)
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setForm($form);
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader($title)
|
||||
->setHeaderIcon($header_icon);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setFooter($box);
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->appendChild($view);
|
||||
}
|
||||
|
||||
}
|
|
@ -14,10 +14,6 @@ abstract class PhabricatorDashboardProfileController
|
|||
return $this->dashboard;
|
||||
}
|
||||
|
||||
public function buildApplicationMenu() {
|
||||
return $this->buildSideNavView()->getMenu();
|
||||
}
|
||||
|
||||
protected function buildHeaderView() {
|
||||
$viewer = $this->getViewer();
|
||||
$dashboard = $this->getDashboard();
|
||||
|
@ -49,50 +45,10 @@ abstract class PhabricatorDashboardProfileController
|
|||
|
||||
$dashboard = $this->getDashboard();
|
||||
if ($dashboard) {
|
||||
$id = $dashboard->getID();
|
||||
$dashboard_uri = $this->getApplicationURI("/view/{$id}/");
|
||||
$crumbs->addTextCrumb($dashboard->getName(), $dashboard_uri);
|
||||
$crumbs->addTextCrumb($dashboard->getName(), $dashboard->getURI());
|
||||
}
|
||||
|
||||
return $crumbs;
|
||||
}
|
||||
|
||||
protected function buildSideNavView($filter = null) {
|
||||
$viewer = $this->getViewer();
|
||||
$dashboard = $this->getDashboard();
|
||||
$id = $dashboard->getID();
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$dashboard,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$nav = id(new AphrontSideNavFilterView())
|
||||
->setBaseURI(new PhutilURI($this->getApplicationURI()));
|
||||
|
||||
$nav->addLabel(pht('Dashboard'));
|
||||
|
||||
$nav->addFilter(
|
||||
'view',
|
||||
pht('View Dashboard'),
|
||||
$this->getApplicationURI("/view/{$id}/"),
|
||||
'fa-dashboard');
|
||||
|
||||
$nav->addFilter(
|
||||
'arrange',
|
||||
pht('Arrange Panels'),
|
||||
$this->getApplicationURI("/arrange/{$id}/"),
|
||||
'fa-columns');
|
||||
|
||||
$nav->addFilter(
|
||||
'manage',
|
||||
pht('Manage Dashboard'),
|
||||
$this->getApplicationURI("/manage/{$id}/"),
|
||||
'fa-gears');
|
||||
|
||||
$nav->selectFilter($filter);
|
||||
|
||||
return $nav;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,185 +7,160 @@ final class PhabricatorDashboardQueryPanelInstallController
|
|||
$viewer = $request->getViewer();
|
||||
|
||||
$v_dashboard = null;
|
||||
$v_name = null;
|
||||
$v_column = 0;
|
||||
$v_engine = $request->getURIData('engineKey');
|
||||
$v_query = $request->getURIData('queryKey');
|
||||
$e_dashboard = null;
|
||||
|
||||
$v_name = null;
|
||||
$e_name = true;
|
||||
|
||||
// Validate Engines
|
||||
$engines = PhabricatorApplicationSearchEngine::getAllEngines();
|
||||
foreach ($engines as $name => $engine) {
|
||||
if (!$engine->canUseInPanelContext()) {
|
||||
unset($engines[$name]);
|
||||
}
|
||||
}
|
||||
if (!in_array($v_engine, array_keys($engines))) {
|
||||
return new Aphront404Response();
|
||||
$v_engine = $request->getStr('engine');
|
||||
if (!strlen($v_engine)) {
|
||||
$v_engine = $request->getURIData('engineKey');
|
||||
}
|
||||
|
||||
// Validate Queries
|
||||
$engine = $engines[$v_engine];
|
||||
$engine->setViewer($viewer);
|
||||
$good_query = false;
|
||||
if ($engine->isBuiltinQuery($v_query)) {
|
||||
$good_query = true;
|
||||
} else {
|
||||
$saved_query = id(new PhabricatorSavedQueryQuery())
|
||||
->setViewer($viewer)
|
||||
->withEngineClassNames(array($v_engine))
|
||||
->withQueryKeys(array($v_query))
|
||||
->executeOne();
|
||||
if ($saved_query) {
|
||||
$good_query = true;
|
||||
}
|
||||
}
|
||||
if (!$good_query) {
|
||||
return new Aphront404Response();
|
||||
$v_query = $request->getStr('query');
|
||||
if (!strlen($v_query)) {
|
||||
$v_query = $request->getURIData('queryKey');
|
||||
}
|
||||
|
||||
$engines = PhabricatorApplicationSearchEngine::getAllEngines();
|
||||
$engine = idx($engines, $v_engine);
|
||||
if ($engine) {
|
||||
$engine = id(clone $engine)
|
||||
->setViewer($viewer);
|
||||
|
||||
$redirect_uri = $engine->getQueryResultsPageURI($v_query);
|
||||
|
||||
$named_query = idx($engine->loadEnabledNamedQueries(), $v_query);
|
||||
if ($named_query) {
|
||||
$v_name = $named_query->getQueryName();
|
||||
}
|
||||
} else {
|
||||
$redirect_uri = '/';
|
||||
}
|
||||
|
||||
$errors = array();
|
||||
|
||||
$xaction_name = PhabricatorDashboardPanelNameTransaction::TRANSACTIONTYPE;
|
||||
$xaction_engine =
|
||||
PhabricatorDashboardQueryPanelApplicationTransaction::TRANSACTIONTYPE;
|
||||
$xaction_query =
|
||||
PhabricatorDashboardQueryPanelQueryTransaction::TRANSACTIONTYPE;
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
$v_dashboard = $request->getInt('dashboardID');
|
||||
$v_name = $request->getStr('name');
|
||||
if (!$v_name) {
|
||||
$errors[] = pht('You must provide a name for this panel.');
|
||||
$e_name = pht('Required');
|
||||
}
|
||||
|
||||
$v_dashboard = head($request->getArr('dashboardPHIDs'));
|
||||
if (!$v_dashboard) {
|
||||
$errors[] = pht('You must select a dashboard.');
|
||||
$e_dashboard = pht('Required');
|
||||
} else {
|
||||
$dashboard = id(new PhabricatorDashboardQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($v_dashboard))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->withPHIDs(array($v_dashboard))
|
||||
->executeOne();
|
||||
|
||||
if (!$dashboard) {
|
||||
$errors[] = pht('Please select a valid dashboard.');
|
||||
$errors[] = pht('You must select a valid dashboard.');
|
||||
$e_dashboard = pht('Invalid');
|
||||
}
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$dashboard,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
if (!$can_edit) {
|
||||
$errors[] = pht(
|
||||
'You must select a dashboard you have permission to edit.');
|
||||
}
|
||||
}
|
||||
|
||||
if (!$errors) {
|
||||
$redirect_uri = "/dashboard/arrange/{$v_dashboard}/";
|
||||
$done_uri = $dashboard->getURI();
|
||||
|
||||
// First, create a new panel.
|
||||
|
||||
$panel_type = id(new PhabricatorDashboardQueryPanelType())
|
||||
->getPanelTypeKey();
|
||||
$panel = PhabricatorDashboardPanel::initializeNewPanel($viewer);
|
||||
$panel->setPanelType($panel_type);
|
||||
|
||||
$field_list = PhabricatorCustomField::getObjectFields(
|
||||
$panel,
|
||||
PhabricatorCustomField::ROLE_EDIT);
|
||||
|
||||
$field_list
|
||||
->setViewer($viewer)
|
||||
->readFieldsFromStorage($panel);
|
||||
|
||||
$panel->requireImplementation()->initializeFieldsFromRequest(
|
||||
$panel,
|
||||
$field_list,
|
||||
$request);
|
||||
$panel = PhabricatorDashboardPanel::initializeNewPanel($viewer)
|
||||
->setPanelType($panel_type);
|
||||
|
||||
$xactions = array();
|
||||
|
||||
$xactions[] = id(new PhabricatorDashboardPanelTransaction())
|
||||
->setTransactionType(PhabricatorDashboardPanelTransaction::TYPE_NAME)
|
||||
->setNewValue($v_name);
|
||||
|
||||
$xactions[] = id(new PhabricatorDashboardPanelTransaction())
|
||||
->setTransactionType(PhabricatorTransactions::TYPE_CUSTOMFIELD)
|
||||
->setMetadataValue('customfield:key', 'std:dashboard:core:class')
|
||||
->setOldValue(null)
|
||||
$xactions[] = $panel->getApplicationTransactionTemplate()
|
||||
->setTransactionType($xaction_engine)
|
||||
->setNewValue($v_engine);
|
||||
|
||||
$xactions[] = id(new PhabricatorDashboardPanelTransaction())
|
||||
->setTransactionType(PhabricatorTransactions::TYPE_CUSTOMFIELD)
|
||||
->setMetadataValue('customfield:key', 'std:dashboard:core:key')
|
||||
->setOldValue(null)
|
||||
$xactions[] = $panel->getApplicationTransactionTemplate()
|
||||
->setTransactionType($xaction_query)
|
||||
->setNewValue($v_query);
|
||||
|
||||
$editor = id(new PhabricatorDashboardPanelTransactionEditor())
|
||||
$xactions[] = $panel->getApplicationTransactionTemplate()
|
||||
->setTransactionType($xaction_name)
|
||||
->setNewValue($v_name);
|
||||
|
||||
$editor = $panel->getApplicationTransactionEditor()
|
||||
->setActor($viewer)
|
||||
->setContinueOnNoEffect(true)
|
||||
->setContentSourceFromRequest($request)
|
||||
->applyTransactions($panel, $xactions);
|
||||
|
||||
PhabricatorDashboardTransactionEditor::addPanelToDashboard(
|
||||
$viewer,
|
||||
PhabricatorContentSource::newFromRequest($request),
|
||||
$panel,
|
||||
$dashboard,
|
||||
$request->getInt('column', 0));
|
||||
// Now that we've created a panel, add it to the dashboard.
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI($redirect_uri);
|
||||
$xactions = array();
|
||||
|
||||
$ref_list = clone $dashboard->getPanelRefList();
|
||||
$ref_list->newPanelRef($panel);
|
||||
$new_panels = $ref_list->toDictionary();
|
||||
|
||||
$xactions[] = $dashboard->getApplicationTransactionTemplate()
|
||||
->setTransactionType(
|
||||
PhabricatorDashboardPanelsTransaction::TRANSACTIONTYPE)
|
||||
->setNewValue($new_panels);
|
||||
|
||||
$editor = $dashboard->getApplicationTransactionEditor()
|
||||
->setActor($viewer)
|
||||
->setContentSourceFromRequest($request)
|
||||
->setContinueOnNoEffect(true)
|
||||
->setContinueOnMissingFields(true)
|
||||
->applyTransactions($dashboard, $xactions);
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI($done_uri);
|
||||
}
|
||||
}
|
||||
|
||||
// Make this a select for now, as we don't expect someone to have
|
||||
// edit access to a vast number of dashboards.
|
||||
// Can add optiongroup if needed down the road.
|
||||
$dashboards = id(new PhabricatorDashboardQuery())
|
||||
->setViewer($viewer)
|
||||
->withStatuses(array(
|
||||
PhabricatorDashboard::STATUS_ACTIVE,
|
||||
))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->execute();
|
||||
$options = mpull($dashboards, 'getName', 'getID');
|
||||
asort($options);
|
||||
|
||||
$redirect_uri = $engine->getQueryResultsPageURI($v_query);
|
||||
|
||||
if (!$options) {
|
||||
$notice = id(new PHUIInfoView())
|
||||
->setSeverity(PHUIInfoView::SEVERITY_NOTICE)
|
||||
->appendChild(pht('You do not have access to any dashboards. To '.
|
||||
'continue, please create a dashboard first.'));
|
||||
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('No Dashboards'))
|
||||
->setWidth(AphrontDialogView::WIDTH_FORM)
|
||||
->appendChild($notice)
|
||||
->addCancelButton($redirect_uri);
|
||||
if ($v_dashboard) {
|
||||
$dashboard_phids = array($v_dashboard);
|
||||
} else {
|
||||
$dashboard_phids = array();
|
||||
}
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($viewer)
|
||||
->addHiddenInput('engine', $v_engine)
|
||||
->addHiddenInput('query', $v_query)
|
||||
->addHiddenInput('column', $v_column)
|
||||
->appendChild(
|
||||
->setViewer($viewer)
|
||||
->appendControl(
|
||||
id(new AphrontFormTextControl())
|
||||
->setLabel(pht('Name'))
|
||||
->setName('name')
|
||||
->setValue($v_name)
|
||||
->setError($e_name))
|
||||
->appendChild(
|
||||
id(new AphrontFormSelectControl())
|
||||
->setUser($this->getViewer())
|
||||
->setValue($v_dashboard)
|
||||
->setName('dashboardID')
|
||||
->setOptions($options)
|
||||
->appendControl(
|
||||
id(new AphrontFormTokenizerControl())
|
||||
->setValue($dashboard_phids)
|
||||
->setError($e_dashboard)
|
||||
->setName('dashboardPHIDs')
|
||||
->setLimit(1)
|
||||
->setDatasource(new PhabricatorDashboardDatasource())
|
||||
->setLabel(pht('Dashboard')));
|
||||
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Add Panel to Dashboard'))
|
||||
->setErrors($errors)
|
||||
->setWidth(AphrontDialogView::WIDTH_FORM)
|
||||
->appendChild($form->buildLayoutView())
|
||||
->addHiddenInput('engine', $v_engine)
|
||||
->addHiddenInput('query', $v_query)
|
||||
->appendForm($form)
|
||||
->addCancelButton($redirect_uri)
|
||||
->addSubmitButton(pht('Add Panel'));
|
||||
|
||||
|
|
|
@ -1,89 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardRemovePanelController
|
||||
extends PhabricatorDashboardController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
$dashboard = id(new PhabricatorDashboardQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->executeOne();
|
||||
if (!$dashboard) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
// NOTE: If you can edit a dashboard, you can remove panels from it even
|
||||
// if you don't have permission to see them or they aren't valid. We only
|
||||
// require that the panel be present on the dashboard.
|
||||
|
||||
$v_panel = $request->getStr('panelPHID');
|
||||
|
||||
$panel_on_dashboard = false;
|
||||
$layout = $dashboard->getLayoutConfigObject();
|
||||
$columns = $layout->getPanelLocations();
|
||||
foreach ($columns as $column) {
|
||||
foreach ($column as $column_panel_phid) {
|
||||
if ($column_panel_phid == $v_panel) {
|
||||
$panel_on_dashboard = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$panel_on_dashboard) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$redirect_uri = $this->getApplicationURI(
|
||||
'arrange/'.$dashboard->getID().'/');
|
||||
$layout_config = $dashboard->getLayoutConfigObject();
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
$xactions = array();
|
||||
$xactions[] = id(new PhabricatorDashboardTransaction())
|
||||
->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
|
||||
->setMetadataValue(
|
||||
'edge:type',
|
||||
PhabricatorDashboardDashboardHasPanelEdgeType::EDGECONST)
|
||||
->setNewValue(
|
||||
array(
|
||||
'-' => array(
|
||||
$v_panel => $v_panel,
|
||||
),
|
||||
));
|
||||
|
||||
$layout_config->removePanel($v_panel);
|
||||
$dashboard->setLayoutConfigFromObject($layout_config);
|
||||
|
||||
$editor = id(new PhabricatorDashboardTransactionEditor())
|
||||
->setActor($viewer)
|
||||
->setContentSourceFromRequest($request)
|
||||
->setContinueOnMissingFields(true)
|
||||
->setContinueOnNoEffect(true)
|
||||
->applyTransactions($dashboard, $xactions);
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI($redirect_uri);
|
||||
}
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($viewer)
|
||||
->addHiddenInput('confirm', true)
|
||||
->addHiddenInput('panelPHID', $v_panel)
|
||||
->appendChild(pht('Are you sure you want to remove this panel?'));
|
||||
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Remove Panel'))
|
||||
->appendChild($form->buildLayoutView())
|
||||
->addCancelButton($redirect_uri)
|
||||
->addSubmitButton(pht('Remove Panel'));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardViewController
|
||||
extends PhabricatorDashboardProfileController {
|
||||
|
||||
public function shouldAllowPublic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
$dashboard = id(new PhabricatorDashboardQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->needPanels(true)
|
||||
->executeOne();
|
||||
if (!$dashboard) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
$this->setDashboard($dashboard);
|
||||
|
||||
$dashboard_uri = $this->getApplicationURI("view/{$id}/");
|
||||
$title = $dashboard->getName();
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb(pht('View'));
|
||||
|
||||
if ($dashboard->getPanelPHIDs()) {
|
||||
$rendered_dashboard = id(new PhabricatorDashboardRenderingEngine())
|
||||
->setViewer($viewer)
|
||||
->setDashboard($dashboard)
|
||||
->renderDashboard();
|
||||
$content = id(new PHUIBoxView())
|
||||
->addClass('dashboard-preview-box')
|
||||
->appendChild($rendered_dashboard);
|
||||
} else {
|
||||
$content = id(new PHUIInfoView())
|
||||
->setSeverity(PHUIInfoView::SEVERITY_NOTICE)
|
||||
->appendChild(pht('This dashboard has no panels yet.'));
|
||||
}
|
||||
|
||||
$navigation = $this->buildSideNavView('view');
|
||||
$header = $this->buildHeaderView();
|
||||
|
||||
$install_button = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setText('Install Dashboard')
|
||||
->setIcon('fa-plus')
|
||||
->setColor(PHUIButtonView::GREEN)
|
||||
->setWorkflow(true)
|
||||
->setHref($this->getApplicationURI("/install/{$id}/"));
|
||||
$header->addActionLink($install_button);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setFooter(array(
|
||||
$content,
|
||||
));
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->setNavigation($navigation)
|
||||
->appendChild($view);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,243 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardAdjustController
|
||||
extends PhabricatorDashboardController {
|
||||
|
||||
private $contextPHID;
|
||||
private $panelKey;
|
||||
private $columnKey;
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$context_phid = $request->getStr('contextPHID');
|
||||
|
||||
$dashboard = id(new PhabricatorDashboardQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($context_phid))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->executeOne();
|
||||
if (!$dashboard) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$this->contextPHID = $context_phid;
|
||||
|
||||
$done_uri = $dashboard->getURI();
|
||||
$ref_list = $dashboard->getPanelRefList();
|
||||
|
||||
$panel_ref = null;
|
||||
$panel_key = $request->getStr('panelKey');
|
||||
if (strlen($panel_key)) {
|
||||
$panel_ref = $ref_list->getPanelRef($panel_key);
|
||||
if (!$panel_ref) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$this->panelKey = $panel_key;
|
||||
}
|
||||
|
||||
$column_key = $request->getStr('columnKey');
|
||||
if (strlen($column_key)) {
|
||||
$columns = $ref_list->getColumns();
|
||||
if (!isset($columns[$column_key])) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
$this->columnKey = $column_key;
|
||||
}
|
||||
|
||||
$after_ref = null;
|
||||
$after_key = $request->getStr('afterKey');
|
||||
if (strlen($after_key)) {
|
||||
$after_ref = $ref_list->getPanelRef($after_key);
|
||||
if (!$after_ref) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
}
|
||||
|
||||
switch ($request->getURIData('op')) {
|
||||
case 'add':
|
||||
return $this->handleAddRequest($dashboard, $done_uri);
|
||||
case 'remove':
|
||||
if (!$panel_ref) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
return $this->handleRemoveRequest($dashboard, $panel_ref, $done_uri);
|
||||
case 'move':
|
||||
return $this->handleMoveRequest($dashboard, $panel_ref, $after_ref);
|
||||
}
|
||||
}
|
||||
|
||||
private function handleAddRequest(
|
||||
PhabricatorDashboard $dashboard,
|
||||
$done_uri) {
|
||||
$request = $this->getRequest();
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$errors = array();
|
||||
|
||||
$panel_phid = null;
|
||||
$e_panel = true;
|
||||
if ($request->isFormPost()) {
|
||||
$panel_phid = head($request->getArr('panelPHIDs'));
|
||||
|
||||
if (!$panel_phid) {
|
||||
$errors[] = pht('You must choose a panel to add to the dashboard.');
|
||||
$e_panel = pht('Required');
|
||||
} else {
|
||||
$panel = id(new PhabricatorDashboardPanelQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($panel_phid))
|
||||
->executeOne();
|
||||
if (!$panel) {
|
||||
$errors[] = pht('You must choose a valid panel.');
|
||||
$e_panel = pht('Invalid');
|
||||
}
|
||||
}
|
||||
|
||||
if (!$errors) {
|
||||
$xactions = array();
|
||||
|
||||
$ref_list = clone $dashboard->getPanelRefList();
|
||||
$ref_list->newPanelRef($panel, $this->columnKey);
|
||||
$new_panels = $ref_list->toDictionary();
|
||||
|
||||
$xactions[] = $dashboard->getApplicationTransactionTemplate()
|
||||
->setTransactionType(
|
||||
PhabricatorDashboardPanelsTransaction::TRANSACTIONTYPE)
|
||||
->setNewValue($new_panels);
|
||||
|
||||
$editor = $dashboard->getApplicationTransactionEditor()
|
||||
->setActor($viewer)
|
||||
->setContentSourceFromRequest($request)
|
||||
->setContinueOnNoEffect(true)
|
||||
->setContinueOnMissingFields(true);
|
||||
|
||||
$editor->applyTransactions($dashboard, $xactions);
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI($done_uri);
|
||||
}
|
||||
}
|
||||
|
||||
if ($panel_phid) {
|
||||
$panel_phids = array($panel_phid);
|
||||
} else {
|
||||
$panel_phids = array();
|
||||
}
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setViewer($viewer)
|
||||
->appendRemarkupInstructions(
|
||||
pht('Choose a panel to add to this dashboard:'))
|
||||
->appendControl(
|
||||
id(new AphrontFormTokenizerControl())
|
||||
->setDatasource(new PhabricatorDashboardPanelDatasource())
|
||||
->setLimit(1)
|
||||
->setName('panelPHIDs')
|
||||
->setLabel(pht('Panel'))
|
||||
->setError($e_panel)
|
||||
->setValue($panel_phids));
|
||||
|
||||
return $this->newEditDialog()
|
||||
->setTitle(pht('Add Panel'))
|
||||
->setWidth(AphrontDialogView::WIDTH_FORM)
|
||||
->setErrors($errors)
|
||||
->appendForm($form)
|
||||
->addCancelButton($done_uri)
|
||||
->addSubmitButton(pht('Add Panel'));
|
||||
}
|
||||
|
||||
private function handleRemoveRequest(
|
||||
PhabricatorDashboard $dashboard,
|
||||
PhabricatorDashboardPanelRef $panel_ref,
|
||||
$done_uri) {
|
||||
$request = $this->getRequest();
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
// NOTE: If you can edit a dashboard, you can remove panels from it even
|
||||
// if you don't have permission to see them or they aren't valid. We only
|
||||
// require that the panel be present on the dashboard.
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
$xactions = array();
|
||||
|
||||
$ref_list = clone $dashboard->getPanelRefList();
|
||||
$ref_list->removePanelRef($panel_ref);
|
||||
$new_panels = $ref_list->toDictionary();
|
||||
|
||||
$xactions[] = $dashboard->getApplicationTransactionTemplate()
|
||||
->setTransactionType(
|
||||
PhabricatorDashboardPanelsTransaction::TRANSACTIONTYPE)
|
||||
->setNewValue($new_panels);
|
||||
|
||||
$editor = $dashboard->getApplicationTransactionEditor()
|
||||
->setActor($viewer)
|
||||
->setContentSourceFromRequest($request)
|
||||
->setContinueOnNoEffect(true)
|
||||
->setContinueOnMissingFields(true);
|
||||
|
||||
$editor->applyTransactions($dashboard, $xactions);
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI($done_uri);
|
||||
}
|
||||
|
||||
$panel_phid = $panel_ref->getPanelPHID();
|
||||
$handles = $viewer->loadHandles(array($panel_phid));
|
||||
$handle = $handles[$panel_phid];
|
||||
|
||||
$message = pht(
|
||||
'Remove panel %s from dashboard %s?',
|
||||
phutil_tag('strong', array(), $handle->getFullName()),
|
||||
phutil_tag('strong', array(), $dashboard->getName()));
|
||||
|
||||
return $this->newEditDialog()
|
||||
->setTitle(pht('Remove Dashboard Panel'))
|
||||
->appendParagraph($message)
|
||||
->addCancelButton($done_uri)
|
||||
->addSubmitButton(pht('Remove Panel'));
|
||||
}
|
||||
|
||||
private function handleMoveRequest(
|
||||
PhabricatorDashboard $dashboard,
|
||||
PhabricatorDashboardPanelRef $panel_ref,
|
||||
PhabricatorDashboardPanelRef $after_ref = null) {
|
||||
|
||||
$request = $this->getRequest();
|
||||
$request->validateCSRF();
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$xactions = array();
|
||||
|
||||
$ref_list = clone $dashboard->getPanelRefList();
|
||||
$ref_list->movePanelRef($panel_ref, $this->columnKey, $after_ref);
|
||||
$new_panels = $ref_list->toDictionary();
|
||||
|
||||
$xactions[] = $dashboard->getApplicationTransactionTemplate()
|
||||
->setTransactionType(
|
||||
PhabricatorDashboardPanelsTransaction::TRANSACTIONTYPE)
|
||||
->setNewValue($new_panels);
|
||||
|
||||
$editor = $dashboard->getApplicationTransactionEditor()
|
||||
->setActor($viewer)
|
||||
->setContentSourceFromRequest($request)
|
||||
->setContinueOnNoEffect(true)
|
||||
->setContinueOnMissingFields(true);
|
||||
|
||||
$editor->applyTransactions($dashboard, $xactions);
|
||||
|
||||
return id(new AphrontAjaxResponse())->setContent(array());
|
||||
}
|
||||
|
||||
|
||||
private function newEditDialog() {
|
||||
return $this->newDialog()
|
||||
->addHiddenInput('contextPHID', $this->contextPHID)
|
||||
->addHiddenInput('panelKey', $this->panelKey)
|
||||
->addHiddenInput('columnKey', $this->columnKey);
|
||||
}
|
||||
|
||||
}
|
|
@ -20,7 +20,7 @@ final class PhabricatorDashboardArchiveController
|
|||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$view_uri = $this->getApplicationURI('manage/'.$dashboard->getID().'/');
|
||||
$view_uri = $dashboard->getURI();
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
if ($dashboard->isArchived()) {
|
||||
|
@ -32,7 +32,8 @@ final class PhabricatorDashboardArchiveController
|
|||
$xactions = array();
|
||||
|
||||
$xactions[] = id(new PhabricatorDashboardTransaction())
|
||||
->setTransactionType(PhabricatorDashboardTransaction::TYPE_STATUS)
|
||||
->setTransactionType(
|
||||
PhabricatorDashboardStatusTransaction::TRANSACTIONTYPE)
|
||||
->setNewValue($new_status);
|
||||
|
||||
id(new PhabricatorDashboardTransactionEditor())
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardEditController
|
||||
extends PhabricatorDashboardController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
return id(new PhabricatorDashboardEditEngine())
|
||||
->setController($this)
|
||||
->buildResponse();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardInstallController
|
||||
extends PhabricatorDashboardController {
|
||||
|
||||
private $dashboard;
|
||||
|
||||
public function setDashboard(PhabricatorDashboard $dashboard) {
|
||||
$this->dashboard = $dashboard;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDashboard() {
|
||||
return $this->dashboard;
|
||||
}
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
$dashboard = id(new PhabricatorDashboardQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->executeOne();
|
||||
if (!$dashboard) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$this->setDashboard($dashboard);
|
||||
$cancel_uri = $dashboard->getURI();
|
||||
|
||||
$workflow_key = $request->getURIData('workflowKey');
|
||||
|
||||
$workflows = PhabricatorDashboardInstallWorkflow::getAllWorkflows();
|
||||
if (!isset($workflows[$workflow_key])) {
|
||||
return $this->newWorkflowDialog($dashboard, $workflows);
|
||||
}
|
||||
|
||||
return id(clone $workflows[$workflow_key])
|
||||
->setRequest($request)
|
||||
->setViewer($viewer)
|
||||
->setDashboard($dashboard)
|
||||
->setMode($request->getURIData('modeKey'))
|
||||
->handleRequest($request);
|
||||
}
|
||||
|
||||
private function newWorkflowDialog(
|
||||
PhabricatorDashboard $dashboard,
|
||||
array $workflows) {
|
||||
$viewer = $this->getViewer();
|
||||
$cancel_uri = $dashboard->getURI();
|
||||
|
||||
$menu = id(new PHUIObjectItemListView())
|
||||
->setViewer($viewer)
|
||||
->setFlush(true)
|
||||
->setBig(true);
|
||||
|
||||
foreach ($workflows as $key => $workflow) {
|
||||
$item = $workflow->getWorkflowMenuItem();
|
||||
|
||||
$item_href = urisprintf('install/%d/%s/', $dashboard->getID(), $key);
|
||||
$item_href = $this->getApplicationURI($item_href);
|
||||
$item->setHref($item_href);
|
||||
|
||||
$menu->addItem($item);
|
||||
}
|
||||
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Add Dashboard to Menu'))
|
||||
->setWidth(AphrontDialogView::WIDTH_FORM)
|
||||
->appendChild($menu)
|
||||
->addCancelButton($cancel_uri);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,202 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardViewController
|
||||
extends PhabricatorDashboardProfileController {
|
||||
|
||||
public function shouldAllowPublic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
$dashboard = id(new PhabricatorDashboardQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->executeOne();
|
||||
if (!$dashboard) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
$this->setDashboard($dashboard);
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$dashboard,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$title = $dashboard->getName();
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$header = $this->buildHeaderView();
|
||||
|
||||
$curtain = $this->buildCurtainView($dashboard);
|
||||
|
||||
$usage_box = $this->newUsageView($dashboard);
|
||||
|
||||
$timeline = $this->buildTransactionTimeline(
|
||||
$dashboard,
|
||||
new PhabricatorDashboardTransactionQuery());
|
||||
$timeline->setShouldTerminate(true);
|
||||
|
||||
$rendered_dashboard = id(new PhabricatorDashboardRenderingEngine())
|
||||
->setViewer($viewer)
|
||||
->setDashboard($dashboard)
|
||||
->setArrangeMode($can_edit)
|
||||
->renderDashboard();
|
||||
|
||||
$dashboard_box = id(new PHUIBoxView())
|
||||
->addClass('dashboard-preview-box')
|
||||
->appendChild($rendered_dashboard);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setCurtain($curtain)
|
||||
->setMainColumn(
|
||||
array(
|
||||
$dashboard_box,
|
||||
$usage_box,
|
||||
$timeline,
|
||||
));
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->appendChild($view);
|
||||
|
||||
}
|
||||
|
||||
private function buildCurtainView(PhabricatorDashboard $dashboard) {
|
||||
$viewer = $this->getViewer();
|
||||
$id = $dashboard->getID();
|
||||
|
||||
$curtain = $this->newCurtainView($dashboard);
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$dashboard,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Edit Dashboard'))
|
||||
->setIcon('fa-pencil')
|
||||
->setHref($this->getApplicationURI("edit/{$id}/"))
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit));
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Add Dashboard to Menu'))
|
||||
->setIcon('fa-wrench')
|
||||
->setHref($this->getApplicationURI("/install/{$id}/"))
|
||||
->setWorkflow(true));
|
||||
|
||||
if ($dashboard->isArchived()) {
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Activate Dashboard'))
|
||||
->setIcon('fa-check')
|
||||
->setHref($this->getApplicationURI("archive/{$id}/"))
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(true));
|
||||
} else {
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Archive Dashboard'))
|
||||
->setIcon('fa-ban')
|
||||
->setHref($this->getApplicationURI("archive/{$id}/"))
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(true));
|
||||
}
|
||||
|
||||
return $curtain;
|
||||
}
|
||||
|
||||
private function newUsageView(PhabricatorDashboard $dashboard) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$custom_phids = array();
|
||||
if ($viewer->getPHID()) {
|
||||
$custom_phids[] = $viewer->getPHID();
|
||||
}
|
||||
|
||||
$items = id(new PhabricatorProfileMenuItemConfigurationQuery())
|
||||
->setViewer($viewer)
|
||||
->withAffectedObjectPHIDs(
|
||||
array(
|
||||
$dashboard->getPHID(),
|
||||
))
|
||||
->withCustomPHIDs($custom_phids, $include_global = true)
|
||||
->execute();
|
||||
|
||||
$handle_phids = array();
|
||||
foreach ($items as $item) {
|
||||
$handle_phids[] = $item->getProfilePHID();
|
||||
$custom_phid = $item->getCustomPHID();
|
||||
if ($custom_phid) {
|
||||
$handle_phids[] = $custom_phid;
|
||||
}
|
||||
}
|
||||
|
||||
if ($handle_phids) {
|
||||
$handles = $viewer->loadHandles($handle_phids);
|
||||
} else {
|
||||
$handles = array();
|
||||
}
|
||||
|
||||
$items = msortv($items, 'newUsageSortVector');
|
||||
|
||||
$rows = array();
|
||||
foreach ($items as $item) {
|
||||
$profile_phid = $item->getProfilePHID();
|
||||
$custom_phid = $item->getCustomPHID();
|
||||
|
||||
$profile = $handles[$profile_phid]->renderLink();
|
||||
$profile_icon = $handles[$profile_phid]->getIcon();
|
||||
|
||||
if ($custom_phid) {
|
||||
$custom = $handles[$custom_phid]->renderLink();
|
||||
} else {
|
||||
$custom = pht('Global');
|
||||
}
|
||||
|
||||
$type = $item->getProfileMenuTypeDescription();
|
||||
|
||||
$rows[] = array(
|
||||
id(new PHUIIconView())->setIcon($profile_icon),
|
||||
$type,
|
||||
$profile,
|
||||
$custom,
|
||||
);
|
||||
}
|
||||
|
||||
$usage_table = id(new AphrontTableView($rows))
|
||||
->setNoDataString(
|
||||
pht('This dashboard has not been added to any menus.'))
|
||||
->setHeaders(
|
||||
array(
|
||||
null,
|
||||
pht('Type'),
|
||||
pht('Menu'),
|
||||
pht('Global/Personal'),
|
||||
))
|
||||
->setColumnClasses(
|
||||
array(
|
||||
'center',
|
||||
null,
|
||||
'pri',
|
||||
'wide',
|
||||
));
|
||||
|
||||
$header_view = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Dashboard Used By'));
|
||||
|
||||
$usage_box = id(new PHUIObjectBoxView())
|
||||
->setTable($usage_table)
|
||||
->setHeader($header_view);
|
||||
|
||||
return $usage_box;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -25,7 +25,8 @@ final class PhabricatorDashboardPanelArchiveController
|
|||
if ($request->isFormPost()) {
|
||||
$xactions = array();
|
||||
$xactions[] = id(new PhabricatorDashboardPanelTransaction())
|
||||
->setTransactionType(PhabricatorDashboardPanelTransaction::TYPE_ARCHIVE)
|
||||
->setTransactionType(
|
||||
PhabricatorDashboardPanelStatusTransaction::TRANSACTIONTYPE)
|
||||
->setNewValue((int)!$panel->getIsArchived());
|
||||
|
||||
id(new PhabricatorDashboardPanelTransactionEditor())
|
|
@ -0,0 +1,104 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardPanelEditController
|
||||
extends PhabricatorDashboardController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$engine = id(new PhabricatorDashboardPanelEditEngine())
|
||||
->setController($this);
|
||||
|
||||
// We can create or edit a panel in the context of a dashboard or
|
||||
// container panel, like a tab panel. If we started this flow on some
|
||||
// container object, we want to return to that container when we're done
|
||||
// editing.
|
||||
|
||||
$context_phid = $request->getStr('contextPHID');
|
||||
if (strlen($context_phid)) {
|
||||
$context = id(new PhabricatorObjectQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($context_phid))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->executeOne();
|
||||
if (!$context) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
if (!($context instanceof PhabricatorDashboardPanelContainerInterface)) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$engine
|
||||
->setContextObject($context)
|
||||
->addContextParameter('contextPHID', $context_phid);
|
||||
} else {
|
||||
$context = null;
|
||||
}
|
||||
|
||||
$id = $request->getURIData('id');
|
||||
if (!$id) {
|
||||
$column_key = $request->getStr('columnKey');
|
||||
|
||||
if ($context) {
|
||||
$cancel_uri = $context->getURI();
|
||||
} else {
|
||||
$cancel_uri = $this->getApplicationURI('panel/');
|
||||
}
|
||||
|
||||
$panel_type = $request->getStr('panelType');
|
||||
$panel_types = PhabricatorDashboardPanelType::getAllPanelTypes();
|
||||
if (empty($panel_types[$panel_type])) {
|
||||
return $this->buildPanelTypeResponse($cancel_uri);
|
||||
}
|
||||
|
||||
$engine
|
||||
->addContextParameter('panelType', $panel_type)
|
||||
->addContextParameter('columnKey', $column_key)
|
||||
->setPanelType($panel_type)
|
||||
->setColumnKey($column_key);
|
||||
}
|
||||
|
||||
return $engine->buildResponse();
|
||||
}
|
||||
|
||||
private function buildPanelTypeResponse($cancel_uri) {
|
||||
$viewer = $this->getViewer();
|
||||
$request = $this->getRequest();
|
||||
|
||||
$base_uri = $request->getRequestURI();
|
||||
$base_uri = new PhutilURI($base_uri);
|
||||
|
||||
$menu = id(new PHUIObjectItemListView())
|
||||
->setViewer($viewer)
|
||||
->setFlush(true)
|
||||
->setBig(true);
|
||||
|
||||
$panel_types = PhabricatorDashboardPanelType::getAllPanelTypes();
|
||||
foreach ($panel_types as $panel_type) {
|
||||
$item = id(new PHUIObjectItemView())
|
||||
->setClickable(true)
|
||||
->setImageIcon($panel_type->getIcon())
|
||||
->setHeader($panel_type->getPanelTypeName())
|
||||
->addAttribute($panel_type->getPanelTypeDescription());
|
||||
|
||||
$type_uri = id(clone $base_uri)
|
||||
->replaceQueryParam('panelType', $panel_type->getPanelTypeKey());
|
||||
|
||||
$item->setHref($type_uri);
|
||||
|
||||
$menu->addItem($item);
|
||||
}
|
||||
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Choose Panel Type'))
|
||||
->setWidth(AphrontDialogView::WIDTH_FORM)
|
||||
->appendChild($menu)
|
||||
->addCancelButton($cancel_uri);
|
||||
}
|
||||
|
||||
}
|
|
@ -43,7 +43,7 @@ final class PhabricatorDashboardPanelListController
|
|||
id(new PHUIListItemView())
|
||||
->setIcon('fa-plus-square')
|
||||
->setName(pht('Create Panel'))
|
||||
->setHref($this->getApplicationURI().'panel/create/'));
|
||||
->setHref($this->getApplicationURI().'panel/edit/'));
|
||||
|
||||
return $crumbs;
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ final class PhabricatorDashboardPanelListController
|
|||
$create_button = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setText(pht('Create a Panel'))
|
||||
->setHref('/dashboard/panel/create/')
|
||||
->setHref('/dashboard/panel/edit/')
|
||||
->setColor(PHUIButtonView::GREEN);
|
||||
|
||||
$icon = $this->getApplication()->getIcon();
|
|
@ -31,14 +31,28 @@ final class PhabricatorDashboardPanelRenderController
|
|||
$parent_phids = array();
|
||||
}
|
||||
|
||||
$rendered_panel = id(new PhabricatorDashboardPanelRenderingEngine())
|
||||
$engine = id(new PhabricatorDashboardPanelRenderingEngine())
|
||||
->setViewer($viewer)
|
||||
->setPanel($panel)
|
||||
->setPanelPHID($panel->getPHID())
|
||||
->setParentPanelPHIDs($parent_phids)
|
||||
->setMovable($request->getBool('movable'))
|
||||
->setHeaderMode($request->getStr('headerMode'))
|
||||
->setDashboardID($request->getInt('dashboardID'))
|
||||
->renderPanel();
|
||||
->setPanelKey($request->getStr('panelKey'));
|
||||
|
||||
$context_phid = $request->getStr('contextPHID');
|
||||
if ($context_phid) {
|
||||
$context = id(new PhabricatorObjectQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($context_phid))
|
||||
->executeOne();
|
||||
if (!$context) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
$engine->setContextObject($context);
|
||||
}
|
||||
|
||||
$rendered_panel = $engine->renderPanel();
|
||||
|
||||
if ($request->isAjax()) {
|
||||
return id(new AphrontAjaxResponse())
|
|
@ -0,0 +1,354 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardPanelTabsController
|
||||
extends PhabricatorDashboardController {
|
||||
|
||||
private $contextObject;
|
||||
|
||||
private function setContextObject($context_object) {
|
||||
$this->contextObject = $context_object;
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function getContextObject() {
|
||||
return $this->contextObject;
|
||||
}
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$panel = id(new PhabricatorDashboardPanelQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($request->getURIData('id')))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->executeOne();
|
||||
if (!$panel) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$tabs_type = id(new PhabricatorDashboardTabsPanelType())
|
||||
->getPanelTypeKey();
|
||||
|
||||
// This controller may only be used to edit tab panels.
|
||||
$panel_type = $panel->getPanelType();
|
||||
if ($panel_type !== $tabs_type) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$op = $request->getURIData('op');
|
||||
$after = $request->getStr('after');
|
||||
if (!strlen($after)) {
|
||||
$after = null;
|
||||
}
|
||||
|
||||
$target = $request->getStr('target');
|
||||
if (!strlen($target)) {
|
||||
$target = null;
|
||||
}
|
||||
|
||||
$impl = $panel->getImplementation();
|
||||
$config = $impl->getPanelConfiguration($panel);
|
||||
|
||||
$cancel_uri = $panel->getURI();
|
||||
|
||||
if ($after !== null) {
|
||||
$found = false;
|
||||
foreach ($config as $key => $spec) {
|
||||
if ((string)$key === $after) {
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$found) {
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Adjacent Tab Not Found'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'Adjacent tab ("%s") was not found on this panel. It may have '.
|
||||
'been removed.',
|
||||
$after))
|
||||
->addCancelButton($cancel_uri);
|
||||
}
|
||||
}
|
||||
|
||||
if ($target !== null) {
|
||||
$found = false;
|
||||
foreach ($config as $key => $spec) {
|
||||
if ((string)$key === $target) {
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$found) {
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Target Tab Not Found'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'Target tab ("%s") was not found on this panel. It may have '.
|
||||
'been removed.',
|
||||
$target))
|
||||
->addCancelButton($cancel_uri);
|
||||
}
|
||||
}
|
||||
|
||||
// Tab panels may be edited from the panel page, or from the context of
|
||||
// a dashboard. If we're editing from a dashboard, we want to redirect
|
||||
// back to the dashboard after making changes.
|
||||
|
||||
$context_phid = $request->getStr('contextPHID');
|
||||
$context = null;
|
||||
if (strlen($context_phid)) {
|
||||
$context = id(new PhabricatorObjectQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($context_phid))
|
||||
->executeOne();
|
||||
if (!$context) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
switch (phid_get_type($context_phid)) {
|
||||
case PhabricatorDashboardDashboardPHIDType::TYPECONST:
|
||||
$cancel_uri = $context->getURI();
|
||||
break;
|
||||
case PhabricatorDashboardPanelPHIDType::TYPECONST:
|
||||
$cancel_uri = $context->getURI();
|
||||
break;
|
||||
default:
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Context Object Unsupported'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'Context object ("%s") has unsupported type. Panels should '.
|
||||
'be rendered from the context of a dashboard or another '.
|
||||
'panel.',
|
||||
$context_phid))
|
||||
->addCancelButton($cancel_uri);
|
||||
}
|
||||
|
||||
$this->setContextObject($context);
|
||||
}
|
||||
|
||||
switch ($op) {
|
||||
case 'add':
|
||||
return $this->handleAddOperation($panel, $after, $cancel_uri);
|
||||
case 'remove':
|
||||
return $this->handleRemoveOperation($panel, $target, $cancel_uri);
|
||||
case 'move':
|
||||
break;
|
||||
case 'rename':
|
||||
return $this->handleRenameOperation($panel, $target, $cancel_uri);
|
||||
}
|
||||
}
|
||||
|
||||
private function handleAddOperation(
|
||||
PhabricatorDashboardPanel $panel,
|
||||
$after,
|
||||
$cancel_uri) {
|
||||
$request = $this->getRequest();
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$panel_phid = null;
|
||||
$errors = array();
|
||||
if ($request->isFormPost()) {
|
||||
$panel_phid = $request->getArr('panelPHID');
|
||||
$panel_phid = head($panel_phid);
|
||||
|
||||
$add_panel = id(new PhabricatorDashboardPanelQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($panel_phid))
|
||||
->executeOne();
|
||||
if (!$add_panel) {
|
||||
$errors[] = pht('You must select a valid panel.');
|
||||
}
|
||||
|
||||
if (!$errors) {
|
||||
$add_panel_config = array(
|
||||
'name' => null,
|
||||
'panelID' => $add_panel->getID(),
|
||||
);
|
||||
$add_panel_key = Filesystem::readRandomCharacters(12);
|
||||
|
||||
$impl = $panel->getImplementation();
|
||||
$old_config = $impl->getPanelConfiguration($panel);
|
||||
$new_config = array();
|
||||
if ($after === null) {
|
||||
$new_config = $old_config;
|
||||
$new_config[] = $add_panel_config;
|
||||
} else {
|
||||
foreach ($old_config as $key => $value) {
|
||||
$new_config[$key] = $value;
|
||||
if ((string)$key === $after) {
|
||||
$new_config[$add_panel_key] = $add_panel_config;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$xactions = array();
|
||||
|
||||
$xactions[] = $panel->getApplicationTransactionTemplate()
|
||||
->setTransactionType(
|
||||
PhabricatorDashboardTabsPanelTabsTransaction::TRANSACTIONTYPE)
|
||||
->setNewValue($new_config);
|
||||
|
||||
$editor = id(new PhabricatorDashboardPanelTransactionEditor())
|
||||
->setContentSourceFromRequest($request)
|
||||
->setActor($viewer)
|
||||
->setContinueOnNoEffect(true)
|
||||
->setContinueOnMissingFields(true);
|
||||
|
||||
$editor->applyTransactions($panel, $xactions);
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI($cancel_uri);
|
||||
}
|
||||
}
|
||||
|
||||
if ($panel_phid) {
|
||||
$v_panel = array($panel_phid);
|
||||
} else {
|
||||
$v_panel = array();
|
||||
}
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setViewer($viewer)
|
||||
->appendControl(
|
||||
id(new AphrontFormTokenizerControl())
|
||||
->setDatasource(new PhabricatorDashboardPanelDatasource())
|
||||
->setLimit(1)
|
||||
->setName('panelPHID')
|
||||
->setLabel(pht('Panel'))
|
||||
->setValue($v_panel));
|
||||
|
||||
return $this->newEditDialog()
|
||||
->setTitle(pht('Choose Dashboard Panel'))
|
||||
->setErrors($errors)
|
||||
->addHiddenInput('after', $after)
|
||||
->appendForm($form)
|
||||
->addCancelButton($cancel_uri)
|
||||
->addSubmitButton(pht('Add Panel'));
|
||||
}
|
||||
|
||||
private function handleRemoveOperation(
|
||||
PhabricatorDashboardPanel $panel,
|
||||
$target,
|
||||
$cancel_uri) {
|
||||
$request = $this->getRequest();
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$panel_phid = null;
|
||||
$errors = array();
|
||||
if ($request->isFormPost()) {
|
||||
$impl = $panel->getImplementation();
|
||||
$old_config = $impl->getPanelConfiguration($panel);
|
||||
|
||||
$new_config = $this->removePanel($old_config, $target);
|
||||
$this->writePanelConfig($panel, $new_config);
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI($cancel_uri);
|
||||
}
|
||||
|
||||
return $this->newEditDialog()
|
||||
->setTitle(pht('Remove tab?'))
|
||||
->addHiddenInput('target', $target)
|
||||
->appendParagraph(pht('Really remove this tab?'))
|
||||
->addCancelButton($cancel_uri)
|
||||
->addSubmitButton(pht('Remove Tab'));
|
||||
}
|
||||
|
||||
private function handleRenameOperation(
|
||||
PhabricatorDashboardPanel $panel,
|
||||
$target,
|
||||
$cancel_uri) {
|
||||
$request = $this->getRequest();
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$impl = $panel->getImplementation();
|
||||
$old_config = $impl->getPanelConfiguration($panel);
|
||||
|
||||
$spec = $old_config[$target];
|
||||
$name = idx($spec, 'name');
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
$name = $request->getStr('name');
|
||||
|
||||
$new_config = $this->renamePanel($old_config, $target, $name);
|
||||
$this->writePanelConfig($panel, $new_config);
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI($cancel_uri);
|
||||
}
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setViewer($viewer)
|
||||
->appendControl(
|
||||
id(new AphrontFormTextControl())
|
||||
->setValue($name)
|
||||
->setName('name')
|
||||
->setLabel(pht('Tab Name')));
|
||||
|
||||
return $this->newEditDialog()
|
||||
->setTitle(pht('Rename Panel'))
|
||||
->addHiddenInput('target', $target)
|
||||
->appendForm($form)
|
||||
->addCancelButton($cancel_uri)
|
||||
->addSubmitButton(pht('Rename Tab'));
|
||||
}
|
||||
|
||||
|
||||
private function writePanelConfig(
|
||||
PhabricatorDashboardPanel $panel,
|
||||
array $config) {
|
||||
$request = $this->getRequest();
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$xactions = array();
|
||||
|
||||
$xactions[] = $panel->getApplicationTransactionTemplate()
|
||||
->setTransactionType(
|
||||
PhabricatorDashboardTabsPanelTabsTransaction::TRANSACTIONTYPE)
|
||||
->setNewValue($config);
|
||||
|
||||
$editor = id(new PhabricatorDashboardPanelTransactionEditor())
|
||||
->setContentSourceFromRequest($request)
|
||||
->setActor($viewer)
|
||||
->setContinueOnNoEffect(true)
|
||||
->setContinueOnMissingFields(true);
|
||||
|
||||
return $editor->applyTransactions($panel, $xactions);
|
||||
}
|
||||
|
||||
private function removePanel(array $config, $target) {
|
||||
$result = array();
|
||||
|
||||
foreach ($config as $key => $panel_spec) {
|
||||
if ((string)$key === $target) {
|
||||
continue;
|
||||
}
|
||||
$result[$key] = $panel_spec;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function renamePanel(array $config, $target, $name) {
|
||||
$config[$target]['name'] = $name;
|
||||
return $config;
|
||||
}
|
||||
|
||||
protected function newEditDialog() {
|
||||
$dialog = $this->newDialog()
|
||||
->setWidth(AphrontDialogView::WIDTH_FORM);
|
||||
|
||||
$context = $this->getContextObject();
|
||||
if ($context) {
|
||||
$dialog->addHiddenInput('contextPHID', $context->getPHID());
|
||||
}
|
||||
|
||||
return $dialog;
|
||||
}
|
||||
|
||||
}
|
|
@ -19,6 +19,11 @@ final class PhabricatorDashboardPanelViewController
|
|||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$panel,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$title = $panel->getMonogram().' '.$panel->getName();
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb(
|
||||
|
@ -29,17 +34,21 @@ final class PhabricatorDashboardPanelViewController
|
|||
|
||||
$header = $this->buildHeaderView($panel);
|
||||
$curtain = $this->buildCurtainView($panel);
|
||||
$properties = $this->buildPropertyView($panel);
|
||||
|
||||
$usage_box = $this->newUsageView($panel);
|
||||
|
||||
$timeline = $this->buildTransactionTimeline(
|
||||
$panel,
|
||||
new PhabricatorDashboardPanelTransactionQuery());
|
||||
$timeline->setShouldTerminate(true);
|
||||
|
||||
$rendered_panel = id(new PhabricatorDashboardPanelRenderingEngine())
|
||||
->setViewer($viewer)
|
||||
->setPanel($panel)
|
||||
->setContextObject($panel)
|
||||
->setPanelPHID($panel->getPHID())
|
||||
->setParentPanelPHIDs(array())
|
||||
->setEditMode(true)
|
||||
->renderPanel();
|
||||
|
||||
$preview = id(new PHUIBoxView())
|
||||
|
@ -50,10 +59,10 @@ final class PhabricatorDashboardPanelViewController
|
|||
->setHeader($header)
|
||||
->setCurtain($curtain)
|
||||
->setMainColumn(array(
|
||||
$properties,
|
||||
$rendered_panel,
|
||||
$usage_box,
|
||||
$timeline,
|
||||
))
|
||||
->setFooter($rendered_panel);
|
||||
));
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
|
@ -65,18 +74,11 @@ final class PhabricatorDashboardPanelViewController
|
|||
$viewer = $this->getViewer();
|
||||
$id = $panel->getID();
|
||||
|
||||
$button = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setText(pht('View Panel'))
|
||||
->setIcon('fa-columns')
|
||||
->setHref($this->getApplicationURI("panel/render/{$id}/"));
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setUser($viewer)
|
||||
->setHeader($panel->getName())
|
||||
->setPolicyObject($panel)
|
||||
->setHeaderIcon('fa-columns')
|
||||
->addActionLink($button);
|
||||
->setHeaderIcon('fa-window-maximize');
|
||||
|
||||
if (!$panel->getIsArchived()) {
|
||||
$header->setStatus('fa-check', 'bluegrey', pht('Active'));
|
||||
|
@ -124,51 +126,51 @@ final class PhabricatorDashboardPanelViewController
|
|||
return $curtain;
|
||||
}
|
||||
|
||||
private function buildPropertyView(PhabricatorDashboardPanel $panel) {
|
||||
private function newUsageView(PhabricatorDashboardPanel $panel) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$properties = id(new PHUIPropertyListView())
|
||||
->setUser($viewer);
|
||||
|
||||
$descriptions = PhabricatorPolicyQuery::renderPolicyDescriptions(
|
||||
$viewer,
|
||||
$panel);
|
||||
|
||||
$panel_type = $panel->getImplementation();
|
||||
if ($panel_type) {
|
||||
$type_name = $panel_type->getPanelTypeName();
|
||||
} else {
|
||||
$type_name = phutil_tag(
|
||||
'em',
|
||||
array(),
|
||||
nonempty($panel->getPanelType(), pht('null')));
|
||||
}
|
||||
|
||||
$properties->addProperty(
|
||||
pht('Panel Type'),
|
||||
$type_name);
|
||||
|
||||
$properties->addProperty(
|
||||
pht('Editable By'),
|
||||
$descriptions[PhabricatorPolicyCapability::CAN_EDIT]);
|
||||
|
||||
$dashboard_phids = PhabricatorEdgeQuery::loadDestinationPHIDs(
|
||||
$object_phids = PhabricatorEdgeQuery::loadDestinationPHIDs(
|
||||
$panel->getPHID(),
|
||||
PhabricatorDashboardPanelHasDashboardEdgeType::EDGECONST);
|
||||
PhabricatorDashboardPanelUsedByObjectEdgeType::EDGECONST);
|
||||
|
||||
$does_not_appear = pht(
|
||||
'This panel does not appear on any dashboards.');
|
||||
|
||||
$properties->addProperty(
|
||||
pht('Appears On'),
|
||||
$dashboard_phids
|
||||
? $viewer->renderHandleList($dashboard_phids)
|
||||
: phutil_tag('em', array(), $does_not_appear));
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Details'))
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->addPropertyList($properties);
|
||||
if ($object_phids) {
|
||||
$handles = $viewer->loadHandles($object_phids);
|
||||
} else {
|
||||
$handles = array();
|
||||
}
|
||||
|
||||
$rows = array();
|
||||
foreach ($object_phids as $object_phid) {
|
||||
$handle = $handles[$object_phid];
|
||||
|
||||
$icon = $handle->getIcon();
|
||||
|
||||
$rows[] = array(
|
||||
id(new PHUIIconView())->setIcon($icon),
|
||||
$handle->getTypeName(),
|
||||
$handle->renderLink(),
|
||||
);
|
||||
}
|
||||
|
||||
$usage_table = id(new AphrontTableView($rows))
|
||||
->setNoDataString(
|
||||
pht(
|
||||
'This panel is not used on any dashboard or inside any other '.
|
||||
'panel container.'))
|
||||
->setColumnClasses(
|
||||
array(
|
||||
'center',
|
||||
'',
|
||||
'pri wide',
|
||||
));
|
||||
|
||||
$header_view = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Panel Used By'));
|
||||
|
||||
$usage_box = id(new PHUIObjectBoxView())
|
||||
->setTable($usage_table)
|
||||
->setHeader($header_view);
|
||||
|
||||
return $usage_box;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
abstract class PhabricatorDashboardPortalController
|
||||
extends PhabricatorDashboardController {
|
||||
|
||||
protected function buildApplicationCrumbs() {
|
||||
$crumbs = new PHUICrumbsView();
|
||||
|
||||
$crumbs->addCrumb(
|
||||
id(new PHUICrumbView())
|
||||
->setHref('/portal/')
|
||||
->setName(pht('Portals'))
|
||||
->setIcon('fa-compass'));
|
||||
|
||||
return $crumbs;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardPortalEditController
|
||||
extends PhabricatorDashboardPortalController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
return id(new PhabricatorDashboardPortalEditEngine())
|
||||
->setController($this)
|
||||
->buildResponse();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardPortalListController
|
||||
extends PhabricatorDashboardPortalController {
|
||||
|
||||
public function shouldAllowPublic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
return id(new PhabricatorDashboardPortalSearchEngine())
|
||||
->setController($this)
|
||||
->buildResponse();
|
||||
}
|
||||
|
||||
protected function buildApplicationCrumbs() {
|
||||
$crumbs = parent::buildApplicationCrumbs();
|
||||
|
||||
id(new PhabricatorDashboardPortalEditEngine())
|
||||
->setViewer($this->getViewer())
|
||||
->addActionToCrumbs($crumbs);
|
||||
|
||||
return $crumbs;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardPortalViewController
|
||||
extends PhabricatorDashboardPortalController {
|
||||
|
||||
private $portal;
|
||||
|
||||
public function setPortal(PhabricatorDashboardPortal $portal) {
|
||||
$this->portal = $portal;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPortal() {
|
||||
return $this->portal;
|
||||
}
|
||||
|
||||
public function shouldAllowPublic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $this->getViewer();
|
||||
$id = $request->getURIData('portalID');
|
||||
|
||||
$portal = id(new PhabricatorDashboardPortalQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->executeOne();
|
||||
if (!$portal) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$this->setPortal($portal);
|
||||
|
||||
$engine = id(new PhabricatorDashboardPortalProfileMenuEngine())
|
||||
->setProfileObject($portal)
|
||||
->setController($this);
|
||||
|
||||
return $engine->buildResponse();
|
||||
}
|
||||
|
||||
protected function buildApplicationCrumbs() {
|
||||
$crumbs = parent::buildApplicationCrumbs();
|
||||
|
||||
$portal = $this->getPortal();
|
||||
if ($portal) {
|
||||
$crumbs->addTextCrumb($portal->getName(), $portal->getURI());
|
||||
}
|
||||
|
||||
return $crumbs;
|
||||
}
|
||||
|
||||
public function newTimelineView() {
|
||||
return $this->buildTransactionTimeline(
|
||||
$this->getPortal(),
|
||||
new PhabricatorDashboardPortalTransactionQuery());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardPanelCoreCustomField
|
||||
extends PhabricatorDashboardPanelCustomField
|
||||
implements PhabricatorStandardCustomFieldInterface {
|
||||
|
||||
public function getStandardCustomFieldNamespace() {
|
||||
return 'dashboard:core';
|
||||
}
|
||||
|
||||
public function createFields($object) {
|
||||
if (!$object->getPanelType()) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$impl = $object->requireImplementation();
|
||||
$specs = $impl->getFieldSpecifications();
|
||||
return PhabricatorStandardCustomField::buildStandardFields($this, $specs);
|
||||
}
|
||||
|
||||
public function shouldUseStorage() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function readValueFromObject(PhabricatorCustomFieldInterface $object) {
|
||||
$key = $this->getProxy()->getRawStandardFieldKey();
|
||||
$this->setValueFromStorage($object->getProperty($key));
|
||||
$this->didSetValueFromStorage();
|
||||
}
|
||||
|
||||
public function applyApplicationTransactionInternalEffects(
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
$object = $this->getObject();
|
||||
$key = $this->getProxy()->getRawStandardFieldKey();
|
||||
|
||||
$this->setValueFromApplicationTransactions($xaction->getNewValue());
|
||||
$value = $this->getValueForStorage();
|
||||
|
||||
$object->setProperty($key, $value);
|
||||
}
|
||||
|
||||
public function applyApplicationTransactionExternalEffects(
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
<?php
|
||||
|
||||
abstract class PhabricatorDashboardPanelCustomField
|
||||
extends PhabricatorCustomField {}
|
|
@ -1,114 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardPanelTabsCustomField
|
||||
extends PhabricatorStandardCustomField {
|
||||
|
||||
public function getFieldType() {
|
||||
return 'dashboard.tabs';
|
||||
}
|
||||
|
||||
public function shouldAppearInApplicationSearch() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function readValueFromRequest(AphrontRequest $request) {
|
||||
$value = array();
|
||||
|
||||
$names = $request->getArr($this->getFieldKey().'_name');
|
||||
$panel_ids = $request->getArr($this->getFieldKey().'_panelID');
|
||||
$panels = array();
|
||||
foreach ($panel_ids as $panel_id) {
|
||||
$panels[] = $panel_id[0];
|
||||
}
|
||||
foreach ($names as $idx => $name) {
|
||||
$panel_id = idx($panels, $idx);
|
||||
if (strlen($name) && $panel_id) {
|
||||
$value[] = array(
|
||||
'name' => $name,
|
||||
'panelID' => $panel_id,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$this->setFieldValue($value);
|
||||
}
|
||||
|
||||
public function getApplicationTransactionTitle(
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
$author_phid = $xaction->getAuthorPHID();
|
||||
$old = $xaction->getOldValue();
|
||||
$new = $xaction->getNewValue();
|
||||
|
||||
$new_tabs = array();
|
||||
if ($new) {
|
||||
foreach ($new as $new_tab) {
|
||||
$new_tabs[] = $new_tab['name'];
|
||||
}
|
||||
$new_tabs = implode(' | ', $new_tabs);
|
||||
}
|
||||
|
||||
$old_tabs = array();
|
||||
if ($old) {
|
||||
foreach ($old as $old_tab) {
|
||||
$old_tabs[] = $old_tab['name'];
|
||||
}
|
||||
$old_tabs = implode(' | ', $old_tabs);
|
||||
}
|
||||
|
||||
if (!$old) {
|
||||
// In case someone makes a tab panel with no tabs.
|
||||
if ($new) {
|
||||
return pht(
|
||||
'%s set the tabs to "%s".',
|
||||
$xaction->renderHandleLink($author_phid),
|
||||
$new_tabs);
|
||||
}
|
||||
} else if (!$new) {
|
||||
return pht(
|
||||
'%s removed tabs.',
|
||||
$xaction->renderHandleLink($author_phid));
|
||||
} else {
|
||||
return pht(
|
||||
'%s changed the tabs from "%s" to "%s".',
|
||||
$xaction->renderHandleLink($author_phid),
|
||||
$old_tabs,
|
||||
$new_tabs);
|
||||
}
|
||||
}
|
||||
|
||||
public function renderEditControl(array $handles) {
|
||||
// NOTE: This includes archived panels so we don't mutate the tabs
|
||||
// when saving a tab panel that includes archived panels. This whole UI is
|
||||
// hopefully temporary anyway.
|
||||
|
||||
$value = $this->getFieldValue();
|
||||
if (!is_array($value)) {
|
||||
$value = array();
|
||||
}
|
||||
|
||||
$out = array();
|
||||
for ($ii = 1; $ii <= 6; $ii++) {
|
||||
$tab = idx($value, ($ii - 1), array());
|
||||
$panel = idx($tab, 'panelID', null);
|
||||
$panel_id = array();
|
||||
if ($panel) {
|
||||
$panel_id[] = $panel;
|
||||
}
|
||||
$out[] = id(new AphrontFormTextControl())
|
||||
->setName($this->getFieldKey().'_name[]')
|
||||
->setValue(idx($tab, 'name'))
|
||||
->setLabel(pht('Tab %d Name', $ii));
|
||||
|
||||
$out[] = id(new AphrontFormTokenizerControl())
|
||||
->setUser($this->getViewer())
|
||||
->setDatasource(new PhabricatorDashboardPanelDatasource())
|
||||
->setName($this->getFieldKey().'_panelID[]')
|
||||
->setValue($panel_id)
|
||||
->setLimit(1)
|
||||
->setLabel(pht('Tab %d Panel', $ii));
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,103 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardDashboardHasPanelEdgeType
|
||||
extends PhabricatorEdgeType {
|
||||
|
||||
const EDGECONST = 45;
|
||||
|
||||
public function getInverseEdgeConstant() {
|
||||
return PhabricatorDashboardPanelHasDashboardEdgeType::EDGECONST;
|
||||
}
|
||||
|
||||
public function shouldWriteInverseTransactions() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getTransactionAddString(
|
||||
$actor,
|
||||
$add_count,
|
||||
$add_edges) {
|
||||
|
||||
return pht(
|
||||
'%s added %s panel(s): %s.',
|
||||
$actor,
|
||||
$add_count,
|
||||
$add_edges);
|
||||
}
|
||||
|
||||
public function getTransactionRemoveString(
|
||||
$actor,
|
||||
$rem_count,
|
||||
$rem_edges) {
|
||||
|
||||
return pht(
|
||||
'%s removed %s panel(s): %s.',
|
||||
$actor,
|
||||
$rem_count,
|
||||
$rem_edges);
|
||||
}
|
||||
|
||||
public function getTransactionEditString(
|
||||
$actor,
|
||||
$total_count,
|
||||
$add_count,
|
||||
$add_edges,
|
||||
$rem_count,
|
||||
$rem_edges) {
|
||||
|
||||
return pht(
|
||||
'%s edited panel(s), added %s: %s; removed %s: %s.',
|
||||
$actor,
|
||||
$add_count,
|
||||
$add_edges,
|
||||
$rem_count,
|
||||
$rem_edges);
|
||||
}
|
||||
|
||||
public function getFeedAddString(
|
||||
$actor,
|
||||
$object,
|
||||
$add_count,
|
||||
$add_edges) {
|
||||
|
||||
return pht(
|
||||
'%s added %s panel(s) for %s: %s.',
|
||||
$actor,
|
||||
$add_count,
|
||||
$object,
|
||||
$add_edges);
|
||||
}
|
||||
|
||||
public function getFeedRemoveString(
|
||||
$actor,
|
||||
$object,
|
||||
$rem_count,
|
||||
$rem_edges) {
|
||||
|
||||
return pht(
|
||||
'%s removed %s panel(s) for %s: %s.',
|
||||
$actor,
|
||||
$rem_count,
|
||||
$object,
|
||||
$rem_edges);
|
||||
}
|
||||
|
||||
public function getFeedEditString(
|
||||
$actor,
|
||||
$object,
|
||||
$total_count,
|
||||
$add_count,
|
||||
$add_edges,
|
||||
$rem_count,
|
||||
$rem_edges) {
|
||||
|
||||
return pht(
|
||||
'%s edited panel(s) for %s, added %s: %s; removed %s: %s.',
|
||||
$actor,
|
||||
$object,
|
||||
$add_count,
|
||||
$add_edges,
|
||||
$rem_count,
|
||||
$rem_edges);
|
||||
}
|
||||
}
|
|
@ -1,103 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardPanelHasDashboardEdgeType
|
||||
extends PhabricatorEdgeType {
|
||||
|
||||
const EDGECONST = 46;
|
||||
|
||||
public function getInverseEdgeConstant() {
|
||||
return PhabricatorDashboardDashboardHasPanelEdgeType::EDGECONST;
|
||||
}
|
||||
|
||||
public function shouldWriteInverseTransactions() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getTransactionAddString(
|
||||
$actor,
|
||||
$add_count,
|
||||
$add_edges) {
|
||||
|
||||
return pht(
|
||||
'%s added %s dashboard(s): %s.',
|
||||
$actor,
|
||||
$add_count,
|
||||
$add_edges);
|
||||
}
|
||||
|
||||
public function getTransactionRemoveString(
|
||||
$actor,
|
||||
$rem_count,
|
||||
$rem_edges) {
|
||||
|
||||
return pht(
|
||||
'%s removed %s dashboard(s): %s.',
|
||||
$actor,
|
||||
$rem_count,
|
||||
$rem_edges);
|
||||
}
|
||||
|
||||
public function getTransactionEditString(
|
||||
$actor,
|
||||
$total_count,
|
||||
$add_count,
|
||||
$add_edges,
|
||||
$rem_count,
|
||||
$rem_edges) {
|
||||
|
||||
return pht(
|
||||
'%s edited dashboard(s), added %s: %s; removed %s: %s.',
|
||||
$actor,
|
||||
$add_count,
|
||||
$add_edges,
|
||||
$rem_count,
|
||||
$rem_edges);
|
||||
}
|
||||
|
||||
public function getFeedAddString(
|
||||
$actor,
|
||||
$object,
|
||||
$add_count,
|
||||
$add_edges) {
|
||||
|
||||
return pht(
|
||||
'%s added %s dashboard(s) for %s: %s.',
|
||||
$actor,
|
||||
$add_count,
|
||||
$object,
|
||||
$add_edges);
|
||||
}
|
||||
|
||||
public function getFeedRemoveString(
|
||||
$actor,
|
||||
$object,
|
||||
$rem_count,
|
||||
$rem_edges) {
|
||||
|
||||
return pht(
|
||||
'%s removed %s dashboard(s) for %s: %s.',
|
||||
$actor,
|
||||
$rem_count,
|
||||
$object,
|
||||
$rem_edges);
|
||||
}
|
||||
|
||||
public function getFeedEditString(
|
||||
$actor,
|
||||
$object,
|
||||
$total_count,
|
||||
$add_count,
|
||||
$add_edges,
|
||||
$rem_count,
|
||||
$rem_edges) {
|
||||
|
||||
return pht(
|
||||
'%s edited dashboard(s) for %s, added %s: %s; removed %s: %s.',
|
||||
$actor,
|
||||
$object,
|
||||
$add_count,
|
||||
$add_edges,
|
||||
$rem_count,
|
||||
$rem_edges);
|
||||
}
|
||||
}
|
|
@ -1,17 +1,11 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardPanelSearchApplicationCustomField
|
||||
extends PhabricatorStandardCustomField {
|
||||
final class PhabricatorDashboardQueryPanelApplicationEditField
|
||||
extends PhabricatorEditField {
|
||||
|
||||
public function getFieldType() {
|
||||
return 'search.application';
|
||||
}
|
||||
private $controlID;
|
||||
|
||||
public function shouldAppearInApplicationSearch() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function renderEditControl(array $handles) {
|
||||
protected function newControl() {
|
||||
$engines = id(new PhutilClassMapQuery())
|
||||
->setAncestorClass('PhabricatorApplicationSearchEngine')
|
||||
->setFilterMethod('canUseInPanelContext')
|
||||
|
@ -31,7 +25,7 @@ final class PhabricatorDashboardPanelSearchApplicationCustomField
|
|||
|
||||
$options = array();
|
||||
|
||||
$value = $this->getFieldValue();
|
||||
$value = $this->getValueForControl();
|
||||
if (strlen($value) && empty($engines[$value])) {
|
||||
$options[$value] = $value;
|
||||
}
|
||||
|
@ -42,12 +36,24 @@ final class PhabricatorDashboardPanelSearchApplicationCustomField
|
|||
}
|
||||
|
||||
return id(new AphrontFormSelectControl())
|
||||
->setID($this->getFieldControlID())
|
||||
->setLabel($this->getFieldName())
|
||||
->setCaption($this->getCaption())
|
||||
->setName($this->getFieldKey())
|
||||
->setValue($this->getFieldValue())
|
||||
->setID($this->getControlID())
|
||||
->setOptions($options);
|
||||
}
|
||||
|
||||
protected function newHTTPParameterType() {
|
||||
return new AphrontSelectHTTPParameterType();
|
||||
}
|
||||
|
||||
public function getControlID() {
|
||||
if (!$this->controlID) {
|
||||
$this->controlID = celerity_generate_unique_node_id();
|
||||
}
|
||||
|
||||
return $this->controlID;
|
||||
}
|
||||
|
||||
protected function newConduitParameterType() {
|
||||
return new ConduitStringParameterType();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,23 +1,26 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardPanelSearchQueryCustomField
|
||||
extends PhabricatorStandardCustomField {
|
||||
final class PhabricatorDashboardQueryPanelQueryEditField
|
||||
extends PhabricatorEditField {
|
||||
|
||||
public function getFieldType() {
|
||||
return 'search.query';
|
||||
private $applicationControlID;
|
||||
|
||||
public function setApplicationControlID($id) {
|
||||
$this->applicationControlID = $id;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function shouldAppearInApplicationSearch() {
|
||||
return false;
|
||||
public function getApplicationControlID() {
|
||||
return $this->applicationControlID;
|
||||
}
|
||||
|
||||
public function renderEditControl(array $handles) {
|
||||
protected function newControl() {
|
||||
$engines = id(new PhutilClassMapQuery())
|
||||
->setAncestorClass('PhabricatorApplicationSearchEngine')
|
||||
->setFilterMethod('canUseInPanelContext')
|
||||
->execute();
|
||||
|
||||
$value = $this->getFieldValue();
|
||||
$value = $this->getValueForControl();
|
||||
|
||||
$queries = array();
|
||||
$seen = false;
|
||||
|
@ -43,12 +46,14 @@ final class PhabricatorDashboardPanelSearchQueryCustomField
|
|||
|
||||
$options = array($value => $name);
|
||||
|
||||
$app_control_key = $this->getFieldConfigValue('control.application');
|
||||
$application_id = $this->getApplicationControlID();
|
||||
$control_id = celerity_generate_unique_node_id();
|
||||
|
||||
Javelin::initBehavior(
|
||||
'dashboard-query-panel-select',
|
||||
array(
|
||||
'applicationID' => $this->getFieldControlID($app_control_key),
|
||||
'queryID' => $this->getFieldControlID(),
|
||||
'applicationID' => $application_id,
|
||||
'queryID' => $control_id,
|
||||
'options' => $queries,
|
||||
'value' => array(
|
||||
'key' => strlen($value) ? $value : null,
|
||||
|
@ -57,12 +62,16 @@ final class PhabricatorDashboardPanelSearchQueryCustomField
|
|||
));
|
||||
|
||||
return id(new AphrontFormSelectControl())
|
||||
->setID($this->getFieldControlID())
|
||||
->setLabel($this->getFieldName())
|
||||
->setCaption($this->getCaption())
|
||||
->setName($this->getFieldKey())
|
||||
->setValue($this->getFieldValue())
|
||||
->setID($control_id)
|
||||
->setOptions($options);
|
||||
}
|
||||
|
||||
protected function newHTTPParameterType() {
|
||||
return new AphrontSelectHTTPParameterType();
|
||||
}
|
||||
|
||||
protected function newConduitParameterType() {
|
||||
return new ConduitStringParameterType();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardEditEngine
|
||||
extends PhabricatorEditEngine {
|
||||
|
||||
const ENGINECONST = 'dashboard';
|
||||
|
||||
public function isEngineConfigurable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getEngineName() {
|
||||
return pht('Dashboards');
|
||||
}
|
||||
|
||||
public function getSummaryHeader() {
|
||||
return pht('Edit Dashboards');
|
||||
}
|
||||
|
||||
public function getSummaryText() {
|
||||
return pht('This engine is used to modify dashboards.');
|
||||
}
|
||||
|
||||
public function getEngineApplicationClass() {
|
||||
return 'PhabricatorDashboardApplication';
|
||||
}
|
||||
|
||||
protected function newEditableObject() {
|
||||
$viewer = $this->getViewer();
|
||||
return PhabricatorDashboard::initializeNewDashboard($viewer);
|
||||
}
|
||||
|
||||
protected function newObjectQuery() {
|
||||
return new PhabricatorDashboardQuery();
|
||||
}
|
||||
|
||||
protected function getObjectCreateTitleText($object) {
|
||||
return pht('Create Dashboard');
|
||||
}
|
||||
|
||||
protected function getObjectCreateButtonText($object) {
|
||||
return pht('Create Dashboard');
|
||||
}
|
||||
|
||||
protected function getObjectCreateCancelURI($object) {
|
||||
return '/dashboard/';
|
||||
}
|
||||
|
||||
protected function getObjectEditTitleText($object) {
|
||||
return pht('Edit Dashboard: %s', $object->getName());
|
||||
}
|
||||
|
||||
protected function getObjectEditShortText($object) {
|
||||
return pht('Edit Dashboard');
|
||||
}
|
||||
|
||||
protected function getObjectCreateShortText() {
|
||||
return pht('Create Dashboard');
|
||||
}
|
||||
|
||||
protected function getObjectName() {
|
||||
return pht('Dashboard');
|
||||
}
|
||||
|
||||
protected function getObjectViewURI($object) {
|
||||
return $object->getURI();
|
||||
}
|
||||
|
||||
protected function buildCustomEditFields($object) {
|
||||
$layout_options = PhabricatorDashboardLayoutMode::getLayoutModeMap();
|
||||
|
||||
$fields = array(
|
||||
id(new PhabricatorTextEditField())
|
||||
->setKey('name')
|
||||
->setLabel(pht('Name'))
|
||||
->setDescription(pht('Name of the dashboard.'))
|
||||
->setConduitDescription(pht('Rename the dashboard.'))
|
||||
->setConduitTypeDescription(pht('New dashboard name.'))
|
||||
->setTransactionType(
|
||||
PhabricatorDashboardNameTransaction::TRANSACTIONTYPE)
|
||||
->setIsRequired(true)
|
||||
->setValue($object->getName()),
|
||||
id(new PhabricatorIconSetEditField())
|
||||
->setKey('icon')
|
||||
->setLabel(pht('Icon'))
|
||||
->setTransactionType(
|
||||
PhabricatorDashboardIconTransaction::TRANSACTIONTYPE)
|
||||
->setIconSet(new PhabricatorDashboardIconSet())
|
||||
->setDescription(pht('Dashboard icon.'))
|
||||
->setConduitDescription(pht('Change the dashboard icon.'))
|
||||
->setConduitTypeDescription(pht('New dashboard icon.'))
|
||||
->setValue($object->getIcon()),
|
||||
id(new PhabricatorSelectEditField())
|
||||
->setKey('layout')
|
||||
->setLabel(pht('Layout'))
|
||||
->setDescription(pht('Dashboard layout mode.'))
|
||||
->setConduitDescription(pht('Change the dashboard layout mode.'))
|
||||
->setConduitTypeDescription(pht('New dashboard layout mode.'))
|
||||
->setTransactionType(
|
||||
PhabricatorDashboardLayoutTransaction::TRANSACTIONTYPE)
|
||||
->setOptions($layout_options)
|
||||
->setValue($object->getRawLayoutMode()),
|
||||
);
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
}
|
|
@ -6,6 +6,8 @@ final class PhabricatorDashboardPanelEditEngine
|
|||
const ENGINECONST = 'dashboard.panel';
|
||||
|
||||
private $panelType;
|
||||
private $contextObject;
|
||||
private $columnKey;
|
||||
|
||||
public function setPanelType($panel_type) {
|
||||
$this->panelType = $panel_type;
|
||||
|
@ -16,6 +18,24 @@ final class PhabricatorDashboardPanelEditEngine
|
|||
return $this->panelType;
|
||||
}
|
||||
|
||||
public function setContextObject($context) {
|
||||
$this->contextObject = $context;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getContextObject() {
|
||||
return $this->contextObject;
|
||||
}
|
||||
|
||||
public function setColumnKey($column_key) {
|
||||
$this->columnKey = $column_key;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getColumnKey() {
|
||||
return $this->columnKey;
|
||||
}
|
||||
|
||||
public function isEngineConfigurable() {
|
||||
return false;
|
||||
}
|
||||
|
@ -63,6 +83,33 @@ final class PhabricatorDashboardPanelEditEngine
|
|||
return pht('Create Panel');
|
||||
}
|
||||
|
||||
protected function getObjectCreateCancelURI($object) {
|
||||
$context = $this->getContextObject();
|
||||
if ($context) {
|
||||
return $context->getURI();
|
||||
}
|
||||
|
||||
return parent::getObjectCreateCancelURI($object);
|
||||
}
|
||||
|
||||
public function getEffectiveObjectEditDoneURI($object) {
|
||||
$context = $this->getContextObject();
|
||||
if ($context) {
|
||||
return $context->getURI();
|
||||
}
|
||||
|
||||
return parent::getEffectiveObjectEditDoneURI($object);
|
||||
}
|
||||
|
||||
protected function getObjectEditCancelURI($object) {
|
||||
$context = $this->getContextObject();
|
||||
if ($context) {
|
||||
return $context->getURI();
|
||||
}
|
||||
|
||||
return parent::getObjectEditCancelURI($object);
|
||||
}
|
||||
|
||||
protected function getObjectEditTitleText($object) {
|
||||
return pht('Edit Panel: %s', $object->getName());
|
||||
}
|
||||
|
@ -83,18 +130,58 @@ final class PhabricatorDashboardPanelEditEngine
|
|||
return $object->getURI();
|
||||
}
|
||||
|
||||
protected function didApplyTransactions($object, array $xactions) {
|
||||
$context = $this->getContextObject();
|
||||
|
||||
if ($context instanceof PhabricatorDashboard) {
|
||||
$viewer = $this->getViewer();
|
||||
$controller = $this->getController();
|
||||
$request = $controller->getRequest();
|
||||
|
||||
$dashboard = $context;
|
||||
|
||||
$xactions = array();
|
||||
|
||||
$ref_list = clone $dashboard->getPanelRefList();
|
||||
|
||||
$ref_list->newPanelRef($object, $this->getColumnKey());
|
||||
$new_panels = $ref_list->toDictionary();
|
||||
|
||||
$xactions[] = $dashboard->getApplicationTransactionTemplate()
|
||||
->setTransactionType(
|
||||
PhabricatorDashboardPanelsTransaction::TRANSACTIONTYPE)
|
||||
->setNewValue($new_panels);
|
||||
|
||||
$editor = $dashboard->getApplicationTransactionEditor()
|
||||
->setActor($viewer)
|
||||
->setContentSourceFromRequest($request)
|
||||
->setContinueOnNoEffect(true)
|
||||
->setContinueOnMissingFields(true);
|
||||
|
||||
$editor->applyTransactions($dashboard, $xactions);
|
||||
}
|
||||
}
|
||||
|
||||
protected function buildCustomEditFields($object) {
|
||||
return array(
|
||||
$fields = array(
|
||||
id(new PhabricatorTextEditField())
|
||||
->setKey('name')
|
||||
->setLabel(pht('Name'))
|
||||
->setDescription(pht('Name of the panel.'))
|
||||
->setConduitDescription(pht('Rename the panel.'))
|
||||
->setConduitTypeDescription(pht('New panel name.'))
|
||||
->setTransactionType(PhabricatorDashboardPanelTransaction::TYPE_NAME)
|
||||
->setTransactionType(
|
||||
PhabricatorDashboardPanelNameTransaction::TRANSACTIONTYPE)
|
||||
->setIsRequired(true)
|
||||
->setValue($object->getName()),
|
||||
);
|
||||
|
||||
$panel_fields = $object->getEditEngineFields();
|
||||
foreach ($panel_fields as $panel_field) {
|
||||
$fields[] = $panel_field;
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,96 +18,11 @@ final class PhabricatorDashboardPanelTransactionEditor
|
|||
$types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
|
||||
$types[] = PhabricatorTransactions::TYPE_EDGE;
|
||||
|
||||
$types[] = PhabricatorDashboardPanelTransaction::TYPE_NAME;
|
||||
$types[] = PhabricatorDashboardPanelTransaction::TYPE_ARCHIVE;
|
||||
|
||||
return $types;
|
||||
}
|
||||
|
||||
protected function getCustomTransactionOldValue(
|
||||
PhabricatorLiskDAO $object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
switch ($xaction->getTransactionType()) {
|
||||
case PhabricatorDashboardPanelTransaction::TYPE_NAME:
|
||||
if ($this->getIsNewObject()) {
|
||||
return null;
|
||||
protected function supportsSearch() {
|
||||
return true;
|
||||
}
|
||||
return $object->getName();
|
||||
case PhabricatorDashboardPanelTransaction::TYPE_ARCHIVE:
|
||||
return (int)$object->getIsArchived();
|
||||
}
|
||||
|
||||
return parent::getCustomTransactionOldValue($object, $xaction);
|
||||
}
|
||||
|
||||
protected function getCustomTransactionNewValue(
|
||||
PhabricatorLiskDAO $object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
switch ($xaction->getTransactionType()) {
|
||||
case PhabricatorDashboardPanelTransaction::TYPE_NAME:
|
||||
return $xaction->getNewValue();
|
||||
case PhabricatorDashboardPanelTransaction::TYPE_ARCHIVE:
|
||||
return (int)$xaction->getNewValue();
|
||||
}
|
||||
return parent::getCustomTransactionNewValue($object, $xaction);
|
||||
}
|
||||
|
||||
protected function applyCustomInternalTransaction(
|
||||
PhabricatorLiskDAO $object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
switch ($xaction->getTransactionType()) {
|
||||
case PhabricatorDashboardPanelTransaction::TYPE_NAME:
|
||||
$object->setName($xaction->getNewValue());
|
||||
return;
|
||||
case PhabricatorDashboardPanelTransaction::TYPE_ARCHIVE:
|
||||
$object->setIsArchived((int)$xaction->getNewValue());
|
||||
return;
|
||||
}
|
||||
|
||||
return parent::applyCustomInternalTransaction($object, $xaction);
|
||||
}
|
||||
|
||||
protected function applyCustomExternalTransaction(
|
||||
PhabricatorLiskDAO $object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
|
||||
switch ($xaction->getTransactionType()) {
|
||||
case PhabricatorDashboardPanelTransaction::TYPE_NAME:
|
||||
case PhabricatorDashboardPanelTransaction::TYPE_ARCHIVE:
|
||||
return;
|
||||
}
|
||||
|
||||
return parent::applyCustomExternalTransaction($object, $xaction);
|
||||
}
|
||||
|
||||
protected function validateTransaction(
|
||||
PhabricatorLiskDAO $object,
|
||||
$type,
|
||||
array $xactions) {
|
||||
|
||||
$errors = parent::validateTransaction($object, $type, $xactions);
|
||||
|
||||
switch ($type) {
|
||||
case PhabricatorDashboardPanelTransaction::TYPE_NAME:
|
||||
$missing = $this->validateIsEmptyTextField(
|
||||
$object->getName(),
|
||||
$xactions);
|
||||
|
||||
if ($missing) {
|
||||
$error = new PhabricatorApplicationTransactionValidationError(
|
||||
$type,
|
||||
pht('Required'),
|
||||
pht('Panel name is required.'),
|
||||
nonempty(last($xactions), null));
|
||||
|
||||
$error->setIsMissingFieldError(true);
|
||||
$errors[] = $error;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardPortalEditEngine
|
||||
extends PhabricatorEditEngine {
|
||||
|
||||
const ENGINECONST = 'portal';
|
||||
|
||||
public function isEngineConfigurable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getEngineName() {
|
||||
return pht('Portals');
|
||||
}
|
||||
|
||||
public function getSummaryHeader() {
|
||||
return pht('Edit Portals');
|
||||
}
|
||||
|
||||
public function getSummaryText() {
|
||||
return pht('This engine is used to modify portals.');
|
||||
}
|
||||
|
||||
public function getEngineApplicationClass() {
|
||||
return 'PhabricatorDashboardApplication';
|
||||
}
|
||||
|
||||
protected function newEditableObject() {
|
||||
return PhabricatorDashboardPortal::initializeNewPortal();
|
||||
}
|
||||
|
||||
protected function newObjectQuery() {
|
||||
return new PhabricatorDashboardPortalQuery();
|
||||
}
|
||||
|
||||
protected function getObjectCreateTitleText($object) {
|
||||
return pht('Create Portal');
|
||||
}
|
||||
|
||||
protected function getObjectCreateButtonText($object) {
|
||||
return pht('Create Portal');
|
||||
}
|
||||
|
||||
protected function getObjectEditTitleText($object) {
|
||||
return pht('Edit Portal: %s', $object->getName());
|
||||
}
|
||||
|
||||
protected function getObjectEditShortText($object) {
|
||||
return pht('Edit Portal');
|
||||
}
|
||||
|
||||
protected function getObjectCreateShortText() {
|
||||
return pht('Create Portal');
|
||||
}
|
||||
|
||||
protected function getObjectName() {
|
||||
return pht('Portal');
|
||||
}
|
||||
|
||||
protected function getObjectViewURI($object) {
|
||||
if ($this->getIsCreate()) {
|
||||
return $object->getURI();
|
||||
} else {
|
||||
return '/portal/view/'.$object->getID().'/view/manage/';
|
||||
}
|
||||
}
|
||||
|
||||
protected function getEditorURI() {
|
||||
return '/portal/edit/';
|
||||
}
|
||||
|
||||
protected function buildCustomEditFields($object) {
|
||||
return array(
|
||||
id(new PhabricatorTextEditField())
|
||||
->setKey('name')
|
||||
->setLabel(pht('Name'))
|
||||
->setDescription(pht('Name of the portal.'))
|
||||
->setConduitDescription(pht('Rename the portal.'))
|
||||
->setConduitTypeDescription(pht('New portal name.'))
|
||||
->setTransactionType(
|
||||
PhabricatorDashboardPortalNameTransaction::TRANSACTIONTYPE)
|
||||
->setIsRequired(true)
|
||||
->setValue($object->getName()),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardPortalEditor
|
||||
extends PhabricatorApplicationTransactionEditor {
|
||||
|
||||
public function getEditorApplicationClass() {
|
||||
return 'PhabricatorDashboardApplication';
|
||||
}
|
||||
|
||||
public function getEditorObjectsDescription() {
|
||||
return pht('Portals');
|
||||
}
|
||||
|
||||
public function getCreateObjectTitle($author, $object) {
|
||||
return pht('%s created this portal.', $author);
|
||||
}
|
||||
|
||||
public function getCreateObjectTitleForFeed($author, $object) {
|
||||
return pht('%s created %s.', $author, $object);
|
||||
}
|
||||
|
||||
public function getTransactionTypes() {
|
||||
$types = parent::getTransactionTypes();
|
||||
|
||||
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
|
||||
$types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
|
||||
|
||||
return $types;
|
||||
}
|
||||
|
||||
protected function supportsSearch() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -11,38 +11,6 @@ final class PhabricatorDashboardTransactionEditor
|
|||
return pht('Dashboards');
|
||||
}
|
||||
|
||||
public static function addPanelToDashboard(
|
||||
PhabricatorUser $actor,
|
||||
PhabricatorContentSource $content_source,
|
||||
PhabricatorDashboardPanel $panel,
|
||||
PhabricatorDashboard $dashboard,
|
||||
$column) {
|
||||
|
||||
$xactions = array();
|
||||
$xactions[] = id(new PhabricatorDashboardTransaction())
|
||||
->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
|
||||
->setMetadataValue(
|
||||
'edge:type',
|
||||
PhabricatorDashboardDashboardHasPanelEdgeType::EDGECONST)
|
||||
->setNewValue(
|
||||
array(
|
||||
'+' => array(
|
||||
$panel->getPHID() => $panel->getPHID(),
|
||||
),
|
||||
));
|
||||
|
||||
$layout_config = $dashboard->getLayoutConfigObject();
|
||||
$layout_config->setPanelLocation($column, $panel->getPHID());
|
||||
$dashboard->setLayoutConfigFromObject($layout_config);
|
||||
|
||||
$editor = id(new PhabricatorDashboardTransactionEditor())
|
||||
->setActor($actor)
|
||||
->setContentSource($content_source)
|
||||
->setContinueOnMissingFields(true)
|
||||
->setContinueOnNoEffect(true)
|
||||
->applyTransactions($dashboard, $xactions);
|
||||
}
|
||||
|
||||
public function getTransactionTypes() {
|
||||
$types = parent::getTransactionTypes();
|
||||
|
||||
|
@ -50,133 +18,11 @@ final class PhabricatorDashboardTransactionEditor
|
|||
$types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
|
||||
$types[] = PhabricatorTransactions::TYPE_EDGE;
|
||||
|
||||
$types[] = PhabricatorDashboardTransaction::TYPE_NAME;
|
||||
$types[] = PhabricatorDashboardTransaction::TYPE_ICON;
|
||||
$types[] = PhabricatorDashboardTransaction::TYPE_STATUS;
|
||||
$types[] = PhabricatorDashboardTransaction::TYPE_LAYOUT_MODE;
|
||||
|
||||
return $types;
|
||||
}
|
||||
|
||||
protected function getCustomTransactionOldValue(
|
||||
PhabricatorLiskDAO $object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
switch ($xaction->getTransactionType()) {
|
||||
case PhabricatorDashboardTransaction::TYPE_NAME:
|
||||
if ($this->getIsNewObject()) {
|
||||
return null;
|
||||
protected function supportsSearch() {
|
||||
return true;
|
||||
}
|
||||
return $object->getName();
|
||||
case PhabricatorDashboardTransaction::TYPE_ICON:
|
||||
if ($this->getIsNewObject()) {
|
||||
return null;
|
||||
}
|
||||
return $object->getIcon();
|
||||
case PhabricatorDashboardTransaction::TYPE_STATUS:
|
||||
if ($this->getIsNewObject()) {
|
||||
return null;
|
||||
}
|
||||
return $object->getStatus();
|
||||
case PhabricatorDashboardTransaction::TYPE_LAYOUT_MODE:
|
||||
if ($this->getIsNewObject()) {
|
||||
return null;
|
||||
}
|
||||
$layout_config = $object->getLayoutConfigObject();
|
||||
return $layout_config->getLayoutMode();
|
||||
}
|
||||
|
||||
return parent::getCustomTransactionOldValue($object, $xaction);
|
||||
}
|
||||
|
||||
protected function getCustomTransactionNewValue(
|
||||
PhabricatorLiskDAO $object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
switch ($xaction->getTransactionType()) {
|
||||
case PhabricatorDashboardTransaction::TYPE_NAME:
|
||||
case PhabricatorDashboardTransaction::TYPE_ICON:
|
||||
case PhabricatorDashboardTransaction::TYPE_STATUS:
|
||||
case PhabricatorDashboardTransaction::TYPE_LAYOUT_MODE:
|
||||
return $xaction->getNewValue();
|
||||
}
|
||||
return parent::getCustomTransactionNewValue($object, $xaction);
|
||||
}
|
||||
|
||||
protected function applyCustomInternalTransaction(
|
||||
PhabricatorLiskDAO $object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
switch ($xaction->getTransactionType()) {
|
||||
case PhabricatorDashboardTransaction::TYPE_NAME:
|
||||
$object->setName($xaction->getNewValue());
|
||||
return;
|
||||
case PhabricatorDashboardTransaction::TYPE_ICON:
|
||||
$object->setIcon($xaction->getNewValue());
|
||||
return;
|
||||
case PhabricatorDashboardTransaction::TYPE_STATUS:
|
||||
$object->setStatus($xaction->getNewValue());
|
||||
return;
|
||||
case PhabricatorDashboardTransaction::TYPE_LAYOUT_MODE:
|
||||
$old_layout = $object->getLayoutConfigObject();
|
||||
$new_layout = clone $old_layout;
|
||||
$new_layout->setLayoutMode($xaction->getNewValue());
|
||||
if ($old_layout->isMultiColumnLayout() !=
|
||||
$new_layout->isMultiColumnLayout()) {
|
||||
$panel_phids = $object->getPanelPHIDs();
|
||||
$new_locations = $new_layout->getDefaultPanelLocations();
|
||||
foreach ($panel_phids as $panel_phid) {
|
||||
$new_locations[0][] = $panel_phid;
|
||||
}
|
||||
$new_layout->setPanelLocations($new_locations);
|
||||
}
|
||||
$object->setLayoutConfigFromObject($new_layout);
|
||||
return;
|
||||
}
|
||||
|
||||
return parent::applyCustomInternalTransaction($object, $xaction);
|
||||
}
|
||||
|
||||
protected function applyCustomExternalTransaction(
|
||||
PhabricatorLiskDAO $object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
|
||||
switch ($xaction->getTransactionType()) {
|
||||
case PhabricatorDashboardTransaction::TYPE_NAME:
|
||||
case PhabricatorDashboardTransaction::TYPE_ICON:
|
||||
case PhabricatorDashboardTransaction::TYPE_STATUS:
|
||||
case PhabricatorDashboardTransaction::TYPE_LAYOUT_MODE:
|
||||
return;
|
||||
}
|
||||
|
||||
return parent::applyCustomExternalTransaction($object, $xaction);
|
||||
}
|
||||
|
||||
protected function validateTransaction(
|
||||
PhabricatorLiskDAO $object,
|
||||
$type,
|
||||
array $xactions) {
|
||||
|
||||
$errors = parent::validateTransaction($object, $type, $xactions);
|
||||
|
||||
switch ($type) {
|
||||
case PhabricatorDashboardTransaction::TYPE_NAME:
|
||||
$missing = $this->validateIsEmptyTextField(
|
||||
$object->getName(),
|
||||
$xactions);
|
||||
|
||||
if ($missing) {
|
||||
$error = new PhabricatorApplicationTransactionValidationError(
|
||||
$type,
|
||||
pht('Required'),
|
||||
pht('Dashboard name is required.'),
|
||||
nonempty(last($xactions), null));
|
||||
|
||||
$error->setIsMissingFieldError(true);
|
||||
$errors[] = $error;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardFerretEngine
|
||||
extends PhabricatorFerretEngine {
|
||||
|
||||
public function getApplicationName() {
|
||||
return 'dashboard';
|
||||
}
|
||||
|
||||
public function getScopeName() {
|
||||
return 'dashboard';
|
||||
}
|
||||
|
||||
public function newSearchEngine() {
|
||||
return new PhabricatorDashboardSearchEngine();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardFulltextEngine
|
||||
extends PhabricatorFulltextEngine {
|
||||
|
||||
protected function buildAbstractDocument(
|
||||
PhabricatorSearchAbstractDocument $document,
|
||||
$object) {
|
||||
|
||||
$dashboard = $object;
|
||||
|
||||
$document->setDocumentTitle($dashboard->getName());
|
||||
|
||||
$document->addRelationship(
|
||||
$dashboard->isArchived()
|
||||
? PhabricatorSearchRelationship::RELATIONSHIP_CLOSED
|
||||
: PhabricatorSearchRelationship::RELATIONSHIP_OPEN,
|
||||
$dashboard->getPHID(),
|
||||
PhabricatorDashboardDashboardPHIDType::TYPECONST,
|
||||
PhabricatorTime::getNow());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardPanelFerretEngine
|
||||
extends PhabricatorFerretEngine {
|
||||
|
||||
public function getApplicationName() {
|
||||
return 'dashboard';
|
||||
}
|
||||
|
||||
public function getScopeName() {
|
||||
return 'panel';
|
||||
}
|
||||
|
||||
public function newSearchEngine() {
|
||||
return new PhabricatorDashboardPanelSearchEngine();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardPanelFulltextEngine
|
||||
extends PhabricatorFulltextEngine {
|
||||
|
||||
protected function buildAbstractDocument(
|
||||
PhabricatorSearchAbstractDocument $document,
|
||||
$object) {
|
||||
|
||||
$panel = $object;
|
||||
|
||||
$document->setDocumentTitle($panel->getName());
|
||||
|
||||
$document->addRelationship(
|
||||
$panel->getIsArchived()
|
||||
? PhabricatorSearchRelationship::RELATIONSHIP_CLOSED
|
||||
: PhabricatorSearchRelationship::RELATIONSHIP_OPEN,
|
||||
$panel->getPHID(),
|
||||
PhabricatorDashboardPanelPHIDType::TYPECONST,
|
||||
PhabricatorTime::getNow());
|
||||
}
|
||||
|
||||
}
|
|
@ -12,16 +12,28 @@ final class PhabricatorDashboardPanelRenderingEngine extends Phobject {
|
|||
private $enableAsyncRendering;
|
||||
private $parentPanelPHIDs;
|
||||
private $headerMode = self::HEADER_MODE_NORMAL;
|
||||
private $dashboardID;
|
||||
private $movable = true;
|
||||
private $movable;
|
||||
private $panelHandle;
|
||||
private $editMode;
|
||||
private $contextObject;
|
||||
private $panelKey;
|
||||
|
||||
public function setDashboardID($id) {
|
||||
$this->dashboardID = $id;
|
||||
public function setContextObject($object) {
|
||||
$this->contextObject = $object;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDashboardID() {
|
||||
return $this->dashboardID;
|
||||
public function getContextObject() {
|
||||
return $this->contextObject;
|
||||
}
|
||||
|
||||
public function setPanelKey($panel_key) {
|
||||
$this->panelKey = $panel_key;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPanelKey() {
|
||||
return $this->panelKey;
|
||||
}
|
||||
|
||||
public function setHeaderMode($header_mode) {
|
||||
|
@ -33,6 +45,24 @@ final class PhabricatorDashboardPanelRenderingEngine extends Phobject {
|
|||
return $this->headerMode;
|
||||
}
|
||||
|
||||
public function setPanelHandle(PhabricatorObjectHandle $panel_handle) {
|
||||
$this->panelHandle = $panel_handle;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPanelHandle() {
|
||||
return $this->panelHandle;
|
||||
}
|
||||
|
||||
public function isEditMode() {
|
||||
return $this->editMode;
|
||||
}
|
||||
|
||||
public function setEditMode($mode) {
|
||||
$this->editMode = $mode;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow the engine to render the panel via Ajax.
|
||||
*/
|
||||
|
@ -90,11 +120,19 @@ final class PhabricatorDashboardPanelRenderingEngine extends Phobject {
|
|||
$panel = $this->getPanel();
|
||||
|
||||
if (!$panel) {
|
||||
$handle = $this->getPanelHandle();
|
||||
if ($handle->getPolicyFiltered()) {
|
||||
return $this->renderErrorPanel(
|
||||
pht('Missing or Restricted Panel'),
|
||||
pht('Restricted Panel'),
|
||||
pht(
|
||||
'This panel does not exist, or you do not have permission '.
|
||||
'to see it.'));
|
||||
'You do not have permission to see this panel.'));
|
||||
} else {
|
||||
return $this->renderErrorPanel(
|
||||
pht('Invalid Panel'),
|
||||
pht(
|
||||
'This panel is invalid or does not exist. It may have been '.
|
||||
'deleted.'));
|
||||
}
|
||||
}
|
||||
|
||||
$panel_type = $panel->getImplementation();
|
||||
|
@ -144,10 +182,10 @@ final class PhabricatorDashboardPanelRenderingEngine extends Phobject {
|
|||
|
||||
|
||||
private function renderAsyncPanel() {
|
||||
$context_phid = $this->getContextPHID();
|
||||
$panel = $this->getPanel();
|
||||
|
||||
$panel_id = celerity_generate_unique_node_id();
|
||||
$dashboard_id = $this->getDashboardID();
|
||||
|
||||
Javelin::initBehavior(
|
||||
'dashboard-async-panel',
|
||||
|
@ -155,7 +193,9 @@ final class PhabricatorDashboardPanelRenderingEngine extends Phobject {
|
|||
'panelID' => $panel_id,
|
||||
'parentPanelPHIDs' => $this->getParentPanelPHIDs(),
|
||||
'headerMode' => $this->getHeaderMode(),
|
||||
'dashboardID' => $dashboard_id,
|
||||
'contextPHID' => $context_phid,
|
||||
'panelKey' => $this->getPanelKey(),
|
||||
'movable' => $this->getMovable(),
|
||||
'uri' => '/dashboard/panel/render/'.$panel->getID().'/',
|
||||
));
|
||||
|
||||
|
@ -185,12 +225,13 @@ final class PhabricatorDashboardPanelRenderingEngine extends Phobject {
|
|||
->setHeader($title);
|
||||
break;
|
||||
}
|
||||
|
||||
$icon = id(new PHUIIconView())
|
||||
->setIcon('fa-warning red msr');
|
||||
|
||||
$content = id(new PHUIBoxView())
|
||||
->addClass('dashboard-box')
|
||||
->addMargin(PHUI::MARGIN_MEDIUM)
|
||||
->addMargin(PHUI::MARGIN_LARGE)
|
||||
->appendChild($icon)
|
||||
->appendChild($body);
|
||||
|
||||
|
@ -240,11 +281,11 @@ final class PhabricatorDashboardPanelRenderingEngine extends Phobject {
|
|||
if ($panel) {
|
||||
$box->setMetadata(
|
||||
array(
|
||||
'objectPHID' => $panel->getPHID(),
|
||||
'panelKey' => $this->getPanelKey(),
|
||||
));
|
||||
}
|
||||
|
||||
return phutil_tag_div('dashboard-pane', $box);
|
||||
return $box;
|
||||
}
|
||||
|
||||
|
||||
|
@ -256,8 +297,11 @@ final class PhabricatorDashboardPanelRenderingEngine extends Phobject {
|
|||
$header = null;
|
||||
break;
|
||||
case self::HEADER_MODE_EDIT:
|
||||
// In edit mode, include the panel monogram to make managing boards
|
||||
// a little easier.
|
||||
$header_text = pht('%s %s', $panel->getMonogram(), $panel->getName());
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader($panel->getName());
|
||||
->setHeader($header_text);
|
||||
$header = $this->addPanelHeaderActions($header);
|
||||
break;
|
||||
case self::HEADER_MODE_NORMAL:
|
||||
|
@ -277,42 +321,65 @@ final class PhabricatorDashboardPanelRenderingEngine extends Phobject {
|
|||
|
||||
private function addPanelHeaderActions(
|
||||
PHUIHeaderView $header) {
|
||||
$panel = $this->getPanel();
|
||||
|
||||
$dashboard_id = $this->getDashboardID();
|
||||
$viewer = $this->getViewer();
|
||||
$panel = $this->getPanel();
|
||||
$context_phid = $this->getContextPHID();
|
||||
|
||||
$actions = array();
|
||||
|
||||
if ($panel) {
|
||||
$panel_id = $panel->getID();
|
||||
|
||||
$edit_uri = "/dashboard/panel/edit/{$panel_id}/";
|
||||
$edit_uri = new PhutilURI($edit_uri);
|
||||
if ($dashboard_id) {
|
||||
$edit_uri->replaceQueryParam('dashboardID', $dashboard_id);
|
||||
}
|
||||
$params = array(
|
||||
'contextPHID' => $context_phid,
|
||||
);
|
||||
$edit_uri = new PhutilURI($edit_uri, $params);
|
||||
|
||||
$action_edit = id(new PHUIIconView())
|
||||
$actions[] = id(new PhabricatorActionView())
|
||||
->setIcon('fa-pencil')
|
||||
->setWorkflow(true)
|
||||
->setHref((string)$edit_uri);
|
||||
->setName(pht('Edit Panel'))
|
||||
->setHref($edit_uri);
|
||||
|
||||
$header->addActionItem($action_edit);
|
||||
$actions[] = id(new PhabricatorActionView())
|
||||
->setIcon('fa-window-maximize')
|
||||
->setName(pht('View Panel Details'))
|
||||
->setHref($panel->getURI());
|
||||
}
|
||||
|
||||
if ($dashboard_id) {
|
||||
if ($context_phid) {
|
||||
$panel_phid = $this->getPanelPHID();
|
||||
|
||||
$remove_uri = "/dashboard/removepanel/{$dashboard_id}/";
|
||||
$remove_uri = id(new PhutilURI($remove_uri))
|
||||
->replaceQueryParam('panelPHID', $panel_phid);
|
||||
$remove_uri = urisprintf('/dashboard/adjust/remove/');
|
||||
$params = array(
|
||||
'contextPHID' => $context_phid,
|
||||
'panelKey' => $this->getPanelKey(),
|
||||
);
|
||||
$remove_uri = new PhutilURI($remove_uri, $params);
|
||||
|
||||
$action_remove = id(new PHUIIconView())
|
||||
->setIcon('fa-trash-o')
|
||||
->setHref((string)$remove_uri)
|
||||
$actions[] = id(new PhabricatorActionView())
|
||||
->setIcon('fa-times')
|
||||
->setHref($remove_uri)
|
||||
->setName(pht('Remove Panel'))
|
||||
->setWorkflow(true);
|
||||
|
||||
$header->addActionItem($action_remove);
|
||||
}
|
||||
|
||||
$dropdown_menu = id(new PhabricatorActionListView())
|
||||
->setViewer($viewer);
|
||||
|
||||
foreach ($actions as $action) {
|
||||
$dropdown_menu->addAction($action);
|
||||
}
|
||||
|
||||
$action_menu = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setIcon('fa-cog')
|
||||
->setText(pht('Manage Panel'))
|
||||
->setDropdownMenu($dropdown_menu);
|
||||
|
||||
$header->addActionLink($action_menu);
|
||||
|
||||
return $header;
|
||||
}
|
||||
|
||||
|
@ -353,5 +420,14 @@ final class PhabricatorDashboardPanelRenderingEngine extends Phobject {
|
|||
}
|
||||
}
|
||||
|
||||
private function getContextPHID() {
|
||||
$context = $this->getContextObject();
|
||||
|
||||
if ($context) {
|
||||
return $context->getPHID();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardPortalFerretEngine
|
||||
extends PhabricatorFerretEngine {
|
||||
|
||||
public function getApplicationName() {
|
||||
return 'dashboard';
|
||||
}
|
||||
|
||||
public function getScopeName() {
|
||||
return 'portal';
|
||||
}
|
||||
|
||||
public function newSearchEngine() {
|
||||
return new PhabricatorDashboardPortalSearchEngine();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardPortalFulltextEngine
|
||||
extends PhabricatorFulltextEngine {
|
||||
|
||||
protected function buildAbstractDocument(
|
||||
PhabricatorSearchAbstractDocument $document,
|
||||
$object) {
|
||||
|
||||
$portal = $object;
|
||||
|
||||
$document->setDocumentTitle($portal->getName());
|
||||
|
||||
$document->addRelationship(
|
||||
$portal->isArchived()
|
||||
? PhabricatorSearchRelationship::RELATIONSHIP_CLOSED
|
||||
: PhabricatorSearchRelationship::RELATIONSHIP_OPEN,
|
||||
$portal->getPHID(),
|
||||
PhabricatorDashboardPortalPHIDType::TYPECONST,
|
||||
PhabricatorTime::getNow());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardPortalProfileMenuEngine
|
||||
extends PhabricatorProfileMenuEngine {
|
||||
|
||||
protected function isMenuEngineConfigurable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function isMenuEnginePersonalizable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getItemURI($path) {
|
||||
$portal = $this->getProfileObject();
|
||||
|
||||
return $portal->getURI().$path;
|
||||
}
|
||||
|
||||
protected function getBuiltinProfileItems($object) {
|
||||
$items = array();
|
||||
|
||||
$items[] = $this->newDividerItem('tail');
|
||||
|
||||
$items[] = $this->newManageItem();
|
||||
|
||||
$items[] = $this->newItem()
|
||||
->setMenuItemKey(PhabricatorDashboardPortalMenuItem::MENUITEMKEY)
|
||||
->setBuiltinKey('manage')
|
||||
->setIsTailItem(true);
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
protected function newNoMenuItemsView(array $items) {
|
||||
$object = $this->getProfileObject();
|
||||
$builtins = $this->getBuiltinProfileItems($object);
|
||||
|
||||
if (count($items) <= count($builtins)) {
|
||||
return $this->newEmptyView(
|
||||
pht('New Portal'),
|
||||
pht('Use "Edit Menu" to add menu items to this portal.'));
|
||||
} else {
|
||||
return $this->newEmptyValue(
|
||||
pht('No Portal Content'),
|
||||
pht(
|
||||
'None of the visible menu items in this portal can render any '.
|
||||
'content.'));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -11,11 +11,19 @@ final class PhabricatorDashboardRenderingEngine extends Phobject {
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function getViewer() {
|
||||
return $this->viewer;
|
||||
}
|
||||
|
||||
public function setDashboard(PhabricatorDashboard $dashboard) {
|
||||
$this->dashboard = $dashboard;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDashboard() {
|
||||
return $this->dashboard;
|
||||
}
|
||||
|
||||
public function setArrangeMode($mode) {
|
||||
$this->arrangeMode = $mode;
|
||||
return $this;
|
||||
|
@ -23,83 +31,121 @@ final class PhabricatorDashboardRenderingEngine extends Phobject {
|
|||
|
||||
public function renderDashboard() {
|
||||
require_celerity_resource('phabricator-dashboard-css');
|
||||
$dashboard = $this->dashboard;
|
||||
$viewer = $this->viewer;
|
||||
$dashboard = $this->getDashboard();
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$layout_config = $dashboard->getLayoutConfigObject();
|
||||
$panel_grid_locations = $layout_config->getPanelLocations();
|
||||
$panels = mpull($dashboard->getPanels(), null, 'getPHID');
|
||||
$dashboard_id = celerity_generate_unique_node_id();
|
||||
$result = id(new AphrontMultiColumnView())
|
||||
->setID($dashboard_id)
|
||||
->setFluidLayout(true)
|
||||
->setGutter(AphrontMultiColumnView::GUTTER_LARGE);
|
||||
$is_editable = $this->arrangeMode;
|
||||
|
||||
if ($this->arrangeMode) {
|
||||
if ($is_editable) {
|
||||
$h_mode = PhabricatorDashboardPanelRenderingEngine::HEADER_MODE_EDIT;
|
||||
} else {
|
||||
$h_mode = PhabricatorDashboardPanelRenderingEngine::HEADER_MODE_NORMAL;
|
||||
}
|
||||
|
||||
foreach ($panel_grid_locations as $column => $panel_column_locations) {
|
||||
$panel_phids = $panel_column_locations;
|
||||
$panel_phids = $dashboard->getPanelPHIDs();
|
||||
if ($panel_phids) {
|
||||
$panels = id(new PhabricatorDashboardPanelQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs($panel_phids)
|
||||
->execute();
|
||||
$panels = mpull($panels, null, 'getPHID');
|
||||
|
||||
// TODO: This list may contain duplicates when the dashboard itself
|
||||
// does not? Perhaps this is related to T10612. For now, just unique
|
||||
// the list before moving on.
|
||||
$panel_phids = array_unique($panel_phids);
|
||||
$handles = $viewer->loadHandles($panel_phids);
|
||||
} else {
|
||||
$panels = array();
|
||||
$handles = array();
|
||||
}
|
||||
|
||||
$ref_list = $dashboard->getPanelRefList();
|
||||
$columns = $ref_list->getColumns();
|
||||
|
||||
$dashboard_id = celerity_generate_unique_node_id();
|
||||
|
||||
$result = id(new AphrontMultiColumnView())
|
||||
->setID($dashboard_id)
|
||||
->setFluidLayout(true)
|
||||
->setGutter(AphrontMultiColumnView::GUTTER_LARGE);
|
||||
|
||||
foreach ($columns as $column) {
|
||||
$column_views = array();
|
||||
foreach ($column->getPanelRefs() as $panel_ref) {
|
||||
$panel_phid = $panel_ref->getPanelPHID();
|
||||
|
||||
$column_result = array();
|
||||
foreach ($panel_phids as $panel_phid) {
|
||||
$panel_engine = id(new PhabricatorDashboardPanelRenderingEngine())
|
||||
->setViewer($viewer)
|
||||
->setDashboardID($dashboard->getID())
|
||||
->setEnableAsyncRendering(true)
|
||||
->setContextObject($dashboard)
|
||||
->setPanelKey($panel_ref->getPanelKey())
|
||||
->setPanelPHID($panel_phid)
|
||||
->setParentPanelPHIDs(array())
|
||||
->setHeaderMode($h_mode);
|
||||
->setHeaderMode($h_mode)
|
||||
->setEditMode($is_editable)
|
||||
->setMovable(true)
|
||||
->setPanelHandle($handles[$panel_phid]);
|
||||
|
||||
$panel = idx($panels, $panel_phid);
|
||||
if ($panel) {
|
||||
$panel_engine->setPanel($panel);
|
||||
}
|
||||
|
||||
$column_result[] = $panel_engine->renderPanel();
|
||||
}
|
||||
$column_class = $layout_config->getColumnClass(
|
||||
$column,
|
||||
$this->arrangeMode);
|
||||
if ($this->arrangeMode) {
|
||||
$column_result[] = $this->renderAddPanelPlaceHolder($column);
|
||||
$column_result[] = $this->renderAddPanelUI($column);
|
||||
}
|
||||
$result->addColumn(
|
||||
$column_result,
|
||||
$column_class,
|
||||
$sigil = 'dashboard-column',
|
||||
$metadata = array('columnID' => $column));
|
||||
$column_views[] = $panel_engine->renderPanel();
|
||||
}
|
||||
|
||||
if ($this->arrangeMode) {
|
||||
$column_classes = $column->getClasses();
|
||||
|
||||
$column_tail = array();
|
||||
if ($is_editable) {
|
||||
$column_tail[] = $this->renderAddPanelPlaceHolder();
|
||||
$column_tail[] = $this->renderAddPanelUI($column);
|
||||
}
|
||||
|
||||
$sigil = 'dashboard-column';
|
||||
|
||||
$metadata = array(
|
||||
'columnKey' => $column->getColumnKey(),
|
||||
);
|
||||
|
||||
$column_view = javelin_tag(
|
||||
'div',
|
||||
array(
|
||||
'sigil' => $sigil,
|
||||
'meta' => $metadata,
|
||||
),
|
||||
$column_views);
|
||||
|
||||
$result->addColumn(
|
||||
array(
|
||||
$column_view,
|
||||
$column_tail,
|
||||
),
|
||||
implode(' ', $column_classes));
|
||||
}
|
||||
|
||||
if ($is_editable) {
|
||||
$params = array(
|
||||
'contextPHID' => $dashboard->getPHID(),
|
||||
);
|
||||
$move_uri = new PhutilURI('/dashboard/adjust/move/', $params);
|
||||
|
||||
Javelin::initBehavior(
|
||||
'dashboard-move-panels',
|
||||
array(
|
||||
'dashboardID' => $dashboard_id,
|
||||
'moveURI' => '/dashboard/movepanel/'.$dashboard->getID().'/',
|
||||
'dashboardNodeID' => $dashboard_id,
|
||||
'moveURI' => (string)$move_uri,
|
||||
));
|
||||
}
|
||||
|
||||
$view = id(new PHUIBoxView())
|
||||
->addClass('dashboard-view')
|
||||
->appendChild($result);
|
||||
->appendChild(
|
||||
array(
|
||||
$result,
|
||||
));
|
||||
|
||||
return $view;
|
||||
}
|
||||
|
||||
private function renderAddPanelPlaceHolder($column) {
|
||||
$dashboard = $this->dashboard;
|
||||
$panels = $dashboard->getPanels();
|
||||
|
||||
private function renderAddPanelPlaceHolder() {
|
||||
return javelin_tag(
|
||||
'span',
|
||||
array(
|
||||
|
@ -109,19 +155,23 @@ final class PhabricatorDashboardRenderingEngine extends Phobject {
|
|||
pht('This column does not have any panels yet.'));
|
||||
}
|
||||
|
||||
private function renderAddPanelUI($column) {
|
||||
$dashboard_id = $this->dashboard->getID();
|
||||
private function renderAddPanelUI(PhabricatorDashboardColumn $column) {
|
||||
$dashboard = $this->getDashboard();
|
||||
$column_key = $column->getColumnKey();
|
||||
|
||||
$create_uri = id(new PhutilURI('/dashboard/panel/create/'))
|
||||
->replaceQueryParam('dashboardID', $dashboard_id)
|
||||
->replaceQueryParam('column', $column);
|
||||
$create_uri = id(new PhutilURI('/dashboard/panel/edit/'))
|
||||
->replaceQueryParam('contextPHID', $dashboard->getPHID())
|
||||
->replaceQueryParam('columnKey', $column_key);
|
||||
|
||||
$add_uri = id(new PhutilURI('/dashboard/addpanel/'.$dashboard_id.'/'))
|
||||
->replaceQueryParam('column', $column);
|
||||
$add_uri = id(new PhutilURI('/dashboard/adjust/add/'))
|
||||
->replaceQueryParam('contextPHID', $dashboard->getPHID())
|
||||
->replaceQueryParam('columnKey', $column_key);
|
||||
|
||||
$create_button = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setHref($create_uri)
|
||||
->setIcon('fa-plus')
|
||||
->setColor(PHUIButtonView::GREY)
|
||||
->setWorkflow(true)
|
||||
->setText(pht('Create Panel'))
|
||||
->addClass(PHUI::MARGIN_MEDIUM);
|
||||
|
@ -129,6 +179,8 @@ final class PhabricatorDashboardRenderingEngine extends Phobject {
|
|||
$add_button = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setHref($add_uri)
|
||||
->setIcon('fa-window-maximize')
|
||||
->setColor(PHUIButtonView::GREY)
|
||||
->setWorkflow(true)
|
||||
->setText(pht('Add Existing Panel'))
|
||||
->addClass(PHUI::MARGIN_MEDIUM);
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardPanelContainerIndexEngineExtension
|
||||
extends PhabricatorEdgeIndexEngineExtension {
|
||||
|
||||
const EXTENSIONKEY = 'dashboard.panel.container';
|
||||
|
||||
public function getExtensionName() {
|
||||
return pht('Dashboard Panel Containers');
|
||||
}
|
||||
|
||||
public function shouldIndexObject($object) {
|
||||
if (!($object instanceof PhabricatorDashboardPanelContainerInterface)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function getIndexEdgeType() {
|
||||
return PhabricatorObjectUsesDashboardPanelEdgeType::EDGECONST;
|
||||
}
|
||||
|
||||
protected function getIndexDestinationPHIDs($object) {
|
||||
return $object->getDashboardPanelContainerPanelPHIDs();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
|
||||
abstract class PhabricatorDashboardApplicationInstallWorkflow
|
||||
extends PhabricatorDashboardInstallWorkflow {
|
||||
|
||||
abstract protected function newApplication();
|
||||
|
||||
protected function canInstallToGlobalMenu() {
|
||||
return PhabricatorPolicyFilter::hasCapability(
|
||||
$this->getViewer(),
|
||||
$this->newApplication(),
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
}
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $this->getViewer();
|
||||
$application = $this->newApplication();
|
||||
$can_global = $this->canInstallToGlobalMenu();
|
||||
|
||||
switch ($this->getMode()) {
|
||||
case 'global':
|
||||
if (!$can_global) {
|
||||
return $this->newGlobalPermissionDialog();
|
||||
} else if ($request->isFormPost()) {
|
||||
return $this->installDashboard($application, null);
|
||||
} else {
|
||||
return $this->newGlobalConfirmDialog();
|
||||
}
|
||||
case 'personal':
|
||||
if ($request->isFormPost()) {
|
||||
return $this->installDashboard($application, $viewer->getPHID());
|
||||
} else {
|
||||
return $this->newPersonalConfirmDialog();
|
||||
}
|
||||
}
|
||||
|
||||
$global_item = $this->newGlobalMenuItem()
|
||||
->setDisabled(!$can_global);
|
||||
|
||||
$menu = $this->newMenuFromItemMap(
|
||||
array(
|
||||
'personal' => $this->newPersonalMenuItem(),
|
||||
'global' => $global_item,
|
||||
));
|
||||
|
||||
return $this->newApplicationModeDialog()
|
||||
->appendChild($menu);
|
||||
}
|
||||
|
||||
abstract protected function newGlobalPermissionDialog();
|
||||
abstract protected function newGlobalConfirmDialog();
|
||||
abstract protected function newPersonalConfirmDialog();
|
||||
|
||||
abstract protected function newPersonalMenuItem();
|
||||
abstract protected function newGlobalMenuItem();
|
||||
abstract protected function newApplicationModeDialog();
|
||||
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardFavoritesInstallWorkflow
|
||||
extends PhabricatorDashboardApplicationInstallWorkflow {
|
||||
|
||||
const WORKFLOWKEY = 'favorites';
|
||||
|
||||
public function getOrder() {
|
||||
return 4000;
|
||||
}
|
||||
|
||||
protected function newWorkflowMenuItem() {
|
||||
return $this->newMenuItem()
|
||||
->setHeader(pht('Add to Favorites Menu'))
|
||||
->setImageIcon('fa-bookmark')
|
||||
->addAttribute(
|
||||
pht(
|
||||
'Add this dashboard to the favorites menu in the main '.
|
||||
'menu bar.'));
|
||||
}
|
||||
|
||||
protected function newProfileEngine() {
|
||||
return new PhabricatorFavoritesProfileMenuEngine();
|
||||
}
|
||||
|
||||
protected function newApplication() {
|
||||
return new PhabricatorFavoritesApplication();
|
||||
}
|
||||
|
||||
protected function newApplicationModeDialog() {
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Add Dashboard to Favorites Menu'));
|
||||
}
|
||||
|
||||
protected function newPersonalMenuItem() {
|
||||
return $this->newMenuItem()
|
||||
->setHeader(pht('Add to Personal Favorites'))
|
||||
->setImageIcon('fa-user')
|
||||
->addAttribute(
|
||||
pht(
|
||||
'Add this dashboard to your list of personal favorite menu items, '.
|
||||
'visible to only you.'));
|
||||
}
|
||||
|
||||
protected function newGlobalMenuItem() {
|
||||
return $this->newMenuItem()
|
||||
->setHeader(pht('Add to Global Favorites'))
|
||||
->setImageIcon('fa-globe')
|
||||
->addAttribute(
|
||||
pht(
|
||||
'Add this dashboard to the global favorites menu, visible to all '.
|
||||
'users.'));
|
||||
}
|
||||
|
||||
protected function newGlobalPermissionDialog() {
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('No Permission'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'You do not have permission to install items on the global '.
|
||||
'favorites menu.'));
|
||||
}
|
||||
|
||||
protected function newGlobalConfirmDialog() {
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Add Dashboard to Global Favorites'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'Add dashboard %s as a global menu item in the favorites menu?',
|
||||
$this->getDashboardDisplayName()))
|
||||
->addSubmitButton(pht('Add to Favorites'));
|
||||
}
|
||||
|
||||
protected function newPersonalConfirmDialog() {
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Add Dashboard to Personal Favorites'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'Add dashboard %s as a personal menu item in the favorites menu?',
|
||||
$this->getDashboardDisplayName()))
|
||||
->addSubmitButton(pht('Add to Favorites'));
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardHomeInstallWorkflow
|
||||
extends PhabricatorDashboardApplicationInstallWorkflow {
|
||||
|
||||
const WORKFLOWKEY = 'home';
|
||||
|
||||
public function getOrder() {
|
||||
return 1000;
|
||||
}
|
||||
|
||||
protected function newWorkflowMenuItem() {
|
||||
return $this->newMenuItem()
|
||||
->setHeader(pht('Add to Home Page Menu'))
|
||||
->setImageIcon('fa-home')
|
||||
->addAttribute(
|
||||
pht(
|
||||
'Add this dashboard to the menu on the home page.'));
|
||||
}
|
||||
|
||||
protected function newProfileEngine() {
|
||||
return new PhabricatorHomeProfileMenuEngine();
|
||||
}
|
||||
|
||||
protected function newApplication() {
|
||||
return new PhabricatorHomeApplication();
|
||||
}
|
||||
|
||||
protected function newApplicationModeDialog() {
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Add Dashboard to Home Menu'));
|
||||
}
|
||||
|
||||
protected function newPersonalMenuItem() {
|
||||
return $this->newMenuItem()
|
||||
->setHeader(pht('Add to Personal Home Menu'))
|
||||
->setImageIcon('fa-user')
|
||||
->addAttribute(
|
||||
pht(
|
||||
'Add this dashboard to your list of personal home menu items, '.
|
||||
'visible to only you.'));
|
||||
}
|
||||
|
||||
protected function newGlobalMenuItem() {
|
||||
return $this->newMenuItem()
|
||||
->setHeader(pht('Add to Global Home Menu'))
|
||||
->setImageIcon('fa-globe')
|
||||
->addAttribute(
|
||||
pht(
|
||||
'Add this dashboard to the global home menu, visible to all '.
|
||||
'users.'));
|
||||
}
|
||||
|
||||
protected function newGlobalPermissionDialog() {
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('No Permission'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'You do not have permission to install items on the global home '.
|
||||
'menu.'));
|
||||
}
|
||||
|
||||
protected function newGlobalConfirmDialog() {
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Add Dashboard to Global Home Page'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'Add dashboard %s as a global menu item on the home page?',
|
||||
$this->getDashboardDisplayName()))
|
||||
->addSubmitButton(pht('Add to Home'));
|
||||
}
|
||||
|
||||
protected function newPersonalConfirmDialog() {
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Add Dashboard to Personal Home Page'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'Add dashboard %s as a personal menu item on your home page?',
|
||||
$this->getDashboardDisplayName()))
|
||||
->addSubmitButton(pht('Add to Home'));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,143 @@
|
|||
<?php
|
||||
|
||||
abstract class PhabricatorDashboardInstallWorkflow
|
||||
extends Phobject {
|
||||
|
||||
private $request;
|
||||
private $viewer;
|
||||
private $dashboard;
|
||||
private $mode;
|
||||
|
||||
final public function setViewer(PhabricatorUser $viewer) {
|
||||
$this->viewer = $viewer;
|
||||
return $this;
|
||||
}
|
||||
|
||||
final public function getViewer() {
|
||||
return $this->viewer;
|
||||
}
|
||||
|
||||
final public function setDashboard(PhabricatorDashboard $dashboard) {
|
||||
$this->dashboard = $dashboard;
|
||||
return $this;
|
||||
}
|
||||
|
||||
final public function getDashboard() {
|
||||
return $this->dashboard;
|
||||
}
|
||||
|
||||
final public function setMode($mode) {
|
||||
$this->mode = $mode;
|
||||
return $this;
|
||||
}
|
||||
|
||||
final public function getMode() {
|
||||
return $this->mode;
|
||||
}
|
||||
|
||||
final public function setRequest(AphrontRequest $request) {
|
||||
$this->request = $request;
|
||||
return $this;
|
||||
}
|
||||
|
||||
final public function getRequest() {
|
||||
return $this->request;
|
||||
}
|
||||
|
||||
final public function getWorkflowKey() {
|
||||
return $this->getPhobjectClassConstant('WORKFLOWKEY', 32);
|
||||
}
|
||||
|
||||
final public static function getAllWorkflows() {
|
||||
return id(new PhutilClassMapQuery())
|
||||
->setAncestorClass(__CLASS__)
|
||||
->setUniqueMethod('getWorkflowKey')
|
||||
->setSortMethod('getOrder')
|
||||
->execute();
|
||||
}
|
||||
|
||||
final public function getWorkflowMenuItem() {
|
||||
return $this->newWorkflowMenuItem();
|
||||
}
|
||||
|
||||
abstract public function getOrder();
|
||||
abstract protected function newWorkflowMenuItem();
|
||||
|
||||
final protected function newMenuItem() {
|
||||
return id(new PHUIObjectItemView())
|
||||
->setClickable(true);
|
||||
}
|
||||
|
||||
abstract public function handleRequest(AphrontRequest $request);
|
||||
|
||||
final protected function newDialog() {
|
||||
$dashboard = $this->getDashboard();
|
||||
|
||||
return id(new AphrontDialogView())
|
||||
->setViewer($this->getViewer())
|
||||
->setWidth(AphrontDialogView::WIDTH_FORM)
|
||||
->addCancelButton($dashboard->getURI());
|
||||
}
|
||||
|
||||
final protected function newMenuFromItemMap(array $map) {
|
||||
$viewer = $this->getViewer();
|
||||
$dashboard = $this->getDashboard();
|
||||
|
||||
$menu = id(new PHUIObjectItemListView())
|
||||
->setViewer($viewer)
|
||||
->setFlush(true)
|
||||
->setBig(true);
|
||||
|
||||
foreach ($map as $key => $item) {
|
||||
$item->setHref(
|
||||
urisprintf(
|
||||
'/dashboard/install/%d/%s/%s/',
|
||||
$dashboard->getID(),
|
||||
$this->getWorkflowKey(),
|
||||
$key));
|
||||
|
||||
$menu->addItem($item);
|
||||
}
|
||||
|
||||
return $menu;
|
||||
}
|
||||
|
||||
abstract protected function newProfileEngine();
|
||||
|
||||
final protected function installDashboard($profile_object, $custom_phid) {
|
||||
$dashboard = $this->getDashboard();
|
||||
$engine = $this->newProfileEngine()
|
||||
->setProfileObject($profile_object);
|
||||
|
||||
$request = $this->getRequest();
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$config = PhabricatorProfileMenuItemConfiguration::initializeNewItem(
|
||||
$profile_object,
|
||||
new PhabricatorDashboardProfileMenuItem(),
|
||||
$custom_phid);
|
||||
|
||||
$config->setMenuItemProperty('dashboardPHID', $dashboard->getPHID());
|
||||
|
||||
$xactions = array();
|
||||
|
||||
$editor = id(new PhabricatorProfileMenuEditor())
|
||||
->setActor($viewer)
|
||||
->setContinueOnNoEffect(true)
|
||||
->setContinueOnMissingFields(true)
|
||||
->setContentSourceFromRequest($request);
|
||||
|
||||
$editor->applyTransactions($config, $xactions);
|
||||
|
||||
$done_uri = $engine->getItemURI(urisprintf('view/%d/', $config->getID()));
|
||||
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI($done_uri);
|
||||
}
|
||||
|
||||
final protected function getDashboardDisplayName() {
|
||||
$dashboard = $this->getDashboard();
|
||||
return phutil_tag('strong', array(), $dashboard->getName());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
<?php
|
||||
|
||||
abstract class PhabricatorDashboardObjectInstallWorkflow
|
||||
extends PhabricatorDashboardInstallWorkflow {
|
||||
|
||||
abstract protected function newQuery();
|
||||
abstract protected function newConfirmDialog($object);
|
||||
abstract protected function newObjectSelectionForm($object);
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$target_identifier = null;
|
||||
|
||||
$target_tokens = $request->getArr('target');
|
||||
if ($target_tokens) {
|
||||
$target_identifier = head($target_tokens);
|
||||
}
|
||||
|
||||
if (!strlen($target_identifier)) {
|
||||
$target_identifier = $request->getStr('target');
|
||||
}
|
||||
|
||||
if (!strlen($target_identifier)) {
|
||||
$target_identifier = $this->getMode();
|
||||
}
|
||||
|
||||
$target = null;
|
||||
if (strlen($target_identifier)) {
|
||||
$targets = array();
|
||||
|
||||
if (ctype_digit($target_identifier)) {
|
||||
$targets = $this->newQuery()
|
||||
->setViewer($viewer)
|
||||
->withIDs(array((int)$target_identifier))
|
||||
->execute();
|
||||
}
|
||||
|
||||
if (!$targets) {
|
||||
$targets = $this->newQuery()
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($target_identifier))
|
||||
->execute();
|
||||
}
|
||||
|
||||
if ($targets) {
|
||||
$target = head($targets);
|
||||
}
|
||||
}
|
||||
|
||||
if ($target) {
|
||||
$target_phid = $target->getPHID();
|
||||
} else {
|
||||
$target_phid = null;
|
||||
}
|
||||
|
||||
if ($target) {
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$target,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
} else {
|
||||
$can_edit = null;
|
||||
}
|
||||
|
||||
if ($request->isFormPost() && $target && $can_edit) {
|
||||
if ($request->getBool('confirm')) {
|
||||
return $this->installDashboard($target, null);
|
||||
} else {
|
||||
return $this->newConfirmDialog($target)
|
||||
->addHiddenInput('confirm', 1)
|
||||
->addHiddenInput('target', $target_phid);
|
||||
}
|
||||
}
|
||||
|
||||
$errors = array();
|
||||
if (strlen($target_identifier)) {
|
||||
if (!$target) {
|
||||
$errors[] = pht('Choose a valid object.');
|
||||
} else if (!$can_edit) {
|
||||
$errors[] = pht(
|
||||
'You do not have permission to edit the selected object. '.
|
||||
'You can only install dashboards on objects you can edit.');
|
||||
}
|
||||
} else if ($request->getBool('pick')) {
|
||||
$errors[] = pht(
|
||||
'Choose an object to install this dashboard on.');
|
||||
}
|
||||
|
||||
$form = $this->newObjectSelectionForm($target)
|
||||
->addHiddenInput('pick', 1);
|
||||
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Add Dashboard to Project Menu'))
|
||||
->setErrors($errors)
|
||||
->appendForm($form)
|
||||
->addSubmitButton(pht('Continue'));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardPortalInstallWorkflow
|
||||
extends PhabricatorDashboardObjectInstallWorkflow {
|
||||
|
||||
const WORKFLOWKEY = 'portal';
|
||||
|
||||
public function getOrder() {
|
||||
return 2000;
|
||||
}
|
||||
|
||||
protected function newWorkflowMenuItem() {
|
||||
return $this->newMenuItem()
|
||||
->setHeader(pht('Add to Portal Menu'))
|
||||
->setImageIcon('fa-compass')
|
||||
->addAttribute(
|
||||
pht('Add this dashboard to the menu on a portal.'));
|
||||
}
|
||||
|
||||
protected function newProfileEngine() {
|
||||
return new PhabricatorDashboardPortalProfileMenuEngine();
|
||||
}
|
||||
|
||||
protected function newQuery() {
|
||||
return new PhabricatorDashboardPortalQuery();
|
||||
}
|
||||
|
||||
protected function newConfirmDialog($object) {
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Add Dashboard to Portal Menu'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'Add the dashboard %s to portal %s?',
|
||||
$this->getDashboardDisplayName(),
|
||||
phutil_tag('strong', array(), $object->getName())))
|
||||
->addSubmitButton(pht('Add to Portal'));
|
||||
}
|
||||
protected function newObjectSelectionForm($object) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
if ($object) {
|
||||
$tokenizer_value = array($object->getPHID());
|
||||
} else {
|
||||
$tokenizer_value = array();
|
||||
}
|
||||
|
||||
return id(new AphrontFormView())
|
||||
->setViewer($viewer)
|
||||
->appendInstructions(
|
||||
pht(
|
||||
'Select which portal you want to add the dashboard %s to.',
|
||||
$this->getDashboardDisplayName()))
|
||||
->appendControl(
|
||||
id(new AphrontFormTokenizerControl())
|
||||
->setName('target')
|
||||
->setLimit(1)
|
||||
->setLabel(pht('Add to Portal'))
|
||||
->setValue($tokenizer_value)
|
||||
->setDatasource(new PhabricatorDashboardPortalDatasource()));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardProjectInstallWorkflow
|
||||
extends PhabricatorDashboardObjectInstallWorkflow {
|
||||
|
||||
const WORKFLOWKEY = 'project';
|
||||
|
||||
public function getOrder() {
|
||||
return 3000;
|
||||
}
|
||||
|
||||
protected function newWorkflowMenuItem() {
|
||||
return $this->newMenuItem()
|
||||
->setHeader(pht('Add to Project Menu'))
|
||||
->setImageIcon('fa-briefcase')
|
||||
->addAttribute(
|
||||
pht('Add this dashboard to the menu for a project.'));
|
||||
}
|
||||
|
||||
protected function newProfileEngine() {
|
||||
return new PhabricatorProjectProfileMenuEngine();
|
||||
}
|
||||
|
||||
protected function newQuery() {
|
||||
return new PhabricatorProjectQuery();
|
||||
}
|
||||
|
||||
protected function newConfirmDialog($object) {
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Add Dashboard to Project Menu'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'Add the dashboard %s to the menu for project %s?',
|
||||
$this->getDashboardDisplayName(),
|
||||
phutil_tag('strong', array(), $object->getName())))
|
||||
->addSubmitButton(pht('Add to Project'));
|
||||
}
|
||||
|
||||
protected function newObjectSelectionForm($object) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
if ($object) {
|
||||
$tokenizer_value = array($object->getPHID());
|
||||
} else {
|
||||
$tokenizer_value = array();
|
||||
}
|
||||
|
||||
return id(new AphrontFormView())
|
||||
->setViewer($viewer)
|
||||
->appendInstructions(
|
||||
pht(
|
||||
'Select which project menu you want to add the dashboard %s to.',
|
||||
$this->getDashboardDisplayName()))
|
||||
->appendControl(
|
||||
id(new AphrontFormTokenizerControl())
|
||||
->setName('target')
|
||||
->setLimit(1)
|
||||
->setLabel(pht('Add to Project'))
|
||||
->setValue($tokenizer_value)
|
||||
->setDatasource(new PhabricatorProjectDatasource()));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
interface PhabricatorDashboardPanelContainerInterface {
|
||||
|
||||
/**
|
||||
* Return a list of Dashboard Panel PHIDs used by this container.
|
||||
*
|
||||
* @return list<phid>
|
||||
*/
|
||||
public function getDashboardPanelContainerPanelPHIDs();
|
||||
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardColumn
|
||||
extends Phobject {
|
||||
|
||||
private $columnKey;
|
||||
private $classes = array();
|
||||
private $refs = array();
|
||||
|
||||
public function setColumnKey($column_key) {
|
||||
$this->columnKey = $column_key;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getColumnKey() {
|
||||
return $this->columnKey;
|
||||
}
|
||||
|
||||
public function addClass($class) {
|
||||
$this->classes[] = $class;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getClasses() {
|
||||
return $this->classes;
|
||||
}
|
||||
|
||||
public function setPanelRefs(array $refs) {
|
||||
assert_instances_of($refs, 'PhabricatorDashboardPanelRef');
|
||||
$this->refs = $refs;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addPanelRef(PhabricatorDashboardPanelRef $ref) {
|
||||
$this->refs[] = $ref;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPanelRefs() {
|
||||
return $this->refs;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardFullLayoutMode
|
||||
extends PhabricatorDashboardLayoutMode {
|
||||
|
||||
const LAYOUTMODE = 'layout-mode-full';
|
||||
|
||||
public function getLayoutModeOrder() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function getLayoutModeName() {
|
||||
return pht('One Column: 100%%');
|
||||
}
|
||||
|
||||
public function getLayoutModeColumns() {
|
||||
return array(
|
||||
$this->newColumn()
|
||||
->setColumnKey('main'),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue