mirror of
https://we.phorge.it/source/phorge.git
synced 2025-04-11 11:58:33 +02:00
Show child documents on Phriction pages
Summary: Pull the next couple levels of hierarchy and render them at the bottom of the page. This might need some tweaking but it seems OK at first glance. Test Plan: https://secure.phabricator.com/file/info/PHID-FILE-ef0af5d4dc6dceaeb2e3/ Also reduced limit to 1 and verified the "more" behavior worked properly. Reviewed By: hsb Reviewers: hsb, codeblock, jungejason, tuomaspelkonen, aran CC: aran, hsb Differential Revision: 676
This commit is contained in:
parent
0bf6766089
commit
86783fcd07
3 changed files with 143 additions and 1 deletions
src/applications/phriction/controller/document
webroot/rsrc/css/application/phriction
|
@ -137,6 +137,8 @@ class PhrictionDocumentController
|
||||||
$version_note = $version_note->render();
|
$version_note = $version_note->render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$children = $this->renderChildren($slug);
|
||||||
|
|
||||||
$page =
|
$page =
|
||||||
'<div class="phriction-header">'.
|
'<div class="phriction-header">'.
|
||||||
$button.
|
$button.
|
||||||
|
@ -144,7 +146,8 @@ class PhrictionDocumentController
|
||||||
$breadcrumbs.
|
$breadcrumbs.
|
||||||
'</div>'.
|
'</div>'.
|
||||||
$version_note.
|
$version_note.
|
||||||
$page_content;
|
$page_content.
|
||||||
|
$children;
|
||||||
|
|
||||||
return $this->buildStandardPageResponse(
|
return $this->buildStandardPageResponse(
|
||||||
$page,
|
$page,
|
||||||
|
@ -208,4 +211,124 @@ class PhrictionDocumentController
|
||||||
'</div>';
|
'</div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function renderChildren($slug) {
|
||||||
|
$document_dao = new PhrictionDocument();
|
||||||
|
$content_dao = new PhrictionContent();
|
||||||
|
$conn = $document_dao->establishConnection('r');
|
||||||
|
|
||||||
|
$limit = 50;
|
||||||
|
$d_child = PhrictionDocument::getSlugDepth($slug) + 1;
|
||||||
|
$d_grandchild = PhrictionDocument::getSlugDepth($slug) + 2;
|
||||||
|
|
||||||
|
// Select children and grandchildren.
|
||||||
|
$children = queryfx_all(
|
||||||
|
$conn,
|
||||||
|
'SELECT d.slug, d.depth, c.title FROM %T d JOIN %T c
|
||||||
|
ON d.contentID = c.id
|
||||||
|
WHERE d.slug LIKE %> AND d.depth IN (%d, %d)
|
||||||
|
ORDER BY d.depth, c.title LIMIT %d',
|
||||||
|
$document_dao->getTableName(),
|
||||||
|
$content_dao->getTableName(),
|
||||||
|
($slug == '/' ? '' : $slug),
|
||||||
|
$d_child,
|
||||||
|
$d_grandchild,
|
||||||
|
$limit);
|
||||||
|
|
||||||
|
if (!$children) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We're going to render in one of three modes to try to accommodate
|
||||||
|
// different information scales:
|
||||||
|
//
|
||||||
|
// - If we found fewer than $limit rows, we know we have all the children
|
||||||
|
// and grandchildren and there aren't all that many. We can just render
|
||||||
|
// everything.
|
||||||
|
// - If we found $limit rows but the results included some grandchildren,
|
||||||
|
// we just throw them out and render only the children, as we know we
|
||||||
|
// have them all.
|
||||||
|
// - If we found $limit rows and the results have no grandchildren, we
|
||||||
|
// have a ton of children. Render them and then let the user know that
|
||||||
|
// this is not an exhaustive list.
|
||||||
|
|
||||||
|
if (count($children) == $limit) {
|
||||||
|
$more_children = true;
|
||||||
|
foreach ($children as $child) {
|
||||||
|
if ($child['depth'] == $d_grandchild) {
|
||||||
|
$more_children = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$show_grandchildren = false;
|
||||||
|
} else {
|
||||||
|
$show_grandchildren = true;
|
||||||
|
$more_children = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$grandchildren = array();
|
||||||
|
foreach ($children as $key => $child) {
|
||||||
|
if ($child['depth'] == $d_child) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
unset($children[$key]);
|
||||||
|
if ($show_grandchildren) {
|
||||||
|
$ancestors = PhrictionDocument::getSlugAncestry($child['slug']);
|
||||||
|
$grandchildren[end($ancestors)][] = $child;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill in any missing children.
|
||||||
|
$known_slugs = ipull($children, null, 'slug');
|
||||||
|
foreach ($grandchildren as $slug => $ignored) {
|
||||||
|
if (empty($known_slugs[$slug])) {
|
||||||
|
$children[] = array(
|
||||||
|
'slug' => $slug,
|
||||||
|
'depth' => $d_child,
|
||||||
|
'title' => PhrictionDocument::getDefaultSlugTitle($slug),
|
||||||
|
'empty' => true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$list = array();
|
||||||
|
$list[] = '<ul>';
|
||||||
|
foreach ($children as $child) {
|
||||||
|
$list[] = $this->renderChildDocumentLink($child);
|
||||||
|
$grand = idx($grandchildren, $child['slug'], array());
|
||||||
|
if ($grand) {
|
||||||
|
$list[] = '<ul>';
|
||||||
|
foreach ($grand as $grandchild) {
|
||||||
|
$list[] = $this->renderChildDocumentLink($grandchild);
|
||||||
|
}
|
||||||
|
$list[] = '</ul>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($more_children) {
|
||||||
|
$list[] = '<li>More...</li>';
|
||||||
|
}
|
||||||
|
$list[] = '</ul>';
|
||||||
|
$list = implode("\n", $list);
|
||||||
|
|
||||||
|
return
|
||||||
|
'<div class="phriction-children">'.
|
||||||
|
'<div class="phriction-children-header">Document Hierarchy</div>'.
|
||||||
|
$list.
|
||||||
|
'</div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
private function renderChildDocumentLink(array $info) {
|
||||||
|
$item = phutil_render_tag(
|
||||||
|
'a',
|
||||||
|
array(
|
||||||
|
'href' => PhrictionDocument::getSlugURI($info['slug']),
|
||||||
|
),
|
||||||
|
phutil_escape_html($info['title']));
|
||||||
|
|
||||||
|
if (isset($info['empty'])) {
|
||||||
|
$item = '<em>'.$item.'</em>';
|
||||||
|
}
|
||||||
|
|
||||||
|
return '<li>'.$item.'</li>';
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ phutil_require_module('phabricator', 'applications/phriction/controller/base');
|
||||||
phutil_require_module('phabricator', 'applications/phriction/storage/content');
|
phutil_require_module('phabricator', 'applications/phriction/storage/content');
|
||||||
phutil_require_module('phabricator', 'applications/phriction/storage/document');
|
phutil_require_module('phabricator', 'applications/phriction/storage/document');
|
||||||
phutil_require_module('phabricator', 'infrastructure/celerity/api');
|
phutil_require_module('phabricator', 'infrastructure/celerity/api');
|
||||||
|
phutil_require_module('phabricator', 'storage/queryfx');
|
||||||
phutil_require_module('phabricator', 'view/form/error');
|
phutil_require_module('phabricator', 'view/form/error');
|
||||||
phutil_require_module('phabricator', 'view/utils');
|
phutil_require_module('phabricator', 'view/utils');
|
||||||
|
|
||||||
|
|
|
@ -38,3 +38,21 @@
|
||||||
.phriction-document-crumbs a {
|
.phriction-document-crumbs a {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.phriction-children {
|
||||||
|
padding: 1em 2em;
|
||||||
|
background: #eeeeee;
|
||||||
|
border-top: 1px solid #dddddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.phriction-children ul {
|
||||||
|
margin-left: 2.5em;
|
||||||
|
list-style: circle;
|
||||||
|
color: #999999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.phriction-children-header {
|
||||||
|
padding: 0 0 .5em 0;
|
||||||
|
margin: 0;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue