mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-18 19:40:55 +01:00
Create dashboard panels inline on dashboards
Summary: Fixes T5308. - Allows you to create a panel directly on a dashboard. - Also, include existing panels with a select instead of a text field. This won't scale as well but should be fine for now, and is way easier to use. Test Plan: See comment. Reviewers: chad Reviewed By: chad Subscribers: epriestley Maniphest Tasks: T5308 Differential Revision: https://secure.phabricator.com/D9501
This commit is contained in:
parent
b8bc0aa2b0
commit
6f4ebcb8d9
9 changed files with 243 additions and 173 deletions
|
@ -1488,7 +1488,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorDashboardPHIDTypePanel' => 'applications/dashboard/phid/PhabricatorDashboardPHIDTypePanel.php',
|
||||
'PhabricatorDashboardPanel' => 'applications/dashboard/storage/PhabricatorDashboardPanel.php',
|
||||
'PhabricatorDashboardPanelCoreCustomField' => 'applications/dashboard/customfield/PhabricatorDashboardPanelCoreCustomField.php',
|
||||
'PhabricatorDashboardPanelCreateController' => 'applications/dashboard/controller/PhabricatorDashboardPanelCreateController.php',
|
||||
'PhabricatorDashboardPanelCustomField' => 'applications/dashboard/customfield/PhabricatorDashboardPanelCustomField.php',
|
||||
'PhabricatorDashboardPanelEditController' => 'applications/dashboard/controller/PhabricatorDashboardPanelEditController.php',
|
||||
'PhabricatorDashboardPanelListController' => 'applications/dashboard/controller/PhabricatorDashboardPanelListController.php',
|
||||
|
@ -4313,7 +4312,6 @@ phutil_register_library_map(array(
|
|||
0 => 'PhabricatorDashboardPanelCustomField',
|
||||
1 => 'PhabricatorStandardCustomFieldInterface',
|
||||
),
|
||||
'PhabricatorDashboardPanelCreateController' => 'PhabricatorDashboardController',
|
||||
'PhabricatorDashboardPanelCustomField' => 'PhabricatorCustomField',
|
||||
'PhabricatorDashboardPanelEditController' => 'PhabricatorDashboardController',
|
||||
'PhabricatorDashboardPanelListController' => 'PhabricatorDashboardController',
|
||||
|
|
|
@ -34,7 +34,7 @@ final class PhabricatorApplicationDashboard extends PhabricatorApplication {
|
|||
'panel/' => array(
|
||||
'(?:query/(?P<queryKey>[^/]+)/)?'
|
||||
=> 'PhabricatorDashboardPanelListController',
|
||||
'create/' => 'PhabricatorDashboardPanelCreateController',
|
||||
'create/' => 'PhabricatorDashboardPanelEditController',
|
||||
'edit/(?:(?P<id>\d+)/)?' => 'PhabricatorDashboardPanelEditController',
|
||||
'render/(?P<id>\d+)/' => 'PhabricatorDashboardPanelRenderController',
|
||||
),
|
||||
|
|
|
@ -26,82 +26,74 @@ final class PhabricatorDashboardAddPanelController
|
|||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$redirect_uri = $this->getApplicationURI(
|
||||
'manage/'.$dashboard->getID().'/');
|
||||
$layout_config = $dashboard->getLayoutConfigObject();
|
||||
$redirect_uri = $this->getApplicationURI('manage/'.$dashboard->getID().'/');
|
||||
|
||||
$v_panel = $request->getStr('panel');
|
||||
$e_panel = true;
|
||||
$errors = array();
|
||||
if ($request->isFormPost()) {
|
||||
if (strlen($v_panel)) {
|
||||
$panel = id(new PhabricatorObjectQuery())
|
||||
$panel = id(new PhabricatorDashboardPanelQuery())
|
||||
->setViewer($viewer)
|
||||
->withNames(array($v_panel))
|
||||
->withTypes(array(PhabricatorDashboardPHIDTypePanel::TYPECONST))
|
||||
->withIDs(array($v_panel))
|
||||
->executeOne();
|
||||
if (!$panel) {
|
||||
$errors[] = pht('No such panel!');
|
||||
$e_panel = pht('Invalid');
|
||||
}
|
||||
} else {
|
||||
$errors[] = pht('Name a panel to add.');
|
||||
$errors[] = pht('Select a panel to add.');
|
||||
$e_panel = pht('Required');
|
||||
}
|
||||
|
||||
if (!$errors) {
|
||||
$xactions = array();
|
||||
$xactions[] = id(new PhabricatorDashboardTransaction())
|
||||
->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
|
||||
->setMetadataValue(
|
||||
'edge:type',
|
||||
PhabricatorEdgeConfig::TYPE_DASHBOARD_HAS_PANEL)
|
||||
->setNewValue(
|
||||
array(
|
||||
'+' => array(
|
||||
$panel->getPHID() => $panel->getPHID(),
|
||||
),
|
||||
));
|
||||
|
||||
$layout_config->setPanelLocation(
|
||||
$request->getInt('column', 0),
|
||||
$panel->getPHID());
|
||||
$dashboard->setLayoutConfigFromObject($layout_config);
|
||||
|
||||
$editor = id(new PhabricatorDashboardTransactionEditor())
|
||||
->setActor($viewer)
|
||||
->setContentSourceFromRequest($request)
|
||||
->setContinueOnMissingFields(true)
|
||||
->setContinueOnNoEffect(true)
|
||||
->applyTransactions($dashboard, $xactions);
|
||||
PhabricatorDashboardTransactionEditor::addPanelToDashboard(
|
||||
$viewer,
|
||||
PhabricatorContentSource::newFromRequest($request),
|
||||
$panel,
|
||||
$dashboard,
|
||||
$request->getInt('column', 0));
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI($redirect_uri);
|
||||
}
|
||||
}
|
||||
|
||||
$panels = id(new PhabricatorDashboardPanelQuery())
|
||||
->setViewer($viewer)
|
||||
->execute();
|
||||
|
||||
if (!$panels) {
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('No Panels Exist Yet'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'You have not created any dashboard panels yet, so you can not '.
|
||||
'add an existing panel.'))
|
||||
->appendParagraph(
|
||||
pht('Instead, add a new panel.'))
|
||||
->addCancelButton($redirect_uri);
|
||||
}
|
||||
|
||||
$panel_options = array();
|
||||
foreach ($panels as $panel) {
|
||||
$panel_options[$panel->getID()] = pht(
|
||||
'%s %s',
|
||||
$panel->getMonogram(),
|
||||
$panel->getName());
|
||||
}
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($viewer)
|
||||
->addHiddenInput('src', $request->getStr('src', 'edit'))
|
||||
->addHiddenInput('column', $request->getInt('column'))
|
||||
->appendRemarkupInstructions(
|
||||
pht('Enter a panel monogram like `W123`.'))
|
||||
pht('Choose a panel to add to this dashboard:'))
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
id(new AphrontFormSelectControl())
|
||||
->setName('panel')
|
||||
->setLabel(pht('Panel'))
|
||||
->setValue($v_panel)
|
||||
->setError($e_panel));
|
||||
|
||||
if ($layout_config->isMultiColumnLayout()) {
|
||||
$form
|
||||
->appendRemarkupInstructions(
|
||||
pht('Choose which column the panel should reside in.'))
|
||||
->appendChild(
|
||||
id(new AphrontFormSelectControl())
|
||||
->setName('column')
|
||||
->setLabel(pht('Column'))
|
||||
->setOptions($layout_config->getColumnSelectOptions())
|
||||
->setValue($request->getInt('column')));
|
||||
}
|
||||
->setError($e_panel)
|
||||
->setOptions($panel_options));
|
||||
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Add Panel'))
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardPanelCreateController
|
||||
extends PhabricatorDashboardController {
|
||||
|
||||
public function processRequest() {
|
||||
$request = $this->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,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
|
@ -13,6 +13,28 @@ final class PhabricatorDashboardPanelEditController
|
|||
$request = $this->getRequest();
|
||||
$viewer = $request->getUser();
|
||||
|
||||
// If the user is trying to create a panel directly on a dashboard, make
|
||||
// sure they have permission to see and edit the dashboard.
|
||||
|
||||
$dashboard_id = $request->getInt('dashboardID');
|
||||
$dashboard = null;
|
||||
if ($dashboard_id) {
|
||||
$dashboard = id(new PhabricatorDashboardQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($dashboard_id))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->executeOne();
|
||||
if (!$dashboard) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$manage_uri = $this->getApplicationURI('manage/'.$dashboard_id.'/');
|
||||
}
|
||||
|
||||
if ($this->id) {
|
||||
$is_create = false;
|
||||
|
||||
|
@ -33,11 +55,10 @@ final class PhabricatorDashboardPanelEditController
|
|||
$is_create = true;
|
||||
|
||||
$panel = PhabricatorDashboardPanel::initializeNewPanel($viewer);
|
||||
|
||||
$types = PhabricatorDashboardPanelType::getAllPanelTypes();
|
||||
$type = $request->getStr('type');
|
||||
if (empty($types[$type])) {
|
||||
return new Aphront404Response();
|
||||
return $this->processPanelTypeRequest($request);
|
||||
}
|
||||
|
||||
$panel->setPanelType($type);
|
||||
|
@ -47,12 +68,20 @@ final class PhabricatorDashboardPanelEditController
|
|||
$title = pht('New Panel');
|
||||
$header = pht('Create New Panel');
|
||||
$button = pht('Create Panel');
|
||||
if ($dashboard) {
|
||||
$cancel_uri = $manage_uri;
|
||||
} else {
|
||||
$cancel_uri = $this->getApplicationURI('panel/');
|
||||
}
|
||||
} else {
|
||||
$title = pht('Edit %s', $panel->getMonogram());
|
||||
$header = pht('Edit %s %s', $panel->getMonogram(), $panel->getName());
|
||||
$button = pht('Save Panel');
|
||||
$cancel_uri = $this->getPanelRedirectURI($panel);
|
||||
if ($dashboard) {
|
||||
$cancel_uri = $manage_uri;
|
||||
} else {
|
||||
$cancel_uri = '/'.$panel->getMonogram();
|
||||
}
|
||||
}
|
||||
|
||||
$v_name = $panel->getName();
|
||||
|
@ -67,7 +96,10 @@ final class PhabricatorDashboardPanelEditController
|
|||
|
||||
$validation_exception = null;
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
// NOTE: We require 'edit' to distinguish between the "Choose a Type"
|
||||
// and "Create a Panel" dialogs.
|
||||
|
||||
if ($request->isFormPost() && $request->getBool('edit')) {
|
||||
$v_name = $request->getStr('name');
|
||||
$v_view_policy = $request->getStr('viewPolicy');
|
||||
$v_edit_policy = $request->getStr('editPolicy');
|
||||
|
@ -102,8 +134,23 @@ final class PhabricatorDashboardPanelEditController
|
|||
->setContentSourceFromRequest($request)
|
||||
->applyTransactions($panel, $xactions);
|
||||
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI($this->getPanelRedirectURI($panel));
|
||||
// If we're creating a panel directly on a dashboard, add it now.
|
||||
if ($dashboard) {
|
||||
PhabricatorDashboardTransactionEditor::addPanelToDashboard(
|
||||
$viewer,
|
||||
PhabricatorContentSource::newFromRequest($request),
|
||||
$panel,
|
||||
$dashboard,
|
||||
$request->getInt('column', 0));
|
||||
}
|
||||
|
||||
if ($dashboard) {
|
||||
$done_uri = $manage_uri;
|
||||
} else {
|
||||
$done_uri = '/'.$panel->getMonogram();
|
||||
}
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI($done_uri);
|
||||
} catch (PhabricatorApplicationTransactionValidationException $ex) {
|
||||
$validation_exception = $ex;
|
||||
|
||||
|
@ -121,7 +168,9 @@ final class PhabricatorDashboardPanelEditController
|
|||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($viewer)
|
||||
->addHiddenInput('edit', true)
|
||||
->addHiddenInput('dashboardID', $request->getInt('dashboardID'))
|
||||
->addHiddenInput('column', $request->getInt('column'))
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setLabel(pht('Name'))
|
||||
|
@ -189,16 +238,83 @@ final class PhabricatorDashboardPanelEditController
|
|||
));
|
||||
}
|
||||
|
||||
private function getPanelRedirectURI(PhabricatorDashboardPanel $panel) {
|
||||
$request = $this->getRequest();
|
||||
$dashboard_id = $request->getInt('dashboardID');
|
||||
if ($dashboard_id) {
|
||||
$uri = $this->getApplicationURI('manage/'.$dashboard_id.'/');
|
||||
private function processPanelTypeRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getUser();
|
||||
|
||||
$types = PhabricatorDashboardPanelType::getAllPanelTypes();
|
||||
|
||||
$v_type = null;
|
||||
$errors = array();
|
||||
if ($request->isFormPost()) {
|
||||
$v_type = $request->getStr('type');
|
||||
if (!isset($types[$v_type])) {
|
||||
$errors[] = pht('You must select a type of panel to create.');
|
||||
}
|
||||
}
|
||||
|
||||
$cancel_uri = $this->getApplicationURI('panel/');
|
||||
|
||||
if (!$v_type) {
|
||||
$v_type = key($types);
|
||||
}
|
||||
|
||||
$panel_types = id(new AphrontFormRadioButtonControl())
|
||||
->setName('type')
|
||||
->setValue($v_type);
|
||||
|
||||
foreach ($types as $key => $type) {
|
||||
$panel_types->addButton(
|
||||
$key,
|
||||
$type->getPanelTypeName(),
|
||||
$type->getPanelTypeDescription());
|
||||
}
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($viewer)
|
||||
->addHiddenInput('dashboardID', $request->getInt('dashboardID'))
|
||||
->addHiddenInput('column', $request->getInt('column'))
|
||||
->appendRemarkupInstructions(
|
||||
pht(
|
||||
'Choose the type of dashboard panel to create:'))
|
||||
->appendChild($panel_types);
|
||||
|
||||
if ($request->isAjax()) {
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Add New Panel'))
|
||||
->setWidth(AphrontDialogView::WIDTH_FORM)
|
||||
->setErrors($errors)
|
||||
->appendChild($form->buildLayoutView())
|
||||
->addCancelbutton($cancel_uri)
|
||||
->addSubmitButton(pht('Continue'));
|
||||
} else {
|
||||
$uri = '/'.$panel->getMonogram();
|
||||
$form->appendChild(
|
||||
id(new AphrontFormSubmitControl())
|
||||
->setValue(pht('Continue'))
|
||||
->addCancelButton($cancel_uri));
|
||||
}
|
||||
|
||||
return $uri;
|
||||
$title = pht('Create Dashboard Panel');
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb(
|
||||
pht('Panels'),
|
||||
$this->getApplicationURI('panel/'));
|
||||
$crumbs->addTextCrumb(pht('New Panel'));
|
||||
|
||||
$box = id(new PHUIObjectBoxView())
|
||||
->setHeaderText($title)
|
||||
->setFormErrors($errors)
|
||||
->setForm($form);
|
||||
|
||||
return $this->buildApplicationPage(
|
||||
array(
|
||||
$crumbs,
|
||||
$box,
|
||||
),
|
||||
array(
|
||||
'title' => $title,
|
||||
'device' => true,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -136,9 +136,14 @@ final class PhabricatorDashboardPanelViewController
|
|||
PhabricatorEdgeConfig::TYPE_PANEL_HAS_DASHBOARD);
|
||||
$this->loadHandles($dashboard_phids);
|
||||
|
||||
$does_not_appear = pht(
|
||||
'This panel does not appear on any dashboards.');
|
||||
|
||||
$properties->addProperty(
|
||||
pht('Appears On'),
|
||||
$this->renderHandlesForPHIDs($dashboard_phids));
|
||||
$dashboard_phids
|
||||
? $this->renderHandlesForPHIDs($dashboard_phids)
|
||||
: phutil_tag('em', array(), $does_not_appear));
|
||||
|
||||
return $properties;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,38 @@
|
|||
final class PhabricatorDashboardTransactionEditor
|
||||
extends PhabricatorApplicationTransactionEditor {
|
||||
|
||||
public static function addPanelToDashboard(
|
||||
PhabricatorUser $actor,
|
||||
PhabricatorContentSource $content_source,
|
||||
PhabricatorDashboardPanel $panel,
|
||||
PhabricatorDashboard $dashboard,
|
||||
$column) {
|
||||
|
||||
$xactions = array();
|
||||
$xactions[] = id(new PhabricatorDashboardTransaction())
|
||||
->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
|
||||
->setMetadataValue(
|
||||
'edge:type',
|
||||
PhabricatorEdgeConfig::TYPE_DASHBOARD_HAS_PANEL)
|
||||
->setNewValue(
|
||||
array(
|
||||
'+' => array(
|
||||
$panel->getPHID() => $panel->getPHID(),
|
||||
),
|
||||
));
|
||||
|
||||
$layout_config = $dashboard->getLayoutConfigObject();
|
||||
$layout_config->setPanelLocation($column, $panel->getPHID());
|
||||
$dashboard->setLayoutConfigFromObject($layout_config);
|
||||
|
||||
$editor = id(new PhabricatorDashboardTransactionEditor())
|
||||
->setActor($actor)
|
||||
->setContentSource($content_source)
|
||||
->setContinueOnMissingFields(true)
|
||||
->setContinueOnNoEffect(true)
|
||||
->applyTransactions($dashboard, $xactions);
|
||||
}
|
||||
|
||||
public function getTransactionTypes() {
|
||||
$types = parent::getTransactionTypes();
|
||||
|
||||
|
|
|
@ -86,45 +86,53 @@ final class PhabricatorDashboardRenderingEngine extends Phobject {
|
|||
}
|
||||
|
||||
private function renderAddPanelPlaceHolder($column) {
|
||||
$uri = $this->getAddPanelURI($column);
|
||||
|
||||
$dashboard = $this->dashboard;
|
||||
$panels = $dashboard->getPanels();
|
||||
$layout_config = $dashboard->getLayoutConfigObject();
|
||||
if ($layout_config->isMultiColumnLayout() && count($panels)) {
|
||||
$text = pht('Drag a panel here or click to add a panel.');
|
||||
} else {
|
||||
$text = pht('Click to add a panel.');
|
||||
}
|
||||
|
||||
return javelin_tag(
|
||||
'a',
|
||||
'span',
|
||||
array(
|
||||
'sigil' => 'workflow',
|
||||
'class' => 'drag-ghost dashboard-panel-placeholder',
|
||||
'href' => (string) $uri),
|
||||
$text);
|
||||
),
|
||||
pht('This column does not have any panels yet.'));
|
||||
}
|
||||
|
||||
private function renderAddPanelUI($column) {
|
||||
$uri = $this->getAddPanelURI($column);
|
||||
$dashboard_id = $this->dashboard->getID();
|
||||
|
||||
return id(new PHUIButtonView())
|
||||
$create_uri = id(new PhutilURI('/dashboard/panel/create/'))
|
||||
->setQueryParam('dashboardID', $dashboard_id)
|
||||
->setQueryParam('column', $column);
|
||||
|
||||
$add_uri = id(new PhutilURI('/dashboard/addpanel/'.$dashboard_id.'/'))
|
||||
->setQueryParam('column', $column);
|
||||
|
||||
$create_button = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setHref((string) $uri)
|
||||
->setHref($create_uri)
|
||||
->setWorkflow(true)
|
||||
->setColor(PHUIButtonView::GREY)
|
||||
->setIcon(id(new PHUIIconView())
|
||||
->setIconFont('fa-plus'))
|
||||
->setText(pht('Add Panel'))
|
||||
->addClass(PHUI::MARGIN_LARGE);
|
||||
}
|
||||
->setText(pht('Create Panel'))
|
||||
->addClass(PHUI::MARGIN_MEDIUM);
|
||||
|
||||
private function getAddPanelURI($column) {
|
||||
$dashboard = $this->dashboard;
|
||||
$uri = id(new PhutilURI('/dashboard/addpanel/'.$dashboard->getID().'/'))
|
||||
->setQueryParam('column', $column)
|
||||
->setQueryParam('src', 'arrange');
|
||||
return $uri;
|
||||
$add_button = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setHref($add_uri)
|
||||
->setWorkflow(true)
|
||||
->setColor(PHUIButtonView::GREY)
|
||||
->setText(pht('Add Existing Panel'))
|
||||
->addClass(PHUI::MARGIN_MEDIUM);
|
||||
|
||||
return phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'style' => 'text-align: center;',
|
||||
),
|
||||
array(
|
||||
$create_button,
|
||||
$add_button,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -50,18 +50,12 @@
|
|||
.aphront-multi-column-fluid
|
||||
.aphront-multi-column-column.dashboard-column-empty
|
||||
.dashboard-panel-placeholder {
|
||||
color: {$greytext};
|
||||
display: block;
|
||||
padding: 24px;
|
||||
margin: 16px 16px 0px 16px;
|
||||
}
|
||||
|
||||
.aphront-multi-column-fluid
|
||||
.aphront-multi-column-column.dashboard-column-empty
|
||||
.dashboard-panel-placeholder:hover {
|
||||
text-decoration: none;
|
||||
border: 1px {$greyborder} dashed;
|
||||
color: {$darkgreytext};
|
||||
color: {$greytext};
|
||||
}
|
||||
|
||||
.aphront-multi-column-fluid
|
||||
|
|
Loading…
Reference in a new issue