1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-20 04:20:55 +01:00

Allow users to search for signatures across documents

Summary:
Ref T3116. You can already search for sigatures on a specific document, but allow them to be searched across documents too.

In particular, this lets users answer questions like "Which of these 5 documents has alincoln signed?" / "Has alincoln signed all the stuff I care about?" / "who has signed either L5 or equivalent document L22?", etc.

Test Plan: {F171658}

Reviewers: chad

Reviewed By: chad

Subscribers: epriestley

Maniphest Tasks: T3116

Differential Revision: https://secure.phabricator.com/D9770
This commit is contained in:
epriestley 2014-06-28 16:37:36 -07:00
parent 5242fb0572
commit 88d9366701
5 changed files with 99 additions and 33 deletions

View file

@ -49,8 +49,8 @@ final class PhabricatorApplicationLegalpad extends PhabricatorApplication {
'done/' => 'LegalpadDocumentDoneController', 'done/' => 'LegalpadDocumentDoneController',
'verify/(?P<code>[^/]+)/' => 'verify/(?P<code>[^/]+)/' =>
'LegalpadDocumentSignatureVerificationController', 'LegalpadDocumentSignatureVerificationController',
'signatures/(?P<id>\d+)/(?:query/(?P<queryKey>[^/]+)/)?' 'signatures/(?:(?P<id>\d+)/)?(?:query/(?P<queryKey>[^/]+)/)?' =>
=> 'LegalpadDocumentSignatureListController', 'LegalpadDocumentSignatureListController',
'document/' => array( 'document/' => array(
'preview/' => 'PhabricatorMarkupPreviewController'), 'preview/' => 'PhabricatorMarkupPreviewController'),
)); ));

View file

@ -19,6 +19,9 @@ abstract class LegalpadController extends PhabricatorController {
->setViewer($user) ->setViewer($user)
->addNavigationItems($nav->getMenu()); ->addNavigationItems($nav->getMenu());
$nav->addLabel(pht('Signatures'));
$nav->addFilter('signatures/', pht('Find Signatures'));
return $nav; return $nav;
} }

View file

@ -7,7 +7,7 @@ final class LegalpadDocumentSignatureListController extends LegalpadController {
private $document; private $document;
public function willProcessRequest(array $data) { public function willProcessRequest(array $data) {
$this->documentID = $data['id']; $this->documentID = idx($data, 'id');
$this->queryKey = idx($data, 'queryKey'); $this->queryKey = idx($data, 'queryKey');
} }
@ -15,23 +15,28 @@ final class LegalpadDocumentSignatureListController extends LegalpadController {
$request = $this->getRequest(); $request = $this->getRequest();
$user = $request->getUser(); $user = $request->getUser();
$document = id(new LegalpadDocumentQuery()) if ($this->documentID) {
->setViewer($user) $document = id(new LegalpadDocumentQuery())
->withIDs(array($this->documentID)) ->setViewer($user)
->requireCapabilities( ->withIDs(array($this->documentID))
array( ->requireCapabilities(
PhabricatorPolicyCapability::CAN_VIEW, array(
PhabricatorPolicyCapability::CAN_EDIT, PhabricatorPolicyCapability::CAN_VIEW,
)) PhabricatorPolicyCapability::CAN_EDIT,
->executeOne(); ))
if (!$document) { ->executeOne();
return new Aphront404Response(); if (!$document) {
return new Aphront404Response();
}
$this->document = $document;
} }
$this->document = $document; $engine = id(new LegalpadDocumentSignatureSearchEngine());
$engine = id(new LegalpadDocumentSignatureSearchEngine()) if ($this->document) {
->setDocument($document); $engine->setDocument($this->document);
}
$controller = id(new PhabricatorApplicationSearchController($request)) $controller = id(new PhabricatorApplicationSearchController($request))
->setQueryKey($this->queryKey) ->setQueryKey($this->queryKey)
@ -47,10 +52,14 @@ final class LegalpadDocumentSignatureListController extends LegalpadController {
$nav = new AphrontSideNavFilterView(); $nav = new AphrontSideNavFilterView();
$nav->setBaseURI(new PhutilURI($this->getApplicationURI())); $nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
id(new LegalpadDocumentSignatureSearchEngine()) $engine = id(new LegalpadDocumentSignatureSearchEngine())
->setViewer($user) ->setViewer($user);
->setDocument($this->document)
->addNavigationItems($nav->getMenu()); if ($this->document) {
$engine->setDocument($this->document);
}
$engine->addNavigationItems($nav->getMenu());
return $nav; return $nav;
} }
@ -58,9 +67,15 @@ final class LegalpadDocumentSignatureListController extends LegalpadController {
public function buildApplicationCrumbs() { public function buildApplicationCrumbs() {
$crumbs = parent::buildApplicationCrumbs(); $crumbs = parent::buildApplicationCrumbs();
$crumbs->addTextCrumb( if ($this->document) {
$this->document->getMonogram(), $crumbs->addTextCrumb(
'/'.$this->document->getMonogram()); $this->document->getMonogram(),
'/'.$this->document->getMonogram());
} else {
$crumbs->addTextCrumb(
pht('Signatures'),
'/legalpad/signatures/');
}
return $crumbs; return $crumbs;
} }

View file

@ -37,8 +37,8 @@ final class PhabricatorLegalpadPHIDTypeDocument extends PhabricatorPHIDType {
$document = $objects[$phid]; $document = $objects[$phid];
$name = $document->getDocumentBody()->getTitle(); $name = $document->getDocumentBody()->getTitle();
$handle->setName($name); $handle->setName($name);
$handle->setFullName($name); $handle->setFullName($document->getMonogram().' '.$name);
$handle->setURI('/legalpad/view/'.$document->getID().'/'); $handle->setURI('/'.$document->getMonogram());
} }
} }

