mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-10 08:52:39 +01:00
Use ApplicationSearch to search for Legalpad signatures
Summary: Ref T3116. Currently, document signatures are just in a big list that you can't search through. - Make it easier to check if a specific user has signed. - Restrict this UI to users who have edit permission on the document (roughly, you need to be a document manager to see the full signature list). (It's currently possible to generate a Dashboard panel using this query, but it will just throw an exception. I'm going to leave it like that for now, we might reasonably expose some "view signatures across doucments" UI later so someone can quickly check if a user has signed 5 documents or something.) Test Plan: {F171576} Reviewers: chad Reviewed By: chad Subscribers: epriestley Maniphest Tasks: T3116 Differential Revision: https://secure.phabricator.com/D9765
This commit is contained in:
parent
45d61b7110
commit
d8bba221b5
4 changed files with 204 additions and 90 deletions
|
@ -873,6 +873,7 @@ phutil_register_library_map(array(
|
|||
'LegalpadDocumentSignature' => 'applications/legalpad/storage/LegalpadDocumentSignature.php',
|
||||
'LegalpadDocumentSignatureListController' => 'applications/legalpad/controller/LegalpadDocumentSignatureListController.php',
|
||||
'LegalpadDocumentSignatureQuery' => 'applications/legalpad/query/LegalpadDocumentSignatureQuery.php',
|
||||
'LegalpadDocumentSignatureSearchEngine' => 'applications/legalpad/query/LegalpadDocumentSignatureSearchEngine.php',
|
||||
'LegalpadDocumentSignatureVerificationController' => 'applications/legalpad/controller/LegalpadDocumentSignatureVerificationController.php',
|
||||
'LegalpadMockMailReceiver' => 'applications/legalpad/mail/LegalpadMockMailReceiver.php',
|
||||
'LegalpadReplyHandler' => 'applications/legalpad/mail/LegalpadReplyHandler.php',
|
||||
|
@ -3633,6 +3634,7 @@ phutil_register_library_map(array(
|
|||
),
|
||||
'LegalpadDocumentSignatureListController' => 'LegalpadController',
|
||||
'LegalpadDocumentSignatureQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'LegalpadDocumentSignatureSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||
'LegalpadDocumentSignatureVerificationController' => 'LegalpadController',
|
||||
'LegalpadMockMailReceiver' => 'PhabricatorObjectMailReceiver',
|
||||
'LegalpadReplyHandler' => 'PhabricatorMailReplyHandler',
|
||||
|
|
|
@ -41,15 +41,16 @@ final class PhabricatorApplicationLegalpad extends PhabricatorApplication {
|
|||
'/L(?P<id>\d+)' => 'LegalpadDocumentSignController',
|
||||
'/legalpad/' => array(
|
||||
'' => 'LegalpadDocumentListController',
|
||||
'(query/(?P<queryKey>[^/]+)/)?' => 'LegalpadDocumentListController',
|
||||
'(?:query/(?P<queryKey>[^/]+)/)?' => 'LegalpadDocumentListController',
|
||||
'create/' => 'LegalpadDocumentEditController',
|
||||
'edit/(?P<id>\d+)/' => 'LegalpadDocumentEditController',
|
||||
'comment/(?P<id>\d+)/' => 'LegalpadDocumentCommentController',
|
||||
'view/(?P<id>\d+)/' => 'LegalpadDocumentManageController',
|
||||
'done/' => 'LegalpadDocumentDoneController',
|
||||
'verify/(?P<code>[^/]+)/' =>
|
||||
'LegalpadDocumentSignatureVerificationController',
|
||||
'signatures/(?P<id>\d+)/' => 'LegalpadDocumentSignatureListController',
|
||||
'LegalpadDocumentSignatureVerificationController',
|
||||
'signatures/(?P<id>\d+)/(?:query/(?P<queryKey>[^/]+)/)?'
|
||||
=> 'LegalpadDocumentSignatureListController',
|
||||
'document/' => array(
|
||||
'preview/' => 'PhabricatorMarkupPreviewController'),
|
||||
));
|
||||
|
|
|
@ -2,10 +2,13 @@
|
|||
|
||||
final class LegalpadDocumentSignatureListController extends LegalpadController {
|
||||
|
||||
private $documentId;
|
||||
private $documentID;
|
||||
private $queryKey;
|
||||
private $document;
|
||||
|
||||
public function willProcessRequest(array $data) {
|
||||
$this->documentId = $data['id'];
|
||||
$this->documentID = $data['id'];
|
||||
$this->queryKey = idx($data, 'queryKey');
|
||||
}
|
||||
|
||||
public function processRequest() {
|
||||
|
@ -14,108 +17,52 @@ final class LegalpadDocumentSignatureListController extends LegalpadController {
|
|||
|
||||
$document = id(new LegalpadDocumentQuery())
|
||||
->setViewer($user)
|
||||
->withIDs(array($this->documentId))
|
||||
->withIDs(array($this->documentID))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->executeOne();
|
||||
|
||||
if (!$document) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$title = pht('Signatures for %s', $document->getMonogram());
|
||||
$this->document = $document;
|
||||
|
||||
$pager = id(new AphrontCursorPagerView())
|
||||
->readFromRequest($request);
|
||||
$signatures = id(new LegalpadDocumentSignatureQuery())
|
||||
->setViewer($user)
|
||||
->withDocumentPHIDs(array($document->getPHID()))
|
||||
->executeWithCursorPager($pager);
|
||||
$engine = id(new LegalpadDocumentSignatureSearchEngine())
|
||||
->setDocument($document);
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs($this->buildSideNav());
|
||||
$crumbs->addTextCrumb(
|
||||
$document->getMonogram(),
|
||||
$this->getApplicationURI('view/'.$document->getID()));
|
||||
$controller = id(new PhabricatorApplicationSearchController($request))
|
||||
->setQueryKey($this->queryKey)
|
||||
->setSearchEngine($engine)
|
||||
->setNavigation($this->buildSideNav());
|
||||
|
||||
$crumbs->addTextCrumb(
|
||||
pht('Signatures'));
|
||||
$list = $this->renderResultsList($document, $signatures);
|
||||
$list->setPager($pager);
|
||||
|
||||
return $this->buildApplicationPage(
|
||||
array(
|
||||
$crumbs,
|
||||
$list,
|
||||
),
|
||||
array(
|
||||
'title' => $title,
|
||||
));
|
||||
return $this->delegateToController($controller);
|
||||
}
|
||||
|
||||
private function renderResultsList(
|
||||
LegalpadDocument $document,
|
||||
array $signatures) {
|
||||
assert_instances_of($signatures, 'LegalpadDocumentSignature');
|
||||
|
||||
public function buildSideNav($for_app = false) {
|
||||
$user = $this->getRequest()->getUser();
|
||||
|
||||
$list = new PHUIObjectItemListView();
|
||||
$list->setUser($user);
|
||||
$nav = new AphrontSideNavFilterView();
|
||||
$nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
|
||||
|
||||
foreach ($signatures as $signature) {
|
||||
$created = phabricator_date($signature->getDateCreated(), $user);
|
||||
id(new LegalpadDocumentSignatureSearchEngine())
|
||||
->setViewer($user)
|
||||
->setDocument($this->document)
|
||||
->addNavigationItems($nav->getMenu());
|
||||
|
||||
$data = $signature->getSignatureData();
|
||||
return $nav;
|
||||
}
|
||||
|
||||
$sig_data = phutil_tag(
|
||||
'div',
|
||||
array(),
|
||||
array(
|
||||
phutil_tag(
|
||||
'div',
|
||||
array(),
|
||||
phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => 'mailto:'.$data['email'],
|
||||
),
|
||||
$data['email'])),
|
||||
phutil_tag(
|
||||
'div',
|
||||
array(),
|
||||
$data['address_1']),
|
||||
phutil_tag(
|
||||
'div',
|
||||
array(),
|
||||
$data['address_2']),
|
||||
phutil_tag(
|
||||
'div',
|
||||
array(),
|
||||
$data['phone'])
|
||||
));
|
||||
public function buildApplicationCrumbs() {
|
||||
$crumbs = parent::buildApplicationCrumbs();
|
||||
|
||||
$item = id(new PHUIObjectItemView())
|
||||
->setObject($signature)
|
||||
->setHeader($data['name'])
|
||||
->setSubhead($sig_data)
|
||||
->addIcon('none', pht('Signed %s', $created));
|
||||
$crumbs->addTextCrumb(
|
||||
$this->document->getMonogram(),
|
||||
'/'.$this->document->getMonogram());
|
||||
|
||||
$good_sig = true;
|
||||
if (!$signature->isVerified()) {
|
||||
$item->addFootIcon('disable', 'Unverified Email');
|
||||
$good_sig = false;
|
||||
}
|
||||
if ($signature->getDocumentVersion() != $document->getVersions()) {
|
||||
$item->addFootIcon('delete', 'Stale Signature');
|
||||
$good_sig = false;
|
||||
}
|
||||
|
||||
if ($good_sig) {
|
||||
$item->setBarColor('green');
|
||||
}
|
||||
|
||||
$list->addItem($item);
|
||||
}
|
||||
|
||||
return $list;
|
||||
return $crumbs;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,164 @@
|
|||
<?php
|
||||
|
||||
final class LegalpadDocumentSignatureSearchEngine
|
||||
extends PhabricatorApplicationSearchEngine {
|
||||
|
||||
private $document;
|
||||
|
||||
public function getResultTypeDescription() {
|
||||
return pht('Legalpad Signatures');
|
||||
}
|
||||
|
||||
public function getApplicationClassName() {
|
||||
return 'PhabricatorApplicationLegalpad';
|
||||
}
|
||||
|
||||
public function setDocument(LegalpadDocument $document) {
|
||||
$this->document = $document;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function buildSavedQueryFromRequest(AphrontRequest $request) {
|
||||
$saved = new PhabricatorSavedQuery();
|
||||
|
||||
$saved->setParameter(
|
||||
'signerPHIDs',
|
||||
$this->readUsersFromRequest($request, 'signers'));
|
||||
|
||||
return $saved;
|
||||
}
|
||||
|
||||
public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) {
|
||||
$query = id(new LegalpadDocumentSignatureQuery());
|
||||
|
||||
$signer_phids = $saved->getParameter('signerPHIDs', array());
|
||||
if ($signer_phids) {
|
||||
$query->withSignerPHIDs($signer_phids);
|
||||
}
|
||||
|
||||
if ($this->document) {
|
||||
$query->withDocumentPHIDs(array($this->document->getPHID()));
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function buildSearchForm(
|
||||
AphrontFormView $form,
|
||||
PhabricatorSavedQuery $saved_query) {
|
||||
|
||||
$signer_phids = $saved_query->getParameter('signerPHIDs', array());
|
||||
|
||||
$phids = array_merge($signer_phids);
|
||||
$handles = id(new PhabricatorHandleQuery())
|
||||
->setViewer($this->requireViewer())
|
||||
->withPHIDs($phids)
|
||||
->execute();
|
||||
|
||||
$form
|
||||
->appendChild(
|
||||
id(new AphrontFormTokenizerControl())
|
||||
->setDatasource('/typeahead/common/users/')
|
||||
->setName('signers')
|
||||
->setLabel(pht('Signers'))
|
||||
->setValue(array_select_keys($handles, $signer_phids)));
|
||||
}
|
||||
|
||||
protected function getURI($path) {
|
||||
if ($this->document) {
|
||||
return '/legalpad/signatures/'.$this->document->getID().'/'.$path;
|
||||
} else {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Searching for signatures outside of a document context is not '.
|
||||
'currently supported.'));
|
||||
}
|
||||
}
|
||||
|
||||
public function getBuiltinQueryNames() {
|
||||
$names = array(
|
||||
'all' => pht('All Signatures'),
|
||||
);
|
||||
|
||||
return $names;
|
||||
}
|
||||
|
||||
public function buildSavedQueryFromBuiltin($query_key) {
|
||||
|
||||
$query = $this->newSavedQuery();
|
||||
$query->setQueryKey($query_key);
|
||||
|
||||
switch ($query_key) {
|
||||
case 'all':
|
||||
return $query;
|
||||
}
|
||||
|
||||
return parent::buildSavedQueryFromBuiltin($query_key);
|
||||
}
|
||||
|
||||
protected function getRequiredHandlePHIDsForResultList(
|
||||
array $documents,
|
||||
PhabricatorSavedQuery $query) {
|
||||
return mpull($documents, 'getSignerPHID');
|
||||
}
|
||||
|
||||
protected function renderResultList(
|
||||
array $signatures,
|
||||
PhabricatorSavedQuery $query,
|
||||
array $handles) {
|
||||
assert_instances_of($signatures, 'LegalpadDocumentSignature');
|
||||
|
||||
$viewer = $this->requireViewer();
|
||||
|
||||
$list = new PHUIObjectItemListView();
|
||||
$list->setUser($viewer);
|
||||
|
||||
foreach ($signatures as $signature) {
|
||||
$created = phabricator_date($signature->getDateCreated(), $viewer);
|
||||
|
||||
$data = $signature->getSignatureData();
|
||||
|
||||
$sig_data = phutil_tag(
|
||||
'div',
|
||||
array(),
|
||||
array(
|
||||
phutil_tag(
|
||||
'div',
|
||||
array(),
|
||||
phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => 'mailto:'.$data['email'],
|
||||
),
|
||||
$data['email'])),
|
||||
));
|
||||
|
||||
$item = id(new PHUIObjectItemView())
|
||||
->setObject($signature)
|
||||
->setHeader($data['name'])
|
||||
->setSubhead($sig_data)
|
||||
->addIcon('none', pht('Signed %s', $created));
|
||||
|
||||
$good_sig = true;
|
||||
if (!$signature->isVerified()) {
|
||||
$item->addFootIcon('disable', 'Unverified Email');
|
||||
$good_sig = false;
|
||||
}
|
||||
|
||||
$document = $signature->getDocument();
|
||||
if ($signature->getDocumentVersion() != $document->getVersions()) {
|
||||
$item->addFootIcon('delete', 'Stale Signature');
|
||||
$good_sig = false;
|
||||
}
|
||||
|
||||
if ($good_sig) {
|
||||
$item->setBarColor('green');
|
||||
}
|
||||
|
||||
$list->addItem($item);
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue