1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-22 14:52:41 +01:00

Somewhat give Phriction the new Breadcrumb UI.

Summary:
Okay, just a forewarning, this is horrible right now.

But I think it's an okay enough start that it's worth sending what I've done.

This rips out the old Phriction breadcrumb UI and replaces it with the new one
that other apps have been starting to use.

Test Plan: Looked at a bunch of Phriction pages.

Reviewers: epriestley

CC: aran, Korvin

Differential Revision: https://secure.phabricator.com/D4183
This commit is contained in:
Ricky Elrod 2013-01-11 11:39:22 -08:00 committed by epriestley
parent 16a0f4a88e
commit 368657a570
6 changed files with 217 additions and 163 deletions

View file

@ -632,7 +632,7 @@ celerity_register_resource_map(array(
),
'aphront-form-view-css' =>
array(
'uri' => '/res/6f1739eb/rsrc/css/aphront/form-view.css',
'uri' => '/res/cd15aff5/rsrc/css/aphront/form-view.css',
'type' => 'css',
'requires' =>
array(
@ -3246,7 +3246,7 @@ celerity_register_resource_map(array(
), array(
'packages' =>
array(
'6e748adf' =>
'367c20f1' =>
array(
'name' => 'core.pkg.css',
'symbols' =>
@ -3291,7 +3291,7 @@ celerity_register_resource_map(array(
37 => 'phabricator-object-item-list-view-css',
38 => 'global-drag-and-drop-css',
),
'uri' => '/res/pkg/6e748adf/core.pkg.css',
'uri' => '/res/pkg/367c20f1/core.pkg.css',
'type' => 'css',
),
'2921e259' =>
@ -3480,19 +3480,19 @@ celerity_register_resource_map(array(
'reverse' =>
array(
'aphront-attached-file-view-css' => 'ac211174',
'aphront-crumbs-view-css' => '6e748adf',
'aphront-dialog-view-css' => '6e748adf',
'aphront-error-view-css' => '6e748adf',
'aphront-form-view-css' => '6e748adf',
'aphront-crumbs-view-css' => '367c20f1',
'aphront-dialog-view-css' => '367c20f1',
'aphront-error-view-css' => '367c20f1',
'aphront-form-view-css' => '367c20f1',
'aphront-headsup-action-list-view-css' => '20933a11',
'aphront-headsup-view-css' => '6e748adf',
'aphront-list-filter-view-css' => '6e748adf',
'aphront-pager-view-css' => '6e748adf',
'aphront-panel-view-css' => '6e748adf',
'aphront-table-view-css' => '6e748adf',
'aphront-tokenizer-control-css' => '6e748adf',
'aphront-tooltip-css' => '6e748adf',
'aphront-typeahead-control-css' => '6e748adf',
'aphront-headsup-view-css' => '367c20f1',
'aphront-list-filter-view-css' => '367c20f1',
'aphront-pager-view-css' => '367c20f1',
'aphront-panel-view-css' => '367c20f1',
'aphront-table-view-css' => '367c20f1',
'aphront-tokenizer-control-css' => '367c20f1',
'aphront-tooltip-css' => '367c20f1',
'aphront-typeahead-control-css' => '367c20f1',
'differential-changeset-view-css' => '20933a11',
'differential-core-view-css' => '20933a11',
'differential-inline-comment-editor' => '76556a8f',
@ -3506,7 +3506,7 @@ celerity_register_resource_map(array(
'differential-table-of-contents-css' => '20933a11',
'diffusion-commit-view-css' => 'c8ce2d88',
'diffusion-icons-css' => 'c8ce2d88',
'global-drag-and-drop-css' => '6e748adf',
'global-drag-and-drop-css' => '367c20f1',
'inline-comment-summary-css' => '20933a11',
'javelin-aphlict' => '2921e259',
'javelin-behavior' => 'fbeded59',
@ -3575,49 +3575,49 @@ celerity_register_resource_map(array(
'javelin-util' => 'fbeded59',
'javelin-vector' => 'fbeded59',
'javelin-workflow' => 'fbeded59',
'lightbox-attachment-css' => '6e748adf',
'lightbox-attachment-css' => '367c20f1',
'maniphest-task-summary-css' => 'ac211174',
'maniphest-transaction-detail-css' => 'ac211174',
'phabricator-app-buttons-css' => '6e748adf',
'phabricator-app-buttons-css' => '367c20f1',
'phabricator-busy' => '2921e259',
'phabricator-content-source-view-css' => '20933a11',
'phabricator-core-buttons-css' => '6e748adf',
'phabricator-core-css' => '6e748adf',
'phabricator-crumbs-view-css' => '6e748adf',
'phabricator-directory-css' => '6e748adf',
'phabricator-core-buttons-css' => '367c20f1',
'phabricator-core-css' => '367c20f1',
'phabricator-crumbs-view-css' => '367c20f1',
'phabricator-directory-css' => '367c20f1',
'phabricator-drag-and-drop-file-upload' => '76556a8f',
'phabricator-dropdown-menu' => '2921e259',
'phabricator-file-upload' => '2921e259',
'phabricator-filetree-view-css' => '6e748adf',
'phabricator-flag-css' => '6e748adf',
'phabricator-form-view-css' => '6e748adf',
'phabricator-header-view-css' => '6e748adf',
'phabricator-jump-nav' => '6e748adf',
'phabricator-filetree-view-css' => '367c20f1',
'phabricator-flag-css' => '367c20f1',
'phabricator-form-view-css' => '367c20f1',
'phabricator-header-view-css' => '367c20f1',
'phabricator-jump-nav' => '367c20f1',
'phabricator-keyboard-shortcut' => '2921e259',
'phabricator-keyboard-shortcut-manager' => '2921e259',
'phabricator-main-menu-view' => '6e748adf',
'phabricator-main-menu-view' => '367c20f1',
'phabricator-menu-item' => '2921e259',
'phabricator-nav-view-css' => '6e748adf',
'phabricator-nav-view-css' => '367c20f1',
'phabricator-notification' => '2921e259',
'phabricator-notification-css' => '6e748adf',
'phabricator-notification-menu-css' => '6e748adf',
'phabricator-object-item-list-view-css' => '6e748adf',
'phabricator-notification-css' => '367c20f1',
'phabricator-notification-menu-css' => '367c20f1',
'phabricator-object-item-list-view-css' => '367c20f1',
'phabricator-object-selector-css' => '20933a11',
'phabricator-paste-file-upload' => '2921e259',
'phabricator-prefab' => '2921e259',
'phabricator-project-tag-css' => 'ac211174',
'phabricator-remarkup-css' => '6e748adf',
'phabricator-remarkup-css' => '367c20f1',
'phabricator-shaped-request' => '76556a8f',
'phabricator-side-menu-view-css' => '6e748adf',
'phabricator-standard-page-view' => '6e748adf',
'phabricator-side-menu-view-css' => '367c20f1',
'phabricator-standard-page-view' => '367c20f1',
'phabricator-textareautils' => '2921e259',
'phabricator-tooltip' => '2921e259',
'phabricator-transaction-view-css' => '6e748adf',
'phabricator-zindex-css' => '6e748adf',
'sprite-apps-large-css' => '6e748adf',
'sprite-gradient-css' => '6e748adf',
'sprite-icon-css' => '6e748adf',
'sprite-menu-css' => '6e748adf',
'syntax-highlighting-css' => '6e748adf',
'phabricator-transaction-view-css' => '367c20f1',
'phabricator-zindex-css' => '367c20f1',
'sprite-apps-large-css' => '367c20f1',
'sprite-gradient-css' => '367c20f1',
'sprite-icon-css' => '367c20f1',
'sprite-menu-css' => '367c20f1',
'syntax-highlighting-css' => '367c20f1',
),
));

View file

@ -20,4 +20,81 @@ abstract class PhrictionController extends PhabricatorController {
$response = new AphrontWebpageResponse();
return $response->setContent($page->render());
}
public function buildSideNavView($filter = null, $for_app = false) {
$user = $this->getRequest()->getUser();
$nav = new AphrontSideNavFilterView();
$nav->setBaseURI(new PhutilURI('/phriction/list/'));
if ($for_app) {
$nav->addFilter('', pht('Root Document'), '/w/');
$nav->addFilter('', pht('Create Document'), '/phriction/new');
}
$nav->addLabel('Filters');
$nav->addFilter('active', pht('Active Documents'));
$nav->addFilter('all', pht('All Documents'));
$nav->addFilter('updates', pht('Recently Updated'));
$nav->selectFilter($filter, 'active');
return $nav;
}
public function buildApplicationMenu() {
return $this->buildSideNavView(null, true)->getMenu();
}
public function buildApplicationCrumbs() {
$crumbs = parent::buildApplicationCrumbs();
$crumbs->addAction(
id(new PhabricatorMenuItemView())
->setName(pht('Create Document'))
->setHref('/phriction/new/')
->setIcon('create'));
return $crumbs;
}
public function renderBreadcrumbs($slug) {
$ancestor_handles = array();
$ancestral_slugs = PhabricatorSlug::getAncestry($slug);
$ancestral_slugs[] = $slug;
if ($ancestral_slugs) {
$empty_slugs = array_fill_keys($ancestral_slugs, null);
$ancestors = id(new PhrictionDocument())->loadAllWhere(
'slug IN (%Ls)',
$ancestral_slugs);
$ancestors = mpull($ancestors, null, 'getSlug');
$ancestor_phids = mpull($ancestors, 'getPHID');
$handles = array();
if ($ancestor_phids) {
$handles = $this->loadViewerHandles($ancestor_phids);
}
$ancestor_handles = array();
foreach ($ancestral_slugs as $slug) {
if (isset($ancestors[$slug])) {
$ancestor_handles[] = $handles[$ancestors[$slug]->getPHID()];
} else {
$handle = new PhabricatorObjectHandle();
$handle->setName(PhabricatorSlug::getDefaultTitle($slug));
$handle->setURI(PhrictionDocument::getSlugURI($slug));
$ancestor_handles[] = $handle;
}
}
}
$breadcrumbs = array();
foreach ($ancestor_handles as $ancestor_handle) {
$breadcrumbs[] = id(new PhabricatorCrumbView())
->setName($ancestor_handle->getName())
->setHref($ancestor_handle->getUri());
}
return $breadcrumbs;
}
}

View file

@ -30,11 +30,12 @@ final class PhrictionDocumentController
'slug = %s',
$slug);
$breadcrumbs = $this->renderBreadcrumbs($slug);
$version_note = null;
if (!$document) {
$document = new PhrictionDocument();
if (PhrictionDocument::isProjectSlug($slug)) {
$project = id(new PhabricatorProject())->loadOneWhere(
'phrictionSlug = %s',
@ -130,7 +131,12 @@ final class PhrictionDocumentController
$handles[$project_phid]->renderLink().'.';
}
$index_link = phutil_render_tag(
'a',
array(
'href' => '/phriction/',
),
pht('Document Index'));
$byline =
'<div class="phriction-byline">'.
@ -157,34 +163,10 @@ final class PhrictionDocumentController
$page_content =
'<div class="phriction-content">'.
$index_link.
$byline.
$core_content.
'</div>';
$create_button = javelin_render_tag(
'a',
array(
'href' => '/phriction/new/',
'class' => 'button green',
'sigil' => 'workflow',
),
pht('New Document'));
$edit_button = phutil_render_tag(
'a',
array(
'href' => '/phriction/edit/'.$document->getID().'/',
'class' => 'button',
),
pht('Edit Document'));
$history_button = phutil_render_tag(
'a',
array(
'href' => PhrictionDocument::getSlugURI($slug, 'history'),
'class' => 'button grey',
),
pht('View History'));
// these float right so history_button which is right most goes first
$buttons = $history_button.$edit_button.$create_button;
}
if ($version_note) {
@ -193,74 +175,59 @@ final class PhrictionDocumentController
$children = $this->renderChildren($slug);
$crumbs = $this->buildApplicationCrumbs();
$crumb_views = $this->renderBreadcrumbs($slug);
foreach ($crumb_views as $view) {
$crumbs->addCrumb($view);
}
$actions = $this->buildActionView($user, $document);
$header = id(new PhabricatorHeaderView())
->setHeader($page_title);
$page =
'<div class="phriction-header">'.
$buttons.
'<h1>'.phutil_escape_html($page_title).'</h1>'.
$breadcrumbs.
'</div>'.
$crumbs->render().
$header->render().
$actions->render().
$version_note.
$page_content.
$children;
return $this->buildStandardPageResponse(
$page,
return $this->buildApplicationPage(
array(
'title' => 'Phriction - '.$page_title,
$page,
),
array(
'title' => $page_title,
'device' => true,
));
}
private function renderBreadcrumbs($slug) {
private function buildActionView(
PhabricatorUser $user,
PhrictionDocument $document) {
$can_edit = PhabricatorPolicyFilter::hasCapability(
$user,
$document,
PhabricatorPolicyCapability::CAN_EDIT);
$ancestor_handles = array();
$ancestral_slugs = PhabricatorSlug::getAncestry($slug);
$ancestral_slugs[] = $slug;
if ($ancestral_slugs) {
$empty_slugs = array_fill_keys($ancestral_slugs, null);
$ancestors = id(new PhrictionDocument())->loadAllWhere(
'slug IN (%Ls)',
$ancestral_slugs);
$ancestors = mpull($ancestors, null, 'getSlug');
$slug = PhabricatorSlug::normalize($this->slug);
$ancestor_phids = mpull($ancestors, 'getPHID');
$handles = array();
if ($ancestor_phids) {
$handles = $this->loadViewerHandles($ancestor_phids);
}
$ancestor_handles = array();
foreach ($ancestral_slugs as $slug) {
if (isset($ancestors[$slug])) {
$ancestor_handles[] = $handles[$ancestors[$slug]->getPHID()];
} else {
$handle = new PhabricatorObjectHandle();
$handle->setName(PhabricatorSlug::getDefaultTitle($slug));
$handle->setURI(PhrictionDocument::getSlugURI($slug));
$ancestor_handles[] = $handle;
}
}
}
$breadcrumbs = array();
foreach ($ancestor_handles as $ancestor_handle) {
$breadcrumbs[] = $ancestor_handle->renderLink();
}
$list = phutil_render_tag(
'a',
array(
'href' => '/phriction/',
),
'Document Index');
return
'<div class="phriction-breadcrumbs">'.
$list.' &middot; '.
'<span class="phriction-document-crumbs">'.
implode(" \xC2\xBB ", $breadcrumbs).
'</span>'.
'</div>';
return id(new PhabricatorActionListView())
->setUser($user)
->setObject($document)
->addAction(
id(new PhabricatorActionView())
->setName(pht('Edit Document'))
->setIcon('edit')
->setHref('/phriction/edit/'.$document->getID().'/'))
->addAction(
id(new PhabricatorActionView())
->setName(pht('View History'))
->setIcon('history')
->setHref(PhrictionDocument::getSlugURI($slug, 'history')));
}
private function renderChildren($slug) {

View file

@ -96,21 +96,6 @@ final class PhrictionHistoryController
);
}
$crumbs = new AphrontCrumbsView();
$crumbs->setCrumbs(
array(
'Phriction',
phutil_render_tag(
'a',
array(
'href' => PhrictionDocument::getSlugURI($document->getSlug()),
),
phutil_escape_html($current->getTitle())
),
'History',
));
$table = new AphrontTableView($rows);
$table->setHeaders(
array(
@ -135,18 +120,30 @@ final class PhrictionHistoryController
'',
));
$crumbs = $this->buildApplicationCrumbs();
$crumb_views = $this->renderBreadcrumbs($document->getSlug());
foreach ($crumb_views as $view) {
$crumbs->addCrumb($view);
}
$crumbs->addCrumb(
id(new PhabricatorCrumbView())
->setName(pht('History'))
->setHref(
PhrictionDocument::getSlugURI($document->getSlug(), 'history')));
$panel = new AphrontPanelView();
$panel->setHeader('Document History');
$panel->appendChild($table);
$panel->appendChild($pager);
return $this->buildStandardPageResponse(
return $this->buildApplicationPage(
array(
$crumbs,
$panel,
),
array(
'title' => 'Document History',
'device' => true,
));
}

View file

@ -18,21 +18,24 @@ final class PhrictionListController
$user = $request->getUser();
$views = array(
'active' => 'Active Documents',
'all' => 'All Documents',
'updates' => 'Recently Updated',
'active' => pht('Active Documents'),
'all' => pht('All Documents'),
'updates' => pht('Recently Updated'),
);
if (empty($views[$this->view])) {
$this->view = 'active';
}
$nav = new AphrontSideNavFilterView();
$nav->setBaseURI(new PhutilURI('/phriction/list/'));
foreach ($views as $view => $name) {
$nav->addFilter($view, $name);
}
$nav->selectFilter($this->view, null);
$nav = $this->buildSideNavView($this->view);
$header = id(new PhabricatorHeaderView())
->setHeader($views[$this->view]);
$nav->appendChild(
array(
$header,
));
$pager = new AphrontPagerView();
$pager->setURI($request->getRequestURI(), 'page');
@ -45,7 +48,6 @@ final class PhrictionListController
$handles = $this->loadViewerHandles($phids);
$rows = array();
foreach ($documents as $document) {
$content = $document->getContent();
@ -79,24 +81,19 @@ final class PhrictionListController
'right',
));
$view_headers = array(
'active' => 'Active Documents',
'all' => 'All Documents',
'updates' => 'Recently Updated Documents',
);
$view_header = $view_headers[$this->view];
$view_header = $views[$this->view];
$panel = new AphrontPanelView();
$panel->setHeader($view_header);
$panel->appendChild($document_table);
$panel->appendChild($pager);
$nav->appendChild($panel);
return $this->buildStandardPageResponse($nav,
array(
'title' => 'Phriction Main'
));
return $this->buildApplicationPage(
$nav,
array(
'title' => pht('Phriction Main'),
));
}
private function loadDocuments(AphrontPagerView $pager) {

View file

@ -3,7 +3,8 @@
/**
* @group phriction
*/
final class PhrictionDocument extends PhrictionDAO {
final class PhrictionDocument extends PhrictionDAO
implements PhabricatorPolicyInterface {
protected $id;
protected $phid;
@ -83,4 +84,19 @@ final class PhrictionDocument extends PhrictionDAO {
return $parts[1].'/';
}
// TODO: Customize this? Copypasta from PhabricatorPaste.
public function getCapabilities() {
return array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
);
}
public function getPolicy($capability) {
return PhabricatorPolicies::POLICY_USER;
}
public function hasAutomaticCapability($capability, PhabricatorUser $user) {
return false;
}
}