View file

@ -25,6 +25,15 @@ final class LegalpadDocumentSignatureSearchEngine
'signerPHIDs', 'signerPHIDs',
$this->readUsersFromRequest($request, 'signers')); $this->readUsersFromRequest($request, 'signers'));
$saved->setParameter(
'documentPHIDs',
$this->readPHIDsFromRequest(
$request,
'documents',
array(
PhabricatorLegalpadPHIDTypeDocument::TYPECONST,
)));
return $saved; return $saved;
} }
@ -38,6 +47,11 @@ final class LegalpadDocumentSignatureSearchEngine
if ($this->document) { if ($this->document) {
$query->withDocumentPHIDs(array($this->document->getPHID())); $query->withDocumentPHIDs(array($this->document->getPHID()));
} else {
$document_phids = $saved->getParameter('documentPHIDs', array());
if ($document_phids) {
$query->withDocumentPHIDs($document_phids);
}
} }
return $query; return $query;
@ -47,14 +61,25 @@ final class LegalpadDocumentSignatureSearchEngine
AphrontFormView $form, AphrontFormView $form,
PhabricatorSavedQuery $saved_query) { PhabricatorSavedQuery $saved_query) {
$document_phids = $saved_query->getParameter('documentPHIDs', array());
$signer_phids = $saved_query->getParameter('signerPHIDs', array()); $signer_phids = $saved_query->getParameter('signerPHIDs', array());
$phids = array_merge($signer_phids); $phids = array_merge($document_phids, $signer_phids);
$handles = id(new PhabricatorHandleQuery()) $handles = id(new PhabricatorHandleQuery())
->setViewer($this->requireViewer()) ->setViewer($this->requireViewer())
->withPHIDs($phids) ->withPHIDs($phids)
->execute(); ->execute();
if (!$this->document) {
$form
->appendChild(
id(new AphrontFormTokenizerControl())
->setDatasource('/typeahead/common/legalpaddocuments/')
->setName('documents')
->setLabel(pht('Documents'))
->setValue(array_select_keys($handles, $document_phids)));
}
$form $form
->appendChild( ->appendChild(
id(new AphrontFormTokenizerControl()) id(new AphrontFormTokenizerControl())
@ -68,10 +93,7 @@ final class LegalpadDocumentSignatureSearchEngine
if ($this->document) { if ($this->document) {
return '/legalpad/signatures/'.$this->document->getID().'/'.$path; return '/legalpad/signatures/'.$this->document->getID().'/'.$path;
} else { } else {
throw new Exception( return '/legalpad/signatures/'.$path;
pht(
'Searching for signatures outside of a document context is not '.
'currently supported.'));
} }
} }
@ -97,9 +119,12 @@ final class LegalpadDocumentSignatureSearchEngine
} }
protected function getRequiredHandlePHIDsForResultList( protected function getRequiredHandlePHIDsForResultList(
array $documents, array $signatures,
PhabricatorSavedQuery $query) { PhabricatorSavedQuery $query) {
return mpull($documents, 'getSignerPHID');
return array_merge(
mpull($signatures, 'getSignerPHID'),
mpull($signatures, 'getDocumentPHID'));
} }
protected function renderResultList( protected function renderResultList(
@ -150,6 +175,7 @@ final class LegalpadDocumentSignatureSearchEngine
$rows[] = array( $rows[] = array(
$sig_icon, $sig_icon,
$handles[$document->getPHID()]->renderLink(),
$handles[$signature->getSignerPHID()]->renderLink(), $handles[$signature->getSignerPHID()]->renderLink(),
$name, $name,
phutil_tag( phutil_tag(
@ -166,16 +192,26 @@ final class LegalpadDocumentSignatureSearchEngine
->setHeaders( ->setHeaders(
array( array(
'', '',
pht('Document'),
pht('Account'), pht('Account'),
pht('Name'), pht('Name'),
pht('Email'), pht('Email'),
pht('Signed'), pht('Signed'),
)) ))
->setColumnVisibility(
array(
true,
// Only show the "Document" column if we aren't scoped to a
// particular document.
!$this->document,
))
->setColumnClasses( ->setColumnClasses(
array( array(
'', '',
'', '',
'', '',
'',
'wide', 'wide',
'right', 'right',
)); ));
@ -184,6 +220,18 @@ final class LegalpadDocumentSignatureSearchEngine
->setHeaderText(pht('Signatures')) ->setHeaderText(pht('Signatures'))
->appendChild($table); ->appendChild($table);
if (!$this->document) {
$policy_notice = id(new AphrontErrorView())
->setSeverity(AphrontErrorView::SEVERITY_NOTICE)
->setErrors(
array(
pht(
'NOTE: You can only see your own signatures and signatures on '.
'documents you have permission to edit.'),
));
$box->setErrorView($policy_notice);
}
return $box; return $box;
} }