mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-17 20:32:41 +01:00
Add storage and read logic for workboard card cover photos
Summary: No way to set photos yet, but if you magic them in they work. Primarily, this consolidates rendering logic so the move + edit + view controllers all run the same code to do tags / cover photos. Test Plan: {F1095870} Reviewers: chad Reviewed By: chad Differential Revision: https://secure.phabricator.com/D15201
This commit is contained in:
parent
f097c9c595
commit
b6a38b403c
9 changed files with 237 additions and 87 deletions
5
resources/sql/autopatches/20160206.cover.1.sql
Normal file
5
resources/sql/autopatches/20160206.cover.1.sql
Normal file
|
@ -0,0 +1,5 @@
|
|||
ALTER TABLE {$NAMESPACE}_maniphest.maniphest_task
|
||||
ADD properties LONGTEXT NOT NULL COLLATE {$COLLATE_TEXT};
|
||||
|
||||
UPDATE {$NAMESPACE}_maniphest.maniphest_task
|
||||
SET properties = '{}' WHERE properties = '';
|
|
@ -1815,6 +1815,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorBinariesSetupCheck' => 'applications/config/check/PhabricatorBinariesSetupCheck.php',
|
||||
'PhabricatorBitbucketAuthProvider' => 'applications/auth/provider/PhabricatorBitbucketAuthProvider.php',
|
||||
'PhabricatorBoardLayoutEngine' => 'applications/project/engine/PhabricatorBoardLayoutEngine.php',
|
||||
'PhabricatorBoardRenderingEngine' => 'applications/project/engine/PhabricatorBoardRenderingEngine.php',
|
||||
'PhabricatorBot' => 'infrastructure/daemon/bot/PhabricatorBot.php',
|
||||
'PhabricatorBotChannel' => 'infrastructure/daemon/bot/target/PhabricatorBotChannel.php',
|
||||
'PhabricatorBotDebugLogHandler' => 'infrastructure/daemon/bot/handler/PhabricatorBotDebugLogHandler.php',
|
||||
|
@ -6043,6 +6044,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorBinariesSetupCheck' => 'PhabricatorSetupCheck',
|
||||
'PhabricatorBitbucketAuthProvider' => 'PhabricatorOAuth1AuthProvider',
|
||||
'PhabricatorBoardLayoutEngine' => 'Phobject',
|
||||
'PhabricatorBoardRenderingEngine' => 'Phobject',
|
||||
'PhabricatorBot' => 'PhabricatorDaemon',
|
||||
'PhabricatorBotChannel' => 'PhabricatorBotTarget',
|
||||
'PhabricatorBotDebugLogHandler' => 'PhabricatorBotHandler',
|
||||
|
|
|
@ -7,6 +7,7 @@ final class PhabricatorFileThumbnailTransform
|
|||
const TRANSFORM_PINBOARD = 'pinboard';
|
||||
const TRANSFORM_THUMBGRID = 'thumbgrid';
|
||||
const TRANSFORM_PREVIEW = 'preview';
|
||||
const TRANSFORM_WORKCARD = 'workcard';
|
||||
|
||||
private $name;
|
||||
private $key;
|
||||
|
@ -73,6 +74,10 @@ final class PhabricatorFileThumbnailTransform
|
|||
->setName(pht('Preview (220px)'))
|
||||
->setKey(self::TRANSFORM_PREVIEW)
|
||||
->setDimensions(220, null),
|
||||
id(new self())
|
||||
->setName(pht('Workcard (526px)'))
|
||||
->setKey(self::TRANSFORM_WORKCARD)
|
||||
->setDimensions(526, null),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -334,39 +334,27 @@ final class ManiphestEditEngine
|
|||
'sortMap' => $sort_map,
|
||||
);
|
||||
|
||||
// TODO: This should just use HandlePool once we get through the EditEngine
|
||||
// transition.
|
||||
$owner = null;
|
||||
if ($task->getOwnerPHID()) {
|
||||
$owner = id(new PhabricatorHandleQuery())
|
||||
$rendering_engine = id(new PhabricatorBoardRenderingEngine())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($task->getOwnerPHID()))
|
||||
->executeOne();
|
||||
}
|
||||
->setObjects(array($task))
|
||||
->setExcludedProjectPHIDs($board_phids);
|
||||
|
||||
$handle_phids = $task->getProjectPHIDs();
|
||||
$handle_phids = array_fuse($handle_phids);
|
||||
$handle_phids = array_diff_key($handle_phids, $board_phids);
|
||||
$card = $rendering_engine->renderCard($task->getPHID());
|
||||
|
||||
$project_handles = $viewer->loadHandles($handle_phids);
|
||||
$project_handles = iterator_to_array($project_handles);
|
||||
|
||||
$tasks = id(new ProjectBoardTaskCard())
|
||||
->setViewer($viewer)
|
||||
->setTask($task)
|
||||
->setOwner($owner)
|
||||
->setProjectHandles($project_handles)
|
||||
->setCanEdit(true)
|
||||
->getItem();
|
||||
|
||||
$tasks->addClass('phui-workcard');
|
||||
$item = $card->getItem();
|
||||
$item->addClass('phui-workcard');
|
||||
|
||||
$payload = array(
|
||||
'tasks' => $tasks,
|
||||
'tasks' => $item,
|
||||
'data' => $data,
|
||||
);
|
||||
|
||||
return id(new AphrontAjaxResponse())->setContent($payload);
|
||||
return id(new AphrontAjaxResponse())
|
||||
->setContent(
|
||||
array(
|
||||
'tasks' => $item,
|
||||
'data' => $data,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ final class ManiphestTask extends ManiphestDAO
|
|||
|
||||
protected $ownerOrdering;
|
||||
protected $spacePHID;
|
||||
protected $properties = array();
|
||||
|
||||
private $subscriberPHIDs = self::ATTACHABLE;
|
||||
private $groupByProjectPHID = self::ATTACHABLE;
|
||||
|
@ -74,6 +75,7 @@ final class ManiphestTask extends ManiphestDAO
|
|||
'ccPHIDs' => self::SERIALIZATION_JSON,
|
||||
'attached' => self::SERIALIZATION_JSON,
|
||||
'projectPHIDs' => self::SERIALIZATION_JSON,
|
||||
'properties' => self::SERIALIZATION_JSON,
|
||||
),
|
||||
self::CONFIG_COLUMN_SCHEMA => array(
|
||||
'ownerPHID' => 'phid?',
|
||||
|
@ -215,6 +217,19 @@ final class ManiphestTask extends ManiphestDAO
|
|||
);
|
||||
}
|
||||
|
||||
public function setProperty($key, $value) {
|
||||
$this->properties[$key] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getProperty($key, $default = null) {
|
||||
return idx($this->properties, $key, $default);
|
||||
}
|
||||
|
||||
public function getCoverImageThumbnailPHID() {
|
||||
return idx($this->properties, 'cover.thumbnailPHID');
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorSubscribableInterface )----------------------------------- */
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@ final class PhabricatorProjectBoardViewController
|
|||
|
||||
private $id;
|
||||
private $slug;
|
||||
private $handles;
|
||||
private $queryKey;
|
||||
private $filter;
|
||||
private $sortKey;
|
||||
|
@ -226,22 +225,9 @@ final class PhabricatorProjectBoardViewController
|
|||
'project-boards',
|
||||
$behavior_config);
|
||||
|
||||
$this->handles = ManiphestTaskListView::loadTaskHandles($viewer, $tasks);
|
||||
|
||||
$all_project_phids = array();
|
||||
foreach ($tasks as $task) {
|
||||
foreach ($task->getProjectPHIDs() as $project_phid) {
|
||||
$all_project_phids[$project_phid] = $project_phid;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($select_phids as $phid) {
|
||||
unset($all_project_phids[$phid]);
|
||||
}
|
||||
|
||||
$all_handles = $viewer->loadHandles($all_project_phids);
|
||||
$all_handles = iterator_to_array($all_handles);
|
||||
|
||||
$visible_columns = array();
|
||||
$column_phids = array();
|
||||
$visible_phids = array();
|
||||
foreach ($columns as $column) {
|
||||
if (!$this->showHidden) {
|
||||
if ($column->isHidden()) {
|
||||
|
@ -268,6 +254,25 @@ final class PhabricatorProjectBoardViewController
|
|||
$column_tasks = array_select_keys($column_tasks, array_keys($tasks));
|
||||
}
|
||||
|
||||
$column_phid = $column->getPHID();
|
||||
|
||||
$visible_columns[$column_phid] = $column;
|
||||
$column_phids[$column_phid] = $column_tasks;
|
||||
|
||||
foreach ($column_tasks as $phid => $task) {
|
||||
$visible_phids[$phid] = $phid;
|
||||
}
|
||||
}
|
||||
|
||||
$rendering_engine = id(new PhabricatorBoardRenderingEngine())
|
||||
->setViewer($viewer)
|
||||
->setObjects(array_select_keys($tasks, $visible_phids))
|
||||
->setEditMap($task_can_edit_map)
|
||||
->setExcludedProjectPHIDs($select_phids);
|
||||
|
||||
foreach ($visible_columns as $column_phid => $column) {
|
||||
$column_tasks = $column_phids[$column_phid];
|
||||
|
||||
$panel = id(new PHUIWorkpanelView())
|
||||
->setHeader($column->getDisplayName())
|
||||
->setSubHeader($column->getDisplayType())
|
||||
|
@ -317,22 +322,10 @@ final class PhabricatorProjectBoardViewController
|
|||
));
|
||||
|
||||
foreach ($column_tasks as $task) {
|
||||
$owner = null;
|
||||
if ($task->getOwnerPHID()) {
|
||||
$owner = $this->handles[$task->getOwnerPHID()];
|
||||
$card = $rendering_engine->renderCard($task->getPHID());
|
||||
$cards->addItem($card->getItem());
|
||||
}
|
||||
$can_edit = idx($task_can_edit_map, $task->getPHID(), false);
|
||||
|
||||
$handles = array_select_keys($all_handles, $task->getProjectPHIDs());
|
||||
|
||||
$cards->addItem(id(new ProjectBoardTaskCard())
|
||||
->setViewer($viewer)
|
||||
->setProjectHandles($handles)
|
||||
->setTask($task)
|
||||
->setOwner($owner)
|
||||
->setCanEdit($can_edit)
|
||||
->getItem());
|
||||
}
|
||||
$panel->setCards($cards);
|
||||
$board->addPanel($panel);
|
||||
}
|
||||
|
|
|
@ -175,24 +175,11 @@ final class PhabricatorProjectMoveController
|
|||
|
||||
$editor->applyTransactions($object, $xactions);
|
||||
|
||||
$owner = null;
|
||||
if ($object->getOwnerPHID()) {
|
||||
$owner = id(new PhabricatorHandleQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($object->getOwnerPHID()))
|
||||
->executeOne();
|
||||
}
|
||||
|
||||
// Reload the object so it reflects edits which have been applied.
|
||||
$object = id(new ManiphestTaskQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($object_phid))
|
||||
->needProjectPHIDs(true)
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->executeOne();
|
||||
|
||||
$except_phids = array($board_phid);
|
||||
|
@ -206,25 +193,21 @@ final class PhabricatorProjectMoveController
|
|||
}
|
||||
}
|
||||
|
||||
$except_phids = array_fuse($except_phids);
|
||||
$handle_phids = array_fuse($object->getProjectPHIDs());
|
||||
$handle_phids = array_diff_key($handle_phids, $except_phids);
|
||||
|
||||
$project_handles = $viewer->loadHandles($handle_phids);
|
||||
$project_handles = iterator_to_array($project_handles);
|
||||
|
||||
$card = id(new ProjectBoardTaskCard())
|
||||
$rendering_engine = id(new PhabricatorBoardRenderingEngine())
|
||||
->setViewer($viewer)
|
||||
->setTask($object)
|
||||
->setOwner($owner)
|
||||
->setCanEdit(true)
|
||||
->setProjectHandles($project_handles)
|
||||
->getItem();
|
||||
->setObjects(array($object))
|
||||
->setExcludedProjectPHIDs($except_phids);
|
||||
|
||||
$card->addClass('phui-workcard');
|
||||
$card = $rendering_engine->renderCard($object->getPHID());
|
||||
|
||||
return id(new AphrontAjaxResponse())->setContent(
|
||||
array('task' => $card));
|
||||
$item = $card->getItem();
|
||||
$item->addClass('phui-workcard');
|
||||
|
||||
return id(new AphrontAjaxResponse())
|
||||
->setContent(
|
||||
array(
|
||||
'task' => $item,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,144 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorBoardRenderingEngine extends Phobject {
|
||||
|
||||
private $viewer;
|
||||
private $objects;
|
||||
private $excludedProjectPHIDs;
|
||||
private $editMap;
|
||||
|
||||
private $loaded;
|
||||
private $handles;
|
||||
private $coverFiles;
|
||||
|
||||
public function setViewer(PhabricatorUser $viewer) {
|
||||
$this->viewer = $viewer;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getViewer() {
|
||||
return $this->viewer;
|
||||
}
|
||||
|
||||
public function setObjects(array $objects) {
|
||||
$this->objects = mpull($objects, null, 'getPHID');
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getObjects() {
|
||||
return $this->objects;
|
||||
}
|
||||
|
||||
public function setExcludedProjectPHIDs(array $phids) {
|
||||
$this->excludedProjectPHIDs = $phids;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getExcludedProjectPHIDs() {
|
||||
return $this->excludedProjectPHIDs;
|
||||
}
|
||||
|
||||
public function setEditMap(array $edit_map) {
|
||||
$this->editMap = $edit_map;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getEditMap() {
|
||||
return $this->editMap;
|
||||
}
|
||||
|
||||
public function renderCard($phid) {
|
||||
$this->willRender();
|
||||
|
||||
$viewer = $this->getViewer();
|
||||
$object = idx($this->getObjects(), $phid);
|
||||
|
||||
$card = id(new ProjectBoardTaskCard())
|
||||
->setViewer($viewer)
|
||||
->setTask($object)
|
||||
->setCanEdit($this->getCanEdit($phid));
|
||||
|
||||
$owner_phid = $object->getOwnerPHID();
|
||||
if ($owner_phid) {
|
||||
$owner_handle = $this->handles[$owner_phid];
|
||||
$card->setOwner($owner_handle);
|
||||
}
|
||||
|
||||
$project_phids = $object->getProjectPHIDs();
|
||||
$project_handles = array_select_keys($this->handles, $project_phids);
|
||||
if ($project_handles) {
|
||||
$card->setProjectHandles($project_handles);
|
||||
}
|
||||
|
||||
$cover_phid = $object->getCoverImageThumbnailPHID();
|
||||
if ($cover_phid) {
|
||||
$cover_file = idx($this->coverFiles, $cover_phid);
|
||||
if ($cover_file) {
|
||||
$card->setCoverImageFile($cover_file);
|
||||
}
|
||||
}
|
||||
|
||||
return $card;
|
||||
}
|
||||
|
||||
private function willRender() {
|
||||
if ($this->loaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
$phids = array();
|
||||
foreach ($this->objects as $object) {
|
||||
$owner_phid = $object->getOwnerPHID();
|
||||
if ($owner_phid) {
|
||||
$phids[$owner_phid] = $owner_phid;
|
||||
}
|
||||
|
||||
foreach ($object->getProjectPHIDs() as $phid) {
|
||||
$phids[$phid] = $phid;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->excludedProjectPHIDs) {
|
||||
foreach ($this->excludedProjectPHIDs as $excluded_phid) {
|
||||
unset($phids[$excluded_phid]);
|
||||
}
|
||||
}
|
||||
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$handles = $viewer->loadHandles($phids);
|
||||
$handles = iterator_to_array($handles);
|
||||
$this->handles = $handles;
|
||||
|
||||
$cover_phids = array();
|
||||
foreach ($this->objects as $object) {
|
||||
$cover_phid = $object->getCoverImageThumbnailPHID();
|
||||
if ($cover_phid) {
|
||||
$cover_phids[$cover_phid] = $cover_phid;
|
||||
}
|
||||
}
|
||||
|
||||
if ($cover_phids) {
|
||||
$cover_files = id(new PhabricatorFileQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs($cover_phids)
|
||||
->execute();
|
||||
$cover_files = mpull($cover_files, null, 'getPHID');
|
||||
} else {
|
||||
$cover_files = array();
|
||||
}
|
||||
|
||||
$this->coverFiles = $cover_files;
|
||||
|
||||
$this->loaded = true;
|
||||
}
|
||||
|
||||
private function getCanEdit($phid) {
|
||||
if ($this->editMap === null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return idx($this->editMap, $phid);
|
||||
}
|
||||
|
||||
}
|
|
@ -7,6 +7,7 @@ final class ProjectBoardTaskCard extends Phobject {
|
|||
private $task;
|
||||
private $owner;
|
||||
private $canEdit;
|
||||
private $coverImageFile;
|
||||
|
||||
public function setViewer(PhabricatorUser $viewer) {
|
||||
$this->viewer = $viewer;
|
||||
|
@ -25,6 +26,15 @@ final class ProjectBoardTaskCard extends Phobject {
|
|||
return $this->projectHandles;
|
||||
}
|
||||
|
||||
public function setCoverImageFile(PhabricatorFile $cover_image_file) {
|
||||
$this->coverImageFile = $cover_image_file;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCoverImageFile() {
|
||||
return $this->coverImageFile;
|
||||
}
|
||||
|
||||
public function setTask(ManiphestTask $task) {
|
||||
$this->task = $task;
|
||||
return $this;
|
||||
|
@ -84,6 +94,11 @@ final class ProjectBoardTaskCard extends Phobject {
|
|||
$card->addHandleIcon($owner, $owner->getName());
|
||||
}
|
||||
|
||||
$cover_file = $this->getCoverImageFile();
|
||||
if ($cover_file) {
|
||||
$card->setCoverImage($cover_file->getBestURI());
|
||||
}
|
||||
|
||||
if ($task->isClosed()) {
|
||||
$icon = ManiphestTaskStatus::getStatusIcon($task->getStatus());
|
||||
$icon = id(new PHUIIconView())
|
||||
|
|
Loading…
Reference in a new issue