diff --git a/resources/sql/autopatches/20140430.dash.1.paneltype.sql b/resources/sql/autopatches/20140430.dash.1.paneltype.sql new file mode 100644 index 0000000000..d90655cf98 --- /dev/null +++ b/resources/sql/autopatches/20140430.dash.1.paneltype.sql @@ -0,0 +1,2 @@ +ALTER TABLE {$NAMESPACE}_dashboard.dashboard_panel + ADD panelType VARCHAR(64) NOT NULL COLLATE utf8_bin AFTER name; diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index f0b45d8c40..89c5a2be53 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1439,6 +1439,7 @@ phutil_register_library_map(array( 'PhabricatorDashboardPHIDTypeDashboard' => 'applications/dashboard/phid/PhabricatorDashboardPHIDTypeDashboard.php', 'PhabricatorDashboardPHIDTypePanel' => 'applications/dashboard/phid/PhabricatorDashboardPHIDTypePanel.php', 'PhabricatorDashboardPanel' => 'applications/dashboard/storage/PhabricatorDashboardPanel.php', + 'PhabricatorDashboardPanelCreateController' => 'applications/dashboard/controller/PhabricatorDashboardPanelCreateController.php', 'PhabricatorDashboardPanelEditController' => 'applications/dashboard/controller/PhabricatorDashboardPanelEditController.php', 'PhabricatorDashboardPanelListController' => 'applications/dashboard/controller/PhabricatorDashboardPanelListController.php', 'PhabricatorDashboardPanelQuery' => 'applications/dashboard/query/PhabricatorDashboardPanelQuery.php', @@ -1446,6 +1447,8 @@ phutil_register_library_map(array( 'PhabricatorDashboardPanelTransaction' => 'applications/dashboard/storage/PhabricatorDashboardPanelTransaction.php', 'PhabricatorDashboardPanelTransactionEditor' => 'applications/dashboard/editor/PhabricatorDashboardPanelTransactionEditor.php', 'PhabricatorDashboardPanelTransactionQuery' => 'applications/dashboard/query/PhabricatorDashboardPanelTransactionQuery.php', + 'PhabricatorDashboardPanelType' => 'applications/dashboard/paneltype/PhabricatorDashboardPanelType.php', + 'PhabricatorDashboardPanelTypeText' => 'applications/dashboard/paneltype/PhabricatorDashboardPanelTypeText.php', 'PhabricatorDashboardPanelViewController' => 'applications/dashboard/controller/PhabricatorDashboardPanelViewController.php', 'PhabricatorDashboardQuery' => 'applications/dashboard/query/PhabricatorDashboardQuery.php', 'PhabricatorDashboardSearchEngine' => 'applications/dashboard/query/PhabricatorDashboardSearchEngine.php', @@ -4242,6 +4245,7 @@ phutil_register_library_map(array( 0 => 'PhabricatorDashboardDAO', 1 => 'PhabricatorPolicyInterface', ), + 'PhabricatorDashboardPanelCreateController' => 'PhabricatorDashboardController', 'PhabricatorDashboardPanelEditController' => 'PhabricatorDashboardController', 'PhabricatorDashboardPanelListController' => array( @@ -4253,6 +4257,8 @@ phutil_register_library_map(array( 'PhabricatorDashboardPanelTransaction' => 'PhabricatorApplicationTransaction', 'PhabricatorDashboardPanelTransactionEditor' => 'PhabricatorApplicationTransactionEditor', 'PhabricatorDashboardPanelTransactionQuery' => 'PhabricatorApplicationTransactionQuery', + 'PhabricatorDashboardPanelType' => 'Phobject', + 'PhabricatorDashboardPanelTypeText' => 'PhabricatorDashboardPanelType', 'PhabricatorDashboardPanelViewController' => 'PhabricatorDashboardController', 'PhabricatorDashboardQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhabricatorDashboardSearchEngine' => 'PhabricatorApplicationSearchEngine', diff --git a/src/applications/dashboard/application/PhabricatorApplicationDashboard.php b/src/applications/dashboard/application/PhabricatorApplicationDashboard.php index a6654e8951..97bfd47375 100644 --- a/src/applications/dashboard/application/PhabricatorApplicationDashboard.php +++ b/src/applications/dashboard/application/PhabricatorApplicationDashboard.php @@ -27,7 +27,7 @@ final class PhabricatorApplicationDashboard extends PhabricatorApplication { 'panel/' => array( '(?:query/(?P[^/]+)/)?' => 'PhabricatorDashboardPanelListController', - 'create/' => 'PhabricatorDashboardPanelEditController', + 'create/' => 'PhabricatorDashboardPanelCreateController', 'edit/(?:(?P\d+)/)?' => 'PhabricatorDashboardPanelEditController', ), ), diff --git a/src/applications/dashboard/controller/PhabricatorDashboardListController.php b/src/applications/dashboard/controller/PhabricatorDashboardListController.php index 5a25da8a24..0f9b7ba7d6 100644 --- a/src/applications/dashboard/controller/PhabricatorDashboardListController.php +++ b/src/applications/dashboard/controller/PhabricatorDashboardListController.php @@ -28,6 +28,9 @@ final class PhabricatorDashboardListController ->setViewer($user) ->addNavigationItems($nav->getMenu()); + $nav->addLabel(pht('Panels')); + $nav->addFilter('panel/', pht('Manage Panels')); + $nav->selectFilter(null); return $nav; diff --git a/src/applications/dashboard/controller/PhabricatorDashboardPanelCreateController.php b/src/applications/dashboard/controller/PhabricatorDashboardPanelCreateController.php new file mode 100644 index 0000000000..344044a88e --- /dev/null +++ b/src/applications/dashboard/controller/PhabricatorDashboardPanelCreateController.php @@ -0,0 +1,75 @@ +getRequest(); + $viewer = $request->getUser(); + + $types = PhabricatorDashboardPanelType::getAllPanelTypes(); + + $v_type = null; + $errors = array(); + if ($request->isFormPost()) { + $v_type = $request->getStr('type'); + if (!isset($types[$v_type])) { + $errors[] = pht('You must select a type of panel to create.'); + } + + if (!$errors) { + return id(new AphrontRedirectResponse())->setURI( + $this->getApplicationURI('panel/edit/?type='.$v_type)); + } + } + + $cancel_uri = $this->getApplicationURI('panel/'); + + if (!$v_type) { + $v_type = key($types); + } + + $panel_types = id(new AphrontFormRadioButtonControl()) + ->setName('type') + ->setValue($v_type); + + foreach ($types as $key => $type) { + $panel_types->addButton( + $key, + $type->getPanelTypeName(), + $type->getPanelTypeDescription()); + } + + $form = id(new AphrontFormView()) + ->setUser($viewer) + ->appendChild($panel_types) + ->appendChild( + id(new AphrontFormSubmitControl()) + ->setValue(pht('Continue')) + ->addCancelButton($cancel_uri)); + + $crumbs = $this->buildApplicationCrumbs(); + $crumbs->addTextCrumb( + pht('Panels'), + $this->getApplicationURI('panel/')); + $crumbs->addTextCrumb(pht('New Panel')); + + $title = pht('Create Dashboard Panel'); + + $box = id(new PHUIObjectBoxView()) + ->setHeaderText($title) + ->setFormErrors($errors) + ->setForm($form); + + return $this->buildApplicationPage( + array( + $crumbs, + $box, + ), + array( + 'title' => $title, + 'device' => true, + )); + } + +} diff --git a/src/applications/dashboard/controller/PhabricatorDashboardPanelEditController.php b/src/applications/dashboard/controller/PhabricatorDashboardPanelEditController.php index 04c74da79f..483472aacb 100644 --- a/src/applications/dashboard/controller/PhabricatorDashboardPanelEditController.php +++ b/src/applications/dashboard/controller/PhabricatorDashboardPanelEditController.php @@ -33,6 +33,14 @@ final class PhabricatorDashboardPanelEditController $is_create = true; $panel = PhabricatorDashboardPanel::initializeNewPanel($viewer); + + $types = PhabricatorDashboardPanelType::getAllPanelTypes(); + $type = $request->getStr('type'); + if (empty($types[$type])) { + return new Aphront404Response(); + } + + $panel->setPanelType($type); } if ($is_create) { @@ -97,6 +105,7 @@ final class PhabricatorDashboardPanelEditController $this->getApplicationURI('panel/')); if ($is_create) { $crumbs->addTextCrumb(pht('New Panel')); + $form->addHiddenInput('type', $panel->getPanelType()); } else { $crumbs->addTextCrumb( $panel->getMonogram(), diff --git a/src/applications/dashboard/controller/PhabricatorDashboardPanelViewController.php b/src/applications/dashboard/controller/PhabricatorDashboardPanelViewController.php index 5d357d862d..737e4ca04c 100644 --- a/src/applications/dashboard/controller/PhabricatorDashboardPanelViewController.php +++ b/src/applications/dashboard/controller/PhabricatorDashboardPanelViewController.php @@ -94,6 +94,20 @@ final class PhabricatorDashboardPanelViewController $viewer, $panel); + $panel_type = $panel->getImplementation(); + if ($panel_type) { + $type_name = $panel_type->getPanelTypeName(); + } else { + $type_name = phutil_tag( + 'em', + array(), + nonempty($panel->getPanelType(), pht('null'))); + } + + $properties->addProperty( + pht('Panel Type'), + $type_name); + $properties->addProperty( pht('Editable By'), $descriptions[PhabricatorPolicyCapability::CAN_EDIT]); diff --git a/src/applications/dashboard/paneltype/PhabricatorDashboardPanelType.php b/src/applications/dashboard/paneltype/PhabricatorDashboardPanelType.php new file mode 100644 index 0000000000..821384cd83 --- /dev/null +++ b/src/applications/dashboard/paneltype/PhabricatorDashboardPanelType.php @@ -0,0 +1,42 @@ +setAncestorClass(__CLASS__) + ->loadObjects(); + + $map = array(); + foreach ($objects as $object) { + $key = $object->getPanelTypeKey(); + if (!empty($map[$key])) { + $this_class = get_class($object); + $that_class = get_class($map[$key]); + throw new Exception( + pht( + 'Two dashboard panels (of classes "%s" and "%s") have the '. + 'same panel type key ("%s"). Each panel type must have a '. + 'unique panel type key.', + $this_class, + $that_class, + $key)); + } + + $map[$key] = $object; + } + + $types = $map; + } + + return $types; + } + +} diff --git a/src/applications/dashboard/paneltype/PhabricatorDashboardPanelTypeText.php b/src/applications/dashboard/paneltype/PhabricatorDashboardPanelTypeText.php new file mode 100644 index 0000000000..d2f54af222 --- /dev/null +++ b/src/applications/dashboard/paneltype/PhabricatorDashboardPanelTypeText.php @@ -0,0 +1,20 @@ +getID(); } + public function getImplementation() { + return idx( + PhabricatorDashboardPanelType::getAllPanelTypes(), + $this->getPanelType()); + } + + public function requireImplementation() { + $impl = $this->getImplementation(); + if (!$impl) { + throw new Exception( + pht( + 'Attempting to use a panel in a way that requires an '. + 'implementation, but the panel implementation ("%s") is unknown to '. + 'Phabricator.', + $this->getPanelType())); + } + return $impl; + } + /* -( PhabricatorPolicyInterface )----------------------------------------- */