mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-03 20:22:46 +01:00
(stable) Promote 2017 Week 3
This commit is contained in:
commit
307b166207
93 changed files with 1833 additions and 1878 deletions
|
@ -9,8 +9,8 @@ return array(
|
|||
'names' => array(
|
||||
'conpherence.pkg.css' => '0b64e988',
|
||||
'conpherence.pkg.js' => '6249a1cf',
|
||||
'core.pkg.css' => '9c725fa0',
|
||||
'core.pkg.js' => 'a2ead3fe',
|
||||
'core.pkg.css' => 'e75e4f9d',
|
||||
'core.pkg.js' => '2291d3b2',
|
||||
'darkconsole.pkg.js' => 'e7393ebb',
|
||||
'differential.pkg.css' => '9535a7e6',
|
||||
'differential.pkg.js' => 'ddfeb49b',
|
||||
|
@ -21,7 +21,7 @@ return array(
|
|||
'maniphest.pkg.js' => '5ab2753f',
|
||||
'rsrc/css/aphront/aphront-bars.css' => '231ac33c',
|
||||
'rsrc/css/aphront/dark-console.css' => 'f54bf286',
|
||||
'rsrc/css/aphront/dialog-view.css' => '938f52c5',
|
||||
'rsrc/css/aphront/dialog-view.css' => '5e5aa60b',
|
||||
'rsrc/css/aphront/list-filter-view.css' => '5d6f0526',
|
||||
'rsrc/css/aphront/multi-column.css' => '84cc6640',
|
||||
'rsrc/css/aphront/notification.css' => '3f6c89c9',
|
||||
|
@ -34,8 +34,8 @@ return array(
|
|||
'rsrc/css/aphront/typeahead.css' => 'd4f16145',
|
||||
'rsrc/css/application/almanac/almanac.css' => 'dbb9b3af',
|
||||
'rsrc/css/application/auth/auth.css' => '0877ed6e',
|
||||
'rsrc/css/application/base/main-menu-view.css' => 'f03e17be',
|
||||
'rsrc/css/application/base/notification-menu.css' => '1e055865',
|
||||
'rsrc/css/application/base/main-menu-view.css' => '8eac4166',
|
||||
'rsrc/css/application/base/notification-menu.css' => '6a697e43',
|
||||
'rsrc/css/application/base/phabricator-application-launch-view.css' => '95351601',
|
||||
'rsrc/css/application/base/phui-theme.css' => '798c69b8',
|
||||
'rsrc/css/application/base/standard-page-view.css' => '894d8a25',
|
||||
|
@ -96,7 +96,7 @@ return array(
|
|||
'rsrc/css/application/policy/policy-transaction-detail.css' => '82100a43',
|
||||
'rsrc/css/application/policy/policy.css' => '957ea14c',
|
||||
'rsrc/css/application/ponder/ponder-view.css' => 'fbd45f96',
|
||||
'rsrc/css/application/project/project-card-view.css' => '9418c97d',
|
||||
'rsrc/css/application/project/project-card-view.css' => 'd27c67ae',
|
||||
'rsrc/css/application/project/project-view.css' => '1e6f7072',
|
||||
'rsrc/css/application/releeph/releeph-core.css' => '9b3c5733',
|
||||
'rsrc/css/application/releeph/releeph-preview-branch.css' => 'b7a6f4a5',
|
||||
|
@ -108,7 +108,7 @@ return array(
|
|||
'rsrc/css/application/tokens/tokens.css' => '3d0f239e',
|
||||
'rsrc/css/application/uiexample/example.css' => '528b19de',
|
||||
'rsrc/css/core/core.css' => 'd0801452',
|
||||
'rsrc/css/core/remarkup.css' => 'aebc1180',
|
||||
'rsrc/css/core/remarkup.css' => '4a2de2bb',
|
||||
'rsrc/css/core/syntax.css' => '769d3498',
|
||||
'rsrc/css/core/z-index.css' => '5e72c4e0',
|
||||
'rsrc/css/diviner/diviner-shared.css' => 'aa3656aa',
|
||||
|
@ -128,29 +128,29 @@ return array(
|
|||
'rsrc/css/phui/object-item/phui-oi-flush-ui.css' => '9d9685d6',
|
||||
'rsrc/css/phui/object-item/phui-oi-list-view.css' => 'bff632a4',
|
||||
'rsrc/css/phui/object-item/phui-oi-simple-ui.css' => 'a8beebea',
|
||||
'rsrc/css/phui/phui-action-list.css' => 'e1d48300',
|
||||
'rsrc/css/phui/phui-action-list.css' => '5679229f',
|
||||
'rsrc/css/phui/phui-action-panel.css' => '91c7b835',
|
||||
'rsrc/css/phui/phui-badge.css' => '3baef8db',
|
||||
'rsrc/css/phui/phui-basic-nav-view.css' => '7093573b',
|
||||
'rsrc/css/phui/phui-big-info-view.css' => 'bd903741',
|
||||
'rsrc/css/phui/phui-box.css' => '33b629f8',
|
||||
'rsrc/css/phui/phui-button.css' => '43f4912e',
|
||||
'rsrc/css/phui/phui-button.css' => '9718cb0c',
|
||||
'rsrc/css/phui/phui-chart.css' => '6bf6f78e',
|
||||
'rsrc/css/phui/phui-cms.css' => 'be43c8a8',
|
||||
'rsrc/css/phui/phui-comment-form.css' => '48fbd65d',
|
||||
'rsrc/css/phui/phui-comment-panel.css' => 'f50152ad',
|
||||
'rsrc/css/phui/phui-crumbs-view.css' => 'f82868f2',
|
||||
'rsrc/css/phui/phui-curtain-view.css' => '947bf1a4',
|
||||
'rsrc/css/phui/phui-document-pro.css' => 'c354e312',
|
||||
'rsrc/css/phui/phui-document-pro.css' => 'f56738ed',
|
||||
'rsrc/css/phui/phui-document-summary.css' => '9ca48bdf',
|
||||
'rsrc/css/phui/phui-document.css' => 'c32e8dec',
|
||||
'rsrc/css/phui/phui-feed-story.css' => '44a9c8e9',
|
||||
'rsrc/css/phui/phui-fontkit.css' => '9cda225e',
|
||||
'rsrc/css/phui/phui-form-view.css' => '04cc4771',
|
||||
'rsrc/css/phui/phui-form-view.css' => 'adca31ce',
|
||||
'rsrc/css/phui/phui-form.css' => '2342b0e5',
|
||||
'rsrc/css/phui/phui-head-thing.css' => 'fd311e5f',
|
||||
'rsrc/css/phui/phui-header-view.css' => '6ec8f155',
|
||||
'rsrc/css/phui/phui-hovercard.css' => 'de1a2119',
|
||||
'rsrc/css/phui/phui-hovercard.css' => 'e904f5dc',
|
||||
'rsrc/css/phui/phui-icon-set-selector.css' => '1ab67aad',
|
||||
'rsrc/css/phui/phui-icon.css' => '09f46dd9',
|
||||
'rsrc/css/phui/phui-image-mask.css' => 'a8498f9c',
|
||||
|
@ -162,7 +162,7 @@ return array(
|
|||
'rsrc/css/phui/phui-object-box.css' => '6b487c57',
|
||||
'rsrc/css/phui/phui-pager.css' => 'bea33d23',
|
||||
'rsrc/css/phui/phui-pinboard-view.css' => '2495140e',
|
||||
'rsrc/css/phui/phui-profile-menu.css' => '4768721a',
|
||||
'rsrc/css/phui/phui-profile-menu.css' => 'c71ecdcd',
|
||||
'rsrc/css/phui/phui-property-list-view.css' => '6d8e58ac',
|
||||
'rsrc/css/phui/phui-remarkup-preview.css' => '1a8f2591',
|
||||
'rsrc/css/phui/phui-segment-bar-view.css' => '46342871',
|
||||
|
@ -170,10 +170,10 @@ return array(
|
|||
'rsrc/css/phui/phui-status.css' => 'd5263e49',
|
||||
'rsrc/css/phui/phui-tag-view.css' => '84d65f26',
|
||||
'rsrc/css/phui/phui-timeline-view.css' => 'bc523970',
|
||||
'rsrc/css/phui/phui-two-column-view.css' => '7babf5b9',
|
||||
'rsrc/css/phui/phui-two-column-view.css' => 'a0d3858a',
|
||||
'rsrc/css/phui/workboards/phui-workboard-color.css' => 'b60ef38a',
|
||||
'rsrc/css/phui/workboards/phui-workboard.css' => '16441d5e',
|
||||
'rsrc/css/phui/workboards/phui-workcard.css' => '00979e40',
|
||||
'rsrc/css/phui/workboards/phui-workboard.css' => 'c88912ee',
|
||||
'rsrc/css/phui/workboards/phui-workcard.css' => 'cca5fa92',
|
||||
'rsrc/css/phui/workboards/phui-workpanel.css' => 'a3a63478',
|
||||
'rsrc/css/sprite-login.css' => '587d92d7',
|
||||
'rsrc/css/sprite-tokens.css' => '9cdfd599',
|
||||
|
@ -374,7 +374,7 @@ return array(
|
|||
'rsrc/image/texture/table_header_hover.png' => '038ec3b9',
|
||||
'rsrc/image/texture/table_header_tall.png' => 'd56b434f',
|
||||
'rsrc/js/application/aphlict/Aphlict.js' => '5359e785',
|
||||
'rsrc/js/application/aphlict/behavior-aphlict-dropdown.js' => '2a171a9d',
|
||||
'rsrc/js/application/aphlict/behavior-aphlict-dropdown.js' => 'caade6f2',
|
||||
'rsrc/js/application/aphlict/behavior-aphlict-listen.js' => 'fb20ac8d',
|
||||
'rsrc/js/application/aphlict/behavior-aphlict-status.js' => '5e2634b9',
|
||||
'rsrc/js/application/aphlict/behavior-desktop-notifications-control.js' => 'edd1ba66',
|
||||
|
@ -443,7 +443,7 @@ return array(
|
|||
'rsrc/js/application/projects/WorkboardCard.js' => 'c587b80f',
|
||||
'rsrc/js/application/projects/WorkboardColumn.js' => '21df4ff5',
|
||||
'rsrc/js/application/projects/WorkboardController.js' => '55baf5ed',
|
||||
'rsrc/js/application/projects/behavior-project-boards.js' => '14a1faae',
|
||||
'rsrc/js/application/projects/behavior-project-boards.js' => '93ae974f',
|
||||
'rsrc/js/application/projects/behavior-project-create.js' => '065227cc',
|
||||
'rsrc/js/application/projects/behavior-reorder-columns.js' => 'e1d25dfb',
|
||||
'rsrc/js/application/releeph/releeph-preview-branch.js' => 'b2b4fbaf',
|
||||
|
@ -453,7 +453,7 @@ return array(
|
|||
'rsrc/js/application/search/behavior-reorder-profile-menu-items.js' => 'e2e0a072',
|
||||
'rsrc/js/application/search/behavior-reorder-queries.js' => 'e9581f08',
|
||||
'rsrc/js/application/slowvote/behavior-slowvote-embed.js' => '887ad43f',
|
||||
'rsrc/js/application/transactions/behavior-comment-actions.js' => 'b52947eb',
|
||||
'rsrc/js/application/transactions/behavior-comment-actions.js' => '9a6dd75c',
|
||||
'rsrc/js/application/transactions/behavior-reorder-configs.js' => 'd7a74243',
|
||||
'rsrc/js/application/transactions/behavior-reorder-fields.js' => 'b59e1e96',
|
||||
'rsrc/js/application/transactions/behavior-show-older-transactions.js' => '94c65b72',
|
||||
|
@ -530,18 +530,18 @@ return array(
|
|||
'rsrc/js/core/behavior-toggle-class.js' => '92b9ec77',
|
||||
'rsrc/js/core/behavior-tokenizer.js' => 'b3a4b884',
|
||||
'rsrc/js/core/behavior-tooltip.js' => '42fcb747',
|
||||
'rsrc/js/core/behavior-user-menu.js' => '31420f77',
|
||||
'rsrc/js/core/behavior-watch-anchor.js' => '9f36c42d',
|
||||
'rsrc/js/core/behavior-workflow.js' => '0a3f3021',
|
||||
'rsrc/js/core/phtize.js' => 'd254d646',
|
||||
'rsrc/js/phui/behavior-phui-dropdown-menu.js' => '1aa4c968',
|
||||
'rsrc/js/phui/behavior-phui-dropdown-menu.js' => 'b95d6f7d',
|
||||
'rsrc/js/phui/behavior-phui-file-upload.js' => 'b003d4fb',
|
||||
'rsrc/js/phui/behavior-phui-profile-menu.js' => '12884df9',
|
||||
'rsrc/js/phui/behavior-phui-submenu.js' => 'a6f7a73b',
|
||||
'rsrc/js/phui/behavior-phui-tab-group.js' => '0a0b10e9',
|
||||
'rsrc/js/phuix/PHUIXActionListView.js' => 'b5c256b8',
|
||||
'rsrc/js/phuix/PHUIXActionView.js' => '8cf6d262',
|
||||
'rsrc/js/phuix/PHUIXActionView.js' => 'b3465b9b',
|
||||
'rsrc/js/phuix/PHUIXAutocomplete.js' => '6d86ce8b',
|
||||
'rsrc/js/phuix/PHUIXDropdownMenu.js' => '82e270da',
|
||||
'rsrc/js/phuix/PHUIXDropdownMenu.js' => '8018ee50',
|
||||
'rsrc/js/phuix/PHUIXFormControl.js' => 'bbece68d',
|
||||
'rsrc/js/phuix/PHUIXIconView.js' => 'bff6884b',
|
||||
),
|
||||
|
@ -549,7 +549,7 @@ return array(
|
|||
'almanac-css' => 'dbb9b3af',
|
||||
'aphront-bars' => '231ac33c',
|
||||
'aphront-dark-console-css' => 'f54bf286',
|
||||
'aphront-dialog-view-css' => '938f52c5',
|
||||
'aphront-dialog-view-css' => '5e5aa60b',
|
||||
'aphront-list-filter-view-css' => '5d6f0526',
|
||||
'aphront-multi-column-view-css' => '84cc6640',
|
||||
'aphront-panel-view-css' => '8427b78d',
|
||||
|
@ -596,7 +596,7 @@ return array(
|
|||
'inline-comment-summary-css' => '51efda3a',
|
||||
'javelin-aphlict' => '5359e785',
|
||||
'javelin-behavior' => '61cbc29a',
|
||||
'javelin-behavior-aphlict-dropdown' => '2a171a9d',
|
||||
'javelin-behavior-aphlict-dropdown' => 'caade6f2',
|
||||
'javelin-behavior-aphlict-listen' => 'fb20ac8d',
|
||||
'javelin-behavior-aphlict-status' => '5e2634b9',
|
||||
'javelin-behavior-aphront-basic-tokenizer' => 'b3a4b884',
|
||||
|
@ -609,7 +609,7 @@ return array(
|
|||
'javelin-behavior-bulk-job-reload' => 'edf8a145',
|
||||
'javelin-behavior-calendar-month-view' => 'fe33e256',
|
||||
'javelin-behavior-choose-control' => '327a00d1',
|
||||
'javelin-behavior-comment-actions' => 'b52947eb',
|
||||
'javelin-behavior-comment-actions' => '9a6dd75c',
|
||||
'javelin-behavior-config-reorder-fields' => 'b6993408',
|
||||
'javelin-behavior-conpherence-menu' => '7524fcfa',
|
||||
'javelin-behavior-conpherence-participant-pane' => '8604caa8',
|
||||
|
@ -687,15 +687,14 @@ return array(
|
|||
'javelin-behavior-phabricator-watch-anchor' => '9f36c42d',
|
||||
'javelin-behavior-pholio-mock-edit' => 'bee502c8',
|
||||
'javelin-behavior-pholio-mock-view' => 'fbe497e7',
|
||||
'javelin-behavior-phui-dropdown-menu' => '1aa4c968',
|
||||
'javelin-behavior-phui-dropdown-menu' => 'b95d6f7d',
|
||||
'javelin-behavior-phui-file-upload' => 'b003d4fb',
|
||||
'javelin-behavior-phui-hovercards' => 'bcaccd64',
|
||||
'javelin-behavior-phui-profile-menu' => '12884df9',
|
||||
'javelin-behavior-phui-submenu' => 'a6f7a73b',
|
||||
'javelin-behavior-phui-tab-group' => '0a0b10e9',
|
||||
'javelin-behavior-policy-control' => 'd0c516d5',
|
||||
'javelin-behavior-policy-rule-editor' => '5e9f347c',
|
||||
'javelin-behavior-project-boards' => '14a1faae',
|
||||
'javelin-behavior-project-boards' => '93ae974f',
|
||||
'javelin-behavior-project-create' => '065227cc',
|
||||
'javelin-behavior-quicksand-blacklist' => '7927a7d3',
|
||||
'javelin-behavior-read-only-warning' => 'ba158207',
|
||||
|
@ -721,6 +720,7 @@ return array(
|
|||
'javelin-behavior-toggle-widget' => '3dbf94d5',
|
||||
'javelin-behavior-typeahead-browse' => '635de1ec',
|
||||
'javelin-behavior-typeahead-search' => '93d0c9e3',
|
||||
'javelin-behavior-user-menu' => '31420f77',
|
||||
'javelin-behavior-view-placeholder' => '47830651',
|
||||
'javelin-behavior-workflow' => '0a3f3021',
|
||||
'javelin-color' => '7e41274a',
|
||||
|
@ -780,7 +780,7 @@ return array(
|
|||
'paste-css' => '1898e534',
|
||||
'path-typeahead' => 'f7fc67ec',
|
||||
'people-profile-css' => '2473d929',
|
||||
'phabricator-action-list-view-css' => 'e1d48300',
|
||||
'phabricator-action-list-view-css' => '5679229f',
|
||||
'phabricator-application-launch-view-css' => '95351601',
|
||||
'phabricator-busy' => '59a7976a',
|
||||
'phabricator-chatlog-css' => 'd295b020',
|
||||
|
@ -798,15 +798,15 @@ return array(
|
|||
'phabricator-flag-css' => 'bba8f811',
|
||||
'phabricator-keyboard-shortcut' => '1ae869f2',
|
||||
'phabricator-keyboard-shortcut-manager' => '4a021c10',
|
||||
'phabricator-main-menu-view' => 'f03e17be',
|
||||
'phabricator-main-menu-view' => '8eac4166',
|
||||
'phabricator-nav-view-css' => 'b29426e9',
|
||||
'phabricator-notification' => 'ccf1cbf8',
|
||||
'phabricator-notification-css' => '3f6c89c9',
|
||||
'phabricator-notification-menu-css' => '1e055865',
|
||||
'phabricator-notification-menu-css' => '6a697e43',
|
||||
'phabricator-object-selector-css' => '85ee8ce6',
|
||||
'phabricator-phtize' => 'd254d646',
|
||||
'phabricator-prefab' => '8d40ae75',
|
||||
'phabricator-remarkup-css' => 'aebc1180',
|
||||
'phabricator-remarkup-css' => '4a2de2bb',
|
||||
'phabricator-search-results-css' => '64ad079a',
|
||||
'phabricator-shaped-request' => '7cbe244b',
|
||||
'phabricator-slowvote-css' => 'a94b7230',
|
||||
|
@ -842,7 +842,7 @@ return array(
|
|||
'phui-basic-nav-view-css' => '7093573b',
|
||||
'phui-big-info-view-css' => 'bd903741',
|
||||
'phui-box-css' => '33b629f8',
|
||||
'phui-button-css' => '43f4912e',
|
||||
'phui-button-css' => '9718cb0c',
|
||||
'phui-calendar-css' => '477acfaa',
|
||||
'phui-calendar-day-css' => '572b1893',
|
||||
'phui-calendar-list-css' => 'fcc9fb41',
|
||||
|
@ -855,16 +855,16 @@ return array(
|
|||
'phui-curtain-view-css' => '947bf1a4',
|
||||
'phui-document-summary-view-css' => '9ca48bdf',
|
||||
'phui-document-view-css' => 'c32e8dec',
|
||||
'phui-document-view-pro-css' => 'c354e312',
|
||||
'phui-document-view-pro-css' => 'f56738ed',
|
||||
'phui-feed-story-css' => '44a9c8e9',
|
||||
'phui-font-icon-base-css' => '870a7360',
|
||||
'phui-fontkit-css' => '9cda225e',
|
||||
'phui-form-css' => '2342b0e5',
|
||||
'phui-form-view-css' => '04cc4771',
|
||||
'phui-form-view-css' => 'adca31ce',
|
||||
'phui-head-thing-view-css' => 'fd311e5f',
|
||||
'phui-header-view-css' => '6ec8f155',
|
||||
'phui-hovercard' => '1bd28176',
|
||||
'phui-hovercard-view-css' => 'de1a2119',
|
||||
'phui-hovercard-view-css' => 'e904f5dc',
|
||||
'phui-icon-set-selector-css' => '1ab67aad',
|
||||
'phui-icon-view-css' => '09f46dd9',
|
||||
'phui-image-mask-css' => 'a8498f9c',
|
||||
|
@ -883,7 +883,7 @@ return array(
|
|||
'phui-oi-simple-ui-css' => 'a8beebea',
|
||||
'phui-pager-css' => 'bea33d23',
|
||||
'phui-pinboard-view-css' => '2495140e',
|
||||
'phui-profile-menu-css' => '4768721a',
|
||||
'phui-profile-menu-css' => 'c71ecdcd',
|
||||
'phui-property-list-view-css' => '6d8e58ac',
|
||||
'phui-remarkup-preview-css' => '1a8f2591',
|
||||
'phui-segment-bar-view-css' => '46342871',
|
||||
|
@ -892,22 +892,22 @@ return array(
|
|||
'phui-tag-view-css' => '84d65f26',
|
||||
'phui-theme-css' => '798c69b8',
|
||||
'phui-timeline-view-css' => 'bc523970',
|
||||
'phui-two-column-view-css' => '7babf5b9',
|
||||
'phui-two-column-view-css' => 'a0d3858a',
|
||||
'phui-workboard-color-css' => 'b60ef38a',
|
||||
'phui-workboard-view-css' => '16441d5e',
|
||||
'phui-workcard-view-css' => '00979e40',
|
||||
'phui-workboard-view-css' => 'c88912ee',
|
||||
'phui-workcard-view-css' => 'cca5fa92',
|
||||
'phui-workpanel-view-css' => 'a3a63478',
|
||||
'phuix-action-list-view' => 'b5c256b8',
|
||||
'phuix-action-view' => '8cf6d262',
|
||||
'phuix-action-view' => 'b3465b9b',
|
||||
'phuix-autocomplete' => '6d86ce8b',
|
||||
'phuix-dropdown-menu' => '82e270da',
|
||||
'phuix-dropdown-menu' => '8018ee50',
|
||||
'phuix-form-control-view' => 'bbece68d',
|
||||
'phuix-icon-view' => 'bff6884b',
|
||||
'policy-css' => '957ea14c',
|
||||
'policy-edit-css' => '815c66f7',
|
||||
'policy-transaction-detail-css' => '82100a43',
|
||||
'ponder-view-css' => 'fbd45f96',
|
||||
'project-card-view-css' => '9418c97d',
|
||||
'project-card-view-css' => 'd27c67ae',
|
||||
'project-view-css' => '1e6f7072',
|
||||
'releeph-core' => '9b3c5733',
|
||||
'releeph-preview-branch' => 'b7a6f4a5',
|
||||
|
@ -1030,11 +1030,6 @@ return array(
|
|||
'javelin-dom',
|
||||
'javelin-typeahead-normalizer',
|
||||
),
|
||||
'12884df9' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-stratcom',
|
||||
'javelin-dom',
|
||||
),
|
||||
'13c739ea' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-stratcom',
|
||||
|
@ -1049,27 +1044,12 @@ return array(
|
|||
'javelin-dom',
|
||||
'javelin-history',
|
||||
),
|
||||
'14a1faae' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-dom',
|
||||
'javelin-util',
|
||||
'javelin-vector',
|
||||
'javelin-stratcom',
|
||||
'javelin-workflow',
|
||||
'javelin-workboard-controller',
|
||||
),
|
||||
'185bbd53' => array(
|
||||
'javelin-install',
|
||||
),
|
||||
'19f9369b' => array(
|
||||
'phui-oi-list-view-css',
|
||||
),
|
||||
'1aa4c968' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-stratcom',
|
||||
'javelin-dom',
|
||||
'phuix-dropdown-menu',
|
||||
),
|
||||
'1ad0a787' => array(
|
||||
'javelin-install',
|
||||
'javelin-reactor',
|
||||
|
@ -1127,17 +1107,6 @@ return array(
|
|||
'javelin-install',
|
||||
'javelin-util',
|
||||
),
|
||||
'2a171a9d' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-request',
|
||||
'javelin-stratcom',
|
||||
'javelin-vector',
|
||||
'javelin-dom',
|
||||
'javelin-uri',
|
||||
'javelin-behavior-device',
|
||||
'phabricator-title',
|
||||
'phabricator-favicon',
|
||||
),
|
||||
'2b8de964' => array(
|
||||
'javelin-install',
|
||||
'javelin-util',
|
||||
|
@ -1157,6 +1126,9 @@ return array(
|
|||
'2ee659ce' => array(
|
||||
'javelin-install',
|
||||
),
|
||||
'31420f77' => array(
|
||||
'javelin-behavior',
|
||||
),
|
||||
'320810c8' => array(
|
||||
'javelin-install',
|
||||
'javelin-dom',
|
||||
|
@ -1538,6 +1510,13 @@ return array(
|
|||
'javelin-behavior',
|
||||
'javelin-history',
|
||||
),
|
||||
'8018ee50' => array(
|
||||
'javelin-install',
|
||||
'javelin-util',
|
||||
'javelin-dom',
|
||||
'javelin-vector',
|
||||
'javelin-stratcom',
|
||||
),
|
||||
'805b806a' => array(
|
||||
'javelin-magical-init',
|
||||
'javelin-install',
|
||||
|
@ -1545,13 +1524,6 @@ return array(
|
|||
'javelin-vector',
|
||||
'javelin-stratcom',
|
||||
),
|
||||
'82e270da' => array(
|
||||
'javelin-install',
|
||||
'javelin-util',
|
||||
'javelin-dom',
|
||||
'javelin-vector',
|
||||
'javelin-stratcom',
|
||||
),
|
||||
'834a1173' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-scrollbar',
|
||||
|
@ -1610,11 +1582,6 @@ return array(
|
|||
'javelin-stratcom',
|
||||
'javelin-behavior',
|
||||
),
|
||||
'8cf6d262' => array(
|
||||
'javelin-install',
|
||||
'javelin-dom',
|
||||
'javelin-util',
|
||||
),
|
||||
'8d3bc1b2' => array(
|
||||
'javelin-dom',
|
||||
'javelin-util',
|
||||
|
@ -1633,6 +1600,9 @@ return array(
|
|||
'javelin-stratcom',
|
||||
'javelin-util',
|
||||
),
|
||||
'8eac4166' => array(
|
||||
'phui-theme-css',
|
||||
),
|
||||
'8ff5e24c' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-stratcom',
|
||||
|
@ -1654,6 +1624,15 @@ return array(
|
|||
'javelin-stratcom',
|
||||
'javelin-dom',
|
||||
),
|
||||
'93ae974f' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-dom',
|
||||
'javelin-util',
|
||||
'javelin-vector',
|
||||
'javelin-stratcom',
|
||||
'javelin-workflow',
|
||||
'javelin-workboard-controller',
|
||||
),
|
||||
'93d0c9e3' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-stratcom',
|
||||
|
@ -1703,6 +1682,15 @@ return array(
|
|||
'phabricator-phtize',
|
||||
'changeset-view-manager',
|
||||
),
|
||||
'9a6dd75c' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-stratcom',
|
||||
'javelin-workflow',
|
||||
'javelin-dom',
|
||||
'phuix-form-control-view',
|
||||
'phuix-icon-view',
|
||||
'javelin-behavior-phabricator-gesture',
|
||||
),
|
||||
'9a8cb501' => array(
|
||||
'aphront-typeahead-control-css',
|
||||
'phui-tag-view-css',
|
||||
|
@ -1859,6 +1847,11 @@ return array(
|
|||
'javelin-uri',
|
||||
'javelin-request',
|
||||
),
|
||||
'b3465b9b' => array(
|
||||
'javelin-install',
|
||||
'javelin-dom',
|
||||
'javelin-util',
|
||||
),
|
||||
'b3a4b884' => array(
|
||||
'javelin-behavior',
|
||||
'phabricator-prefab',
|
||||
|
@ -1872,15 +1865,6 @@ return array(
|
|||
'javelin-typeahead-preloaded-source',
|
||||
'javelin-util',
|
||||
),
|
||||
'b52947eb' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-stratcom',
|
||||
'javelin-workflow',
|
||||
'javelin-dom',
|
||||
'phuix-form-control-view',
|
||||
'phuix-icon-view',
|
||||
'javelin-behavior-phabricator-gesture',
|
||||
),
|
||||
'b59e1e96' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-stratcom',
|
||||
|
@ -1911,6 +1895,12 @@ return array(
|
|||
'javelin-json',
|
||||
'phabricator-draggable-list',
|
||||
),
|
||||
'b95d6f7d' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-stratcom',
|
||||
'javelin-dom',
|
||||
'phuix-dropdown-menu',
|
||||
),
|
||||
'ba158207' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-uri',
|
||||
|
@ -2003,6 +1993,17 @@ return array(
|
|||
'javelin-stratcom',
|
||||
'phabricator-phtize',
|
||||
),
|
||||
'caade6f2' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-request',
|
||||
'javelin-stratcom',
|
||||
'javelin-vector',
|
||||
'javelin-dom',
|
||||
'javelin-uri',
|
||||
'javelin-behavior-device',
|
||||
'phabricator-title',
|
||||
'phabricator-favicon',
|
||||
),
|
||||
'ccf1cbf8' => array(
|
||||
'javelin-install',
|
||||
'javelin-dom',
|
||||
|
@ -2168,9 +2169,6 @@ return array(
|
|||
'javelin-workflow',
|
||||
'javelin-json',
|
||||
),
|
||||
'f03e17be' => array(
|
||||
'phui-theme-css',
|
||||
),
|
||||
'f12cbc9f' => array(
|
||||
'phui-oi-list-view-css',
|
||||
),
|
||||
|
@ -2429,6 +2427,9 @@ return array(
|
|||
'conpherence-thread-manager',
|
||||
'javelin-behavior-detect-timezone',
|
||||
'javelin-behavior-setup-check-https',
|
||||
'javelin-behavior-aphlict-status',
|
||||
'javelin-behavior-user-menu',
|
||||
'phabricator-favicon',
|
||||
),
|
||||
'darkconsole.pkg.js' => array(
|
||||
'javelin-behavior-dark-console',
|
||||
|
|
|
@ -84,6 +84,9 @@ return array(
|
|||
'conpherence-thread-manager',
|
||||
'javelin-behavior-detect-timezone',
|
||||
'javelin-behavior-setup-check-https',
|
||||
'javelin-behavior-aphlict-status',
|
||||
'javelin-behavior-user-menu',
|
||||
'phabricator-favicon',
|
||||
),
|
||||
'core.pkg.css' => array(
|
||||
'phabricator-core-css',
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
$table = new PhabricatorProfileMenuItemConfiguration();
|
||||
$conn_w = $table->establishConnection('w');
|
||||
|
||||
queryfx(
|
||||
$conn_w,
|
||||
'DELETE FROM %T WHERE menuItemKey = "motivator"',
|
||||
$table->getTableName());
|
|
@ -617,6 +617,7 @@ phutil_register_library_map(array(
|
|||
'DiffusionCommitActionTransaction' => 'applications/diffusion/xaction/DiffusionCommitActionTransaction.php',
|
||||
'DiffusionCommitAffectedFilesHeraldField' => 'applications/diffusion/herald/DiffusionCommitAffectedFilesHeraldField.php',
|
||||
'DiffusionCommitAuditTransaction' => 'applications/diffusion/xaction/DiffusionCommitAuditTransaction.php',
|
||||
'DiffusionCommitAuditorsHeraldField' => 'applications/diffusion/herald/DiffusionCommitAuditorsHeraldField.php',
|
||||
'DiffusionCommitAuditorsTransaction' => 'applications/diffusion/xaction/DiffusionCommitAuditorsTransaction.php',
|
||||
'DiffusionCommitAuthorHeraldField' => 'applications/diffusion/herald/DiffusionCommitAuthorHeraldField.php',
|
||||
'DiffusionCommitAutocloseHeraldField' => 'applications/diffusion/herald/DiffusionCommitAutocloseHeraldField.php',
|
||||
|
@ -629,6 +630,7 @@ phutil_register_library_map(array(
|
|||
'DiffusionCommitDiffContentHeraldField' => 'applications/diffusion/herald/DiffusionCommitDiffContentHeraldField.php',
|
||||
'DiffusionCommitDiffContentRemovedHeraldField' => 'applications/diffusion/herald/DiffusionCommitDiffContentRemovedHeraldField.php',
|
||||
'DiffusionCommitDiffEnormousHeraldField' => 'applications/diffusion/herald/DiffusionCommitDiffEnormousHeraldField.php',
|
||||
'DiffusionCommitDraftEngine' => 'applications/diffusion/engine/DiffusionCommitDraftEngine.php',
|
||||
'DiffusionCommitEditConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionCommitEditConduitAPIMethod.php',
|
||||
'DiffusionCommitEditController' => 'applications/diffusion/controller/DiffusionCommitEditController.php',
|
||||
'DiffusionCommitEditEngine' => 'applications/diffusion/editor/DiffusionCommitEditEngine.php',
|
||||
|
@ -1697,7 +1699,6 @@ phutil_register_library_map(array(
|
|||
'PHUIListItemView' => 'view/phui/PHUIListItemView.php',
|
||||
'PHUIListView' => 'view/phui/PHUIListView.php',
|
||||
'PHUIListViewTestCase' => 'view/layout/__tests__/PHUIListViewTestCase.php',
|
||||
'PHUIMainMenuView' => 'view/phui/PHUIMainMenuView.php',
|
||||
'PHUIObjectBoxView' => 'view/phui/PHUIObjectBoxView.php',
|
||||
'PHUIObjectItemListExample' => 'applications/uiexample/examples/PHUIObjectItemListExample.php',
|
||||
'PHUIObjectItemListView' => 'view/phui/PHUIObjectItemListView.php',
|
||||
|
@ -2591,7 +2592,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorEditEngineConfigurationTransactionQuery' => 'applications/transactions/query/PhabricatorEditEngineConfigurationTransactionQuery.php',
|
||||
'PhabricatorEditEngineConfigurationViewController' => 'applications/transactions/controller/PhabricatorEditEngineConfigurationViewController.php',
|
||||
'PhabricatorEditEngineController' => 'applications/transactions/controller/PhabricatorEditEngineController.php',
|
||||
'PhabricatorEditEngineCreateQuickActions' => 'applications/settings/quickmenu/PhabricatorEditEngineCreateQuickActions.php',
|
||||
'PhabricatorEditEngineDatasource' => 'applications/transactions/typeahead/PhabricatorEditEngineDatasource.php',
|
||||
'PhabricatorEditEngineExtension' => 'applications/transactions/engineextension/PhabricatorEditEngineExtension.php',
|
||||
'PhabricatorEditEngineExtensionModule' => 'applications/transactions/engineextension/PhabricatorEditEngineExtensionModule.php',
|
||||
|
@ -2669,10 +2669,8 @@ phutil_register_library_map(array(
|
|||
'PhabricatorFactSpec' => 'applications/fact/spec/PhabricatorFactSpec.php',
|
||||
'PhabricatorFactUpdateIterator' => 'applications/fact/extract/PhabricatorFactUpdateIterator.php',
|
||||
'PhabricatorFavoritesApplication' => 'applications/favorites/application/PhabricatorFavoritesApplication.php',
|
||||
'PhabricatorFavoritesConstants' => 'applications/favorites/constants/PhabricatorFavoritesConstants.php',
|
||||
'PhabricatorFavoritesController' => 'applications/favorites/controller/PhabricatorFavoritesController.php',
|
||||
'PhabricatorFavoritesMainController' => 'applications/favorites/controller/PhabricatorFavoritesMainController.php',
|
||||
'PhabricatorFavoritesManageProfileMenuItem' => 'applications/favorites/menuitem/PhabricatorFavoritesManageProfileMenuItem.php',
|
||||
'PhabricatorFavoritesMenuItemController' => 'applications/favorites/controller/PhabricatorFavoritesMenuItemController.php',
|
||||
'PhabricatorFavoritesProfileMenuEngine' => 'applications/favorites/engine/PhabricatorFavoritesProfileMenuEngine.php',
|
||||
'PhabricatorFaxContentSource' => 'infrastructure/contentsource/PhabricatorFaxContentSource.php',
|
||||
|
@ -2827,7 +2825,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorHelpDocumentationController' => 'applications/help/controller/PhabricatorHelpDocumentationController.php',
|
||||
'PhabricatorHelpEditorProtocolController' => 'applications/help/controller/PhabricatorHelpEditorProtocolController.php',
|
||||
'PhabricatorHelpKeyboardShortcutController' => 'applications/help/controller/PhabricatorHelpKeyboardShortcutController.php',
|
||||
'PhabricatorHelpMainMenuBarExtension' => 'applications/help/extension/PhabricatorHelpMainMenuBarExtension.php',
|
||||
'PhabricatorHeraldApplication' => 'applications/herald/application/PhabricatorHeraldApplication.php',
|
||||
'PhabricatorHeraldContentSource' => 'applications/herald/contentsource/PhabricatorHeraldContentSource.php',
|
||||
'PhabricatorHighSecurityRequestExceptionHandler' => 'aphront/handler/PhabricatorHighSecurityRequestExceptionHandler.php',
|
||||
|
@ -2840,7 +2837,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorHomeMenuItemController' => 'applications/home/controller/PhabricatorHomeMenuItemController.php',
|
||||
'PhabricatorHomePreferencesSettingsPanel' => 'applications/settings/panel/PhabricatorHomePreferencesSettingsPanel.php',
|
||||
'PhabricatorHomeProfileMenuEngine' => 'applications/home/engine/PhabricatorHomeProfileMenuEngine.php',
|
||||
'PhabricatorHomeQuickCreateController' => 'applications/home/controller/PhabricatorHomeQuickCreateController.php',
|
||||
'PhabricatorHovercardEngineExtension' => 'applications/search/engineextension/PhabricatorHovercardEngineExtension.php',
|
||||
'PhabricatorHovercardEngineExtensionModule' => 'applications/search/engineextension/PhabricatorHovercardEngineExtensionModule.php',
|
||||
'PhabricatorIDsSearchEngineExtension' => 'applications/search/engineextension/PhabricatorIDsSearchEngineExtension.php',
|
||||
|
@ -3024,7 +3020,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorModularTransactionType' => 'applications/transactions/storage/PhabricatorModularTransactionType.php',
|
||||
'PhabricatorMonospacedFontSetting' => 'applications/settings/setting/PhabricatorMonospacedFontSetting.php',
|
||||
'PhabricatorMonospacedTextareasSetting' => 'applications/settings/setting/PhabricatorMonospacedTextareasSetting.php',
|
||||
'PhabricatorMotivatorProfileMenuItem' => 'applications/search/menuitem/PhabricatorMotivatorProfileMenuItem.php',
|
||||
'PhabricatorMultiColumnUIExample' => 'applications/uiexample/examples/PhabricatorMultiColumnUIExample.php',
|
||||
'PhabricatorMultiFactorSettingsPanel' => 'applications/settings/panel/PhabricatorMultiFactorSettingsPanel.php',
|
||||
'PhabricatorMultimeterApplication' => 'applications/multimeter/application/PhabricatorMultimeterApplication.php',
|
||||
|
@ -3316,7 +3311,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorPeopleLogQuery' => 'applications/people/query/PhabricatorPeopleLogQuery.php',
|
||||
'PhabricatorPeopleLogSearchEngine' => 'applications/people/query/PhabricatorPeopleLogSearchEngine.php',
|
||||
'PhabricatorPeopleLogsController' => 'applications/people/controller/PhabricatorPeopleLogsController.php',
|
||||
'PhabricatorPeopleMainMenuBarExtension' => 'applications/people/extension/PhabricatorPeopleMainMenuBarExtension.php',
|
||||
'PhabricatorPeopleManageProfileMenuItem' => 'applications/people/menuitem/PhabricatorPeopleManageProfileMenuItem.php',
|
||||
'PhabricatorPeopleNewController' => 'applications/people/controller/PhabricatorPeopleNewController.php',
|
||||
'PhabricatorPeopleNoOwnerDatasource' => 'applications/people/typeahead/PhabricatorPeopleNoOwnerDatasource.php',
|
||||
|
@ -3422,7 +3416,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorPolicyTestObject' => 'applications/policy/__tests__/PhabricatorPolicyTestObject.php',
|
||||
'PhabricatorPolicyType' => 'applications/policy/constants/PhabricatorPolicyType.php',
|
||||
'PhabricatorPonderApplication' => 'applications/ponder/application/PhabricatorPonderApplication.php',
|
||||
'PhabricatorProfileMenuCollapsedSetting' => 'applications/settings/setting/PhabricatorProfileMenuCollapsedSetting.php',
|
||||
'PhabricatorProfileMenuEditEngine' => 'applications/search/editor/PhabricatorProfileMenuEditEngine.php',
|
||||
'PhabricatorProfileMenuEditor' => 'applications/search/editor/PhabricatorProfileMenuEditor.php',
|
||||
'PhabricatorProfileMenuEngine' => 'applications/search/engine/PhabricatorProfileMenuEngine.php',
|
||||
|
@ -3562,7 +3555,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorQueryOrderItem' => 'infrastructure/query/order/PhabricatorQueryOrderItem.php',
|
||||
'PhabricatorQueryOrderTestCase' => 'infrastructure/query/order/__tests__/PhabricatorQueryOrderTestCase.php',
|
||||
'PhabricatorQueryOrderVector' => 'infrastructure/query/order/PhabricatorQueryOrderVector.php',
|
||||
'PhabricatorQuickActions' => 'applications/settings/quickmenu/PhabricatorQuickActions.php',
|
||||
'PhabricatorRateLimitRequestExceptionHandler' => 'aphront/handler/PhabricatorRateLimitRequestExceptionHandler.php',
|
||||
'PhabricatorRecaptchaConfigOptions' => 'applications/config/option/PhabricatorRecaptchaConfigOptions.php',
|
||||
'PhabricatorRecipientHasBadgeEdgeType' => 'applications/badges/edge/PhabricatorRecipientHasBadgeEdgeType.php',
|
||||
|
@ -3771,7 +3763,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorSettingsListController' => 'applications/settings/controller/PhabricatorSettingsListController.php',
|
||||
'PhabricatorSettingsLogsPanelGroup' => 'applications/settings/panelgroup/PhabricatorSettingsLogsPanelGroup.php',
|
||||
'PhabricatorSettingsMainController' => 'applications/settings/controller/PhabricatorSettingsMainController.php',
|
||||
'PhabricatorSettingsMainMenuBarExtension' => 'applications/settings/extension/PhabricatorSettingsMainMenuBarExtension.php',
|
||||
'PhabricatorSettingsPanel' => 'applications/settings/panel/PhabricatorSettingsPanel.php',
|
||||
'PhabricatorSettingsPanelGroup' => 'applications/settings/panelgroup/PhabricatorSettingsPanelGroup.php',
|
||||
'PhabricatorSettingsTimezoneController' => 'applications/settings/controller/PhabricatorSettingsTimezoneController.php',
|
||||
|
@ -5330,6 +5321,7 @@ phutil_register_library_map(array(
|
|||
'DiffusionCommitActionTransaction' => 'DiffusionCommitTransactionType',
|
||||
'DiffusionCommitAffectedFilesHeraldField' => 'DiffusionCommitHeraldField',
|
||||
'DiffusionCommitAuditTransaction' => 'DiffusionCommitActionTransaction',
|
||||
'DiffusionCommitAuditorsHeraldField' => 'DiffusionCommitHeraldField',
|
||||
'DiffusionCommitAuditorsTransaction' => 'DiffusionCommitTransactionType',
|
||||
'DiffusionCommitAuthorHeraldField' => 'DiffusionCommitHeraldField',
|
||||
'DiffusionCommitAutocloseHeraldField' => 'DiffusionCommitHeraldField',
|
||||
|
@ -5342,6 +5334,7 @@ phutil_register_library_map(array(
|
|||
'DiffusionCommitDiffContentHeraldField' => 'DiffusionCommitHeraldField',
|
||||
'DiffusionCommitDiffContentRemovedHeraldField' => 'DiffusionCommitHeraldField',
|
||||
'DiffusionCommitDiffEnormousHeraldField' => 'DiffusionCommitHeraldField',
|
||||
'DiffusionCommitDraftEngine' => 'PhabricatorDraftEngine',
|
||||
'DiffusionCommitEditConduitAPIMethod' => 'PhabricatorEditEngineAPIMethod',
|
||||
'DiffusionCommitEditController' => 'DiffusionController',
|
||||
'DiffusionCommitEditEngine' => 'PhabricatorEditEngine',
|
||||
|
@ -6574,7 +6567,6 @@ phutil_register_library_map(array(
|
|||
'PHUIListItemView' => 'AphrontTagView',
|
||||
'PHUIListView' => 'AphrontTagView',
|
||||
'PHUIListViewTestCase' => 'PhabricatorTestCase',
|
||||
'PHUIMainMenuView' => 'AphrontView',
|
||||
'PHUIObjectBoxView' => 'AphrontTagView',
|
||||
'PHUIObjectItemListExample' => 'PhabricatorUIExample',
|
||||
'PHUIObjectItemListView' => 'AphrontTagView',
|
||||
|
@ -6678,7 +6670,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorAccessLogConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
||||
'PhabricatorAccessibilitySetting' => 'PhabricatorSelectSetting',
|
||||
'PhabricatorAccountSettingsPanel' => 'PhabricatorEditEngineSettingsPanel',
|
||||
'PhabricatorActionListView' => 'AphrontView',
|
||||
'PhabricatorActionListView' => 'AphrontTagView',
|
||||
'PhabricatorActionView' => 'AphrontView',
|
||||
'PhabricatorActivitySettingsPanel' => 'PhabricatorSettingsPanel',
|
||||
'PhabricatorAdministratorsPolicyRule' => 'PhabricatorPolicyRule',
|
||||
|
@ -7612,7 +7604,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorEditEngineConfigurationTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||
'PhabricatorEditEngineConfigurationViewController' => 'PhabricatorEditEngineController',
|
||||
'PhabricatorEditEngineController' => 'PhabricatorApplicationTransactionController',
|
||||
'PhabricatorEditEngineCreateQuickActions' => 'PhabricatorQuickActions',
|
||||
'PhabricatorEditEngineDatasource' => 'PhabricatorTypeaheadDatasource',
|
||||
'PhabricatorEditEngineExtension' => 'Phobject',
|
||||
'PhabricatorEditEngineExtensionModule' => 'PhabricatorConfigModule',
|
||||
|
@ -7692,10 +7683,8 @@ phutil_register_library_map(array(
|
|||
'PhabricatorFactSpec' => 'Phobject',
|
||||
'PhabricatorFactUpdateIterator' => 'PhutilBufferedIterator',
|
||||
'PhabricatorFavoritesApplication' => 'PhabricatorApplication',
|
||||
'PhabricatorFavoritesConstants' => 'PhabricatorFavoritesController',
|
||||
'PhabricatorFavoritesController' => 'PhabricatorController',
|
||||
'PhabricatorFavoritesMainController' => 'PhabricatorFavoritesController',
|
||||
'PhabricatorFavoritesManageProfileMenuItem' => 'PhabricatorProfileMenuItem',
|
||||
'PhabricatorFavoritesMenuItemController' => 'PhabricatorFavoritesController',
|
||||
'PhabricatorFavoritesProfileMenuEngine' => 'PhabricatorProfileMenuEngine',
|
||||
'PhabricatorFaxContentSource' => 'PhabricatorContentSource',
|
||||
|
@ -7886,7 +7875,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorHelpDocumentationController' => 'PhabricatorHelpController',
|
||||
'PhabricatorHelpEditorProtocolController' => 'PhabricatorHelpController',
|
||||
'PhabricatorHelpKeyboardShortcutController' => 'PhabricatorHelpController',
|
||||
'PhabricatorHelpMainMenuBarExtension' => 'PhabricatorMainMenuBarExtension',
|
||||
'PhabricatorHeraldApplication' => 'PhabricatorApplication',
|
||||
'PhabricatorHeraldContentSource' => 'PhabricatorContentSource',
|
||||
'PhabricatorHighSecurityRequestExceptionHandler' => 'PhabricatorRequestExceptionHandler',
|
||||
|
@ -7899,7 +7887,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorHomeMenuItemController' => 'PhabricatorHomeController',
|
||||
'PhabricatorHomePreferencesSettingsPanel' => 'PhabricatorSettingsPanel',
|
||||
'PhabricatorHomeProfileMenuEngine' => 'PhabricatorProfileMenuEngine',
|
||||
'PhabricatorHomeQuickCreateController' => 'PhabricatorHomeController',
|
||||
'PhabricatorHovercardEngineExtension' => 'Phobject',
|
||||
'PhabricatorHovercardEngineExtensionModule' => 'PhabricatorConfigModule',
|
||||
'PhabricatorIDsSearchEngineExtension' => 'PhabricatorSearchEngineExtension',
|
||||
|
@ -8093,7 +8080,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorModularTransactionType' => 'Phobject',
|
||||
'PhabricatorMonospacedFontSetting' => 'PhabricatorStringSetting',
|
||||
'PhabricatorMonospacedTextareasSetting' => 'PhabricatorSelectSetting',
|
||||
'PhabricatorMotivatorProfileMenuItem' => 'PhabricatorProfileMenuItem',
|
||||
'PhabricatorMultiColumnUIExample' => 'PhabricatorUIExample',
|
||||
'PhabricatorMultiFactorSettingsPanel' => 'PhabricatorSettingsPanel',
|
||||
'PhabricatorMultimeterApplication' => 'PhabricatorApplication',
|
||||
|
@ -8449,7 +8435,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorPeopleLogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhabricatorPeopleLogSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||
'PhabricatorPeopleLogsController' => 'PhabricatorPeopleController',
|
||||
'PhabricatorPeopleMainMenuBarExtension' => 'PhabricatorMainMenuBarExtension',
|
||||
'PhabricatorPeopleManageProfileMenuItem' => 'PhabricatorProfileMenuItem',
|
||||
'PhabricatorPeopleNewController' => 'PhabricatorPeopleController',
|
||||
'PhabricatorPeopleNoOwnerDatasource' => 'PhabricatorTypeaheadDatasource',
|
||||
|
@ -8575,7 +8560,6 @@ phutil_register_library_map(array(
|
|||
),
|
||||
'PhabricatorPolicyType' => 'PhabricatorPolicyConstants',
|
||||
'PhabricatorPonderApplication' => 'PhabricatorApplication',
|
||||
'PhabricatorProfileMenuCollapsedSetting' => 'PhabricatorInternalSetting',
|
||||
'PhabricatorProfileMenuEditEngine' => 'PhabricatorEditEngine',
|
||||
'PhabricatorProfileMenuEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
'PhabricatorProfileMenuEngine' => 'Phobject',
|
||||
|
@ -8749,7 +8733,6 @@ phutil_register_library_map(array(
|
|||
'Phobject',
|
||||
'Iterator',
|
||||
),
|
||||
'PhabricatorQuickActions' => 'Phobject',
|
||||
'PhabricatorRateLimitRequestExceptionHandler' => 'PhabricatorRequestExceptionHandler',
|
||||
'PhabricatorRecaptchaConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
||||
'PhabricatorRecipientHasBadgeEdgeType' => 'PhabricatorEdgeType',
|
||||
|
@ -8796,6 +8779,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorApplicationTransactionInterface',
|
||||
'PhabricatorFulltextInterface',
|
||||
'PhabricatorConduitResultInterface',
|
||||
'PhabricatorDraftInterface',
|
||||
),
|
||||
'PhabricatorRepositoryCommitChangeParserWorker' => 'PhabricatorRepositoryCommitParserWorker',
|
||||
'PhabricatorRepositoryCommitData' => 'PhabricatorRepositoryDAO',
|
||||
|
@ -9015,7 +8999,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorSettingsListController' => 'PhabricatorController',
|
||||
'PhabricatorSettingsLogsPanelGroup' => 'PhabricatorSettingsPanelGroup',
|
||||
'PhabricatorSettingsMainController' => 'PhabricatorController',
|
||||
'PhabricatorSettingsMainMenuBarExtension' => 'PhabricatorMainMenuBarExtension',
|
||||
'PhabricatorSettingsPanel' => 'Phobject',
|
||||
'PhabricatorSettingsPanelGroup' => 'Phobject',
|
||||
'PhabricatorSettingsTimezoneController' => 'PhabricatorController',
|
||||
|
|
|
@ -75,7 +75,7 @@ final class AuditQueryConduitAPIMethod extends AuditConduitAPIMethod {
|
|||
PhabricatorAuditCommitStatusConstants::CONCERN_RAISED,
|
||||
),
|
||||
self::AUDIT_LEGACYSTATUS_ACCEPTED => array(
|
||||
PhabricatorAuditCommitStatusConstants::CONCERN_ACCEPTED,
|
||||
PhabricatorAuditCommitStatusConstants::FULLY_AUDITED,
|
||||
),
|
||||
self::AUDIT_LEGACYSTATUS_PARTIAL => array(
|
||||
PhabricatorAuditCommitStatusConstants::PARTIALLY_AUDITED,
|
||||
|
|
|
@ -14,7 +14,8 @@ final class PhabricatorCommitSearchEngine
|
|||
public function newQuery() {
|
||||
return id(new DiffusionCommitQuery())
|
||||
->needAuditRequests(true)
|
||||
->needCommitData(true);
|
||||
->needCommitData(true)
|
||||
->needDrafts(true);
|
||||
}
|
||||
|
||||
protected function newResultBuckets() {
|
||||
|
@ -140,7 +141,8 @@ final class PhabricatorCommitSearchEngine
|
|||
$bucket = $this->getResultBucket($query);
|
||||
|
||||
$template = id(new PhabricatorAuditListView())
|
||||
->setViewer($viewer);
|
||||
->setViewer($viewer)
|
||||
->setShowDrafts(true);
|
||||
|
||||
$views = array();
|
||||
if ($bucket) {
|
||||
|
|
|
@ -4,6 +4,7 @@ final class PhabricatorAuditListView extends AphrontView {
|
|||
|
||||
private $commits;
|
||||
private $header;
|
||||
private $showDrafts;
|
||||
private $noDataString;
|
||||
private $highlightedAudits;
|
||||
|
||||
|
@ -25,6 +26,15 @@ final class PhabricatorAuditListView extends AphrontView {
|
|||
return $this->header;
|
||||
}
|
||||
|
||||
public function setShowDrafts($show_drafts) {
|
||||
$this->showDrafts = $show_drafts;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getShowDrafts() {
|
||||
return $this->showDrafts;
|
||||
}
|
||||
|
||||
/**
|
||||
* These commits should have both commit data and audit requests attached.
|
||||
*/
|
||||
|
@ -73,7 +83,31 @@ final class PhabricatorAuditListView extends AphrontView {
|
|||
$viewer = $this->getViewer();
|
||||
$rowc = array();
|
||||
|
||||
$handles = $viewer->loadHandles(mpull($this->commits, 'getPHID'));
|
||||
$phids = array();
|
||||
foreach ($this->getCommits() as $commit) {
|
||||
$phids[] = $commit->getPHID();
|
||||
|
||||
foreach ($commit->getAudits() as $audit) {
|
||||
$phids[] = $audit->getAuditorPHID();
|
||||
}
|
||||
|
||||
$author_phid = $commit->getAuthorPHID();
|
||||
if ($author_phid) {
|
||||
$phids[] = $author_phid;
|
||||
}
|
||||
}
|
||||
|
||||
$handles = $viewer->loadHandles($phids);
|
||||
|
||||
$show_drafts = $this->getShowDrafts();
|
||||
|
||||
$draft_icon = id(new PHUIIconView())
|
||||
->setIcon('fa-comment yellow')
|
||||
->addSigil('has-tooltip')
|
||||
->setMetadata(
|
||||
array(
|
||||
'tip' => pht('Unsubmitted Comments'),
|
||||
));
|
||||
|
||||
$list = new PHUIObjectItemListView();
|
||||
foreach ($this->commits as $commit) {
|
||||
|
@ -86,15 +120,6 @@ final class PhabricatorAuditListView extends AphrontView {
|
|||
$commit_desc = $this->getCommitDescription($commit_phid);
|
||||
$committed = phabricator_datetime($commit->getEpoch(), $viewer);
|
||||
|
||||
$audits = mpull($commit->getAudits(), null, 'getAuditorPHID');
|
||||
$auditors = array();
|
||||
$reasons = array();
|
||||
foreach ($audits as $audit) {
|
||||
$auditor_phid = $audit->getAuditorPHID();
|
||||
$auditors[$auditor_phid] = $viewer->renderHandle($auditor_phid);
|
||||
}
|
||||
$auditors = phutil_implode_html(', ', $auditors);
|
||||
|
||||
$status = $commit->getAuditStatus();
|
||||
|
||||
$status_text =
|
||||
|
@ -106,7 +131,7 @@ final class PhabricatorAuditListView extends AphrontView {
|
|||
|
||||
$author_phid = $commit->getAuthorPHID();
|
||||
if ($author_phid) {
|
||||
$author_name = $viewer->renderHandle($author_phid);
|
||||
$author_name = $handles[$author_phid]->renderLink();
|
||||
} else {
|
||||
$author_name = $commit->getCommitData()->getAuthorName();
|
||||
}
|
||||
|
@ -115,14 +140,26 @@ final class PhabricatorAuditListView extends AphrontView {
|
|||
->setObjectName($commit_name)
|
||||
->setHeader($commit_desc)
|
||||
->setHref($commit_link)
|
||||
->addAttribute(pht('Author: %s', $author_name))
|
||||
->addAttribute($reasons)
|
||||
->addByline(pht('Author: %s', $author_name))
|
||||
->addIcon('none', $committed);
|
||||
|
||||
if (!empty($auditors)) {
|
||||
$item->addByLine(pht('Auditors: %s', $auditors));
|
||||
if ($show_drafts) {
|
||||
if ($commit->getHasDraft($viewer)) {
|
||||
$item->addAttribute($draft_icon);
|
||||
}
|
||||
}
|
||||
|
||||
$audits = $commit->getAudits();
|
||||
$auditor_phids = mpull($audits, 'getAuditorPHID');
|
||||
if ($auditor_phids) {
|
||||
$auditor_list = $handles->newSublist($auditor_phids)
|
||||
->renderList()
|
||||
->setAsInline(true);
|
||||
} else {
|
||||
$auditor_list = phutil_tag('em', array(), pht('None'));
|
||||
}
|
||||
$item->addAttribute(pht('Auditors: %s', $auditor_list));
|
||||
|
||||
if ($status_color) {
|
||||
$item->setStatusIcon($status_icon.' '.$status_color, $status_text);
|
||||
}
|
||||
|
|
|
@ -54,6 +54,8 @@ final class PhabricatorAuthRegisterController
|
|||
}
|
||||
}
|
||||
|
||||
$errors = array();
|
||||
|
||||
$user = new PhabricatorUser();
|
||||
|
||||
$default_username = $account->getUsername();
|
||||
|
@ -65,23 +67,37 @@ final class PhabricatorAuthRegisterController
|
|||
$default_email = $invite->getEmailAddress();
|
||||
}
|
||||
|
||||
if (!PhabricatorUserEmail::isValidAddress($default_email)) {
|
||||
$default_email = null;
|
||||
if ($default_email !== null) {
|
||||
if (!PhabricatorUserEmail::isValidAddress($default_email)) {
|
||||
$errors[] = pht(
|
||||
'The email address associated with this external account ("%s") is '.
|
||||
'not a valid email address and can not be used to register a '.
|
||||
'Phabricator account. Choose a different, valid address.',
|
||||
phutil_tag('strong', array(), $default_email));
|
||||
$default_email = null;
|
||||
}
|
||||
}
|
||||
|
||||
if ($default_email !== null) {
|
||||
// We should bypass policy here becase e.g. limiting an application use
|
||||
// to a subset of users should not allow the others to overwrite
|
||||
// configured application emails
|
||||
// configured application emails.
|
||||
$application_email = id(new PhabricatorMetaMTAApplicationEmailQuery())
|
||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||
->withAddresses(array($default_email))
|
||||
->executeOne();
|
||||
if ($application_email) {
|
||||
$errors[] = pht(
|
||||
'The email address associated with this account ("%s") is '.
|
||||
'already in use by an application and can not be used to '.
|
||||
'register a new Phabricator account. Choose a different, valid '.
|
||||
'address.',
|
||||
phutil_tag('strong', array(), $default_email));
|
||||
$default_email = null;
|
||||
}
|
||||
}
|
||||
|
||||
$show_existing = null;
|
||||
if ($default_email !== null) {
|
||||
// If the account source provided an email, but it's not allowed by
|
||||
// the configuration, roadblock the user. Previously, we let the user
|
||||
|
@ -105,9 +121,6 @@ final class PhabricatorAuthRegisterController
|
|||
|
||||
// If the account source provided an email, but another account already
|
||||
// has that email, just pretend we didn't get an email.
|
||||
|
||||
// TODO: See T3472.
|
||||
|
||||
if ($default_email !== null) {
|
||||
$same_email = id(new PhabricatorUserEmail())->loadOneWhere(
|
||||
'address = %s',
|
||||
|
@ -118,12 +131,57 @@ final class PhabricatorAuthRegisterController
|
|||
// invite means that the address is nonprimary and unverified and
|
||||
// we're OK to steal it.
|
||||
} else {
|
||||
$show_existing = $default_email;
|
||||
$default_email = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($show_existing !== null) {
|
||||
if (!$request->getInt('phase')) {
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Email Address Already in Use'))
|
||||
->addHiddenInput('phase', 1)
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'You are creating a new Phabricator account linked to an '.
|
||||
'existing external account from outside Phabricator.'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'The email address ("%s") associated with the external account '.
|
||||
'is already in use by an existing Phabricator account. Multiple '.
|
||||
'Phabricator accounts may not have the same email address, so '.
|
||||
'you can not use this email address to register a new '.
|
||||
'Phabricator account.',
|
||||
phutil_tag('strong', array(), $show_existing)))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'If you want to register a new account, continue with this '.
|
||||
'registration workflow and choose a new, unique email address '.
|
||||
'for the new account.'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'If you want to link an existing Phabricator account to this '.
|
||||
'external account, do not continue. Instead: log in to your '.
|
||||
'existing account, then go to "Settings" and link the account '.
|
||||
'in the "External Accounts" panel.'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'If you continue, you will create a new account. You will not '.
|
||||
'be able to link this external account to an existing account.'))
|
||||
->addCancelButton('/auth/login/', pht('Cancel'))
|
||||
->addSubmitButton(pht('Create New Account'));
|
||||
} else {
|
||||
$errors[] = pht(
|
||||
'The external account you are registering with has an email address '.
|
||||
'that is already in use ("%s") by an existing Phabricator account. '.
|
||||
'Choose a new, valid email address to register a new Phabricator '.
|
||||
'account.',
|
||||
phutil_tag('strong', array(), $show_existing));
|
||||
}
|
||||
}
|
||||
|
||||
$profile = id(new PhabricatorRegistrationProfile())
|
||||
->setDefaultUsername($default_username)
|
||||
->setDefaultEmail($default_email)
|
||||
|
@ -167,8 +225,6 @@ final class PhabricatorAuthRegisterController
|
|||
$value_email = $default_email;
|
||||
$value_password = null;
|
||||
|
||||
$errors = array();
|
||||
|
||||
$require_real_name = PhabricatorEnv::getEnvConfig('user.require-real-name');
|
||||
|
||||
$e_username = strlen($value_username) ? null : true;
|
||||
|
@ -193,7 +249,14 @@ final class PhabricatorAuthRegisterController
|
|||
$e_username = null;
|
||||
}
|
||||
|
||||
if (($request->isFormPost() || !$can_edit_anything) && !$from_invite) {
|
||||
$try_register =
|
||||
($request->isFormPost() || !$can_edit_anything) &&
|
||||
!$from_invite &&
|
||||
($request->getInt('phase') != 1);
|
||||
|
||||
if ($try_register) {
|
||||
$errors = array();
|
||||
|
||||
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
|
||||
|
||||
if ($must_set_password && !$skip_captcha) {
|
||||
|
@ -402,7 +465,8 @@ final class PhabricatorAuthRegisterController
|
|||
}
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($request->getUser());
|
||||
->setUser($request->getUser())
|
||||
->addHiddenInput('phase', 2);
|
||||
|
||||
if (!$is_default) {
|
||||
$form->appendChild(
|
||||
|
|
|
@ -13,9 +13,7 @@ final class PhabricatorAuthMainMenuBarExtension
|
|||
$viewer = $this->getViewer();
|
||||
|
||||
if ($viewer->isLoggedIn()) {
|
||||
return array(
|
||||
$this->buildLogoutMenu(),
|
||||
);
|
||||
return array();
|
||||
}
|
||||
|
||||
$controller = $this->getController();
|
||||
|
@ -30,25 +28,6 @@ final class PhabricatorAuthMainMenuBarExtension
|
|||
);
|
||||
}
|
||||
|
||||
private function buildLogoutMenu() {
|
||||
$controller = $this->getController();
|
||||
|
||||
$is_selected = ($controller instanceof PhabricatorLogoutController);
|
||||
|
||||
$bar_item = id(new PHUIListItemView())
|
||||
->addClass('core-menu-item')
|
||||
->setName(pht('Log Out'))
|
||||
->setIcon('fa-sign-out')
|
||||
->setWorkflow(true)
|
||||
->setHref('/logout/')
|
||||
->setSelected($is_selected)
|
||||
->setAural(pht('Log Out'));
|
||||
|
||||
return id(new PHUIMainMenuView())
|
||||
->setOrder(900)
|
||||
->setMenuBarItem($bar_item);
|
||||
}
|
||||
|
||||
private function buildLoginMenu() {
|
||||
$controller = $this->getController();
|
||||
|
||||
|
@ -58,16 +37,12 @@ final class PhabricatorAuthMainMenuBarExtension
|
|||
$uri->setQueryParam('next', $path);
|
||||
}
|
||||
|
||||
$bar_item = id(new PHUIListItemView())
|
||||
->addClass('core-menu-item')
|
||||
->setName(pht('Log In'))
|
||||
->setIcon('fa-sign-in')
|
||||
return id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setText(pht('Log In'))
|
||||
->setHref($uri)
|
||||
->setAural(pht('Log In'));
|
||||
|
||||
return id(new PHUIMainMenuView())
|
||||
->setOrder(900)
|
||||
->setMenuBarItem($bar_item);
|
||||
->setNoCSS(true)
|
||||
->addClass('phabricator-core-login-button');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -172,41 +172,40 @@ abstract class PhabricatorApplication
|
|||
|
||||
$articles = $this->getHelpDocumentationArticles($viewer);
|
||||
if ($articles) {
|
||||
$items[] = id(new PHUIListItemView())
|
||||
->setType(PHUIListItemView::TYPE_LABEL)
|
||||
->setName(pht('%s Documentation', $this->getName()));
|
||||
foreach ($articles as $article) {
|
||||
$item = id(new PHUIListItemView())
|
||||
$item = id(new PhabricatorActionView())
|
||||
->setName($article['name'])
|
||||
->setIcon('fa-book')
|
||||
->setHref($article['href'])
|
||||
->addSigil('help-item')
|
||||
->setOpenInNewWindow(true);
|
||||
|
||||
$items[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
$command_specs = $this->getMailCommandObjects();
|
||||
if ($command_specs) {
|
||||
$items[] = id(new PHUIListItemView())
|
||||
->setType(PHUIListItemView::TYPE_LABEL)
|
||||
->setName(pht('Email Help'));
|
||||
foreach ($command_specs as $key => $spec) {
|
||||
$object = $spec['object'];
|
||||
|
||||
$class = get_class($this);
|
||||
$href = '/applications/mailcommands/'.$class.'/'.$key.'/';
|
||||
|
||||
$item = id(new PHUIListItemView())
|
||||
$item = id(new PhabricatorActionView())
|
||||
->setName($spec['name'])
|
||||
->setIcon('fa-envelope-o')
|
||||
->setHref($href)
|
||||
->addSigil('help-item')
|
||||
->setOpenInNewWindow(true);
|
||||
$items[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
return $items;
|
||||
if ($items) {
|
||||
$divider = id(new PhabricatorActionView())
|
||||
->addSigil('help-item')
|
||||
->setType(PhabricatorActionView::TYPE_DIVIDER);
|
||||
array_unshift($items, $divider);
|
||||
}
|
||||
|
||||
return array_values($items);
|
||||
}
|
||||
|
||||
public function getHelpDocumentationArticles(PhabricatorUser $viewer) {
|
||||
|
|
|
@ -29,7 +29,7 @@ final class CelerityDefaultPostprocessor
|
|||
"Arial, sans-serif",
|
||||
|
||||
// Drop Shadow
|
||||
'dropshadow' => '0 1px 6px rgba(0, 0, 0, .25)',
|
||||
'dropshadow' => '0 2px 12px rgba(0, 0, 0, .20)',
|
||||
'whitetextshadow' => '0 1px 0 rgba(255, 255, 255, 1)',
|
||||
|
||||
// Anchors
|
||||
|
|
|
@ -142,9 +142,11 @@ final class DifferentialGetCommitMessageConduitAPIMethod
|
|||
private function loadCustomFieldStorage(
|
||||
PhabricatorUser $viewer,
|
||||
DifferentialRevision $revision) {
|
||||
|
||||
$custom_field_list = PhabricatorCustomField::getObjectFields(
|
||||
$revision,
|
||||
DifferentialCustomField::ROLE_COMMITMESSAGE);
|
||||
PhabricatorCustomField::ROLE_STORAGE);
|
||||
|
||||
$custom_field_list
|
||||
->setViewer($viewer)
|
||||
->readFieldsFromStorage($revision);
|
||||
|
|
|
@ -36,10 +36,6 @@ final class DifferentialAuditorsField
|
|||
return true;
|
||||
}
|
||||
|
||||
public function shouldAppearInCommitMessage() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function shouldAppearInConduitTransactions() {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -91,10 +91,6 @@ final class DifferentialBlameRevisionField
|
|||
$xaction->renderHandleLink($object_phid));
|
||||
}
|
||||
|
||||
public function shouldAppearInCommitMessage() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function shouldAppearInConduitDictionary() {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -156,15 +156,6 @@ abstract class DifferentialCoreCustomField
|
|||
return $this->value;
|
||||
}
|
||||
|
||||
public function readValueFromCommitMessage($value) {
|
||||
$this->setValue($value);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function renderCommitMessageValue(array $handles) {
|
||||
return $this->getValue();
|
||||
}
|
||||
|
||||
public function getConduitDictionaryValue() {
|
||||
return $this->getValue();
|
||||
}
|
||||
|
|
|
@ -7,9 +7,6 @@
|
|||
abstract class DifferentialCustomField
|
||||
extends PhabricatorCustomField {
|
||||
|
||||
const ROLE_COMMITMESSAGE = 'differential:commitmessage';
|
||||
const ROLE_COMMITMESSAGEEDIT = 'differential:commitmessageedit';
|
||||
|
||||
/**
|
||||
* TODO: It would be nice to remove this, but a lot of different code is
|
||||
* bound together by it. Until everything is modernized, retaining the old
|
||||
|
@ -25,18 +22,6 @@ abstract class DifferentialCustomField
|
|||
return $this->getFieldKeyForConduit();
|
||||
}
|
||||
|
||||
public function shouldEnableForRole($role) {
|
||||
switch ($role) {
|
||||
case self::ROLE_COMMITMESSAGE:
|
||||
return $this->shouldAppearInCommitMessage();
|
||||
case self::ROLE_COMMITMESSAGEEDIT:
|
||||
return $this->shouldAppearInCommitMessage() &&
|
||||
$this->shouldAllowEditInCommitMessage();
|
||||
}
|
||||
|
||||
return parent::shouldEnableForRole($role);
|
||||
}
|
||||
|
||||
protected function parseObjectList(
|
||||
$value,
|
||||
array $types,
|
||||
|
@ -97,39 +82,6 @@ abstract class DifferentialCustomField
|
|||
/* -( Integration with Commit Messages )----------------------------------- */
|
||||
|
||||
|
||||
/**
|
||||
* @task commitmessage
|
||||
*/
|
||||
public function shouldAppearInCommitMessage() {
|
||||
if ($this->getProxy()) {
|
||||
return $this->getProxy()->shouldAppearInCommitMessage();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @task commitmessage
|
||||
*/
|
||||
public function shouldAppearInCommitMessageTemplate() {
|
||||
if ($this->getProxy()) {
|
||||
return $this->getProxy()->shouldAppearInCommitMessageTemplate();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @task commitmessage
|
||||
*/
|
||||
public function shouldAllowEditInCommitMessage() {
|
||||
if ($this->getProxy()) {
|
||||
return $this->getProxy()->shouldAllowEditInCommitMessage();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @task commitmessage
|
||||
*/
|
||||
|
@ -141,95 +93,6 @@ abstract class DifferentialCustomField
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* @task commitmessage
|
||||
*/
|
||||
public function getCommitMessageLabels() {
|
||||
if ($this->getProxy()) {
|
||||
return $this->getProxy()->getCommitMessageLabels();
|
||||
}
|
||||
return array($this->renderCommitMessageLabel());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @task commitmessage
|
||||
*/
|
||||
public function parseValueFromCommitMessage($value) {
|
||||
if ($this->getProxy()) {
|
||||
return $this->getProxy()->parseValueFromCommitMessage($value);
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @task commitmessage
|
||||
*/
|
||||
public function readValueFromCommitMessage($value) {
|
||||
if ($this->getProxy()) {
|
||||
$this->getProxy()->readValueFromCommitMessage($value);
|
||||
return $this;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @task commitmessage
|
||||
*/
|
||||
public function shouldOverwriteWhenCommitMessageIsEdited() {
|
||||
if ($this->getProxy()) {
|
||||
return $this->getProxy()->shouldOverwriteWhenCommitMessageIsEdited();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @task commitmessage
|
||||
*/
|
||||
public function getRequiredHandlePHIDsForCommitMessage() {
|
||||
if ($this->getProxy()) {
|
||||
return $this->getProxy()->getRequiredHandlePHIDsForCommitMessage();
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @task commitmessage
|
||||
*/
|
||||
public function renderCommitMessageLabel() {
|
||||
if ($this->getProxy()) {
|
||||
return $this->getProxy()->renderCommitMessageLabel();
|
||||
}
|
||||
return $this->getFieldName();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @task commitmessage
|
||||
*/
|
||||
public function renderCommitMessageValue(array $handles) {
|
||||
if ($this->getProxy()) {
|
||||
return $this->getProxy()->renderCommitMessageValue($handles);
|
||||
}
|
||||
throw new PhabricatorCustomFieldImplementationIncompleteException($this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @task commitmessage
|
||||
*/
|
||||
public function validateCommitMessageValue($value) {
|
||||
if ($this->getProxy()) {
|
||||
return $this->getProxy()->validateCommitMessageValue($value);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* -( Integration with Diff Properties )----------------------------------- */
|
||||
|
||||
|
||||
|
|
|
@ -270,39 +270,6 @@ final class DifferentialJIRAIssuesField
|
|||
$editor->save();
|
||||
}
|
||||
|
||||
public function shouldAppearInCommitMessage() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function shouldAppearInCommitMessageTemplate() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getCommitMessageLabels() {
|
||||
return array(
|
||||
'JIRA',
|
||||
'JIRA Issues',
|
||||
'JIRA Issue',
|
||||
);
|
||||
}
|
||||
|
||||
public function parseValueFromCommitMessage($value) {
|
||||
return preg_split('/[\s,]+/', $value, $limit = -1, PREG_SPLIT_NO_EMPTY);
|
||||
}
|
||||
|
||||
public function readValueFromCommitMessage($value) {
|
||||
$this->setValue($value);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function renderCommitMessageValue(array $handles) {
|
||||
$value = $this->getValue();
|
||||
if (!$value) {
|
||||
return null;
|
||||
}
|
||||
return implode(', ', $value);
|
||||
}
|
||||
|
||||
public function shouldAppearInConduitDictionary() {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -130,14 +130,6 @@ final class DifferentialRevertPlanField
|
|||
return array($xaction->getNewValue());
|
||||
}
|
||||
|
||||
public function shouldAppearInCommitMessage() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function renderCommitMessageValue(array $handles) {
|
||||
return $this->getValue();
|
||||
}
|
||||
|
||||
public function shouldAppearInConduitDictionary() {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ abstract class DifferentialCommitMessageCustomField
|
|||
protected function getCustomFieldOrder($key) {
|
||||
$field_list = PhabricatorCustomField::getObjectFields(
|
||||
new DifferentialRevision(),
|
||||
DifferentialCustomField::ROLE_COMMITMESSAGE);
|
||||
PhabricatorCustomField::ROLE_DEFAULT);
|
||||
|
||||
$fields = $field_list->getFields();
|
||||
|
||||
|
|
|
@ -473,34 +473,9 @@ final class DifferentialRevisionQuery
|
|||
}
|
||||
|
||||
if ($this->needDrafts) {
|
||||
$viewer_phid = $viewer->getPHID();
|
||||
$draft_type = PhabricatorObjectHasDraftEdgeType::EDGECONST;
|
||||
|
||||
if (!$viewer_phid) {
|
||||
// Viewers without a valid PHID can never have drafts.
|
||||
foreach ($revisions as $revision) {
|
||||
$revision->attachHasDraft($viewer, false);
|
||||
}
|
||||
} else {
|
||||
$edge_query = id(new PhabricatorEdgeQuery())
|
||||
->withSourcePHIDs(mpull($revisions, 'getPHID'))
|
||||
->withEdgeTypes(
|
||||
array(
|
||||
$draft_type,
|
||||
))
|
||||
->withDestinationPHIDs(array($viewer_phid));
|
||||
|
||||
$edge_query->execute();
|
||||
|
||||
foreach ($revisions as $revision) {
|
||||
$has_draft = (bool)$edge_query->getDestinationPHIDs(
|
||||
array(
|
||||
$revision->getPHID(),
|
||||
));
|
||||
|
||||
$revision->attachHasDraft($viewer, $has_draft);
|
||||
}
|
||||
}
|
||||
PhabricatorDraftEngine::attachDrafts(
|
||||
$viewer,
|
||||
$revisions);
|
||||
}
|
||||
|
||||
return $revisions;
|
||||
|
|
|
@ -50,7 +50,7 @@ final class DifferentialRevisionAcceptTransaction
|
|||
|
||||
public function generateOldValue($object) {
|
||||
$actor = $this->getActor();
|
||||
return $this->isViewerAcceptingReviewer($object, $actor);
|
||||
return $this->isViewerFullyAccepted($object, $actor);
|
||||
}
|
||||
|
||||
public function applyExternalEffects($object, $value) {
|
||||
|
@ -79,7 +79,7 @@ final class DifferentialRevisionAcceptTransaction
|
|||
}
|
||||
}
|
||||
|
||||
if ($this->isViewerAcceptingReviewer($object, $viewer)) {
|
||||
if ($this->isViewerFullyAccepted($object, $viewer)) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'You can not accept this revision because you have already '.
|
||||
|
|
|
@ -46,7 +46,7 @@ final class DifferentialRevisionRejectTransaction
|
|||
|
||||
public function generateOldValue($object) {
|
||||
$actor = $this->getActor();
|
||||
return $this->isViewerRejectingReviewer($object, $actor);
|
||||
return $this->isViewerFullyRejected($object, $actor);
|
||||
}
|
||||
|
||||
public function applyExternalEffects($object, $value) {
|
||||
|
@ -72,7 +72,7 @@ final class DifferentialRevisionRejectTransaction
|
|||
'not own.'));
|
||||
}
|
||||
|
||||
if ($this->isViewerRejectingReviewer($object, $viewer)) {
|
||||
if ($this->isViewerFullyRejected($object, $viewer)) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'You can not request changes to this revision because you have '.
|
||||
|
|
|
@ -13,10 +13,10 @@ abstract class DifferentialRevisionReviewTransaction
|
|||
return ($this->getViewerReviewerStatus($revision, $viewer) !== null);
|
||||
}
|
||||
|
||||
protected function isViewerAcceptingReviewer(
|
||||
protected function isViewerFullyAccepted(
|
||||
DifferentialRevision $revision,
|
||||
PhabricatorUser $viewer) {
|
||||
return $this->isViewerReviewerStatusAmong(
|
||||
return $this->isViewerReviewerStatusFullyAmong(
|
||||
$revision,
|
||||
$viewer,
|
||||
array(
|
||||
|
@ -24,10 +24,10 @@ abstract class DifferentialRevisionReviewTransaction
|
|||
));
|
||||
}
|
||||
|
||||
protected function isViewerRejectingReviewer(
|
||||
protected function isViewerFullyRejected(
|
||||
DifferentialRevision $revision,
|
||||
PhabricatorUser $viewer) {
|
||||
return $this->isViewerReviewerStatusAmong(
|
||||
return $this->isViewerReviewerStatusFullyAmong(
|
||||
$revision,
|
||||
$viewer,
|
||||
array(
|
||||
|
@ -54,18 +54,34 @@ abstract class DifferentialRevisionReviewTransaction
|
|||
return null;
|
||||
}
|
||||
|
||||
protected function isViewerReviewerStatusAmong(
|
||||
protected function isViewerReviewerStatusFullyAmong(
|
||||
DifferentialRevision $revision,
|
||||
PhabricatorUser $viewer,
|
||||
array $status_list) {
|
||||
|
||||
// If the user themselves is not a reviewer, the reviews they have
|
||||
// authority over can not all be in any set of states since their own
|
||||
// personal review has no state.
|
||||
$status = $this->getViewerReviewerStatus($revision, $viewer);
|
||||
if ($status === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Otherwise, check that all reviews they have authority over are in
|
||||
// the desired set of states.
|
||||
$status_map = array_fuse($status_list);
|
||||
return isset($status_map[$status]);
|
||||
foreach ($revision->getReviewerStatus() as $reviewer) {
|
||||
if (!$reviewer->hasAuthority($viewer)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$status = $reviewer->getStatus();
|
||||
if (!isset($status_map[$status])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function applyReviewerEffect(
|
||||
|
|
|
@ -20,6 +20,10 @@ final class DiffusionRepositoryEditEngine
|
|||
return false;
|
||||
}
|
||||
|
||||
public function isDefaultQuickCreateEngine() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getEngineName() {
|
||||
return pht('Repositories');
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
final class DiffusionCommitDraftEngine
|
||||
extends PhabricatorDraftEngine {
|
||||
|
||||
protected function hasCustomDraftContent() {
|
||||
$viewer = $this->getViewer();
|
||||
$commit = $this->getObject();
|
||||
|
||||
$inlines = PhabricatorAuditInlineComment::loadDraftComments(
|
||||
$viewer,
|
||||
$commit->getPHID(),
|
||||
$raw = true);
|
||||
|
||||
return (bool)$inlines;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
final class DiffusionCommitAuditorsHeraldField
|
||||
extends DiffusionCommitHeraldField {
|
||||
|
||||
const FIELDCONST = 'diffusion.commit.auditors';
|
||||
|
||||
public function getHeraldFieldName() {
|
||||
return pht('Auditors');
|
||||
}
|
||||
|
||||
public function getHeraldFieldValue($object) {
|
||||
$viewer = PhabricatorUser::getOmnipotentUser();
|
||||
|
||||
$commit = id(new DiffusionCommitQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($object->getPHID()))
|
||||
->needAuditRequests(true)
|
||||
->executeOne();
|
||||
|
||||
$audits = $commit->getAudits();
|
||||
|
||||
$phids = array();
|
||||
foreach ($audits as $audit) {
|
||||
if ($audit->isActiveAudit()) {
|
||||
$phids[] = $audit->getAuditorPHID();
|
||||
}
|
||||
}
|
||||
|
||||
return $phids;
|
||||
}
|
||||
|
||||
protected function getHeraldFieldStandardType() {
|
||||
return self::STANDARD_PHID_LIST;
|
||||
}
|
||||
|
||||
protected function getDatasource() {
|
||||
return new DiffusionAuditorDatasource();
|
||||
}
|
||||
|
||||
}
|
|
@ -22,6 +22,7 @@ final class DiffusionCommitQuery
|
|||
private $importing;
|
||||
|
||||
private $needCommitData;
|
||||
private $needDrafts;
|
||||
|
||||
public function withIDs(array $ids) {
|
||||
$this->ids = $ids;
|
||||
|
@ -98,6 +99,11 @@ final class DiffusionCommitQuery
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function needDrafts($need) {
|
||||
$this->needDrafts = $need;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function needAuditRequests($need) {
|
||||
$this->needAuditRequests = $need;
|
||||
return $this;
|
||||
|
@ -239,6 +245,8 @@ final class DiffusionCommitQuery
|
|||
}
|
||||
|
||||
protected function didFilterPage(array $commits) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
if ($this->needCommitData) {
|
||||
$data = id(new PhabricatorRepositoryCommitData())->loadAllWhere(
|
||||
'commitID in (%Ld)',
|
||||
|
@ -268,6 +276,12 @@ final class DiffusionCommitQuery
|
|||
}
|
||||
}
|
||||
|
||||
if ($this->needDrafts) {
|
||||
PhabricatorDraftEngine::attachDrafts(
|
||||
$viewer,
|
||||
$commits);
|
||||
}
|
||||
|
||||
return $commits;
|
||||
}
|
||||
|
||||
|
|
|
@ -187,6 +187,19 @@ final class DiffusionHistoryTableView extends DiffusionView {
|
|||
'type' => $history->getFileType(),
|
||||
));
|
||||
|
||||
$status = $commit->getAuditStatus();
|
||||
$icon = PhabricatorAuditCommitStatusConstants::getStatusIcon($status);
|
||||
$color = PhabricatorAuditCommitStatusConstants::getStatusColor($status);
|
||||
$name = PhabricatorAuditCommitStatusConstants::getStatusName($status);
|
||||
|
||||
$audit_view = id(new PHUIIconView())
|
||||
->setIcon($icon, $color)
|
||||
->addSigil('has-tooltip')
|
||||
->setMetadata(
|
||||
array(
|
||||
'tip' => $name,
|
||||
));
|
||||
|
||||
$rows[] = array(
|
||||
$graph ? $graph[$ii++] : null,
|
||||
$browse,
|
||||
|
@ -194,6 +207,7 @@ final class DiffusionHistoryTableView extends DiffusionView {
|
|||
$drequest->getRepository(),
|
||||
$history->getCommitIdentifier()),
|
||||
$build,
|
||||
$audit_view,
|
||||
($commit ?
|
||||
self::linkRevision(idx($this->revisions, $commit->getPHID())) :
|
||||
null),
|
||||
|
@ -211,7 +225,8 @@ final class DiffusionHistoryTableView extends DiffusionView {
|
|||
pht('Commit'),
|
||||
null,
|
||||
null,
|
||||
pht('Author/Committer'),
|
||||
null,
|
||||
pht('Author'),
|
||||
pht('Details'),
|
||||
pht('Committed'),
|
||||
));
|
||||
|
@ -221,6 +236,7 @@ final class DiffusionHistoryTableView extends DiffusionView {
|
|||
'nudgeright',
|
||||
'',
|
||||
'icon',
|
||||
'icon',
|
||||
'',
|
||||
'',
|
||||
'wide',
|
||||
|
@ -232,6 +248,7 @@ final class DiffusionHistoryTableView extends DiffusionView {
|
|||
true,
|
||||
true,
|
||||
$has_any_build,
|
||||
true,
|
||||
$show_revisions,
|
||||
));
|
||||
$view->setDeviceVisibility(
|
||||
|
@ -241,6 +258,7 @@ final class DiffusionHistoryTableView extends DiffusionView {
|
|||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
|
|
|
@ -15,7 +15,7 @@ final class PhabricatorFavoritesApplication extends PhabricatorApplication {
|
|||
}
|
||||
|
||||
public function getIcon() {
|
||||
return 'fa-star-o';
|
||||
return 'fa-star';
|
||||
}
|
||||
|
||||
public function getRoutes() {
|
||||
|
@ -32,8 +32,82 @@ final class PhabricatorFavoritesApplication extends PhabricatorApplication {
|
|||
return false;
|
||||
}
|
||||
|
||||
public function getApplicationOrder() {
|
||||
return 9;
|
||||
public function buildMainMenuExtraNodes(
|
||||
PhabricatorUser $viewer,
|
||||
PhabricatorController $controller = null) {
|
||||
|
||||
$dropdown = $this->renderFavoritesDropdown($viewer);
|
||||
if (!$dropdown) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setHref('#')
|
||||
->setIcon('fa-star')
|
||||
->addClass('phabricator-core-user-menu')
|
||||
->setNoCSS(true)
|
||||
->setDropdown(true)
|
||||
->setDropdownMenu($dropdown);
|
||||
}
|
||||
|
||||
private function renderFavoritesDropdown(PhabricatorUser $viewer) {
|
||||
$application = __CLASS__;
|
||||
|
||||
$applications = id(new PhabricatorApplicationQuery())
|
||||
->setViewer($viewer)
|
||||
->withClasses(array($application))
|
||||
->withInstalled(true)
|
||||
->execute();
|
||||
$favorites = head($applications);
|
||||
if (!$favorites) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$menu_engine = id(new PhabricatorFavoritesProfileMenuEngine())
|
||||
->setViewer($viewer)
|
||||
->setProfileObject($favorites);
|
||||
|
||||
if ($viewer->getPHID()) {
|
||||
$menu_engine
|
||||
->setCustomPHID($viewer->getPHID())
|
||||
->setMenuType(PhabricatorProfileMenuEngine::MENU_COMBINED);
|
||||
} else {
|
||||
$menu_engine
|
||||
->setMenuType(PhabricatorProfileMenuEngine::MENU_GLOBAL);
|
||||
}
|
||||
|
||||
$filter_view = $menu_engine->buildNavigation();
|
||||
|
||||
$menu_view = $filter_view->getMenu();
|
||||
$item_views = $menu_view->getItems();
|
||||
|
||||
$view = id(new PhabricatorActionListView())
|
||||
->setViewer($viewer);
|
||||
foreach ($item_views as $item) {
|
||||
$type = null;
|
||||
if (!strlen($item->getName())) {
|
||||
$type = PhabricatorActionView::TYPE_DIVIDER;
|
||||
}
|
||||
$action = id(new PhabricatorActionView())
|
||||
->setName($item->getName())
|
||||
->setHref($item->getHref())
|
||||
->setType($type);
|
||||
$view->addAction($action);
|
||||
}
|
||||
|
||||
// Build out edit interface
|
||||
if ($viewer->isLoggedIn()) {
|
||||
$view->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setType(PhabricatorActionView::TYPE_DIVIDER));
|
||||
$view->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Edit Favorites'))
|
||||
->setHref('/favorites/'));
|
||||
}
|
||||
|
||||
return $view;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorFavoritesConstants
|
||||
extends PhabricatorFavoritesController {
|
||||
|
||||
const ITEM_TASK = 'favorites.task';
|
||||
const ITEM_PROJECT = 'favorites.project';
|
||||
const ITEM_REPOSITORY = 'favorites.repository';
|
||||
const ITEM_MANAGE = 'favorites.manage';
|
||||
|
||||
}
|
|
@ -10,6 +10,11 @@ final class PhabricatorFavoritesMainController
|
|||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
|
||||
if (!$viewer->getIsAdmin()) {
|
||||
$uri = '/favorites/personal/item/configure/';
|
||||
return id(new AphrontRedirectResponse())->setURI($uri);
|
||||
}
|
||||
|
||||
$menu = id(new PHUIObjectItemListView())
|
||||
->setUser($viewer);
|
||||
|
||||
|
|
|
@ -7,8 +7,10 @@ final class PhabricatorFavoritesMenuItemController
|
|||
$viewer = $this->getViewer();
|
||||
$type = $request->getURIData('type');
|
||||
$custom_phid = null;
|
||||
$menu = PhabricatorProfileMenuEngine::MENU_GLOBAL;
|
||||
if ($type == 'personal') {
|
||||
$custom_phid = $viewer->getPHID();
|
||||
$menu = PhabricatorProfileMenuEngine::MENU_PERSONAL;
|
||||
}
|
||||
|
||||
$application = 'PhabricatorFavoritesApplication';
|
||||
|
@ -21,7 +23,9 @@ final class PhabricatorFavoritesMenuItemController
|
|||
$engine = id(new PhabricatorFavoritesProfileMenuEngine())
|
||||
->setProfileObject($favorites)
|
||||
->setCustomPHID($custom_phid)
|
||||
->setController($this);
|
||||
->setController($this)
|
||||
->setMenuType($menu)
|
||||
->setShowNavigation(false);
|
||||
|
||||
return $engine->buildResponse();
|
||||
}
|
||||
|
|
|
@ -20,50 +20,28 @@ final class PhabricatorFavoritesProfileMenuEngine
|
|||
|
||||
protected function getBuiltinProfileItems($object) {
|
||||
$items = array();
|
||||
$custom_phid = $this->getCustomPHID();
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
// Built-in Global Defaults
|
||||
if (!$custom_phid) {
|
||||
$create_task = array(
|
||||
'name' => null,
|
||||
'formKey' =>
|
||||
id(new ManiphestEditEngine())->getProfileMenuItemDefault(),
|
||||
);
|
||||
$engines = PhabricatorEditEngine::getAllEditEngines();
|
||||
$engines = msortv($engines, 'getQuickCreateOrderVector');
|
||||
|
||||
$create_project = array(
|
||||
'name' => null,
|
||||
'formKey' =>
|
||||
id(new PhabricatorProjectEditEngine())->getProfileMenuItemDefault(),
|
||||
);
|
||||
foreach ($engines as $engine) {
|
||||
foreach ($engine->getDefaultQuickCreateFormKeys() as $form_key) {
|
||||
$form_hash = PhabricatorHash::digestForIndex($form_key);
|
||||
$builtin_key = "editengine.form({$form_hash})";
|
||||
|
||||
$create_repository = array(
|
||||
'name' => null,
|
||||
'formKey' =>
|
||||
id(new DiffusionRepositoryEditEngine())->getProfileMenuItemDefault(),
|
||||
);
|
||||
$properties = array(
|
||||
'name' => null,
|
||||
'formKey' => $form_key,
|
||||
);
|
||||
|
||||
$items[] = $this->newItem()
|
||||
->setBuiltinKey(PhabricatorFavoritesConstants::ITEM_TASK)
|
||||
->setMenuItemKey(PhabricatorEditEngineProfileMenuItem::MENUITEMKEY)
|
||||
->setMenuItemProperties($create_task);
|
||||
|
||||
$items[] = $this->newItem()
|
||||
->setBuiltinKey(PhabricatorFavoritesConstants::ITEM_PROJECT)
|
||||
->setMenuItemKey(PhabricatorEditEngineProfileMenuItem::MENUITEMKEY)
|
||||
->setMenuItemProperties($create_project);
|
||||
|
||||
$items[] = $this->newItem()
|
||||
->setBuiltinKey(PhabricatorFavoritesConstants::ITEM_REPOSITORY)
|
||||
->setMenuItemKey(PhabricatorEditEngineProfileMenuItem::MENUITEMKEY)
|
||||
->setMenuItemProperties($create_repository);
|
||||
$items[] = $this->newItem()
|
||||
->setBuiltinKey($builtin_key)
|
||||
->setMenuItemKey(PhabricatorEditEngineProfileMenuItem::MENUITEMKEY)
|
||||
->setMenuItemProperties($properties);
|
||||
}
|
||||
}
|
||||
|
||||
// Single Manage Item, switches URI based on admin/user
|
||||
$items[] = $this->newItem()
|
||||
->setBuiltinKey(PhabricatorFavoritesConstants::ITEM_MANAGE)
|
||||
->setMenuItemKey(
|
||||
PhabricatorFavoritesManageProfileMenuItem::MENUITEMKEY);
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,72 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorFavoritesManageProfileMenuItem
|
||||
extends PhabricatorProfileMenuItem {
|
||||
|
||||
const MENUITEMKEY = 'favorites.manage';
|
||||
|
||||
public function getMenuItemTypeName() {
|
||||
return pht('Manage Favorites');
|
||||
}
|
||||
|
||||
private function getDefaultName() {
|
||||
return pht('Manage');
|
||||
}
|
||||
|
||||
public function canHideMenuItem(
|
||||
PhabricatorProfileMenuItemConfiguration $config) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function canMakeDefault(
|
||||
PhabricatorProfileMenuItemConfiguration $config) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDisplayName(
|
||||
PhabricatorProfileMenuItemConfiguration $config) {
|
||||
$name = $config->getMenuItemProperty('name');
|
||||
|
||||
if (strlen($name)) {
|
||||
return $name;
|
||||
}
|
||||
|
||||
return $this->getDefaultName();
|
||||
}
|
||||
|
||||
public function buildEditEngineFields(
|
||||
PhabricatorProfileMenuItemConfiguration $config) {
|
||||
return array(
|
||||
id(new PhabricatorTextEditField())
|
||||
->setKey('name')
|
||||
->setLabel(pht('Name'))
|
||||
->setPlaceholder($this->getDefaultName())
|
||||
->setValue($config->getMenuItemProperty('name')),
|
||||
);
|
||||
}
|
||||
|
||||
protected function newNavigationMenuItems(
|
||||
PhabricatorProfileMenuItemConfiguration $config) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
if ($viewer->isLoggedIn()) {
|
||||
$admin = $viewer->getIsAdmin();
|
||||
$name = $this->getDisplayName($config);
|
||||
$icon = 'fa-pencil';
|
||||
$href = '/favorites/personal/item/configure/';
|
||||
if ($admin) {
|
||||
$href = '/favorites/';
|
||||
}
|
||||
|
||||
$item = $this->newItem()
|
||||
->setHref($href)
|
||||
->setName($name)
|
||||
->setIcon($icon);
|
||||
}
|
||||
|
||||
return array(
|
||||
$item,
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -31,7 +31,6 @@ final class PhabricatorHelpDocumentationController
|
|||
$list->addItem(
|
||||
id(new PHUIObjectItemView())
|
||||
->setHeader($item->getName())
|
||||
->setWorkflow($item->getWorkflow())
|
||||
->setHref($item->getHref()));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,70 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorHelpMainMenuBarExtension
|
||||
extends PhabricatorMainMenuBarExtension {
|
||||
|
||||
const MAINMENUBARKEY = 'help';
|
||||
|
||||
public function isExtensionEnabledForViewer(PhabricatorUser $viewer) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function buildMainMenus() {
|
||||
$application = $this->getApplication();
|
||||
if (!$application) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$viewer = $this->getViewer();
|
||||
$help_links = $application->getHelpMenuItems($viewer);
|
||||
if (!$help_links) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$help_id = celerity_generate_unique_node_id();
|
||||
|
||||
Javelin::initBehavior(
|
||||
'aphlict-dropdown',
|
||||
array(
|
||||
'bubbleID' => $help_id,
|
||||
'dropdownID' => 'phabricator-help-menu',
|
||||
'local' => true,
|
||||
'desktop' => true,
|
||||
'right' => true,
|
||||
));
|
||||
|
||||
$help_name = pht('%s Help', $application->getName());
|
||||
|
||||
$help_item = id(new PHUIListItemView())
|
||||
->setIcon('fa-book')
|
||||
->addClass('core-menu-item')
|
||||
->setID($help_id)
|
||||
->setName($help_name)
|
||||
->setHref('/help/documentation/'.get_class($application).'/')
|
||||
->setAural($help_name);
|
||||
|
||||
$view = new PHUIListView();
|
||||
foreach ($help_links as $help_link) {
|
||||
$view->addMenuItem($help_link);
|
||||
}
|
||||
|
||||
$dropdown_menu = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'id' => 'phabricator-help-menu',
|
||||
'class' => 'phabricator-main-menu-dropdown phui-list-sidenav',
|
||||
'style' => 'display: none',
|
||||
),
|
||||
$view);
|
||||
|
||||
$help_menu = id(new PHUIMainMenuView())
|
||||
->setOrder(200)
|
||||
->setMenuBarItem($help_item)
|
||||
->appendChild($dropdown_menu);
|
||||
|
||||
return array(
|
||||
$help_menu,
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
final class PhabricatorHomeApplication extends PhabricatorApplication {
|
||||
|
||||
private $quickItems;
|
||||
const DASHBOARD_DEFAULT = 'dashboard:default';
|
||||
|
||||
public function getBaseURI() {
|
||||
|
@ -26,7 +25,6 @@ final class PhabricatorHomeApplication extends PhabricatorApplication {
|
|||
'/' => 'PhabricatorHomeMainController',
|
||||
'/(?P<only>home)/' => 'PhabricatorHomeMainController',
|
||||
'/home/' => array(
|
||||
'create/' => 'PhabricatorHomeQuickCreateController',
|
||||
'menu/' => array(
|
||||
'' => 'PhabricatorHomeMenuController',
|
||||
'(?P<type>global|personal)/item/' => $this->getProfileMenuRouting(
|
||||
|
@ -44,73 +42,114 @@ final class PhabricatorHomeApplication extends PhabricatorApplication {
|
|||
return 9;
|
||||
}
|
||||
|
||||
public function buildMainMenuItems(
|
||||
PhabricatorUser $user,
|
||||
PhabricatorController $controller = null) {
|
||||
|
||||
$quick_items = $this->getQuickActionItems($user);
|
||||
if (!$quick_items) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$items = array();
|
||||
$create_id = celerity_generate_unique_node_id();
|
||||
|
||||
Javelin::initBehavior(
|
||||
'aphlict-dropdown',
|
||||
array(
|
||||
'bubbleID' => $create_id,
|
||||
'dropdownID' => 'phabricator-quick-create-menu',
|
||||
'local' => true,
|
||||
'desktop' => true,
|
||||
'right' => true,
|
||||
));
|
||||
|
||||
$item = id(new PHUIListItemView())
|
||||
->setName(pht('Quick Actions'))
|
||||
->setIcon('fa-plus')
|
||||
->addClass('core-menu-item')
|
||||
->setHref('/home/create/')
|
||||
->addSigil('quick-create-menu')
|
||||
->setID($create_id)
|
||||
->setAural(pht('Quick Actions'))
|
||||
->setOrder(300);
|
||||
$items[] = $item;
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
public function buildMainMenuExtraNodes(
|
||||
PhabricatorUser $viewer,
|
||||
PhabricatorController $controller = null) {
|
||||
|
||||
$items = $this->getQuickActionItems($viewer);
|
||||
|
||||
$view = null;
|
||||
if ($items) {
|
||||
$view = new PHUIListView();
|
||||
foreach ($items as $item) {
|
||||
$view->addMenuItem($item);
|
||||
}
|
||||
|
||||
return phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'id' => 'phabricator-quick-create-menu',
|
||||
'class' => 'phabricator-main-menu-dropdown phui-list-sidenav',
|
||||
'style' => 'display: none',
|
||||
),
|
||||
$view);
|
||||
if (!$viewer->isLoggedIn()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$image = $viewer->getProfileImageURI();
|
||||
|
||||
$profile_image = id(new PHUIIconView())
|
||||
->setImage($image)
|
||||
->setHeadSize(PHUIIconView::HEAD_SMALL);
|
||||
|
||||
if ($controller) {
|
||||
$application = $controller->getCurrentApplication();
|
||||
} else {
|
||||
$application = null;
|
||||
}
|
||||
$dropdown_menu = $this->renderUserDropdown($viewer, $application);
|
||||
|
||||
$menu_id = celerity_generate_unique_node_id();
|
||||
|
||||
Javelin::initBehavior(
|
||||
'user-menu',
|
||||
array(
|
||||
'menuID' => $menu_id,
|
||||
'menu' => $dropdown_menu->getDropdownMenuMetadata(),
|
||||
));
|
||||
|
||||
return id(new PHUIButtonView())
|
||||
->setID($menu_id)
|
||||
->setTag('a')
|
||||
->setHref('/p/'.$viewer->getUsername().'/')
|
||||
->setIcon($profile_image)
|
||||
->addClass('phabricator-core-user-menu')
|
||||
->setHasCaret(true)
|
||||
->setNoCSS(true);
|
||||
}
|
||||
|
||||
private function renderUserDropdown(
|
||||
PhabricatorUser $viewer,
|
||||
$application) {
|
||||
|
||||
$person_to_show = id(new PHUIObjectItemView())
|
||||
->setObjectName($viewer->getRealName())
|
||||
->setSubHead($viewer->getUsername())
|
||||
->setImageURI($viewer->getProfileImageURI());
|
||||
|
||||
$user_view = id(new PHUIObjectItemListView())
|
||||
->setViewer($viewer)
|
||||
->setFlush(true)
|
||||
->setSimple(true)
|
||||
->addItem($person_to_show)
|
||||
->addClass('phabricator-core-user-profile-object');
|
||||
|
||||
$view = id(new PhabricatorActionListView())
|
||||
->setViewer($viewer);
|
||||
|
||||
// User Menu
|
||||
$view->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->appendChild($user_view));
|
||||
|
||||
$view->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setType(PhabricatorActionView::TYPE_DIVIDER));
|
||||
|
||||
$view->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Profile'))
|
||||
->setHref('/p/'.$viewer->getUsername().'/'));
|
||||
|
||||
$view->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Settings'))
|
||||
->setHref('/settings/user/'.$viewer->getUsername().'/'));
|
||||
|
||||
$view->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Manage'))
|
||||
->setHref('/people/manage/'.$viewer->getID().'/'));
|
||||
|
||||
// Help Menus
|
||||
if ($application) {
|
||||
$help_links = $application->getHelpMenuItems($viewer);
|
||||
if ($help_links) {
|
||||
foreach ($help_links as $link) {
|
||||
$view->addAction($link);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Logout Menu
|
||||
$view->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->addSigil('logout-item')
|
||||
->setType(PhabricatorActionView::TYPE_DIVIDER));
|
||||
|
||||
$view->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Log Out %s', $viewer->getUsername()))
|
||||
->addSigil('logout-item')
|
||||
->setHref('/logout/')
|
||||
->setColor(PhabricatorActionView::RED)
|
||||
->setWorkflow(true));
|
||||
|
||||
return $view;
|
||||
}
|
||||
|
||||
private function getQuickActionItems(PhabricatorUser $viewer) {
|
||||
if ($this->quickItems === null) {
|
||||
$items = PhabricatorQuickActions::loadMenuItemsForUser($viewer);
|
||||
$this->quickItems = $items;
|
||||
}
|
||||
return $this->quickItems;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorHomeQuickCreateController
|
||||
extends PhabricatorHomeController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$items = PhabricatorQuickActions::loadMenuItemsForUser($viewer);
|
||||
|
||||
$list = id(new PHUIObjectItemListView())
|
||||
->setUser($viewer);
|
||||
|
||||
foreach ($items as $item) {
|
||||
$list->addItem(
|
||||
id(new PHUIObjectItemView())
|
||||
->setHeader($item->getName())
|
||||
->setWorkflow($item->getWorkflow())
|
||||
->setHref($item->getHref()));
|
||||
}
|
||||
|
||||
$title = pht('Quick Create');
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb(pht('Quick Create'));
|
||||
$crumbs->setBorder(true);
|
||||
|
||||
$box = id(new PHUIObjectBoxView())
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setObjectList($list);
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader($title)
|
||||
->setHeaderIcon('fa-plus-square');
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setFooter($box);
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->appendChild($view);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -21,6 +21,10 @@ final class ManiphestEditEngine
|
|||
return 'PhabricatorManiphestApplication';
|
||||
}
|
||||
|
||||
public function isDefaultQuickCreateEngine() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function newEditableObject() {
|
||||
return ManiphestTask::initializeNewTask($this->getViewer());
|
||||
}
|
||||
|
|
|
@ -45,11 +45,6 @@ final class PhabricatorPeopleProfileManageController
|
|||
$nav = $this->getProfileMenu();
|
||||
$nav->selectFilter(PhabricatorPeopleProfileMenuEngine::ITEM_MANAGE);
|
||||
|
||||
$timeline = $this->buildTransactionTimeline(
|
||||
$user,
|
||||
new PhabricatorPeopleTransactionQuery());
|
||||
$timeline->setShouldTerminate(true);
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb(pht('Manage'));
|
||||
$crumbs->setBorder(true);
|
||||
|
@ -57,11 +52,7 @@ final class PhabricatorPeopleProfileManageController
|
|||
$manage = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setCurtain($curtain)
|
||||
->addPropertySection(pht('Details'), $properties)
|
||||
->setMainColumn(
|
||||
array(
|
||||
$timeline,
|
||||
));
|
||||
->addPropertySection(pht('Details'), $properties);
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle(
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorPeopleMainMenuBarExtension
|
||||
extends PhabricatorMainMenuBarExtension {
|
||||
|
||||
const MAINMENUBARKEY = 'people';
|
||||
|
||||
public function buildMainMenus() {
|
||||
$viewer = $this->getViewer();
|
||||
$image = $viewer->getProfileImageURI();
|
||||
|
||||
$bar_item = id(new PHUIListItemView())
|
||||
->setName($viewer->getUsername())
|
||||
->setHref('/p/'.$viewer->getUsername().'/')
|
||||
->addClass('core-menu-item')
|
||||
->setAural(pht('Profile'));
|
||||
|
||||
$classes = array(
|
||||
'phabricator-core-menu-icon',
|
||||
'phabricator-core-menu-profile-image',
|
||||
);
|
||||
|
||||
$bar_item->appendChild(
|
||||
phutil_tag(
|
||||
'span',
|
||||
array(
|
||||
'class' => implode(' ', $classes),
|
||||
'style' => 'background-image: url('.$image.')',
|
||||
),
|
||||
''));
|
||||
|
||||
$profile_menu = id(new PHUIMainMenuView())
|
||||
->setOrder(100)
|
||||
->setMenuBarItem($bar_item);
|
||||
|
||||
return array(
|
||||
$profile_menu,
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -11,7 +11,7 @@ final class PhabricatorPhameApplication extends PhabricatorApplication {
|
|||
}
|
||||
|
||||
public function getIcon() {
|
||||
return 'fa-star';
|
||||
return 'fa-feed';
|
||||
}
|
||||
|
||||
public function getShortDescription() {
|
||||
|
|
|
@ -26,6 +26,10 @@ final class PhabricatorProjectEditEngine
|
|||
return $this->milestoneProject;
|
||||
}
|
||||
|
||||
public function isDefaultQuickCreateEngine() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getEngineName() {
|
||||
return pht('Projects');
|
||||
}
|
||||
|
|
|
@ -49,6 +49,19 @@ final class PhabricatorRepositoryAuditRequest
|
|||
return $this->assertAttached($this->commit);
|
||||
}
|
||||
|
||||
public function isActiveAudit() {
|
||||
switch ($this->getAuditStatus()) {
|
||||
case PhabricatorAuditStatusConstants::NONE:
|
||||
case PhabricatorAuditStatusConstants::AUDIT_NOT_REQUIRED:
|
||||
case PhabricatorAuditStatusConstants::RESIGNED:
|
||||
case PhabricatorAuditStatusConstants::CLOSED:
|
||||
case PhabricatorAuditStatusConstants::CC:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function isInteresting() {
|
||||
switch ($this->getAuditStatus()) {
|
||||
case PhabricatorAuditStatusConstants::NONE:
|
||||
|
|
|
@ -14,7 +14,8 @@ final class PhabricatorRepositoryCommit
|
|||
PhabricatorCustomFieldInterface,
|
||||
PhabricatorApplicationTransactionInterface,
|
||||
PhabricatorFulltextInterface,
|
||||
PhabricatorConduitResultInterface {
|
||||
PhabricatorConduitResultInterface,
|
||||
PhabricatorDraftInterface {
|
||||
|
||||
protected $repositoryID;
|
||||
protected $phid;
|
||||
|
@ -39,6 +40,7 @@ final class PhabricatorRepositoryCommit
|
|||
private $audits = self::ATTACHABLE;
|
||||
private $repository = self::ATTACHABLE;
|
||||
private $customFields = self::ATTACHABLE;
|
||||
private $drafts = array();
|
||||
|
||||
public function attachRepository(PhabricatorRepository $repository) {
|
||||
$this->repository = $repository;
|
||||
|
@ -342,6 +344,7 @@ final class PhabricatorRepositoryCommit
|
|||
return nonempty($parsed->getDisplayName(), $parsed->getAddress());
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
||||
|
||||
public function getCapabilities() {
|
||||
|
@ -603,4 +606,20 @@ final class PhabricatorRepositoryCommit
|
|||
return array();
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorDraftInterface )------------------------------------------ */
|
||||
|
||||
public function newDraftEngine() {
|
||||
return new DiffusionCommitDraftEngine();
|
||||
}
|
||||
|
||||
public function getHasDraft(PhabricatorUser $viewer) {
|
||||
return $this->assertAttachedKey($this->drafts, $viewer->getCacheFragment());
|
||||
}
|
||||
|
||||
public function attachHasDraft(PhabricatorUser $viewer, $has_draft) {
|
||||
$this->drafts[$viewer->getCacheFragment()] = $has_draft;
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -109,6 +109,7 @@ final class PhabricatorProfileMenuEditEngine
|
|||
}
|
||||
|
||||
protected function getObjectEditTitleText($object) {
|
||||
$object->willBuildNavigationItems(array($object));
|
||||
return pht('Edit Menu Item: %s', $object->getDisplayName());
|
||||
}
|
||||
|
||||
|
@ -148,4 +149,47 @@ final class PhabricatorProfileMenuEditEngine
|
|||
return $fields;
|
||||
}
|
||||
|
||||
protected function getValidationExceptionShortMessage(
|
||||
PhabricatorApplicationTransactionValidationException $ex,
|
||||
PhabricatorEditField $field) {
|
||||
|
||||
// Menu item properties all have the same transaction type, so we need
|
||||
// to make sure errors about a specific property (like the URI for a
|
||||
// link) are only applied to the field for that particular property. If
|
||||
// we don't do this, the red error text like "Required" will display
|
||||
// next to every field.
|
||||
|
||||
$property_type =
|
||||
PhabricatorProfileMenuItemConfigurationTransaction::TYPE_PROPERTY;
|
||||
|
||||
$xaction_type = $field->getTransactionType();
|
||||
if ($xaction_type == $property_type) {
|
||||
$field_key = $field->getKey();
|
||||
foreach ($ex->getErrors() as $error) {
|
||||
if ($error->getType() !== $xaction_type) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$xaction = $error->getTransaction();
|
||||
if (!$xaction) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$xaction_setting = $xaction->getMetadataValue('property.key');
|
||||
if ($xaction_setting != $field_key) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$short_message = $error->getShortMessage();
|
||||
if ($short_message !== null) {
|
||||
return $short_message;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return parent::getValidationExceptionShortMessage($ex, $field);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -87,4 +87,39 @@ final class PhabricatorProfileMenuEditor
|
|||
return parent::applyCustomExternalTransaction($object, $xaction);
|
||||
}
|
||||
|
||||
protected function validateTransaction(
|
||||
PhabricatorLiskDAO $object,
|
||||
$type,
|
||||
array $xactions) {
|
||||
|
||||
$errors = parent::validateTransaction($object, $type, $xactions);
|
||||
|
||||
$actor = $this->getActor();
|
||||
$menu_item = $object->getMenuItem();
|
||||
$menu_item->setViewer($actor);
|
||||
|
||||
switch ($type) {
|
||||
case PhabricatorProfileMenuItemConfigurationTransaction::TYPE_PROPERTY:
|
||||
$key_map = array();
|
||||
foreach ($xactions as $xaction) {
|
||||
$xaction_key = $xaction->getMetadataValue('property.key');
|
||||
$old = $this->getCustomTransactionOldValue($object, $xaction);
|
||||
$new = $xaction->getNewValue();
|
||||
$key_map[$xaction_key][] = array(
|
||||
'xaction' => $xaction,
|
||||
'old' => $old,
|
||||
'new' => $new,
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($object->validateTransactions($key_map) as $error) {
|
||||
$errors[] = $error;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -6,9 +6,16 @@ abstract class PhabricatorProfileMenuEngine extends Phobject {
|
|||
private $profileObject;
|
||||
private $customPHID;
|
||||
private $items;
|
||||
private $menuType = self::MENU_GLOBAL;
|
||||
private $defaultItem;
|
||||
private $controller;
|
||||
private $navigation;
|
||||
private $showNavigation = true;
|
||||
|
||||
const MENU_GLOBAL = 'global';
|
||||
const MENU_PERSONAL = 'personal';
|
||||
const MENU_COMBINED = 'menu';
|
||||
const ITEM_CUSTOM_DIVIDER = 'engine.divider';
|
||||
|
||||
public function setViewer(PhabricatorUser $viewer) {
|
||||
$this->viewer = $viewer;
|
||||
|
@ -57,10 +64,35 @@ abstract class PhabricatorProfileMenuEngine extends Phobject {
|
|||
return $this->defaultItem;
|
||||
}
|
||||
|
||||
abstract protected function getItemURI($path);
|
||||
public function setMenuType($type) {
|
||||
$this->menuType = $type;
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function getMenuType() {
|
||||
return $this->menuType;
|
||||
}
|
||||
|
||||
public function setShowNavigation($show) {
|
||||
$this->showNavigation = $show;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getShowNavigation() {
|
||||
return $this->showNavigation;
|
||||
}
|
||||
|
||||
abstract protected function getItemURI($path);
|
||||
abstract protected function isMenuEngineConfigurable();
|
||||
|
||||
abstract protected function getBuiltinProfileItems($object);
|
||||
|
||||
protected function getBuiltinCustomProfileItems(
|
||||
$object,
|
||||
$custom_phid) {
|
||||
return array();
|
||||
}
|
||||
|
||||
public function buildResponse() {
|
||||
$controller = $this->getController();
|
||||
|
||||
|
@ -130,6 +162,14 @@ abstract class PhabricatorProfileMenuEngine extends Phobject {
|
|||
$navigation->selectFilter('item.configure');
|
||||
|
||||
$crumbs = $controller->buildApplicationCrumbsForEditEngine();
|
||||
switch ($this->getMenuType()) {
|
||||
case 'personal':
|
||||
$crumbs->addTextCrumb(pht('Personal'));
|
||||
break;
|
||||
case 'global':
|
||||
$crumbs->addTextCrumb(pht('Global'));
|
||||
break;
|
||||
}
|
||||
|
||||
switch ($item_action) {
|
||||
case 'view':
|
||||
|
@ -177,11 +217,15 @@ abstract class PhabricatorProfileMenuEngine extends Phobject {
|
|||
|
||||
$crumbs->setBorder(true);
|
||||
|
||||
return $controller->newPage()
|
||||
$page = $controller->newPage()
|
||||
->setTitle(pht('Configure Menu'))
|
||||
->setNavigation($navigation)
|
||||
->setCrumbs($crumbs)
|
||||
->appendChild($content);
|
||||
|
||||
if ($this->getShowNavigation()) {
|
||||
$page->setNavigation($navigation);
|
||||
}
|
||||
return $page;
|
||||
}
|
||||
|
||||
public function buildNavigation() {
|
||||
|
@ -194,6 +238,7 @@ abstract class PhabricatorProfileMenuEngine extends Phobject {
|
|||
->setBaseURI(new PhutilURI($this->getItemURI('')));
|
||||
|
||||
$menu_items = $this->getItems();
|
||||
|
||||
$filtered_items = array();
|
||||
foreach ($menu_items as $menu_item) {
|
||||
if ($menu_item->isDisabled()) {
|
||||
|
@ -239,11 +284,6 @@ abstract class PhabricatorProfileMenuEngine extends Phobject {
|
|||
}
|
||||
}
|
||||
|
||||
$more_items = $this->newAutomaticMenuItems($nav);
|
||||
foreach ($more_items as $item) {
|
||||
$nav->addMenuItem($item);
|
||||
}
|
||||
|
||||
$nav->selectFilter(null);
|
||||
|
||||
$this->navigation = $nav;
|
||||
|
@ -264,19 +304,25 @@ abstract class PhabricatorProfileMenuEngine extends Phobject {
|
|||
|
||||
$items = $this->loadBuiltinProfileItems();
|
||||
|
||||
if ($this->getCustomPHID()) {
|
||||
$stored_items = id(new PhabricatorProfileMenuItemConfigurationQuery())
|
||||
->setViewer($viewer)
|
||||
->withProfilePHIDs(array($object->getPHID()))
|
||||
->withCustomPHIDs(array($this->getCustomPHID()))
|
||||
->execute();
|
||||
} else {
|
||||
$stored_items = id(new PhabricatorProfileMenuItemConfigurationQuery())
|
||||
->setViewer($viewer)
|
||||
->withProfilePHIDs(array($object->getPHID()))
|
||||
->execute();
|
||||
$query = id(new PhabricatorProfileMenuItemConfigurationQuery())
|
||||
->setViewer($viewer)
|
||||
->withProfilePHIDs(array($object->getPHID()));
|
||||
|
||||
$menu_type = $this->getMenuType();
|
||||
switch ($menu_type) {
|
||||
case self::MENU_GLOBAL:
|
||||
$query->withCustomPHIDs(array(), true);
|
||||
break;
|
||||
case self::MENU_PERSONAL:
|
||||
$query->withCustomPHIDs(array($this->getCustomPHID()), false);
|
||||
break;
|
||||
case self::MENU_COMBINED:
|
||||
$query->withCustomPHIDs(array($this->getCustomPHID()), true);
|
||||
break;
|
||||
}
|
||||
|
||||
$stored_items = $query->execute();
|
||||
|
||||
foreach ($stored_items as $stored_item) {
|
||||
$impl = $stored_item->getMenuItem();
|
||||
$impl->setViewer($viewer);
|
||||
|
@ -305,12 +351,7 @@ abstract class PhabricatorProfileMenuEngine extends Phobject {
|
|||
}
|
||||
}
|
||||
|
||||
$items = msort($items, 'getSortKey');
|
||||
|
||||
// Normalize keys since callers shouldn't rely on this array being
|
||||
// partially keyed.
|
||||
$items = array_values($items);
|
||||
|
||||
$items = $this->arrangeItems($items);
|
||||
|
||||
// Make sure exactly one valid item is marked as default.
|
||||
$default = null;
|
||||
|
@ -343,7 +384,26 @@ abstract class PhabricatorProfileMenuEngine extends Phobject {
|
|||
|
||||
private function loadBuiltinProfileItems() {
|
||||
$object = $this->getProfileObject();
|
||||
$builtins = $this->getBuiltinProfileItems($object);
|
||||
|
||||
$menu_type = $this->getMenuType();
|
||||
switch ($menu_type) {
|
||||
case self::MENU_GLOBAL:
|
||||
$builtins = $this->getBuiltinProfileItems($object);
|
||||
break;
|
||||
case self::MENU_PERSONAL:
|
||||
$builtins = $this->getBuiltinCustomProfileItems(
|
||||
$object,
|
||||
$this->getCustomPHID());
|
||||
break;
|
||||
case self::MENU_COMBINED:
|
||||
$builtins = array();
|
||||
$builtins[] = $this->getBuiltinCustomProfileItems(
|
||||
$object,
|
||||
$this->getCustomPHID());
|
||||
$builtins[] = $this->getBuiltinProfileItems($object);
|
||||
$builtins = array_mergev($builtins);
|
||||
break;
|
||||
}
|
||||
|
||||
$items = PhabricatorProfileMenuItem::getAllMenuItems();
|
||||
$viewer = $this->getViewer();
|
||||
|
@ -410,73 +470,6 @@ abstract class PhabricatorProfileMenuEngine extends Phobject {
|
|||
}
|
||||
}
|
||||
|
||||
private function newAutomaticMenuItems(AphrontSideNavFilterView $nav) {
|
||||
$items = array();
|
||||
|
||||
// NOTE: We're adding a spacer item for the fixed footer, so that if the
|
||||
// menu taller than the page content you can still scroll down the page far
|
||||
// enough to access the last item without the content being obscured by the
|
||||
// fixed items.
|
||||
$items[] = id(new PHUIListItemView())
|
||||
->setHideInApplicationMenu(true)
|
||||
->addClass('phui-profile-menu-spacer');
|
||||
|
||||
$collapse_id = celerity_generate_unique_node_id();
|
||||
$viewer = $this->getViewer();
|
||||
$collapse_key = PhabricatorProfileMenuCollapsedSetting::SETTINGKEY;
|
||||
|
||||
$is_collapsed = $viewer->getUserSetting($collapse_key);
|
||||
|
||||
if ($is_collapsed) {
|
||||
$nav->addClass('phui-profile-menu-collapsed');
|
||||
} else {
|
||||
$nav->addClass('phui-profile-menu-expanded');
|
||||
}
|
||||
|
||||
if ($viewer->isLoggedIn()) {
|
||||
$settings_uri = '/settings/adjust/?key='.$collapse_key;
|
||||
} else {
|
||||
$settings_uri = null;
|
||||
}
|
||||
|
||||
Javelin::initBehavior(
|
||||
'phui-profile-menu',
|
||||
array(
|
||||
'menuID' => $nav->getMainID(),
|
||||
'collapseID' => $collapse_id,
|
||||
'isCollapsed' => (bool)$is_collapsed,
|
||||
'settingsURI' => $settings_uri,
|
||||
));
|
||||
|
||||
$collapse_icon = id(new PHUIIconCircleView())
|
||||
->addClass('phui-list-item-icon')
|
||||
->addClass('phui-profile-menu-visible-when-expanded')
|
||||
->setIcon('fa-chevron-left');
|
||||
|
||||
$expand_icon = id(new PHUIIconCircleView())
|
||||
->addClass('phui-list-item-icon')
|
||||
->addClass('phui-profile-menu-visible-when-collapsed')
|
||||
->addSigil('has-tooltip')
|
||||
->setMetadata(
|
||||
array(
|
||||
'tip' => pht('Expand'),
|
||||
'align' => 'E',
|
||||
))
|
||||
->setIcon('fa-chevron-right');
|
||||
|
||||
$items[] = id(new PHUIListItemView())
|
||||
->setName('Collapse')
|
||||
->addIcon($collapse_icon)
|
||||
->addIcon($expand_icon)
|
||||
->setID($collapse_id)
|
||||
->addClass('phui-profile-menu-footer')
|
||||
->addClass('phui-profile-menu-footer-1')
|
||||
->setHideInApplicationMenu(true)
|
||||
->setHref('#');
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
public function getConfigureURI() {
|
||||
return $this->getItemURI('configure/');
|
||||
}
|
||||
|
@ -558,10 +551,22 @@ abstract class PhabricatorProfileMenuEngine extends Phobject {
|
|||
$viewer = $this->getViewer();
|
||||
$object = $this->getProfileObject();
|
||||
|
||||
PhabricatorPolicyFilter::requireCapability(
|
||||
$viewer,
|
||||
$object,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
$filtered_groups = mgroup($items, 'getMenuItemKey');
|
||||
foreach ($filtered_groups as $group) {
|
||||
$first_item = head($group);
|
||||
$first_item->willBuildNavigationItems($group);
|
||||
}
|
||||
|
||||
// Users only need to be able to edit the object which this menu appears
|
||||
// on if they're editing global menu items. For example, users do not need
|
||||
// to be able to edit the Favorites application to add new items to the
|
||||
// Favorites menu.
|
||||
if (!$this->getCustomPHID()) {
|
||||
PhabricatorPolicyFilter::requireCapability(
|
||||
$viewer,
|
||||
$object,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
}
|
||||
|
||||
$list_id = celerity_generate_unique_node_id();
|
||||
|
||||
|
@ -573,7 +578,8 @@ abstract class PhabricatorProfileMenuEngine extends Phobject {
|
|||
));
|
||||
|
||||
$list = id(new PHUIObjectItemListView())
|
||||
->setID($list_id);
|
||||
->setID($list_id)
|
||||
->setNoDataString(pht('This menu currently has no items.'));
|
||||
|
||||
foreach ($items as $item) {
|
||||
$id = $item->getID();
|
||||
|
@ -710,11 +716,11 @@ abstract class PhabricatorProfileMenuEngine extends Phobject {
|
|||
->setName($doc_name));
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Profile Menu Items'))
|
||||
->setHeader(pht('Menu Items'))
|
||||
->setHeaderIcon('fa-list');
|
||||
|
||||
$box = id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Navigation'))
|
||||
->setHeaderText(pht('Current Menu Items'))
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setObjectList($list);
|
||||
|
||||
|
@ -1022,4 +1028,40 @@ abstract class PhabricatorProfileMenuEngine extends Phobject {
|
|||
return $this;
|
||||
}
|
||||
|
||||
private function arrangeItems(array $items) {
|
||||
// Sort the items.
|
||||
$items = msortv($items, 'getSortVector');
|
||||
|
||||
// If we have some global items and some custom items and are in "combined"
|
||||
// mode, put a hard-coded divider item between them.
|
||||
if ($this->getMenuType() == self::MENU_COMBINED) {
|
||||
$list = array();
|
||||
$seen_custom = false;
|
||||
$seen_global = false;
|
||||
foreach ($items as $item) {
|
||||
if ($item->getCustomPHID()) {
|
||||
$seen_custom = true;
|
||||
} else {
|
||||
if ($seen_custom && !$seen_global) {
|
||||
$list[] = $this->newItem()
|
||||
->setBuiltinKey(self::ITEM_CUSTOM_DIVIDER)
|
||||
->setMenuItemKey(PhabricatorDividerProfileMenuItem::MENUITEMKEY)
|
||||
->attachMenuItem(
|
||||
new PhabricatorDividerProfileMenuItem());
|
||||
}
|
||||
$seen_global = true;
|
||||
}
|
||||
$list[] = $item;
|
||||
}
|
||||
$items = $list;
|
||||
}
|
||||
|
||||
// Normalize keys since callers shouldn't rely on this array being
|
||||
// partially keyed.
|
||||
$items = array_values($items);
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@ final class PhabricatorApplicationProfileMenuItem
|
|||
|
||||
const MENUITEMKEY = 'application';
|
||||
|
||||
const FIELD_APPLICATION = 'application';
|
||||
|
||||
public function getMenuItemTypeIcon() {
|
||||
return 'fa-globe';
|
||||
}
|
||||
|
@ -19,30 +21,45 @@ final class PhabricatorApplicationProfileMenuItem
|
|||
|
||||
public function getDisplayName(
|
||||
PhabricatorProfileMenuItemConfiguration $config) {
|
||||
$app = $this->getApplication($config);
|
||||
if ($app) {
|
||||
return $app->getName();
|
||||
} else {
|
||||
return pht('(Uninstalled Application)');
|
||||
$application = $this->getApplication($config);
|
||||
if (!$application) {
|
||||
return pht('(Restricted/Invalid Application)');
|
||||
}
|
||||
return $app->getName();
|
||||
|
||||
$name = $this->getName($config);
|
||||
if (strlen($name)) {
|
||||
return $name;
|
||||
}
|
||||
|
||||
return $application->getName();
|
||||
}
|
||||
|
||||
public function buildEditEngineFields(
|
||||
PhabricatorProfileMenuItemConfiguration $config) {
|
||||
return array(
|
||||
id(new PhabricatorDatasourceEditField())
|
||||
->setKey('application')
|
||||
->setKey(self::FIELD_APPLICATION)
|
||||
->setLabel(pht('Application'))
|
||||
->setDatasource(new PhabricatorApplicationDatasource())
|
||||
->setIsRequired(true)
|
||||
->setSingleValue($config->getMenuItemProperty('application')),
|
||||
id(new PhabricatorTextEditField())
|
||||
->setKey('name')
|
||||
->setLabel(pht('Name'))
|
||||
->setValue($this->getName($config)),
|
||||
);
|
||||
}
|
||||
|
||||
private function getName(
|
||||
PhabricatorProfileMenuItemConfiguration $config) {
|
||||
return $config->getMenuItemProperty('name');
|
||||
}
|
||||
|
||||
private function getApplication(
|
||||
PhabricatorProfileMenuItemConfiguration $config) {
|
||||
$viewer = $this->getViewer();
|
||||
$phid = $config->getMenuItemProperty('application');
|
||||
|
||||
$app = id(new PhabricatorApplicationQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($phid))
|
||||
|
@ -68,7 +85,7 @@ final class PhabricatorApplicationProfileMenuItem
|
|||
|
||||
$item = $this->newItem()
|
||||
->setHref($app->getApplicationURI())
|
||||
->setName($app->getName())
|
||||
->setName($this->getDisplayName($config))
|
||||
->setIcon($app->getIcon());
|
||||
|
||||
return array(
|
||||
|
@ -76,4 +93,49 @@ final class PhabricatorApplicationProfileMenuItem
|
|||
);
|
||||
}
|
||||
|
||||
public function validateTransactions(
|
||||
PhabricatorProfileMenuItemConfiguration $config,
|
||||
$field_key,
|
||||
$value,
|
||||
array $xactions) {
|
||||
|
||||
$viewer = $this->getViewer();
|
||||
$errors = array();
|
||||
|
||||
if ($field_key == self::FIELD_APPLICATION) {
|
||||
if ($this->isEmptyTransaction($value, $xactions)) {
|
||||
$errors[] = $this->newRequiredError(
|
||||
pht('You must choose an application.'),
|
||||
$field_key);
|
||||
}
|
||||
|
||||
foreach ($xactions as $xaction) {
|
||||
$new = $xaction['new'];
|
||||
|
||||
if (!$new) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($new === $value) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$applications = id(new PhabricatorApplicationQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($new))
|
||||
->execute();
|
||||
if (!$applications) {
|
||||
$errors[] = $this->newInvalidError(
|
||||
pht(
|
||||
'Application "%s" is not a valid application which you have '.
|
||||
'permission to see.',
|
||||
$new),
|
||||
$xaction['xaction']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@ final class PhabricatorDashboardProfileMenuItem
|
|||
|
||||
const MENUITEMKEY = 'dashboard';
|
||||
|
||||
const FIELD_DASHBOARD = 'dashboardPHID';
|
||||
|
||||
private $dashboard;
|
||||
|
||||
public function getMenuItemTypeIcon() {
|
||||
|
@ -70,15 +72,16 @@ final class PhabricatorDashboardProfileMenuItem
|
|||
public function buildEditEngineFields(
|
||||
PhabricatorProfileMenuItemConfiguration $config) {
|
||||
return array(
|
||||
id(new PhabricatorDatasourceEditField())
|
||||
->setKey(self::FIELD_DASHBOARD)
|
||||
->setLabel(pht('Dashboard'))
|
||||
->setIsRequired(true)
|
||||
->setDatasource(new PhabricatorDashboardDatasource())
|
||||
->setSingleValue($config->getMenuItemProperty('dashboardPHID')),
|
||||
id(new PhabricatorTextEditField())
|
||||
->setKey('name')
|
||||
->setLabel(pht('Name'))
|
||||
->setValue($this->getName($config)),
|
||||
id(new PhabricatorDatasourceEditField())
|
||||
->setKey('dashboardPHID')
|
||||
->setLabel(pht('Dashboard'))
|
||||
->setDatasource(new PhabricatorDashboardDatasource())
|
||||
->setSingleValue($config->getMenuItemProperty('dashboardPHID')),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -109,4 +112,49 @@ final class PhabricatorDashboardProfileMenuItem
|
|||
);
|
||||
}
|
||||
|
||||
public function validateTransactions(
|
||||
PhabricatorProfileMenuItemConfiguration $config,
|
||||
$field_key,
|
||||
$value,
|
||||
array $xactions) {
|
||||
|
||||
$viewer = $this->getViewer();
|
||||
$errors = array();
|
||||
|
||||
if ($field_key == self::FIELD_DASHBOARD) {
|
||||
if ($this->isEmptyTransaction($value, $xactions)) {
|
||||
$errors[] = $this->newRequiredError(
|
||||
pht('You must choose a dashboard.'),
|
||||
$field_key);
|
||||
}
|
||||
|
||||
foreach ($xactions as $xaction) {
|
||||
$new = $xaction['new'];
|
||||
|
||||
if (!$new) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($new === $value) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$dashboards = id(new PhabricatorDashboardQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($new))
|
||||
->execute();
|
||||
if (!$dashboards) {
|
||||
$errors[] = $this->newInvalidError(
|
||||
pht(
|
||||
'Dashboard "%s" is not a valid dashboard which you have '.
|
||||
'permission to see.',
|
||||
$new),
|
||||
$xaction['xaction']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@ final class PhabricatorEditEngineProfileMenuItem
|
|||
|
||||
const MENUITEMKEY = 'editengine';
|
||||
|
||||
const FIELD_FORM = 'formKey';
|
||||
|
||||
private $form;
|
||||
|
||||
public function getMenuItemTypeIcon() {
|
||||
|
@ -12,7 +14,7 @@ final class PhabricatorEditEngineProfileMenuItem
|
|||
}
|
||||
|
||||
public function getMenuItemTypeName() {
|
||||
return pht('Forms');
|
||||
return pht('Form');
|
||||
}
|
||||
|
||||
public function canAddToObject($object) {
|
||||
|
@ -51,7 +53,8 @@ final class PhabricatorEditEngineProfileMenuItem
|
|||
|
||||
foreach ($items as $item) {
|
||||
$key = $item->getMenuItemProperty('formKey');
|
||||
list($engine_key, $form_key) = explode('/', $key);
|
||||
list($engine_key, $form_key) = PhabricatorEditEngine::splitFullKey($key);
|
||||
|
||||
if (is_numeric($form_key)) {
|
||||
$form = idx($form_ids, $form_key, null);
|
||||
$item->getMenuItem()->attachForm($form);
|
||||
|
@ -78,15 +81,16 @@ final class PhabricatorEditEngineProfileMenuItem
|
|||
public function buildEditEngineFields(
|
||||
PhabricatorProfileMenuItemConfiguration $config) {
|
||||
return array(
|
||||
id(new PhabricatorDatasourceEditField())
|
||||
->setKey(self::FIELD_FORM)
|
||||
->setLabel(pht('Form'))
|
||||
->setIsRequired(true)
|
||||
->setDatasource(new PhabricatorEditEngineDatasource())
|
||||
->setSingleValue($config->getMenuItemProperty('formKey')),
|
||||
id(new PhabricatorTextEditField())
|
||||
->setKey('name')
|
||||
->setLabel(pht('Name'))
|
||||
->setValue($this->getName($config)),
|
||||
id(new PhabricatorDatasourceEditField())
|
||||
->setKey('formKey')
|
||||
->setLabel(pht('Form'))
|
||||
->setDatasource(new PhabricatorEditEngineDatasource())
|
||||
->setSingleValue($config->getMenuItemProperty('formKey')),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -119,4 +123,53 @@ final class PhabricatorEditEngineProfileMenuItem
|
|||
);
|
||||
}
|
||||
|
||||
public function validateTransactions(
|
||||
PhabricatorProfileMenuItemConfiguration $config,
|
||||
$field_key,
|
||||
$value,
|
||||
array $xactions) {
|
||||
|
||||
$viewer = $this->getViewer();
|
||||
$errors = array();
|
||||
|
||||
if ($field_key == self::FIELD_FORM) {
|
||||
if ($this->isEmptyTransaction($value, $xactions)) {
|
||||
$errors[] = $this->newRequiredError(
|
||||
pht('You must choose a form.'),
|
||||
$field_key);
|
||||
}
|
||||
|
||||
foreach ($xactions as $xaction) {
|
||||
$new = $xaction['new'];
|
||||
|
||||
if (!$new) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($new === $value) {
|
||||
continue;
|
||||
}
|
||||
|
||||
list($engine_key, $form_key) = PhabricatorEditEngine::splitFullKey(
|
||||
$new);
|
||||
|
||||
$forms = id(new PhabricatorEditEngineConfigurationQuery())
|
||||
->setViewer($viewer)
|
||||
->withEngineKeys(array($engine_key))
|
||||
->withIdentifiers(array($form_key))
|
||||
->execute();
|
||||
if (!$forms) {
|
||||
$errors[] = $this->newInvalidError(
|
||||
pht(
|
||||
'Form "%s" is not a valid form which you have permission to '.
|
||||
'see.',
|
||||
$new),
|
||||
$xaction['xaction']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,6 +5,9 @@ final class PhabricatorLinkProfileMenuItem
|
|||
|
||||
const MENUITEMKEY = 'link';
|
||||
|
||||
const FIELD_URI = 'uri';
|
||||
const FIELD_NAME = 'name';
|
||||
|
||||
public function getMenuItemTypeIcon() {
|
||||
return 'fa-link';
|
||||
}
|
||||
|
@ -26,12 +29,12 @@ final class PhabricatorLinkProfileMenuItem
|
|||
PhabricatorProfileMenuItemConfiguration $config) {
|
||||
return array(
|
||||
id(new PhabricatorTextEditField())
|
||||
->setKey('name')
|
||||
->setKey(self::FIELD_NAME)
|
||||
->setLabel(pht('Name'))
|
||||
->setIsRequired(true)
|
||||
->setValue($this->getLinkName($config)),
|
||||
id(new PhabricatorTextEditField())
|
||||
->setKey('uri')
|
||||
->setKey(self::FIELD_URI)
|
||||
->setLabel(pht('URI'))
|
||||
->setIsRequired(true)
|
||||
->setValue($this->getLinkURI($config)),
|
||||
|
@ -91,4 +94,53 @@ final class PhabricatorLinkProfileMenuItem
|
|||
);
|
||||
}
|
||||
|
||||
public function validateTransactions(
|
||||
PhabricatorProfileMenuItemConfiguration $config,
|
||||
$field_key,
|
||||
$value,
|
||||
array $xactions) {
|
||||
|
||||
$viewer = $this->getViewer();
|
||||
$errors = array();
|
||||
|
||||
if ($field_key == self::FIELD_NAME) {
|
||||
if ($this->isEmptyTransaction($value, $xactions)) {
|
||||
$errors[] = $this->newRequiredError(
|
||||
pht('You must choose a link name.'),
|
||||
$field_key);
|
||||
}
|
||||
}
|
||||
|
||||
if ($field_key == self::FIELD_URI) {
|
||||
if ($this->isEmptyTransaction($value, $xactions)) {
|
||||
$errors[] = $this->newRequiredError(
|
||||
pht('You must choose a URI to link to.'),
|
||||
$field_key);
|
||||
}
|
||||
|
||||
foreach ($xactions as $xaction) {
|
||||
$new = $xaction['new'];
|
||||
|
||||
if (!$new) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($new === $value) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$this->isValidLinkURI($new)) {
|
||||
$errors[] = $this->newInvalidError(
|
||||
pht(
|
||||
'URI "%s" is not a valid link URI. It should be a full, valid '.
|
||||
'URI beginning with a protocol like "%s".',
|
||||
$new,
|
||||
'https://'),
|
||||
$xaction['xaction']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,164 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorMotivatorProfileMenuItem
|
||||
extends PhabricatorProfileMenuItem {
|
||||
|
||||
const MENUITEMKEY = 'motivator';
|
||||
|
||||
public function getMenuItemTypeIcon() {
|
||||
return 'fa-coffee';
|
||||
}
|
||||
|
||||
public function getMenuItemTypeName() {
|
||||
return pht('Motivator');
|
||||
}
|
||||
|
||||
public function canAddToObject($object) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDisplayName(
|
||||
PhabricatorProfileMenuItemConfiguration $config) {
|
||||
|
||||
$options = $this->getOptions();
|
||||
$name = idx($options, $config->getMenuItemProperty('source'));
|
||||
if ($name !== null) {
|
||||
return pht('Motivator: %s', $name);
|
||||
} else {
|
||||
return pht('Motivator');
|
||||
}
|
||||
}
|
||||
|
||||
public function buildEditEngineFields(
|
||||
PhabricatorProfileMenuItemConfiguration $config) {
|
||||
return array(
|
||||
id(new PhabricatorInstructionsEditField())
|
||||
->setValue(
|
||||
pht(
|
||||
'Motivate your team with inspirational quotes from great minds. '.
|
||||
'This menu item shows a new quote every day.')),
|
||||
id(new PhabricatorSelectEditField())
|
||||
->setKey('source')
|
||||
->setLabel(pht('Source'))
|
||||
->setOptions($this->getOptions()),
|
||||
);
|
||||
}
|
||||
|
||||
private function getOptions() {
|
||||
return array(
|
||||
'catfacts' => pht('Cat Facts'),
|
||||
);
|
||||
}
|
||||
|
||||
protected function newNavigationMenuItems(
|
||||
PhabricatorProfileMenuItemConfiguration $config) {
|
||||
|
||||
$source = $config->getMenuItemProperty('source');
|
||||
|
||||
switch ($source) {
|
||||
case 'catfacts':
|
||||
default:
|
||||
$facts = $this->getCatFacts();
|
||||
break;
|
||||
}
|
||||
|
||||
$fact = $this->selectFact($facts);
|
||||
|
||||
switch ($source) {
|
||||
case 'catfacts':
|
||||
default:
|
||||
$fact = array(
|
||||
id(new PHUIIconView())->setIcon('fa-paw'),
|
||||
' ',
|
||||
$fact,
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
$fact = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'phui-motivator',
|
||||
),
|
||||
$fact);
|
||||
|
||||
$item = $this->newItem()
|
||||
->appendChild($fact);
|
||||
|
||||
return array(
|
||||
$item,
|
||||
);
|
||||
}
|
||||
|
||||
private function getCatFacts() {
|
||||
return array(
|
||||
pht('Cats purr when they are happy, upset, or asleep.'),
|
||||
pht('The first cats evolved on the savanah about 8,000 years ago.'),
|
||||
pht(
|
||||
'Cats have a tail, two feet, between one and three ears, and two '.
|
||||
'other feet.'),
|
||||
pht('Cats use their keen sense of smell to avoid feeling empathy.'),
|
||||
pht('The first cats evolved in swamps about 65 years ago.'),
|
||||
pht(
|
||||
'You can tell how warm a cat is by examining the coloration: cooler '.
|
||||
'areas are darker.'),
|
||||
pht(
|
||||
'Cat tails are flexible because they contain thousands of tiny '.
|
||||
'bones.'),
|
||||
pht(
|
||||
'A cattail is a wetland plant with an appearance that resembles '.
|
||||
'the tail of a cat.'),
|
||||
pht(
|
||||
'Cats must eat a diet rich in fish to replace the tiny bones in '.
|
||||
'their tails.'),
|
||||
pht('Cats are stealthy predators and nearly invisible to radar.'),
|
||||
pht(
|
||||
'Cats use a special type of magnetism to help them land on their '.
|
||||
'feet.'),
|
||||
pht(
|
||||
'A cat can run seven times faster than a human, but only for a '.
|
||||
'short distance.'),
|
||||
pht(
|
||||
'The largest recorded cat was nearly 11 inches long from nose to '.
|
||||
'tail.'),
|
||||
pht(
|
||||
'Not all cats can retract their claws, but most of them can.'),
|
||||
pht(
|
||||
'In the wild, cats and racoons sometimes hunt together in packs.'),
|
||||
pht(
|
||||
'The Spanish word for cat is "cato". The biggest cat is called '.
|
||||
'"el cato".'),
|
||||
pht(
|
||||
'The Japanese word for cat is "kome", which is also the word for '.
|
||||
'rice. Japanese cats love to eat rice, so the two are synonymous.'),
|
||||
pht('Cats have five pointy ends.'),
|
||||
pht('cat -A can find mice hiding in files.'),
|
||||
pht('A cat\'s visual, olfactory, and auditory senses, '.
|
||||
'Contribute to their hunting skills and natural defenses.'),
|
||||
pht(
|
||||
'Cats with high self-esteem seek out high perches '.
|
||||
'to launch their attacks. Watch out!'),
|
||||
pht('Cats prefer vanilla ice cream.'),
|
||||
pht('Taco cat spelled backwards is taco cat.'),
|
||||
pht(
|
||||
'Cats will often bring you their prey because they feel sorry '.
|
||||
'for your inability to hunt.'),
|
||||
pht('Cats spend most of their time plotting to kill their owner.'),
|
||||
);
|
||||
}
|
||||
|
||||
private function selectFact(array $facts) {
|
||||
// This is a simple pseudorandom number generator that avoids touching
|
||||
// srand(), because it would seed it to a highly predictable value. It
|
||||
// selects a new fact every day.
|
||||
|
||||
$seed = ((int)date('Y') * 366) + (int)date('z');
|
||||
for ($ii = 0; $ii < 32; $ii++) {
|
||||
$seed = ((1664525 * $seed) + 1013904223) % (1 << 31);
|
||||
}
|
||||
|
||||
return $facts[$seed % count($facts)];
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -70,4 +70,41 @@ abstract class PhabricatorProfileMenuItem extends Phobject {
|
|||
return new PHUIListItemView();
|
||||
}
|
||||
|
||||
public function valdateTransactions(
|
||||
PhabricatorProfileMenuItemConfiguration $config,
|
||||
$field_key,
|
||||
$value,
|
||||
array $xactions) {
|
||||
return array();
|
||||
}
|
||||
|
||||
final protected function isEmptyTransaction($value, array $xactions) {
|
||||
$result = $value;
|
||||
foreach ($xactions as $xaction) {
|
||||
$result = $xaction['new'];
|
||||
}
|
||||
|
||||
return !strlen($result);
|
||||
}
|
||||
|
||||
final protected function newError($title, $message, $xaction = null) {
|
||||
return new PhabricatorApplicationTransactionValidationError(
|
||||
PhabricatorProfileMenuItemConfigurationTransaction::TYPE_PROPERTY,
|
||||
$title,
|
||||
$message,
|
||||
$xaction);
|
||||
}
|
||||
|
||||
final protected function newRequiredError($message, $type) {
|
||||
$xaction = id(new PhabricatorProfileMenuItemConfigurationTransaction())
|
||||
->setMetadataValue('property.key', $type);
|
||||
|
||||
return $this->newError(pht('Required'), $message, $xaction)
|
||||
->setIsMissingFieldError(true);
|
||||
}
|
||||
|
||||
final protected function newInvalidError($message, $xaction = null) {
|
||||
return $this->newError(pht('Invalid'), $message, $xaction);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ final class PhabricatorProjectProfileMenuItem
|
|||
extends PhabricatorProfileMenuItem {
|
||||
|
||||
const MENUITEMKEY = 'project';
|
||||
const FIELD_PROJECT = 'project';
|
||||
|
||||
private $project;
|
||||
|
||||
|
@ -71,15 +72,16 @@ final class PhabricatorProjectProfileMenuItem
|
|||
public function buildEditEngineFields(
|
||||
PhabricatorProfileMenuItemConfiguration $config) {
|
||||
return array(
|
||||
id(new PhabricatorDatasourceEditField())
|
||||
->setKey(self::FIELD_PROJECT)
|
||||
->setLabel(pht('Project'))
|
||||
->setIsRequired(true)
|
||||
->setDatasource(new PhabricatorProjectDatasource())
|
||||
->setSingleValue($config->getMenuItemProperty('project')),
|
||||
id(new PhabricatorTextEditField())
|
||||
->setKey('name')
|
||||
->setLabel(pht('Name'))
|
||||
->setValue($this->getName($config)),
|
||||
id(new PhabricatorDatasourceEditField())
|
||||
->setKey('project')
|
||||
->setLabel(pht('Project'))
|
||||
->setDatasource(new PhabricatorProjectDatasource())
|
||||
->setSingleValue($config->getMenuItemProperty('project')),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -110,4 +112,49 @@ final class PhabricatorProjectProfileMenuItem
|
|||
);
|
||||
}
|
||||
|
||||
public function validateTransactions(
|
||||
PhabricatorProfileMenuItemConfiguration $config,
|
||||
$field_key,
|
||||
$value,
|
||||
array $xactions) {
|
||||
|
||||
$viewer = $this->getViewer();
|
||||
$errors = array();
|
||||
|
||||
if ($field_key == self::FIELD_PROJECT) {
|
||||
if ($this->isEmptyTransaction($value, $xactions)) {
|
||||
$errors[] = $this->newRequiredError(
|
||||
pht('You must choose a project.'),
|
||||
$field_key);
|
||||
}
|
||||
|
||||
foreach ($xactions as $xaction) {
|
||||
$new = $xaction['new'];
|
||||
|
||||
if (!$new) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($new === $value) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$projects = id(new PhabricatorProjectQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($new))
|
||||
->execute();
|
||||
if (!$projects) {
|
||||
$errors[] = $this->newInvalidError(
|
||||
pht(
|
||||
'Project "%s" is not a valid project which you have '.
|
||||
'permission to see.',
|
||||
$new),
|
||||
$xaction['xaction']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ final class PhabricatorProfileMenuItemConfigurationQuery
|
|||
private $phids;
|
||||
private $profilePHIDs;
|
||||
private $customPHIDs;
|
||||
private $includeGlobal;
|
||||
|
||||
public function withIDs(array $ids) {
|
||||
$this->ids = $ids;
|
||||
|
@ -23,8 +24,9 @@ final class PhabricatorProfileMenuItemConfigurationQuery
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function withCustomPHIDs(array $phids) {
|
||||
public function withCustomPHIDs(array $phids, $include_global = false) {
|
||||
$this->customPHIDs = $phids;
|
||||
$this->includeGlobal = $include_global;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -61,10 +63,21 @@ final class PhabricatorProfileMenuItemConfigurationQuery
|
|||
}
|
||||
|
||||
if ($this->customPHIDs !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'customPHID IN (%Ls)',
|
||||
$this->customPHIDs);
|
||||
if ($this->customPHIDs && $this->includeGlobal) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'customPHID IN (%Ls) OR customPHID IS NULL',
|
||||
$this->customPHIDs);
|
||||
} else if ($this->customPHIDs) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'customPHID IN (%Ls)',
|
||||
$this->customPHIDs);
|
||||
} else {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'customPHID IS NULL');
|
||||
}
|
||||
}
|
||||
|
||||
return $where;
|
||||
|
|
|
@ -126,18 +126,52 @@ final class PhabricatorProfileMenuItemConfiguration
|
|||
return $this->getMenuItem()->willBuildNavigationItems($items);
|
||||
}
|
||||
|
||||
public function getSortKey() {
|
||||
$order = $this->getMenuItemOrder();
|
||||
if ($order === null) {
|
||||
$order = 'Z';
|
||||
} else {
|
||||
$order = sprintf('%020d', $order);
|
||||
public function validateTransactions(array $map) {
|
||||
$item = $this->getMenuItem();
|
||||
|
||||
$fields = $item->buildEditEngineFields($this);
|
||||
$errors = array();
|
||||
foreach ($fields as $field) {
|
||||
$field_key = $field->getKey();
|
||||
|
||||
$xactions = idx($map, $field_key, array());
|
||||
$value = $this->getMenuItemProperty($field_key);
|
||||
|
||||
$field_errors = $item->validateTransactions(
|
||||
$this,
|
||||
$field_key,
|
||||
$value,
|
||||
$xactions);
|
||||
foreach ($field_errors as $error) {
|
||||
$errors[] = $error;
|
||||
}
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
'~%s%020d',
|
||||
$order,
|
||||
$this->getID());
|
||||
return $errors;
|
||||
}
|
||||
|
||||
public function getSortVector() {
|
||||
// Sort custom items above global items.
|
||||
if ($this->getCustomPHID()) {
|
||||
$is_global = 0;
|
||||
} else {
|
||||
$is_global = 1;
|
||||
}
|
||||
|
||||
// Sort items with an explicit order above items without an explicit order,
|
||||
// so any newly created builtins go to the bottom.
|
||||
$order = $this->getMenuItemOrder();
|
||||
if ($order !== null) {
|
||||
$has_order = 0;
|
||||
} else {
|
||||
$has_order = 1;
|
||||
}
|
||||
|
||||
return id(new PhutilSortVector())
|
||||
->addInt($is_global)
|
||||
->addInt($has_order)
|
||||
->addInt((int)$order)
|
||||
->addInt((int)$this->getID());
|
||||
}
|
||||
|
||||
public function isDisabled() {
|
||||
|
@ -179,6 +213,21 @@ final class PhabricatorProfileMenuItemConfiguration
|
|||
|
||||
|
||||
public function getExtendedPolicy($capability, PhabricatorUser $viewer) {
|
||||
// If this is an item with a custom PHID (like a personal menu item),
|
||||
// we only require that the user can edit the corresponding custom
|
||||
// object (usually their own user profile), not the object that the
|
||||
// menu appears on (which may be an Application like Favorites or Home).
|
||||
if ($capability == PhabricatorPolicyCapability::CAN_EDIT) {
|
||||
if ($this->getCustomPHID()) {
|
||||
return array(
|
||||
array(
|
||||
$this->getCustomPHID(),
|
||||
$capability,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return array(
|
||||
array(
|
||||
$this->getProfileObject(),
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorSettingsMainMenuBarExtension
|
||||
extends PhabricatorMainMenuBarExtension {
|
||||
|
||||
const MAINMENUBARKEY = 'settings';
|
||||
|
||||
public function buildMainMenus() {
|
||||
$controller = $this->getController();
|
||||
$is_selected = ($controller instanceof PhabricatorSettingsMainController);
|
||||
|
||||
$bar_item = id(new PHUIListItemView())
|
||||
->setName(pht('Settings'))
|
||||
->setIcon('fa-wrench')
|
||||
->addClass('core-menu-item')
|
||||
->setSelected($is_selected)
|
||||
->setHref('/settings/')
|
||||
->setAural(pht('Settings'));
|
||||
|
||||
$settings_menu = id(new PHUIMainMenuView())
|
||||
->setMenuBarItem($bar_item)
|
||||
->setOrder(400);
|
||||
|
||||
return array(
|
||||
$settings_menu,
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorEditEngineCreateQuickActions
|
||||
extends PhabricatorQuickActions {
|
||||
|
||||
const QUICKACTIONSKEY = 'editengine.create';
|
||||
|
||||
public function getQuickMenuItems() {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$engines = PhabricatorEditEngine::getAllEditEngines();
|
||||
|
||||
foreach ($engines as $key => $engine) {
|
||||
if (!$engine->hasQuickCreateActions()) {
|
||||
unset($engines[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$engines) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$engine_keys = array_keys($engines);
|
||||
|
||||
$configs = id(new PhabricatorEditEngineConfigurationQuery())
|
||||
->setViewer($viewer)
|
||||
->withEngineKeys($engine_keys)
|
||||
->withIsDefault(true)
|
||||
->withIsDisabled(false)
|
||||
->execute();
|
||||
$configs = msort($configs, 'getCreateSortKey');
|
||||
$configs = mgroup($configs, 'getEngineKey');
|
||||
|
||||
$items = array();
|
||||
foreach ($engines as $key => $engine) {
|
||||
$engine_configs = idx($configs, $key, array());
|
||||
$engine_items = $engine->newQuickCreateActions($engine_configs);
|
||||
foreach ($engine_items as $engine_item) {
|
||||
$items[] = $engine_item;
|
||||
}
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
<?php
|
||||
|
||||
abstract class PhabricatorQuickActions extends Phobject {
|
||||
|
||||
private $viewer;
|
||||
|
||||
public function setViewer(PhabricatorUser $viewer) {
|
||||
$this->viewer = $viewer;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getViewer() {
|
||||
return $this->viewer;
|
||||
}
|
||||
|
||||
public function isEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
abstract public function getQuickMenuItems();
|
||||
|
||||
final public function getQuickActionsKey() {
|
||||
return $this->getPhobjectClassConstant('QUICKACTIONSKEY');
|
||||
}
|
||||
|
||||
public static function getAllQuickActions() {
|
||||
return id(new PhutilClassMapQuery())
|
||||
->setAncestorClass(__CLASS__)
|
||||
->setUniqueMethod('getQuickActionsKey')
|
||||
->execute();
|
||||
}
|
||||
|
||||
public static function loadMenuItemsForUser(PhabricatorUser $viewer) {
|
||||
$actions = self::getAllQuickActions();
|
||||
|
||||
foreach ($actions as $key => $action) {
|
||||
$action->setViewer($viewer);
|
||||
if (!$action->isEnabled()) {
|
||||
unset($actions[$key]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$items = array();
|
||||
foreach ($actions as $key => $action) {
|
||||
foreach ($action->getQuickMenuItems() as $item) {
|
||||
$items[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorProfileMenuCollapsedSetting
|
||||
extends PhabricatorInternalSetting {
|
||||
|
||||
const SETTINGKEY = 'profile-menu.collapsed';
|
||||
|
||||
public function getSettingName() {
|
||||
return pht('Profile Menu Collapsed');
|
||||
}
|
||||
|
||||
}
|
|
@ -95,4 +95,41 @@ abstract class PhabricatorDraftEngine
|
|||
$editor->save();
|
||||
}
|
||||
|
||||
final public static function attachDrafts(
|
||||
PhabricatorUser $viewer,
|
||||
array $objects) {
|
||||
assert_instances_of($objects, 'PhabricatorDraftInterface');
|
||||
|
||||
$viewer_phid = $viewer->getPHID();
|
||||
|
||||
if (!$viewer_phid) {
|
||||
// Viewers without a valid PHID can never have drafts.
|
||||
foreach ($objects as $object) {
|
||||
$object->attachHasDraft($viewer, false);
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
$draft_type = PhabricatorObjectHasDraftEdgeType::EDGECONST;
|
||||
|
||||
$edge_query = id(new PhabricatorEdgeQuery())
|
||||
->withSourcePHIDs(mpull($objects, 'getPHID'))
|
||||
->withEdgeTypes(
|
||||
array(
|
||||
$draft_type,
|
||||
))
|
||||
->withDestinationPHIDs(array($viewer_phid));
|
||||
|
||||
$edge_query->execute();
|
||||
|
||||
foreach ($objects as $object) {
|
||||
$has_draft = (bool)$edge_query->getDestinationPHIDs(
|
||||
array(
|
||||
$object->getPHID(),
|
||||
));
|
||||
|
||||
$object->attachHasDraft($viewer, $has_draft);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,4 +4,25 @@ interface PhabricatorDraftInterface {
|
|||
|
||||
public function newDraftEngine();
|
||||
|
||||
public function getHasDraft(PhabricatorUser $viewer);
|
||||
public function attachHasDraft(PhabricatorUser $viewer, $has_draft);
|
||||
|
||||
}
|
||||
|
||||
/* -( PhabricatorDraftInterface )------------------------------------------ */
|
||||
/*
|
||||
|
||||
public function newDraftEngine() {
|
||||
return new <...>DraftEngine();
|
||||
}
|
||||
|
||||
public function getHasDraft(PhabricatorUser $viewer) {
|
||||
return $this->assertAttachedKey($this->drafts, $viewer->getCacheFragment());
|
||||
}
|
||||
|
||||
public function attachHasDraft(PhabricatorUser $viewer, $has_draft) {
|
||||
$this->drafts[$viewer->getCacheFragment()] = $has_draft;
|
||||
return $this;
|
||||
}
|
||||
|
||||
*/
|
||||
|
|
|
@ -77,6 +77,33 @@ abstract class PhabricatorEditEngine
|
|||
return true;
|
||||
}
|
||||
|
||||
public function isDefaultQuickCreateEngine() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDefaultQuickCreateFormKeys() {
|
||||
$keys = array();
|
||||
|
||||
if ($this->isDefaultQuickCreateEngine()) {
|
||||
$keys[] = self::EDITENGINECONFIG_DEFAULT;
|
||||
}
|
||||
|
||||
foreach ($keys as $idx => $key) {
|
||||
$keys[$idx] = $this->getEngineKey().'/'.$key;
|
||||
}
|
||||
|
||||
return $keys;
|
||||
}
|
||||
|
||||
public static function splitFullKey($full_key) {
|
||||
return explode('/', $full_key, 2);
|
||||
}
|
||||
|
||||
public function getQuickCreateOrderVector() {
|
||||
return id(new PhutilSortVector())
|
||||
->addString($this->getObjectCreateShortText());
|
||||
}
|
||||
|
||||
/**
|
||||
* Force the engine to edit a particular object.
|
||||
*/
|
||||
|
@ -107,10 +134,6 @@ abstract class PhabricatorEditEngine
|
|||
return $this->hideHeader;
|
||||
}
|
||||
|
||||
public function getProfileMenuItemDefault() {
|
||||
return $this->getEngineKey().'/'.self::EDITENGINECONFIG_DEFAULT;
|
||||
}
|
||||
|
||||
|
||||
/* -( Managing Fields )---------------------------------------------------- */
|
||||
|
||||
|
@ -283,14 +306,6 @@ abstract class PhabricatorEditEngine
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* @task text
|
||||
*/
|
||||
protected function getQuickCreateMenuHeaderText() {
|
||||
return $this->getObjectCreateShortText();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a human-readable header describing what this engine is used to do,
|
||||
* like "Configure Maniphest Task Forms".
|
||||
|
@ -2100,50 +2115,6 @@ abstract class PhabricatorEditEngine
|
|||
return $application->getIcon();
|
||||
}
|
||||
|
||||
public function hasQuickCreateActions() {
|
||||
if (!$this->isEngineConfigurable()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function newQuickCreateActions(array $configs) {
|
||||
$items = array();
|
||||
|
||||
if (!$configs) {
|
||||
return array();
|
||||
}
|
||||
|
||||
// If the viewer is logged in and can't create objects, don't show the
|
||||
// menu item. If they're logged out, we assume they could create objects
|
||||
// if they logged in, so we show the item as a hint about how to
|
||||
// accomplish the action.
|
||||
if ($this->getViewer()->isLoggedIn()) {
|
||||
if (!$this->hasCreateCapability()) {
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
if (count($configs) == 1) {
|
||||
$config = head($configs);
|
||||
$items[] = $this->newQuickCreateAction($config);
|
||||
} else {
|
||||
$group_name = $this->getQuickCreateMenuHeaderText();
|
||||
|
||||
$items[] = id(new PHUIListItemView())
|
||||
->setType(PHUIListItemView::TYPE_LABEL)
|
||||
->setName($group_name);
|
||||
|
||||
foreach ($configs as $config) {
|
||||
$items[] = $this->newQuickCreateAction($config)
|
||||
->setIndented(true);
|
||||
}
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
private function loadUsableConfigurationsForCreate() {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
|
@ -2159,20 +2130,6 @@ abstract class PhabricatorEditEngine
|
|||
return $configs;
|
||||
}
|
||||
|
||||
private function newQuickCreateAction(
|
||||
PhabricatorEditEngineConfiguration $config) {
|
||||
|
||||
$item_name = $config->getName();
|
||||
$item_icon = $config->getIcon();
|
||||
$form_key = $config->getIdentifier();
|
||||
$item_uri = $this->getEditURI(null, "form/{$form_key}/");
|
||||
|
||||
return id(new PHUIListItemView())
|
||||
->setName($item_name)
|
||||
->setIcon($item_icon)
|
||||
->setHref($item_uri);
|
||||
}
|
||||
|
||||
protected function getValidationExceptionShortMessage(
|
||||
PhabricatorApplicationTransactionValidationException $ex,
|
||||
PhabricatorEditField $field) {
|
||||
|
|
|
@ -50,7 +50,6 @@ final class PHUIDiffGraphView extends Phobject {
|
|||
|
||||
$thread_count = $pos;
|
||||
for ($n = 0; $n < $thread_count; $n++) {
|
||||
|
||||
if (empty($threads[$n])) {
|
||||
$line .= ' ';
|
||||
continue;
|
||||
|
@ -60,7 +59,7 @@ final class PHUIDiffGraphView extends Phobject {
|
|||
if ($found) {
|
||||
$line .= ' ';
|
||||
$joins[] = $n;
|
||||
unset($threads[$n]);
|
||||
$threads[$n] = false;
|
||||
} else {
|
||||
$line .= 'o';
|
||||
$found = true;
|
||||
|
@ -114,6 +113,7 @@ final class PHUIDiffGraphView extends Phobject {
|
|||
if ($thread_commit == $parent) {
|
||||
$found = true;
|
||||
$splits[] = $idx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -270,7 +270,7 @@ final class PHUIDiffInlineCommentDetailView
|
|||
),
|
||||
'sigil' => 'differential-inline-preview-jump',
|
||||
),
|
||||
pht('Not Visible'));
|
||||
pht('View'));
|
||||
|
||||
$action_buttons[] = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
|
|
|
@ -45,10 +45,10 @@ final class PHUIDiffGraphViewTestCase extends PhabricatorTestCase {
|
|||
'^',
|
||||
'|^',
|
||||
'o ',
|
||||
'|^',
|
||||
'||^',
|
||||
'o ',
|
||||
'x',
|
||||
'| ^',
|
||||
'| |^',
|
||||
'o ',
|
||||
'x ',
|
||||
);
|
||||
|
||||
$this->assertGraph($picture, $graph, pht('Reverse Tree'));
|
||||
|
@ -71,7 +71,30 @@ final class PHUIDiffGraphViewTestCase extends PhabricatorTestCase {
|
|||
'x ',
|
||||
);
|
||||
|
||||
$this->assertGraph($picture, $graph, pht('Reverse Tree'));
|
||||
$this->assertGraph($picture, $graph, pht('Terminated Tree'));
|
||||
}
|
||||
|
||||
public function testThreeWayGraphJoin() {
|
||||
$nodes = array(
|
||||
'A' => array('D', 'C', 'B'),
|
||||
'B' => array('D'),
|
||||
'C' => array('B', 'E', 'F'),
|
||||
'D' => array(),
|
||||
'E' => array(),
|
||||
'F' => array(),
|
||||
);
|
||||
|
||||
$graph = $this->newGraph($nodes);
|
||||
$picture = array(
|
||||
'^',
|
||||
'||o',
|
||||
'|o|',
|
||||
'x| ||',
|
||||
' | x|',
|
||||
' | x',
|
||||
);
|
||||
|
||||
$this->assertGraph($picture, $graph, pht('Three-Way Tree'));
|
||||
}
|
||||
|
||||
private function newGraph(array $nodes) {
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorActionListView extends AphrontView {
|
||||
final class PhabricatorActionListView extends AphrontTagView {
|
||||
|
||||
private $actions = array();
|
||||
private $object;
|
||||
private $id = null;
|
||||
|
||||
public function setObject(PhabricatorLiskDAO $object) {
|
||||
$this->object = $object;
|
||||
|
@ -16,16 +15,19 @@ final class PhabricatorActionListView extends AphrontView {
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function setID($id) {
|
||||
$this->id = $id;
|
||||
return $this;
|
||||
protected function getTagName() {
|
||||
return 'ul';
|
||||
}
|
||||
|
||||
public function getID() {
|
||||
return $this->id;
|
||||
protected function getTagAttributes() {
|
||||
$classes = array();
|
||||
$classes[] = 'phabricator-action-list-view';
|
||||
return array(
|
||||
'class' => implode(' ', $classes),
|
||||
);
|
||||
}
|
||||
|
||||
public function render() {
|
||||
protected function getTagContent() {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$event = new PhabricatorEvent(
|
||||
|
@ -55,13 +57,7 @@ final class PhabricatorActionListView extends AphrontView {
|
|||
}
|
||||
}
|
||||
|
||||
return phutil_tag(
|
||||
'ul',
|
||||
array(
|
||||
'class' => 'phabricator-action-list-view',
|
||||
'id' => $this->id,
|
||||
),
|
||||
$items);
|
||||
return $items;
|
||||
}
|
||||
|
||||
public function getDropdownMenuMetadata() {
|
||||
|
|
|
@ -18,6 +18,13 @@ final class PhabricatorActionView extends AphrontView {
|
|||
private $hidden;
|
||||
private $depth;
|
||||
private $id;
|
||||
private $order;
|
||||
private $color;
|
||||
private $type;
|
||||
|
||||
const TYPE_DIVIDER = 'type-divider';
|
||||
const TYPE_LABEL = 'label';
|
||||
const RED = 'action-item-red';
|
||||
|
||||
public function setSelected($selected) {
|
||||
$this->selected = $selected;
|
||||
|
@ -51,6 +58,11 @@ final class PhabricatorActionView extends AphrontView {
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function setColor($color) {
|
||||
$this->color = $color;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addSigil($sigil) {
|
||||
$this->sigils[] = $sigil;
|
||||
return $this;
|
||||
|
@ -114,6 +126,24 @@ final class PhabricatorActionView extends AphrontView {
|
|||
return $this->id;
|
||||
}
|
||||
|
||||
public function setOrder($order) {
|
||||
$this->order = $order;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getOrder() {
|
||||
return $this->order;
|
||||
}
|
||||
|
||||
public function setType($type) {
|
||||
$this->type = $type;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getType() {
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
public function setSubmenu(array $submenu) {
|
||||
$this->submenu = $submenu;
|
||||
|
||||
|
@ -173,22 +203,26 @@ final class PhabricatorActionView extends AphrontView {
|
|||
->setIcon($this->icon.$color);
|
||||
}
|
||||
|
||||
$sigils = array();
|
||||
if ($this->workflow) {
|
||||
$sigils[] = 'workflow';
|
||||
}
|
||||
|
||||
if ($this->download) {
|
||||
$sigils[] = 'download';
|
||||
}
|
||||
|
||||
if ($this->submenu) {
|
||||
$sigils[] = 'keep-open';
|
||||
}
|
||||
|
||||
if ($this->sigils) {
|
||||
$sigils = array_merge($sigils, $this->sigils);
|
||||
}
|
||||
|
||||
$sigils = $sigils ? implode(' ', $sigils) : null;
|
||||
|
||||
if ($this->href) {
|
||||
|
||||
$sigils = array();
|
||||
if ($this->workflow) {
|
||||
$sigils[] = 'workflow';
|
||||
}
|
||||
if ($this->download) {
|
||||
$sigils[] = 'download';
|
||||
}
|
||||
|
||||
if ($this->sigils) {
|
||||
$sigils = array_merge($sigils, $this->sigils);
|
||||
}
|
||||
|
||||
$sigils = $sigils ? implode(' ', $sigils) : null;
|
||||
|
||||
if ($this->renderAsForm) {
|
||||
if (!$this->hasViewer()) {
|
||||
throw new Exception(
|
||||
|
@ -244,12 +278,13 @@ final class PhabricatorActionView extends AphrontView {
|
|||
array($icon, $this->name, $caret));
|
||||
}
|
||||
} else {
|
||||
$item = phutil_tag(
|
||||
$item = javelin_tag(
|
||||
'span',
|
||||
array(
|
||||
'class' => 'phabricator-action-view-item',
|
||||
'sigil' => $sigils,
|
||||
),
|
||||
array($icon, $this->name));
|
||||
array($icon, $this->name, $this->renderChildren()));
|
||||
}
|
||||
|
||||
$classes = array();
|
||||
|
@ -275,6 +310,18 @@ final class PhabricatorActionView extends AphrontView {
|
|||
$classes[] = 'phabricator-action-view-href';
|
||||
}
|
||||
|
||||
if ($this->icon) {
|
||||
$classes[] = 'action-has-icon';
|
||||
}
|
||||
|
||||
if ($this->color) {
|
||||
$classes[] = $this->color;
|
||||
}
|
||||
|
||||
if ($this->type) {
|
||||
$classes[] = 'phabricator-action-view-'.$this->type;
|
||||
}
|
||||
|
||||
$style = array();
|
||||
|
||||
if ($this->hidden) {
|
||||
|
|
|
@ -767,23 +767,6 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView
|
|||
->setViewer($viewer);
|
||||
$dropdown_query->execute();
|
||||
|
||||
$rendered_dropdowns = array();
|
||||
$applications = array(
|
||||
'PhabricatorHelpApplication',
|
||||
);
|
||||
foreach ($applications as $application_class) {
|
||||
if (!PhabricatorApplication::isClassInstalledForViewer(
|
||||
$application_class,
|
||||
$viewer)) {
|
||||
continue;
|
||||
}
|
||||
$application = PhabricatorApplication::getByClass($application_class);
|
||||
$rendered_dropdowns[$application_class] =
|
||||
$application->buildMainMenuExtraNodes(
|
||||
$viewer,
|
||||
$controller);
|
||||
}
|
||||
|
||||
$hisec_warning_config = $this->getHighSecurityWarningConfig();
|
||||
|
||||
$console_config = null;
|
||||
|
@ -799,6 +782,7 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView
|
|||
|
||||
$application_class = null;
|
||||
$application_search_icon = null;
|
||||
$application_help = null;
|
||||
$controller = $this->getController();
|
||||
if ($controller) {
|
||||
$application = $controller->getCurrentApplication();
|
||||
|
@ -807,6 +791,16 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView
|
|||
if ($application->getApplicationSearchDocumentTypes()) {
|
||||
$application_search_icon = $application->getIcon();
|
||||
}
|
||||
|
||||
$help_items = $application->getHelpMenuItems($viewer);
|
||||
if ($help_items) {
|
||||
$help_list = id(new PhabricatorActionListView())
|
||||
->setViewer($viewer);
|
||||
foreach ($help_items as $help_item) {
|
||||
$help_list->addAction($help_item);
|
||||
}
|
||||
$application_help = $help_list->getDropdownMenuMetadata();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -818,11 +812,11 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView
|
|||
$dropdown_query->getConpherenceData(),
|
||||
),
|
||||
'globalDragAndDrop' => $upload_enabled,
|
||||
'aphlictDropdowns' => $rendered_dropdowns,
|
||||
'hisecWarningConfig' => $hisec_warning_config,
|
||||
'consoleConfig' => $console_config,
|
||||
'applicationClass' => $application_class,
|
||||
'applicationSearchIcon' => $application_search_icon,
|
||||
'helpItems' => $application_help,
|
||||
) + $this->buildAphlictListenConfigData();
|
||||
}
|
||||
|
||||
|
|
|
@ -99,8 +99,10 @@ final class PhabricatorMainMenuSearchView extends AphrontView {
|
|||
'id' => $button_id,
|
||||
'class' => 'phui-icon-view phui-font-fa fa-search',
|
||||
),
|
||||
$search_text),
|
||||
$selector,
|
||||
array(
|
||||
$selector,
|
||||
$search_text,
|
||||
)),
|
||||
$primary_input,
|
||||
$target,
|
||||
)));
|
||||
|
@ -118,7 +120,7 @@ final class PhabricatorMainMenuSearchView extends AphrontView {
|
|||
|
||||
$items[] = array(
|
||||
'icon' => 'fa-globe',
|
||||
'name' => pht('Search All Documents'),
|
||||
'name' => pht('All Documents'),
|
||||
'value' => 'all',
|
||||
);
|
||||
|
||||
|
@ -134,7 +136,7 @@ final class PhabricatorMainMenuSearchView extends AphrontView {
|
|||
|
||||
$items[] = array(
|
||||
'icon' => $application_icon,
|
||||
'name' => pht('Search Current Application'),
|
||||
'name' => pht('Current Application'),
|
||||
'value' => PhabricatorSearchController::SCOPE_CURRENT_APPLICATION,
|
||||
);
|
||||
|
||||
|
|
|
@ -52,10 +52,10 @@ final class PhabricatorMainMenuView extends AphrontView {
|
|||
$alerts[] = $menu;
|
||||
}
|
||||
$menu_bar = array_merge($menu_bar, $dropdowns);
|
||||
$app_button = $this->renderApplicationMenuButton($header_id);
|
||||
$app_button = $this->renderApplicationMenuButton();
|
||||
$search_button = $this->renderSearchMenuButton($header_id);
|
||||
} else {
|
||||
$app_button = $this->renderApplicationMenuButton($header_id);
|
||||
$app_button = $this->renderApplicationMenuButton();
|
||||
if (PhabricatorEnv::getEnvConfig('policy.allow-public')) {
|
||||
$search_button = $this->renderSearchMenuButton($header_id);
|
||||
}
|
||||
|
@ -82,27 +82,17 @@ final class PhabricatorMainMenuView extends AphrontView {
|
|||
phutil_implode_html(' ', $aural));
|
||||
}
|
||||
|
||||
// Build out Header Menus
|
||||
$applications = PhabricatorApplication::getAllInstalledApplications();
|
||||
|
||||
$menus = array();
|
||||
$controller = $this->getController();
|
||||
foreach ($applications as $application) {
|
||||
$app_actions = $application->buildMainMenuItems(
|
||||
$viewer,
|
||||
$controller);
|
||||
$app_extra = $application->buildMainMenuExtraNodes(
|
||||
$viewer,
|
||||
$controller);
|
||||
|
||||
foreach ($app_actions as $action) {
|
||||
$menus[] = id(new PHUIMainMenuView())
|
||||
->setMenuBarItem($action)
|
||||
->setOrder($action->getOrder());
|
||||
}
|
||||
|
||||
if ($app_extra !== null) {
|
||||
$menus[] = id(new PHUIMainMenuView())
|
||||
->appendChild($app_extra);
|
||||
$menus[] = $app_extra;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,26 +116,17 @@ final class PhabricatorMainMenuView extends AphrontView {
|
|||
}
|
||||
}
|
||||
|
||||
// Builds out "login" button
|
||||
foreach ($extensions as $extension) {
|
||||
foreach ($extension->buildMainMenus() as $menu) {
|
||||
$menus[] = $menu;
|
||||
}
|
||||
}
|
||||
|
||||
$menus = msort($menus, 'getOrder');
|
||||
$bar_items = array();
|
||||
foreach ($menus as $menu) {
|
||||
$menu_bar[] = $menu;
|
||||
|
||||
$item = $menu->getMenuBarItem();
|
||||
if ($item === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$bar_items[] = $item;
|
||||
}
|
||||
|
||||
$application_menu = $this->renderApplicationMenu($bar_items);
|
||||
$classes = array();
|
||||
$classes[] = 'phabricator-main-menu';
|
||||
$classes[] = 'phabricator-main-menu-background';
|
||||
|
@ -162,7 +143,6 @@ final class PhabricatorMainMenuView extends AphrontView {
|
|||
$this->renderPhabricatorLogo(),
|
||||
$alerts,
|
||||
$aural,
|
||||
$application_menu,
|
||||
$search_menu,
|
||||
$menu_bar,
|
||||
));
|
||||
|
@ -218,53 +198,37 @@ final class PhabricatorMainMenuView extends AphrontView {
|
|||
return $result;
|
||||
}
|
||||
|
||||
public function renderApplicationMenuButton($header_id) {
|
||||
$button_id = celerity_generate_unique_node_id();
|
||||
return javelin_tag(
|
||||
'a',
|
||||
array(
|
||||
'class' => 'phabricator-main-menu-expand-button '.
|
||||
'phabricator-expand-search-menu',
|
||||
'sigil' => 'jx-toggle-class',
|
||||
'meta' => array(
|
||||
'map' => array(
|
||||
$header_id => 'phabricator-application-menu-expanded',
|
||||
$button_id => 'menu-icon-selected',
|
||||
),
|
||||
),
|
||||
),
|
||||
phutil_tag(
|
||||
'span',
|
||||
array(
|
||||
'class' => 'phabricator-menu-button-icon phui-icon-view '.
|
||||
'phui-font-fa fa-bars',
|
||||
'id' => $button_id,
|
||||
),
|
||||
''));
|
||||
public function renderApplicationMenuButton() {
|
||||
$dropdown = $this->renderApplicationMenu();
|
||||
if (!$dropdown) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setHref('#')
|
||||
->setIcon('fa-bars')
|
||||
->addClass('phabricator-core-user-menu')
|
||||
->addClass('phabricator-core-user-mobile-menu')
|
||||
->setNoCSS(true)
|
||||
->setDropdownMenu($dropdown);
|
||||
}
|
||||
|
||||
private function renderApplicationMenu(array $bar_items) {
|
||||
private function renderApplicationMenu() {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$view = $this->getApplicationMenu();
|
||||
|
||||
if (!$view) {
|
||||
$view = new PHUIListView();
|
||||
}
|
||||
|
||||
$view->addClass('phabricator-dark-menu');
|
||||
$view->addClass('phabricator-application-menu');
|
||||
|
||||
if ($bar_items) {
|
||||
$view->addMenuItem(
|
||||
id(new PHUIListItemView())
|
||||
->setType(PHUIListItemView::TYPE_LABEL)
|
||||
->setName(pht('Actions')));
|
||||
foreach ($bar_items as $bar_item) {
|
||||
$view->addMenuItem($bar_item);
|
||||
if ($view) {
|
||||
$items = $view->getItems();
|
||||
$view = id(new PhabricatorActionListView())
|
||||
->setViewer($viewer);
|
||||
foreach ($items as $item) {
|
||||
$view->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName($item->getName())
|
||||
->setHref($item->getHref())
|
||||
->setType($item->getType()));
|
||||
}
|
||||
}
|
||||
|
||||
return $view;
|
||||
}
|
||||
|
||||
|
@ -296,7 +260,6 @@ final class PhabricatorMainMenuView extends AphrontView {
|
|||
private function renderPhabricatorSearchMenu() {
|
||||
|
||||
$view = new PHUIListView();
|
||||
$view->addClass('phabricator-dark-menu');
|
||||
$view->addClass('phabricator-search-menu');
|
||||
|
||||
$search = $this->renderSearch();
|
||||
|
|
|
@ -27,6 +27,8 @@ final class PHUIButtonView extends AphrontTagView {
|
|||
private $disabled;
|
||||
private $name;
|
||||
private $tooltip;
|
||||
private $noCSS;
|
||||
private $hasCaret;
|
||||
|
||||
public function setName($name) {
|
||||
$this->name = $name;
|
||||
|
@ -87,6 +89,20 @@ final class PHUIButtonView extends AphrontTagView {
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function setNoCSS($no_css) {
|
||||
$this->noCSS = $no_css;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setHasCaret($has_caret) {
|
||||
$this->hasCaret = $has_caret;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getHasCaret() {
|
||||
return $this->hasCaret;
|
||||
}
|
||||
|
||||
public function setIcon($icon, $first = true) {
|
||||
if (!($icon instanceof PHUIIconView)) {
|
||||
$icon = id(new PHUIIconView())
|
||||
|
@ -164,6 +180,10 @@ final class PHUIButtonView extends AphrontTagView {
|
|||
);
|
||||
}
|
||||
|
||||
if ($this->noCSS) {
|
||||
$classes = array();
|
||||
}
|
||||
|
||||
return array(
|
||||
'class' => $classes,
|
||||
'href' => $this->href,
|
||||
|
@ -191,7 +211,7 @@ final class PHUIButtonView extends AphrontTagView {
|
|||
}
|
||||
|
||||
$caret = null;
|
||||
if ($this->dropdown) {
|
||||
if ($this->dropdown || $this->getHasCaret()) {
|
||||
$caret = phutil_tag('span', array('class' => 'caret'), '');
|
||||
}
|
||||
|
||||
|
|
|
@ -202,7 +202,7 @@ final class PHUIListItemView extends AphrontTagView {
|
|||
}
|
||||
|
||||
return array(
|
||||
'class' => $classes,
|
||||
'class' => implode(' ', $classes),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PHUIMainMenuView extends AphrontView {
|
||||
|
||||
private $menuItem;
|
||||
private $extraContent = array();
|
||||
private $order;
|
||||
|
||||
public function setMenuBarItem(PHUIListItemView $menu_item) {
|
||||
$this->menuItem = $menu_item;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getMenuBarItem() {
|
||||
return $this->menuItem;
|
||||
}
|
||||
|
||||
public function setOrder($order) {
|
||||
$this->order = $order;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getOrder() {
|
||||
return $this->order;
|
||||
}
|
||||
|
||||
public function render() {
|
||||
return $this->renderChildren();
|
||||
}
|
||||
|
||||
}
|
|
@ -606,8 +606,8 @@ final class PHUITimelineEventView extends AphrontView {
|
|||
|
||||
$items[] = id(new PhabricatorActionView())
|
||||
->setIcon('fa-quote-left')
|
||||
->setName(pht('Quote Comment'))
|
||||
->setHref('#')
|
||||
->setName(pht('Quote'))
|
||||
->addSigil('transaction-quote')
|
||||
->setMetadata(
|
||||
array(
|
||||
|
@ -619,9 +619,9 @@ final class PHUITimelineEventView extends AphrontView {
|
|||
|
||||
if ($this->getIsNormalComment()) {
|
||||
$items[] = id(new PhabricatorActionView())
|
||||
->setIcon('fa-cutlery')
|
||||
->setIcon('fa-code')
|
||||
->setHref('/transactions/raw/'.$xaction_phid.'/')
|
||||
->setName(pht('View Raw'))
|
||||
->setName(pht('View Remarkup'))
|
||||
->addSigil('transaction-raw')
|
||||
->setMetadata(
|
||||
array(
|
||||
|
@ -646,19 +646,6 @@ final class PHUITimelineEventView extends AphrontView {
|
|||
}
|
||||
}
|
||||
|
||||
if ($this->getIsRemovable()) {
|
||||
$items[] = id(new PhabricatorActionView())
|
||||
->setIcon('fa-times')
|
||||
->setHref('/transactions/remove/'.$xaction_phid.'/')
|
||||
->setName(pht('Remove Comment'))
|
||||
->addSigil('transaction-remove')
|
||||
->setMetadata(
|
||||
array(
|
||||
'anchor' => $anchor,
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
if ($this->getIsEdited()) {
|
||||
$items[] = id(new PhabricatorActionView())
|
||||
->setIcon('fa-list')
|
||||
|
@ -667,6 +654,23 @@ final class PHUITimelineEventView extends AphrontView {
|
|||
->setWorkflow(true);
|
||||
}
|
||||
|
||||
if ($this->getIsRemovable()) {
|
||||
$items[] = id(new PhabricatorActionView())
|
||||
->setType(PhabricatorActionView::TYPE_DIVIDER);
|
||||
|
||||
$items[] = id(new PhabricatorActionView())
|
||||
->setIcon('fa-trash-o')
|
||||
->setHref('/transactions/remove/'.$xaction_phid.'/')
|
||||
->setName(pht('Remove Comment'))
|
||||
->setColor(PhabricatorActionView::RED)
|
||||
->addSigil('transaction-remove')
|
||||
->setMetadata(
|
||||
array(
|
||||
'anchor' => $anchor,
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@
|
|||
}
|
||||
|
||||
.device-phone .phabricator-wordmark {
|
||||
max-width: 112px; /* iPhone 5 limitation */
|
||||
display: none;
|
||||
}
|
||||
|
||||
.phabricator-wordmark {
|
||||
|
@ -119,7 +119,7 @@
|
|||
*/
|
||||
|
||||
.device-desktop .phabricator-main-menu-search {
|
||||
width: 220px;
|
||||
width: 298px;
|
||||
}
|
||||
|
||||
.device .phabricator-main-menu-search {
|
||||
|
@ -130,7 +130,7 @@
|
|||
padding: 8px 0;
|
||||
position: relative;
|
||||
height: 24px;
|
||||
margin: 0 8px;
|
||||
margin: 0 8px 0 0;
|
||||
}
|
||||
|
||||
.phabricator-main-menu-search-target {
|
||||
|
@ -150,6 +150,7 @@
|
|||
|
||||
.device .phabricator-main-menu-search-container {
|
||||
padding: 4px 0;
|
||||
margin: 0 4px;
|
||||
}
|
||||
|
||||
.phabricator-main-menu .phabricator-main-menu-search input {
|
||||
|
@ -169,9 +170,9 @@
|
|||
border-style: solid;
|
||||
background-color: #fff;
|
||||
height: 28px;
|
||||
padding: 3px 30px 3px 6px;
|
||||
padding: 3px 28px 3px 52px;
|
||||
float: left;
|
||||
width: 205px;
|
||||
width: 280px;
|
||||
}
|
||||
|
||||
.device .phabricator-main-menu-search input {
|
||||
|
@ -196,7 +197,7 @@
|
|||
.phabricator-main-menu-search button {
|
||||
color: {$bluetext};
|
||||
position: absolute;
|
||||
background: {$greybackground};
|
||||
background: transparent;
|
||||
border: none;
|
||||
outline: none;
|
||||
box-shadow: none;
|
||||
|
@ -204,7 +205,7 @@
|
|||
min-width: 0;
|
||||
height: 24px;
|
||||
width: 28px;
|
||||
top: 10px;
|
||||
top: 9px;
|
||||
right: -6px;
|
||||
margin: 0 8px 0 0;
|
||||
padding: 0;
|
||||
|
@ -214,20 +215,22 @@
|
|||
.phabricator-main-menu-search button.phabricator-main-menu-search-dropdown {
|
||||
position: absolute;
|
||||
right: auto;
|
||||
left: -45px;
|
||||
width: 40px;
|
||||
background: transparent;
|
||||
left: 12px;
|
||||
width: 46px;
|
||||
background: {$greybackground};
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.device-desktop .phabricator-main-menu-search
|
||||
button.phabricator-main-menu-search-dropdown {
|
||||
height: 28px;
|
||||
top: 8px;
|
||||
height: 24px;
|
||||
top: 10px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.device-desktop .phabricator-main-menu-search
|
||||
button.phabricator-main-menu-search-dropdown:hover .phui-icon-view {
|
||||
color: #fff;
|
||||
color: {$sky};
|
||||
}
|
||||
|
||||
.device .phabricator-main-menu-search
|
||||
|
@ -236,34 +239,24 @@
|
|||
background: {$greybackground};
|
||||
}
|
||||
|
||||
button.phabricator-main-menu-search-dropdown .caret:before {
|
||||
button.phabricator-main-menu-search-dropdown .caret:before,
|
||||
a.phabricator-core-user-menu .caret:before {
|
||||
content: "\f107";
|
||||
font-family: FontAwesome;
|
||||
color: {$hoverwhite};
|
||||
}
|
||||
|
||||
.phabricator-main-menu-search button.phabricator-main-menu-search-dropdown
|
||||
.phui-icon-view {
|
||||
color: {$hoverwhite};
|
||||
color: {$bluetext};
|
||||
font-size: 15px;
|
||||
top: 6px;
|
||||
top: 4px;
|
||||
left: 8px;
|
||||
}
|
||||
|
||||
.device
|
||||
.phabricator-main-menu-search button.phabricator-main-menu-search-dropdown
|
||||
.phui-icon-view {
|
||||
color: {$bluetext};
|
||||
}
|
||||
|
||||
.device button.phabricator-main-menu-search-dropdown .caret:before {
|
||||
color: {$bluetext};
|
||||
}
|
||||
|
||||
.phabricator-main-menu-search-dropdown .caret {
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
top: 5px;
|
||||
right: 18px;
|
||||
top: 2px;
|
||||
border: none;
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
@ -284,7 +277,7 @@ button.phabricator-main-menu-search-dropdown .caret:before {
|
|||
word-wrap: break-word;
|
||||
overflow-y: auto;
|
||||
box-shadow: {$dropshadow};
|
||||
border: 1px solid {$blueborder};
|
||||
border: 1px solid {$lightgreyborder};
|
||||
border-radius: 3px;
|
||||
margin-left: 40px;
|
||||
}
|
||||
|
@ -339,12 +332,6 @@ button.phabricator-main-menu-search-dropdown .caret:before {
|
|||
font-size: {$normalfontsize};
|
||||
}
|
||||
|
||||
.device .phabricator-dark-menu .phui-list-item-type-link
|
||||
.phabricator-main-search-typeahead-result {
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* - Alert ---------------------------------------------------------------------
|
||||
|
||||
|
@ -442,36 +429,6 @@ button.phabricator-main-menu-search-dropdown .caret:before {
|
|||
display: block;
|
||||
}
|
||||
|
||||
/* - Dark Menu -----------------------------------------------------------------
|
||||
|
||||
Styles shared between the "core" menu (left button on mobile) and
|
||||
"application" menu (right button on mobile). These styles give the menu a
|
||||
white-on-black appearance.
|
||||
|
||||
*/
|
||||
|
||||
.device .phabricator-dark-menu,
|
||||
.device .phabricator-dark-menu a.phui-list-item-href {
|
||||
color: {$darkbluetext};
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
.device .phabricator-dark-menu .phui-list-item-type-label {
|
||||
text-transform: uppercase;
|
||||
font-size: {$normalfontsize};
|
||||
background-color: #fff;
|
||||
padding: 6px 0 6px 12px;
|
||||
display: block;
|
||||
font-weight: bold;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.device .phabricator-dark-menu .phui-list-item-href {
|
||||
background-color: #fff;
|
||||
padding: 4px 0 4px 20px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
/* - Core Menu -----------------------------------------------------------------
|
||||
|
||||
|
@ -479,10 +436,6 @@ button.phabricator-main-menu-search-dropdown .caret:before {
|
|||
|
||||
*/
|
||||
|
||||
.phabricator-core-menu-profile-image {
|
||||
background-size: 28px 28px;
|
||||
}
|
||||
|
||||
.device .phabricator-search-menu {
|
||||
display: none;
|
||||
}
|
||||
|
@ -500,12 +453,7 @@ button.phabricator-main-menu-search-dropdown .caret:before {
|
|||
border: 1px solid {$lightblueborder};
|
||||
border-radius: 3px;
|
||||
box-shadow: {$dropshadow};
|
||||
}
|
||||
|
||||
.device .phabricator-dark-menu .phui-list-item-type-link {
|
||||
min-height: 24px;
|
||||
line-height: 20px;
|
||||
background: #fff;
|
||||
background: {$page.background};
|
||||
}
|
||||
|
||||
.device-desktop .phabricator-application-menu {
|
||||
|
@ -531,12 +479,6 @@ button.phabricator-main-menu-search-dropdown .caret:before {
|
|||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.device .phabricator-dark-menu.phabricator-application-menu
|
||||
.phui-list-item-icon.phui-font-fa,
|
||||
.device .phabricator-dark-menu .phabricator-core-menu-icon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.device .phabricator-application-menu .phui-list-item-icon.phui-font-fa {
|
||||
margin: 4px 12px 4px 0;
|
||||
}
|
||||
|
@ -606,29 +548,108 @@ button.phabricator-main-menu-search-dropdown .caret:before {
|
|||
padding-left: 12px;
|
||||
}
|
||||
|
||||
/* - User Menu -----------------------------------------------------------------
|
||||
|
||||
/* - Application Menu ----------------------------------------------------------
|
||||
|
||||
Styles unique to the application menu (right button on mobile).
|
||||
Styles unique to the user profile menu.
|
||||
|
||||
*/
|
||||
|
||||
.device .phabricator-application-menu-expanded .phabricator-application-menu {
|
||||
display: block;
|
||||
position: absolute;
|
||||
border: 1px solid {$blueborder};
|
||||
border-radius: 3px;
|
||||
box-shadow: {$dropshadow};
|
||||
top: 42px;
|
||||
right: 8px;
|
||||
width: 240px;
|
||||
.phabricator-core-user-menu {
|
||||
float: right;
|
||||
display: inline-block;
|
||||
padding: 9px 24px 0 8px;
|
||||
height: 35px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.device .phabricator-application-menu,
|
||||
.device-desktop .phabricator-dark-menu .phui-list-item-type-label {
|
||||
.phabricator-core-user-mobile-menu {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.phabricator-core-user-menu span.phui-icon-view.phuihead-small {
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
background-size: 24px;
|
||||
border-radius: 3px;
|
||||
display: inline-block;
|
||||
margin: 1px 0 0 0;
|
||||
}
|
||||
|
||||
.phabricator-core-user-menu .phui-icon-view {
|
||||
color: {$hoverwhite};
|
||||
font-size: 18px;
|
||||
margin: 4px 0 0 0;
|
||||
}
|
||||
|
||||
.phabricator-core-user-menu .caret {
|
||||
position: absolute;
|
||||
right: 17px;
|
||||
top: 13px;
|
||||
border: none;
|
||||
margin: 1px;
|
||||
color: {$hoverwhite};
|
||||
}
|
||||
|
||||
.phabricator-core-login-button {
|
||||
float: right;
|
||||
display: inline-block;
|
||||
padding: 4px 12px;
|
||||
border-radius: 3px;
|
||||
margin: 8px 6px 4px;
|
||||
border: 1px solid {$hoverwhite};
|
||||
color: {$hoverwhite};
|
||||
}
|
||||
|
||||
.device-desktop .phabricator-core-login-button:hover {
|
||||
border: 1px solid #fff;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.device-desktop .phabricator-core-user-menu:hover .caret,
|
||||
.device-desktop .phabricator-core-user-menu:hover .phui-icon-view {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.device .phabricator-core-user-menu .caret {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.device .phabricator-core-user-mobile-menu {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.device .phabricator-core-user-menu {
|
||||
padding: 9px 8px 0 8px;
|
||||
}
|
||||
|
||||
.device .phabricator-core-user-menu .phui-icon-view {
|
||||
font-size: 20px;
|
||||
margin: 3px 0 0 0;
|
||||
}
|
||||
|
||||
ul.phabricator-core-user-profile-object .phui-oi-objname {
|
||||
font-size: {$biggestfontsize};
|
||||
}
|
||||
|
||||
ul.phabricator-core-user-profile-object li.phui-oi,
|
||||
ul.phabricator-core-user-profile-object .phui-oi-name,
|
||||
ul.phabricator-core-user-profile-object .phui-oi-content,
|
||||
ul.phabricator-core-user-profile-object .phui-oi-subhead {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
ul.phabricator-core-user-profile-object.phui-oi-list-simple .phui-oi-image {
|
||||
height: 36px;
|
||||
width: 36px;
|
||||
}
|
||||
|
||||
ul.phabricator-core-user-profile-object.phui-oi-list-simple
|
||||
.phui-oi-content-box {
|
||||
margin-left: 44px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* - Print ---------------------------------------------------------------------
|
||||
*/
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
word-wrap: break-word;
|
||||
overflow-y: auto;
|
||||
box-shadow: {$dropshadow};
|
||||
border: 1px solid {$blueborder};
|
||||
border: 1px solid {$lightgreyborder};
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
/* When an action list view appears inside a dropdown menu, don't hide it
|
||||
by default. */
|
||||
display: block;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.device .phabricator-action-list-view.phabricator-action-list-toggle,
|
||||
|
@ -18,7 +19,7 @@
|
|||
.phabricator-action-list-view.phabricator-action-list-toggle {
|
||||
display: block;
|
||||
width: 200px;
|
||||
border: 1px solid {$lightblueborder};
|
||||
border: 1px solid {$lightgreyborder};
|
||||
border-radius: 3px;
|
||||
position: absolute;
|
||||
right: 16px;
|
||||
|
@ -58,18 +59,49 @@
|
|||
|
||||
.phabricator-action-view button.phabricator-action-view-item,
|
||||
.phabricator-action-view-item {
|
||||
padding: 4px 4px 4px 28px;
|
||||
padding: 4px 8px 6px 8px;
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
color: {$darkbluetext};
|
||||
}
|
||||
|
||||
.phabricator-action-view-label .phabricator-action-view-item {
|
||||
font-size: {$normalfontsize};
|
||||
.action-has-icon button.phabricator-action-view-item,
|
||||
.action-has-icon .phabricator-action-view-item {
|
||||
padding: 4px 4px 4px 28px;
|
||||
}
|
||||
|
||||
.device-desktop .phabricator-action-view-href:hover
|
||||
.phabricator-action-view-item {
|
||||
text-decoration: none;
|
||||
background: rgba({$alphablue}, .08);
|
||||
color: {$sky};
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.device-desktop .phabricator-action-view-href:hover
|
||||
.phabricator-action-view-icon {
|
||||
color: {$sky};
|
||||
}
|
||||
|
||||
.device-desktop .phabricator-action-view-href.action-item-red:hover
|
||||
.phabricator-action-view-item {
|
||||
background-color: {$sh-redbackground};
|
||||
color: {$sh-redtext};
|
||||
}
|
||||
|
||||
.device-desktop .phabricator-action-view-href.action-item-red:hover
|
||||
.phabricator-action-view-icon {
|
||||
color: {$red};
|
||||
}
|
||||
|
||||
.phabricator-action-view-label .phabricator-action-view-item,
|
||||
.phabricator-action-view-type-label .phabricator-action-view-item {
|
||||
font-size: {$smallerfontsize};
|
||||
font-weight: bold;
|
||||
color: {$bluetext};
|
||||
padding: 4px 8px 6px 8px;
|
||||
display: block;
|
||||
text-transform: uppercase;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
|
@ -87,37 +119,23 @@
|
|||
width: 14px;
|
||||
height: 14px;
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
top: 7px;
|
||||
left: 8px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.device-desktop .phabricator-action-view:hover .phabricator-action-view-item {
|
||||
text-decoration: none;
|
||||
background-color: {$sky};
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.device-desktop .phabricator-action-view:hover .phabricator-action-view-icon {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.phabricator-action-view-disabled .phabricator-action-view-item,
|
||||
.phabricator-action-view-disabled button.phabricator-action-view-item {
|
||||
color: {$lightgreytext};
|
||||
}
|
||||
|
||||
.phabricator-action-view-selected {
|
||||
border-left: 3px solid {$sky};
|
||||
background: {$hoverblue};
|
||||
background: {$sh-violetbackground};
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.phabricator-action-view-selected .phabricator-action-view-item {
|
||||
padding-left: 25px;
|
||||
}
|
||||
|
||||
.phabricator-action-view-selected .phabricator-action-view-icon {
|
||||
left: 6px;
|
||||
.phabricator-action-view-selected:hover a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.phabricator-action-view button[disabled] {
|
||||
|
@ -135,3 +153,8 @@
|
|||
background-color: {$greybackground};
|
||||
color: {$lightgreytext};
|
||||
}
|
||||
|
||||
.phabricator-action-view-type-divider {
|
||||
margin-top: 8px;
|
||||
border-top: 1px solid {$thinblueborder};
|
||||
}
|
||||
|
|
|
@ -198,12 +198,12 @@ button.link:hover {
|
|||
|
||||
.phuix-dropdown-menu {
|
||||
position: absolute;
|
||||
width: 240px;
|
||||
width: 200px;
|
||||
background: #fff;
|
||||
margin-top: -1px;
|
||||
padding: 5px 0;
|
||||
padding: 12px;
|
||||
box-shadow: {$dropshadow};
|
||||
border: 1px solid {$blueborder};
|
||||
border: 1px solid {$lightgreyborder};
|
||||
border-radius: 3px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ a.button.phui-document-toc {
|
|||
|
||||
.phui-document-view-pro .phui-document-toc-list {
|
||||
margin: 8px;
|
||||
border: 1px solid {$blueborder};
|
||||
border: 1px solid {$lightgreyborder};
|
||||
border-radius: 3px;
|
||||
box-shadow: {$dropshadow};
|
||||
width: 200px;
|
||||
|
|
|
@ -460,8 +460,7 @@ body .phui-form-view .remarkup-assist-textarea.aphront-textarea-drag-and-drop {
|
|||
|
||||
.fancy-datepicker-core {
|
||||
background-color: white;
|
||||
border: 1px solid {$lightblueborder};
|
||||
border-bottom: 1px solid {$blueborder};
|
||||
border: 1px solid {$lightgreyborder};
|
||||
box-shadow: {$dropshadow};
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* @provides phui-profile-menu-css
|
||||
*/
|
||||
|
||||
.device-desktop .phui-profile-menu-collapsed .phabricator-nav-local {
|
||||
.device-desktop .phui-profile-menu .phabricator-nav-local {
|
||||
width: {$menu.profile.width.collapsed};
|
||||
max-width: {$menu.profile.width.collapsed};
|
||||
}
|
||||
|
@ -58,8 +58,7 @@
|
|||
background-size: 100%;
|
||||
}
|
||||
|
||||
.phui-profile-menu .phui-profile-menu-collapsed .phabricator-side-menu
|
||||
.phui-list-item-href {
|
||||
.phui-profile-menu .phabricator-side-menu .phui-list-item-href {
|
||||
text-align: center;
|
||||
padding: 42px 4px 14px;
|
||||
line-height: 14px;
|
||||
|
@ -67,19 +66,17 @@
|
|||
font-size: {$smallerfontsize};
|
||||
}
|
||||
|
||||
.phui-profile-menu .phui-profile-menu-collapsed .phabricator-side-menu
|
||||
.phui-list-item-name {
|
||||
.phui-profile-menu .phabricator-side-menu .phui-list-item-name {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.phui-profile-menu .phui-profile-menu-collapsed .phabricator-side-menu
|
||||
.phui-list-item-icon,
|
||||
.phui-profile-menu .phui-profile-menu-collapsed .phabricator-side-menu
|
||||
.phui-list-item-href .phui-list-item-icon {
|
||||
top: 14px;
|
||||
left: 32px;
|
||||
.phui-profile-menu .phabricator-side-menu .phui-list-item-icon,
|
||||
.phui-profile-menu .phabricator-side-menu .phui-list-item-href
|
||||
.phui-list-item-icon {
|
||||
top: 14px;
|
||||
left: 32px;
|
||||
}
|
||||
|
||||
.phui-profile-menu .phabricator-side-menu
|
||||
|
@ -131,14 +128,12 @@
|
|||
padding: 16px;
|
||||
}
|
||||
|
||||
.phui-profile-menu .phui-profile-menu-collapsed .phabricator-side-menu
|
||||
.phui-profile-menu-error {
|
||||
.phui-profile-menu .phabricator-side-menu .phui-profile-menu-error {
|
||||
padding: 16px 8px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
|
||||
.phui-profile-menu .phabricator-side-menu .phui-list-item-disabled
|
||||
.phui-list-item-href,
|
||||
.phui-profile-menu .phui-list-sidenav .phui-list-item-disabled
|
||||
|
@ -153,150 +148,15 @@
|
|||
padding: 8px 12px 16px;
|
||||
}
|
||||
|
||||
.phui-profile-menu .phui-profile-menu-collapsed .phabricator-side-menu
|
||||
.phui-profile-segment-bar {
|
||||
.phui-profile-menu .phabricator-side-menu .phui-profile-segment-bar {
|
||||
padding: 8px 8px 16px;
|
||||
}
|
||||
|
||||
|
||||
.phui-profile-menu .phabricator-side-menu .phui-profile-menu-spacer {
|
||||
box-sizing: border-box;
|
||||
height: {$menu.profile.item.height};
|
||||
}
|
||||
|
||||
.phui-profile-menu .phui-profile-menu-collapsed .phabricator-side-menu
|
||||
.phui-profile-menu-footer
|
||||
.phui-list-item-name {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.phui-profile-menu .phui-profile-menu-expanded
|
||||
.phui-profile-menu-visible-when-collapsed,
|
||||
.phui-profile-menu .phui-profile-menu-collapsed
|
||||
.phui-profile-menu-visible-when-expanded {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
.phui-profile-menu .phui-profile-menu-collapsed .phabricator-side-menu
|
||||
.phui-profile-menu-footer .phui-list-item-href {
|
||||
padding: 20px 0 24px;
|
||||
}
|
||||
|
||||
.phui-profile-menu .phabricator-side-menu .phui-profile-menu-footer
|
||||
.phui-list-item-href:hover {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.phui-profile-menu .phui-profile-menu-collapsed .phabricator-side-menu
|
||||
.phui-profile-menu-footer .phui-list-item-href .phui-list-item-icon {
|
||||
top: 8px;
|
||||
}
|
||||
|
||||
.phui-profile-menu .phui-profile-menu-footer .phui-icon-circle {
|
||||
border-color: {$darkbluetext};
|
||||
}
|
||||
|
||||
.phui-profile-menu .phui-profile-menu-footer .phui-icon-circle .phui-icon-view {
|
||||
color: {$darkbluetext};
|
||||
}
|
||||
|
||||
.phui-profile-menu .phui-profile-menu-footer
|
||||
.phui-icon-circle.phui-list-item-icon {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.phui-profile-menu .phabricator-side-menu .phui-profile-menu-footer-1 {
|
||||
bottom: 0;
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
.phui-profile-menu .phui-profile-menu-footer-1 {
|
||||
width: {$menu.profile.width};
|
||||
}
|
||||
|
||||
.phui-profile-menu .phui-profile-menu-collapsed .phui-profile-menu-footer-1 {
|
||||
width: {$menu.profile.width.collapsed};
|
||||
}
|
||||
|
||||
.phui-profile-menu .phabricator-side-menu
|
||||
.phui-list-item-selected.phui-profile-menu-footer .phui-list-item-href {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.phui-profile-menu .phui-profile-menu-collapsing
|
||||
.phabricator-nav-local {
|
||||
animation: profile-menu-collapse 0.2s;
|
||||
}
|
||||
|
||||
.phui-profile-menu .phui-profile-menu-expanding
|
||||
.phabricator-nav-local {
|
||||
animation: profile-menu-expand 0.2s;
|
||||
}
|
||||
|
||||
.phui-profile-menu .phui-profile-menu-collapsing
|
||||
.phabricator-side-menu .phui-list-item-href {
|
||||
animation: profile-menu-blink 0.2s;
|
||||
}
|
||||
|
||||
.phui-profile-menu .phui-profile-menu-expanding
|
||||
.phabricator-side-menu .phui-list-item-href {
|
||||
animation: profile-menu-blink 0.2s;
|
||||
}
|
||||
|
||||
@keyframes profile-menu-blink {
|
||||
0% {
|
||||
opacity: 1.0;
|
||||
}
|
||||
25% {
|
||||
opacity: 0.0;
|
||||
}
|
||||
75% {
|
||||
opacity: 0.0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes profile-menu-collapse {
|
||||
0% {
|
||||
width: {$menu.profile.width};
|
||||
max-width: {$menu.profile.width};
|
||||
}
|
||||
33% {
|
||||
width: {$menu.profile.width};
|
||||
max-width: {$menu.profile.width};
|
||||
}
|
||||
66% {
|
||||
width: {$menu.profile.width.collapsed};
|
||||
max-width: {$menu.profile.width.collapsed};
|
||||
}
|
||||
100% {
|
||||
width: {$menu.profile.width.collapsed};
|
||||
max-width: {$menu.profile.width.collapsed};
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes profile-menu-expand {
|
||||
0% {
|
||||
width: {$menu.profile.width.collapsed};
|
||||
max-width: {$menu.profile.width.collapsed};
|
||||
}
|
||||
33% {
|
||||
width: {$menu.profile.width.collapsed};
|
||||
max-width: {$menu.profile.width.collapsed};
|
||||
}
|
||||
66% {
|
||||
width: {$menu.profile.width};
|
||||
max-width: {$menu.profile.width};
|
||||
}
|
||||
100% {
|
||||
width: {$menu.profile.width};
|
||||
max-width: {$menu.profile.width};
|
||||
}
|
||||
}
|
||||
|
||||
!print .phui-profile-menu .phabricator-side-menu {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
@ -159,24 +159,6 @@
|
|||
padding: 0 12px;
|
||||
}
|
||||
|
||||
.phabricator-action-view button.phabricator-action-view-item,
|
||||
.phabricator-action-view-item {
|
||||
padding: 5px 4px 5px 28px;
|
||||
}
|
||||
|
||||
.device-desktop .phui-two-column-properties .phabricator-action-view-href:hover
|
||||
.phabricator-action-view-item {
|
||||
text-decoration: none;
|
||||
background-color: rgba({$alphablue}, .08);
|
||||
color: {$sky};
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.device-desktop .phui-two-column-properties .phabricator-action-view-href:hover
|
||||
.phabricator-action-view-icon {
|
||||
color: {$sky};
|
||||
}
|
||||
|
||||
.phui-two-column-view .phui-property-list-section-header,
|
||||
.phui-two-column-view .phui-property-list-text-content {
|
||||
margin: 0 16px;
|
||||
|
@ -199,6 +181,10 @@
|
|||
padding: 12px;
|
||||
}
|
||||
|
||||
.phui-two-column-view .phui-oi-empty .phui-info-view {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.phui-two-column-view .phui-side-column .phui-oi-empty
|
||||
.phui-info-view {
|
||||
margin-bottom: 0;
|
||||
|
|
|
@ -32,11 +32,6 @@
|
|||
}
|
||||
|
||||
.device-desktop .project-board-wrapper .phui-workboard-view-shadow {
|
||||
left: {$menu.profile.width};
|
||||
}
|
||||
|
||||
.device-desktop .phui-profile-menu-collapsed .project-board-wrapper
|
||||
.phui-workboard-view-shadow {
|
||||
left: {$menu.profile.width.collapsed};
|
||||
}
|
||||
|
||||
|
|
|
@ -91,24 +91,6 @@ JX.behavior('aphlict-dropdown', function(config, statics) {
|
|||
null,
|
||||
function (e) {
|
||||
var data = e.getData();
|
||||
if (config.local && config.applicationClass) {
|
||||
var local_dropdowns = data.newResponse.aphlictDropdowns;
|
||||
if (local_dropdowns[config.applicationClass]) {
|
||||
JX.DOM.replace(
|
||||
dropdown,
|
||||
JX.$H(local_dropdowns[config.applicationClass]));
|
||||
dropdown = JX.$(config.dropdownID);
|
||||
if (dropdown.childNodes.length === 0) {
|
||||
JX.DOM.hide(bubble);
|
||||
} else {
|
||||
JX.DOM.show(bubble);
|
||||
}
|
||||
} else {
|
||||
JX.DOM.hide(bubble);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!data.fromServer) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -34,13 +34,6 @@ JX.behavior('project-boards', function(config, statics) {
|
|||
data.menu = new JX.PHUIXDropdownMenu(button);
|
||||
data.menu.setContent(list);
|
||||
data.menu.open();
|
||||
|
||||
JX.DOM.listen(list, 'click', 'tag:a', function(e) {
|
||||
if (!e.isNormalClick()) {
|
||||
return;
|
||||
}
|
||||
data.menu.close();
|
||||
});
|
||||
});
|
||||
|
||||
JX.Stratcom.listen(
|
||||
|
|
|
@ -126,7 +126,7 @@ JX.behavior('comment-actions', function(config) {
|
|||
}
|
||||
|
||||
function force_preview() {
|
||||
if (!config.shouldPreview) {
|
||||
if (!config.showPreview) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
57
webroot/rsrc/js/core/behavior-user-menu.js
Normal file
57
webroot/rsrc/js/core/behavior-user-menu.js
Normal file
|
@ -0,0 +1,57 @@
|
|||
/**
|
||||
* @provides javelin-behavior-user-menu
|
||||
* @requires javelin-behavior
|
||||
*/
|
||||
|
||||
JX.behavior('user-menu', function(config) {
|
||||
var node = JX.$(config.menuID);
|
||||
var list = JX.$H(config.menu.items).getFragment().firstChild;
|
||||
|
||||
var menu = new JX.PHUIXDropdownMenu(node);
|
||||
|
||||
menu.listen('open', function() {
|
||||
menu.setContent(list);
|
||||
});
|
||||
|
||||
// When the user navigates to a new page, we may need to update the links
|
||||
// to documentation in the menu.
|
||||
JX.Stratcom.listen('quicksand-redraw', null, function(e) {
|
||||
var data = e.getData();
|
||||
|
||||
var new_help = data.newResponse.helpItems;
|
||||
var nodes;
|
||||
if (new_help) {
|
||||
nodes = JX.$H(new_help.items).getFragment().firstChild.children;
|
||||
} else {
|
||||
nodes = [];
|
||||
}
|
||||
|
||||
var ii;
|
||||
|
||||
var tail = [];
|
||||
for (ii = list.children.length - 1; ii >= 0; ii--) {
|
||||
var node = list.children[ii];
|
||||
|
||||
// Remove any old help items.
|
||||
if (JX.Stratcom.hasSigil(node.firstChild, 'help-item')) {
|
||||
JX.DOM.remove(node);
|
||||
}
|
||||
|
||||
// Place the logout items aside, if any exist.
|
||||
if (JX.Stratcom.hasSigil(node.firstChild, 'logout-item')) {
|
||||
JX.DOM.remove(node);
|
||||
tail.push(node);
|
||||
}
|
||||
}
|
||||
|
||||
while (nodes.length) {
|
||||
list.appendChild(nodes[0]);
|
||||
}
|
||||
|
||||
tail.reverse();
|
||||
for (ii = 0; ii < tail.length; ii++) {
|
||||
list.appendChild(tail[ii]);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
|
@ -42,18 +42,6 @@ JX.behavior('phui-dropdown-menu', function() {
|
|||
});
|
||||
|
||||
data.menu.open();
|
||||
|
||||
JX.DOM.listen(list, 'click', 'tag:a', function(e) {
|
||||
if (!e.isNormalClick()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (JX.Stratcom.pass()) {
|
||||
return;
|
||||
}
|
||||
|
||||
data.menu.close();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
/**
|
||||
* @provides javelin-behavior-phui-profile-menu
|
||||
* @requires javelin-behavior
|
||||
* javelin-stratcom
|
||||
* javelin-dom
|
||||
*/
|
||||
|
||||
JX.behavior('phui-profile-menu', function(config) {
|
||||
// NOTE: This behavior is not initialized in the rendering pipeline for the
|
||||
// menu, so it can get initialized when we build but do not render a menu
|
||||
// (for example, when a page like the panel edit page only has items in
|
||||
// the mobile/application menu, and does not show the profile menu). For now,
|
||||
// just bail if we can't find the menu.
|
||||
|
||||
try {
|
||||
var menu_node = JX.$(config.menuID);
|
||||
} catch (ex) {
|
||||
return;
|
||||
}
|
||||
|
||||
var collapse_node = JX.$(config.collapseID);
|
||||
|
||||
var is_collapsed = config.isCollapsed;
|
||||
|
||||
JX.DOM.listen(collapse_node, 'click', null, function(e) {
|
||||
is_collapsed = !is_collapsed;
|
||||
|
||||
JX.DOM.alterClass(menu_node, 'phui-profile-menu-collapsing', is_collapsed);
|
||||
JX.DOM.alterClass(menu_node, 'phui-profile-menu-expanding', !is_collapsed);
|
||||
|
||||
var duration = 0.2;
|
||||
|
||||
setTimeout(function() {
|
||||
JX.DOM.alterClass(menu_node, 'phui-profile-menu-collapsed', is_collapsed);
|
||||
JX.DOM.alterClass(menu_node, 'phui-profile-menu-expanded', !is_collapsed);
|
||||
}, (duration / 2) * 1000);
|
||||
|
||||
setTimeout(function() {
|
||||
JX.DOM.alterClass(menu_node, 'phui-profile-menu-collapsing', false);
|
||||
JX.DOM.alterClass(menu_node, 'phui-profile-menu-expanding', false);
|
||||
}, duration * 1000);
|
||||
|
||||
|
||||
if (config.settingsURI) {
|
||||
new JX.Request(config.settingsURI)
|
||||
.setData({value: (is_collapsed ? 1 : 0)})
|
||||
.send();
|
||||
}
|
||||
|
||||
e.kill();
|
||||
});
|
||||
|
||||
});
|
|
@ -77,16 +77,27 @@ JX.install('PHUIXActionView', {
|
|||
|
||||
getNode: function() {
|
||||
if (!this._node) {
|
||||
var attr = {
|
||||
className: 'phabricator-action-view'
|
||||
};
|
||||
var classes = ['phabricator-action-view'];
|
||||
|
||||
if (this._href || this._handler) {
|
||||
classes.push('phabricator-action-view-href');
|
||||
}
|
||||
|
||||
if (this._icon) {
|
||||
classes.push('action-has-icon');
|
||||
}
|
||||
|
||||
var content = [
|
||||
this._buildIconNode(),
|
||||
this._buildNameNode()
|
||||
];
|
||||
|
||||
var attr = {
|
||||
className: classes.join(' ')
|
||||
};
|
||||
this._node = JX.$N('li', attr, content);
|
||||
|
||||
JX.Stratcom.addSigil(this._node, 'phuix-action-view');
|
||||
}
|
||||
|
||||
return this._node;
|
||||
|
|
|
@ -40,6 +40,12 @@ JX.install('PHUIXDropdownMenu', {
|
|||
JX.Stratcom.listen('phuix.dropdown.open', null, JX.bind(this, this.close));
|
||||
|
||||
JX.Stratcom.listen('keydown', null, JX.bind(this, this._onkey));
|
||||
|
||||
JX.DOM.listen(
|
||||
this._getMenuNode(),
|
||||
'click',
|
||||
'tag:a',
|
||||
JX.bind(this, this._onlink));
|
||||
},
|
||||
|
||||
events: ['open', 'close'],
|
||||
|
@ -112,6 +118,28 @@ JX.install('PHUIXDropdownMenu', {
|
|||
e.prevent();
|
||||
},
|
||||
|
||||
_onlink: function(e) {
|
||||
if (!e.isNormalClick()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If this action was built dynamically with PHUIXActionView, don't
|
||||
// do anything by default. The caller is repsonsible for installing a
|
||||
// handler if they want to react to clicks.
|
||||
if (e.getNode('phuix-action-view')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If this item opens a submenu, we don't want to close the current
|
||||
// menu. One submenu is "Edit Related Objects..." on mobile.
|
||||
var link = e.getNode('tag:a');
|
||||
if (JX.Stratcom.hasSigil(link, 'keep-open')) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.close();
|
||||
},
|
||||
|
||||
_onanyclick : function(e) {
|
||||
if (!this._open) {
|
||||
return;
|
||||
|
|
Loading…
Reference in a new issue