mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-10 00:42:41 +01:00
Add basic "View" and "Edit" features to Nuance
Summary: Ref T8783. The "View" UI is where a user would check their request for feedback or a resolution, if it's something that makes sense for them to interact with from the web UI. The "Edit" UI is the manage/admin UI where you'd respond to a request. It's similar to the view UI but will have actions and eventually some queue UI, etc. (I don't think items need a normal "Edit" UI -- it doesn't make sense to "Edit" a tweet or inbound email -- but maybe this will shuffle around a little eventually.) Test Plan: View {F747218} Edit {F747219} Reviewers: chad Reviewed By: chad Maniphest Tasks: T8783 Differential Revision: https://secure.phabricator.com/D13980
This commit is contained in:
parent
9e3f3e692d
commit
c69d465891
7 changed files with 214 additions and 30 deletions
|
@ -3,30 +3,91 @@
|
|||
final class NuanceItemEditController extends NuanceController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$viewer = $this->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
if (!$id) {
|
||||
$item = new NuanceItem();
|
||||
} else {
|
||||
$item = id(new NuanceItemQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->executeOne();
|
||||
}
|
||||
|
||||
if (!$item) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$title = pht('Item %d', $item->getID());
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$title = 'TODO';
|
||||
$crumbs->addTextCrumb($title);
|
||||
$crumbs->addTextCrumb(pht('Edit'));
|
||||
|
||||
$properties = $this->buildPropertyView($item);
|
||||
$actions = $this->buildActionView($item);
|
||||
$properties->setActionList($actions);
|
||||
|
||||
$box = id(new PHUIObjectBoxView())
|
||||
->setHeaderText($title)
|
||||
->addPropertyList($properties);
|
||||
|
||||
return $this->buildApplicationPage(
|
||||
array(
|
||||
$crumbs,
|
||||
$box,
|
||||
),
|
||||
array(
|
||||
'title' => $title,
|
||||
));
|
||||
}
|
||||
|
||||
private function buildPropertyView(NuanceItem $item) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$properties = id(new PHUIPropertyListView())
|
||||
->setUser($viewer)
|
||||
->setObject($item);
|
||||
|
||||
$properties->addProperty(
|
||||
pht('Date Created'),
|
||||
phabricator_datetime($item->getDateCreated(), $viewer));
|
||||
|
||||
$properties->addProperty(
|
||||
pht('Requestor'),
|
||||
$viewer->renderHandle($item->getRequestorPHID()));
|
||||
|
||||
$properties->addProperty(
|
||||
pht('Source'),
|
||||
$viewer->renderHandle($item->getSourcePHID()));
|
||||
|
||||
$source = $item->getSource();
|
||||
$definition = $source->requireDefinition();
|
||||
|
||||
$definition->renderItemEditProperties(
|
||||
$viewer,
|
||||
$item,
|
||||
$properties);
|
||||
|
||||
return $properties;
|
||||
}
|
||||
|
||||
private function buildActionView(NuanceItem $item) {
|
||||
$viewer = $this->getViewer();
|
||||
$id = $item->getID();
|
||||
|
||||
$actions = id(new PhabricatorActionListView())
|
||||
->setUser($viewer);
|
||||
|
||||
$actions->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('View Item'))
|
||||
->setIcon('fa-eye')
|
||||
->setHref($this->getApplicationURI("item/view/{$id}/")));
|
||||
|
||||
return $actions;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -3,25 +3,84 @@
|
|||
final class NuanceItemViewController extends NuanceController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$viewer = $this->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
$item = id(new NuanceItemQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->executeOne();
|
||||
|
||||
if (!$item) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$title = pht('Item %d', $item->getID());
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$title = 'TODO';
|
||||
$crumbs->addTextCrumb($title);
|
||||
|
||||
$properties = $this->buildPropertyView($item);
|
||||
$actions = $this->buildActionView($item);
|
||||
$properties->setActionList($actions);
|
||||
|
||||
$box = id(new PHUIObjectBoxView())
|
||||
->setHeaderText($title)
|
||||
->addPropertyList($properties);
|
||||
|
||||
return $this->buildApplicationPage(
|
||||
array(
|
||||
$crumbs,
|
||||
$box,
|
||||
),
|
||||
array(
|
||||
'title' => $title,
|
||||
));
|
||||
}
|
||||
|
||||
private function buildPropertyView(NuanceItem $item) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$properties = id(new PHUIPropertyListView())
|
||||
->setUser($viewer)
|
||||
->setObject($item);
|
||||
|
||||
$properties->addProperty(
|
||||
pht('Date Created'),
|
||||
phabricator_datetime($item->getDateCreated(), $viewer));
|
||||
|
||||
$source = $item->getSource();
|
||||
$definition = $source->requireDefinition();
|
||||
|
||||
$definition->renderItemViewProperties(
|
||||
$viewer,
|
||||
$item,
|
||||
$properties);
|
||||
|
||||
return $properties;
|
||||
}
|
||||
|
||||
private function buildActionView(NuanceItem $item) {
|
||||
$viewer = $this->getViewer();
|
||||
$id = $item->getID();
|
||||
|
||||
$actions = id(new PhabricatorActionListView())
|
||||
->setUser($viewer);
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$item,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$actions->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Edit Item'))
|
||||
->setIcon('fa-pencil')
|
||||
->setHref($this->getApplicationURI("item/edit/{$id}/"))
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit));
|
||||
|
||||
return $actions;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -29,7 +29,9 @@ final class NuanceRequestorPHIDType extends PhabricatorPHIDType {
|
|||
foreach ($handles as $phid => $handle) {
|
||||
$requestor = $objects[$phid];
|
||||
|
||||
$handle->setName($requestor->getBestName());
|
||||
// TODO: This is currently useless and should be far more informative.
|
||||
$handle->setName(pht('Requestor %d', $requestor->getID()));
|
||||
|
||||
$handle->setURI($requestor->getURI());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,25 +17,42 @@ final class NuanceItemQuery
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function withSourcePHIDs($source_phids) {
|
||||
public function withSourcePHIDs(array $source_phids) {
|
||||
$this->sourcePHIDs = $source_phids;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function newResultObject() {
|
||||
return new NuanceItem();
|
||||
}
|
||||
|
||||
protected function loadPage() {
|
||||
$table = new NuanceItem();
|
||||
$conn = $table->establishConnection('r');
|
||||
return $this->loadStandardPage($this->newResultObject());
|
||||
}
|
||||
|
||||
$data = queryfx_all(
|
||||
$conn,
|
||||
'%Q FROM %T %Q %Q %Q',
|
||||
$this->buildSelectClause($conn),
|
||||
$table->getTableName(),
|
||||
$this->buildWhereClause($conn),
|
||||
$this->buildOrderClause($conn),
|
||||
$this->buildLimitClause($conn));
|
||||
protected function willFilterPage(array $items) {
|
||||
$source_phids = mpull($items, 'getSourcePHID');
|
||||
|
||||
return $table->loadAllFromArray($data);
|
||||
// NOTE: We always load sources, even if the viewer can't formally see
|
||||
// them. If they can see the item, they're allowed to be aware of the
|
||||
// source in some sense.
|
||||
$sources = id(new NuanceSourceQuery())
|
||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||
->withPHIDs($source_phids)
|
||||
->execute();
|
||||
$sources = mpull($sources, null, 'getPHID');
|
||||
|
||||
foreach ($items as $key => $item) {
|
||||
$source = idx($sources, $item->getSourcePHID());
|
||||
if (!$source) {
|
||||
$this->didRejectResult($items[$key]);
|
||||
unset($items[$key]);
|
||||
continue;
|
||||
}
|
||||
$item->attachSource($source);
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
|
||||
|
|
|
@ -61,7 +61,7 @@ final class NuancePhabricatorFormSourceDefinition
|
|||
|
||||
if ($request->isFormPost()) {
|
||||
$properties = array(
|
||||
'complaint' => (string)$request->getStr('text'),
|
||||
'complaint' => (string)$request->getStr('complaint'),
|
||||
);
|
||||
|
||||
$content_source = PhabricatorContentSource::newFromRequest($request);
|
||||
|
@ -100,4 +100,33 @@ final class NuancePhabricatorFormSourceDefinition
|
|||
return $box;
|
||||
}
|
||||
|
||||
public function renderItemViewProperties(
|
||||
PhabricatorUser $viewer,
|
||||
NuanceItem $item,
|
||||
PHUIPropertyListView $view) {
|
||||
$this->renderItemCommonProperties($viewer, $item, $view);
|
||||
}
|
||||
|
||||
public function renderItemEditProperties(
|
||||
PhabricatorUser $viewer,
|
||||
NuanceItem $item,
|
||||
PHUIPropertyListView $view) {
|
||||
$this->renderItemCommonProperties($viewer, $item, $view);
|
||||
}
|
||||
|
||||
private function renderItemCommonProperties(
|
||||
PhabricatorUser $viewer,
|
||||
NuanceItem $item,
|
||||
PHUIPropertyListView $view) {
|
||||
|
||||
$complaint = $item->getNuanceProperty('complaint');
|
||||
$complaint = PhabricatorMarkupEngine::renderOneObject(
|
||||
id(new PhabricatorMarkupOneOff())->setContent($complaint),
|
||||
'default',
|
||||
$viewer);
|
||||
|
||||
$view->addSectionHeader(pht('Complaint'));
|
||||
$view->addTextContent($complaint);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -268,6 +268,20 @@ abstract class NuanceSourceDefinition extends Phobject {
|
|||
return $item;
|
||||
}
|
||||
|
||||
public function renderItemViewProperties(
|
||||
PhabricatorUser $viewer,
|
||||
NuanceItem $item,
|
||||
PHUIPropertyListView $view) {
|
||||
return;
|
||||
}
|
||||
|
||||
public function renderItemEditProperties(
|
||||
PhabricatorUser $viewer,
|
||||
NuanceItem $item,
|
||||
PHUIPropertyListView $view) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* -( Handling Action Requests )------------------------------------------- */
|
||||
|
||||
|
|
|
@ -19,6 +19,8 @@ final class NuanceItem
|
|||
protected $mailKey;
|
||||
protected $dateNuanced;
|
||||
|
||||
private $source = self::ATTACHABLE;
|
||||
|
||||
public static function initializeNewItem() {
|
||||
return id(new NuanceItem())
|
||||
->setDateNuanced(time())
|
||||
|
|
Loading…
Reference in a new issue