Add tags and fix markdown/descriptions

This commit is contained in:
Dennis Eichhorn 2020-12-19 20:24:41 +01:00
parent a5d09a0a34
commit af05cc7830
12 changed files with 223 additions and 44 deletions

View File

@ -20,6 +20,12 @@
"default": null,
"null": true
},
"kanban_board_descraw": {
"name": "kanban_board_descraw",
"type": "TEXT",
"default": null,
"null": true
},
"kanban_board_status": {
"name": "kanban_board_status",
"type": "TINYINT",
@ -44,6 +50,32 @@
}
}
},
"kanban_board_tag": {
"name": "kanban_board_tag",
"fields": {
"kanban_board_tag_id": {
"name": "kanban_board_id",
"type": "INT",
"null": false,
"primary": true,
"autoincrement": true
},
"kanban_board_tag_dst": {
"name": "kanban_board_tag_dst",
"type": "INT",
"null": false,
"foreignTable": "kanban_board",
"foreignKey": "kanban_board_id"
},
"kanban_board_tag_src": {
"name": "kanban_board_tag_src",
"type": "INT",
"null": false,
"foreignTable": "tag",
"foreignKey": "tag_id"
}
}
},
"kanban_column": {
"name": "kanban_column",
"fields": {
@ -141,6 +173,32 @@
}
}
},
"kanban_card_tag": {
"name": "kanban_card_tag",
"fields": {
"kanban_card_tag_id": {
"name": "kanban_card_id",
"type": "INT",
"null": false,
"primary": true,
"autoincrement": true
},
"kanban_card_tag_dst": {
"name": "kanban_card_tag_dst",
"type": "INT",
"null": false,
"foreignTable": "kanban_card",
"foreignKey": "kanban_card_id"
},
"kanban_card_tag_src": {
"name": "kanban_card_tag_src",
"type": "INT",
"null": false,
"foreignTable": "tag",
"foreignKey": "tag_id"
}
}
},
"kanban_card_media": {
"name": "kanban_card_media",
"fields": {
@ -183,6 +241,12 @@
"default": null,
"null": true
},
"kanban_card_comment_descriptionraw": {
"name": "kanban_card_comment_descriptionraw",
"type": "TEXT",
"default": null,
"null": true
},
"kanban_card_comment_card": {
"name": "kanban_card_comment_card",
"type": "INT",

View File

@ -26,6 +26,7 @@ use Modules\Kanban\Models\KanbanCardCommentMapper;
use Modules\Kanban\Models\KanbanCardMapper;
use Modules\Kanban\Models\KanbanColumn;
use Modules\Kanban\Models\KanbanColumnMapper;
use Modules\Tag\Models\NullTag;
use phpOMS\Message\Http\RequestStatusCode;
use phpOMS\Message\NotificationLevel;
use phpOMS\Message\RequestAbstract;
@ -83,8 +84,8 @@ final class ApiController extends Controller
{
$card = new KanbanCard();
$card->name = (string) ($request->getData('title'));
$card->description = Markdown::parse((string) ($request->getData('plain') ?? ''));
$card->descriptionRaw = (string) ($request->getData('plain') ?? '');
$card->description = Markdown::parse((string) ($request->getData('plain') ?? ''));
$card->setColumn((int) $request->getData('column'));
$card->setOrder((int) ($request->getData('order') ?? 1));
$card->setRef((int) ($request->getData('ref') ?? 0));
@ -92,6 +93,23 @@ final class ApiController extends Controller
$card->setType((int) ($request->getData('type') ?? CardType::TEXT));
$card->createdBy = new NullAccount($request->header->account);
if (!empty($tags = $request->getDataJson('tags'))) {
foreach ($tags as $tag) {
if (!isset($tag['id'])) {
$request->setData('title', $tag['title'], true);
$request->setData('color', $tag['color'], true);
$request->setData('icon', $tag['icon'] ?? null, true);
$request->setData('language', $tag['language'], true);
$internalResponse = new HttpResponse();
$this->app->moduleManager->get('Tag')->apiTagCreate($request, $internalResponse, null);
$card->addTag($internalResponse->get($request->uri->__toString())['response']);
} else {
$card->addTag(new NullTag((int) $tag['id']));
}
}
}
return $card;
}
@ -163,7 +181,8 @@ final class ApiController extends Controller
public function createKanbanCardCommentFromRequest(RequestAbstract $request) : KanbanCardComment
{
$comment = new KanbanCardComment();
$comment->description = (string) ($request->getData('plain') ?? '');
$comment->description = Markdown::parse((string) ($request->getData('plain') ?? ''));
$comment->descriptionRaw = (string) ($request->getData('plain') ?? '');
$comment->setCard((int) $request->getData('card'));
$comment->createdBy = new NullAccount($request->header->account);
@ -229,13 +248,31 @@ final class ApiController extends Controller
*/
public function createKanbanBoardFromRequest(RequestAbstract $request) : KanbanBoard
{
$board = new KanbanBoard();
$board->name = (string) $request->getData('title');
$board->description = (string) ($request->getData('plain') ?? '');
$board = new KanbanBoard();
$board->name = (string) $request->getData('title');
$board->description = Markdown::parse((string) ($request->getData('plain') ?? ''));
$board->descriptionRaw = (string) ($request->getData('plain') ?? '');
$board->setOrder((int) ($request->getData('order') ?? 1));
$board->setStatus((int) ($request->getData('status') ?? BoardStatus::ACTIVE));
$board->createdBy = new NullAccount($request->header->account);
if (!empty($tags = $request->getDataJson('tags'))) {
foreach ($tags as $tag) {
if (!isset($tag['id'])) {
$request->setData('title', $tag['title'], true);
$request->setData('color', $tag['color'], true);
$request->setData('icon', $tag['icon'] ?? null, true);
$request->setData('language', $tag['language'], true);
$internalResponse = new HttpResponse();
$this->app->moduleManager->get('Tag')->apiTagCreate($request, $internalResponse, null);
$board->addTag($internalResponse->get($request->uri->__toString())['response']);
} else {
$board->addTag(new NullTag((int) $tag['id']));
}
}
}
return $board;
}

View File

@ -74,7 +74,8 @@ final class BackendController extends Controller
$view->setTemplate('/Modules/Kanban/Theme/Backend/kanban-dashboard');
$view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1005801001, $request, $response));
$list = KanbanBoardMapper::getNewest(50, null, RelationType::ALL, 1);
$list = KanbanBoardMapper::withConditional('language', $response->getLanguage())
::getNewest(50, depth: 3);
$view->setData('boards', $list);
return $view;
@ -96,7 +97,8 @@ final class BackendController extends Controller
{
$view = new View($this->app->l11nManager, $request, $response);
$board = KanbanBoardMapper::get((int) $request->getData('id'));
$board = KanbanBoardMapper::withConditional('language', $response->getLanguage())
::get((int) $request->getData('id'), depth: 5);
$accountId = $request->header->account;
if ($board->createdBy->getId() !== $accountId

View File

@ -16,6 +16,7 @@ namespace Modules\Kanban\Models;
use Modules\Admin\Models\Account;
use Modules\Admin\Models\NullAccount;
use Modules\Tag\Models\Tag;
/**
* Task class.
@ -55,6 +56,22 @@ class KanbanBoard implements \JsonSerializable
*/
public string $description = '';
/**
* Description.
*
* @var string
* @since 1.0.0
*/
public string $descriptionRaw = '';
/**
* Tags.
*
* @var Tag[]
* @since 1.0.0
*/
private array $tags = [];
public Account $createdBy;
public \DateTimeImmutable $createdAt;
@ -136,6 +153,32 @@ class KanbanBoard implements \JsonSerializable
$this->order = $order;
}
/**
* Get tags
*
* @return array
*
* @since 1.0.0
*/
public function getTags() : array
{
return $this->tags;
}
/**
* Add tag
*
* @param Tag $tag Tag
*
* @return void
*
* @since 1.0.0
*/
public function addTag(Tag $tag) : void
{
$this->tags[] = $tag;
}
/**
* Get the columns
*

View File

@ -15,6 +15,7 @@ declare(strict_types=1);
namespace Modules\Kanban\Models;
use Modules\Admin\Models\AccountMapper;
use Modules\Tag\Models\TagMapper;
use phpOMS\DataStorage\Database\DataMapperAbstract;
/**
@ -37,6 +38,7 @@ final class KanbanBoardMapper extends DataMapperAbstract
'kanban_board_id' => ['name' => 'kanban_board_id', 'type' => 'int', 'internal' => 'id'],
'kanban_board_name' => ['name' => 'kanban_board_name', 'type' => 'string', 'internal' => 'name'],
'kanban_board_desc' => ['name' => 'kanban_board_desc', 'type' => 'string', 'internal' => 'description'],
'kanban_board_descraw' => ['name' => 'kanban_board_descraw', 'type' => 'string', 'internal' => 'descriptionRaw'],
'kanban_board_status' => ['name' => 'kanban_board_status', 'type' => 'int', 'internal' => 'status'],
'kanban_board_order' => ['name' => 'kanban_board_order', 'type' => 'int', 'internal' => 'order'],
'kanban_board_created_by' => ['name' => 'kanban_board_created_by', 'type' => 'int', 'internal' => 'createdBy', 'readonly' => true],
@ -56,6 +58,12 @@ final class KanbanBoardMapper extends DataMapperAbstract
'self' => 'kanban_column_board',
'external' => null,
],
'tags' => [
'mapper' => TagMapper::class,
'table' => 'kanban_board_tag',
'self' => 'kanban_board_tag_dst',
'external' => 'kanban_board_tag_src',
],
];
/**

View File

@ -18,6 +18,7 @@ use Modules\Admin\Models\Account;
use Modules\Admin\Models\NullAccount;
use Modules\Media\Models\Media;
use Modules\Tasks\Models\Task;
use Modules\Tag\Models\Tag;
/**
* Kanban card class.
@ -65,6 +66,14 @@ class KanbanCard implements \JsonSerializable
*/
public string $descriptionRaw = '';
/**
* Tags.
*
* @var Tag[]
* @since 1.0.0
*/
private array $tags = [];
private int $column = 0;
private int $order = 0;
@ -77,8 +86,6 @@ class KanbanCard implements \JsonSerializable
private array $comments = [];
private array $labels = [];
/**
* Media
*
@ -311,43 +318,29 @@ class KanbanCard implements \JsonSerializable
}
/**
* Set labels of the card
*
* @param array $labels Labels
*
* @return void
*
* @since 1.0.0
*/
public function setLabels(array $labels) : void
{
$this->labels = $labels;
}
/**
* Get the labels
* Get tags
*
* @return array
*
* @since 1.0.0
*/
public function getLabels() : array
public function getTags() : array
{
return $this->labels;
return $this->tags;
}
/**
* Add a label/tag
* Add tag
*
* @param mixed $label Label
* @param Tag $tag Tag
*
* @return void
*
* @since 1.0.0
*/
public function addLabel($label) : void
public function addTag(Tag $tag) : void
{
$this->labels[] = $label;
$this->tags[] = $tag;
}
/**
@ -365,7 +358,6 @@ class KanbanCard implements \JsonSerializable
'ref' => $this->name,
'createdBy' => $this->name,
'createdAt' => $this->name,
'labels' => $this->name,
'comments' => $this->name,
'media' => $this->name,
];

View File

@ -43,6 +43,14 @@ class KanbanCardComment implements \JsonSerializable
*/
public string $description = '';
/**
* Description.
*
* @var string
* @since 1.0.0
*/
public string $descriptionRaw = '';
private int $card = 0;
public Account $createdBy;

View File

@ -37,6 +37,7 @@ final class KanbanCardCommentMapper extends DataMapperAbstract
protected static array $columns = [
'kanban_card_comment_id' => ['name' => 'kanban_card_comment_id', 'type' => 'int', 'internal' => 'id'],
'kanban_card_comment_description' => ['name' => 'kanban_card_comment_description', 'type' => 'string', 'internal' => 'description'],
'kanban_card_comment_descriptionraw' => ['name' => 'kanban_card_comment_descriptionraw', 'type' => 'string', 'internal' => 'descriptionRaw'],
'kanban_card_comment_card' => ['name' => 'kanban_card_comment_card', 'type' => 'int', 'internal' => 'card'],
'kanban_card_comment_created_at' => ['name' => 'kanban_card_comment_created_at', 'type' => 'DateTimeImmutable', 'internal' => 'createdAt', 'readonly' => true],
'kanban_card_comment_created_by' => ['name' => 'kanban_card_comment_created_by', 'type' => 'int', 'internal' => 'createdBy', 'readonly' => true],

View File

@ -16,6 +16,7 @@ namespace Modules\Kanban\Models;
use Modules\Admin\Models\AccountMapper;
use Modules\Media\Models\MediaMapper;
use Modules\Tag\Models\TagMapper;
use phpOMS\DataStorage\Database\DataMapperAbstract;
/**
@ -80,6 +81,12 @@ final class KanbanCardMapper extends DataMapperAbstract
'self' => 'kanban_card_comment_card',
'external' => null,
],
'tags' => [
'mapper' => TagMapper::class,
'table' => 'kanban_card_tag',
'self' => 'kanban_card_tag_dst',
'external' => 'kanban_card_tag_src',
],
];
/**

View File

@ -11,15 +11,21 @@ $columns = $board->getColumns();
<?php $i = 0; foreach ($columns as $column) : $i++; $cards = $column->getCards(); ?>
<div id="kanban-column-<?= $i; ?>" class="col-xs-12 col-sm-3 box" draggable="true">
<header><?= $this->printHtml($column->name); ?></header>
<?php $j = 0; foreach ($cards as $card) : $j++; $labels = $card->getLabels(); ?>
<a href="<?= $this->printHtml(\phpOMS\Uri\UriFactory::build('{/prefix}kanban/card?{?}&id=' . $card->getId())); ?>">
<?php $j = 0; foreach ($cards as $card) : $j++;
$url = \phpOMS\Uri\UriFactory::build('{/prefix}kanban/card?{?}&id=' . $card->getId());
?>
<section id="kanban-card-<?= $this->printHtml($i . '-' . $j); ?>" class="portlet" draggable="true">
<div class="portlet-head"><?= $this->printHtml($card->name); ?></div>
<div class="portlet-head"><a href="<?= $url; ?>"><?= $this->printHtml($card->name); ?></a></div>
<div class="portlet-body">
<?= $this->printHtml($card->description); ?>
<?php foreach ($labels as $label) : ?>
<span class="tag" style="background: #<?= $this->printHtml(\dechex($label->getColor())); ?>"><?= $this->printHtml($label->getName()); ?></span>
<?php endforeach; ?>
<article><?= $card->description; ?></article>
</div>
<div class="portlet-foot">
<div class="overflowfix">
<?php $tags = $card->getTags(); foreach ($tags as $tag) : ?>
<span class="tag" style="background: <?= $this->printHtml($tag->color); ?>"><?= $tag->icon !== null ? '<i class="' . $this->printHtml($tag->icon ?? '') . '"></i>' : ''; ?><?= $this->printHtml($tag->getTitle()); ?></span>
<?php endforeach; ?>
<a href="<?= $url; ?>" class="button floatRight">More</a>
</div>
</div>
</section>
</a>

View File

@ -8,7 +8,7 @@ $comments = $card->getComments();
<section class="portlet">
<div class="portlet-head"><?= $this->printHtml($card->name); ?></div>
<div class="portlet-body">
<?= $this->printHtml($card->description); ?>
<article><?= $card->description; ?></article>
</div>
</section>
</div>
@ -19,7 +19,7 @@ $comments = $card->getComments();
<div class="col-xs-12">
<section class="portlet">
<div class="portlet-body">
<?= $this->printHtml($comment->description); ?>
<article><?= $comment->description; ?></article>
</div>
</section>
</div>

View File

@ -19,13 +19,24 @@ $boards = $this->getData('boards');
echo $this->getData('nav')->render(); ?>
<div class="row">
<?php foreach ($boards as $board) : ?>
<?php foreach ($boards as $board) :
$url = UriFactory::build('{/prefix}kanban/board?{?}&id=' . $board->getId());
?>
<div class="col-xs-12 col-sm-6 col-lg-3">
<a href="<?= $this->printHtml(UriFactory::build('{/prefix}kanban/board?{?}&id=' . $board->getId())); ?>">
<section class="portlet">
<div class="portlet-head"><?= $this->printHtml($board->name); ?></div>
<div class="portlet-head">
<a href="<?= $url; ?>"><?= $this->printHtml($board->name); ?></a>
</div>
<div class="portlet-body">
<?= $this->printHtml($board->description); ?>
<article><?= $board->description; ?></article>
</div>
<div class="portlet-foot">
<div class="overflowfix">
<?php $tags = $board->getTags(); foreach ($tags as $tag) : ?>
<span class="tag" style="background: <?= $this->printHtml($tag->color); ?>"><?= $tag->icon !== null ? '<i class="' . $this->printHtml($tag->icon ?? '') . '"></i>' : ''; ?><?= $this->printHtml($tag->getTitle()); ?></span>
<?php endforeach; ?>
<a tabindex="0" href="<?= $url; ?>" class="button floatRight">Open</a>
</div>
</div>
</section>
</a>