diff --git a/app/Domain/Goalcanvas/Controllers/Dashboard.php b/app/Domain/Goalcanvas/Controllers/Dashboard.php
index b2f70629a9..41142c627f 100644
--- a/app/Domain/Goalcanvas/Controllers/Dashboard.php
+++ b/app/Domain/Goalcanvas/Controllers/Dashboard.php
@@ -15,6 +15,7 @@
use Leantime\Domain\Queue\Repositories\Queue as QueueRepo;
use Illuminate\Support\Str;
use Leantime\Core\Frontcontroller;
+ use Symfony\Component\HttpFoundation\Response;
/**
*
@@ -49,277 +50,41 @@ public function init(
*
* @access public
*/
- public function run()
- {
- $allCanvas = $this->canvasRepo->getAllCanvas(session("currentProject"));
- //Create default canvas.
- if (!$allCanvas || count($allCanvas) == 0) {
- $values = [
- 'title' => $this->language->__("label.board"),
- 'author' => session("userdata.id"),
- 'projectId' => session("currentProject"),
- ];
- $currentCanvasId = $this->canvasRepo->addCanvas($values);
- $allCanvas = $this->canvasRepo->getAllCanvas(session("currentProject"));
- }
-
- $goalAnalytics = array(
- "numCanvases" => $allCanvas ? count($allCanvas) : 0,
- "numGoals" => "0",
- "goalsOnTrack" => 0,
- "goalsAtRisk" => 0,
- "goalsMiss" => 0,
- "avgPercentComplete" => '0',
- );
-
- $totalPercent = 0;
- foreach ($allCanvas as $canvas) {
- $canvasItems = $this->canvasRepo->getCanvasItemsById($canvas["id"]);
- foreach ($canvasItems as $item) {
- $goalAnalytics["numGoals"]++;
-
- if ($item["status"] == 'status_ontrack') {
- $goalAnalytics["goalsOnTrack"]++;
- }
-
- if ($item["status"] == 'status_atrisk') {
- $goalAnalytics["goalsAtRisk"]++;
- }
-
- if ($item["status"] == 'status_miss') {
- $goalAnalytics["goalsMiss"]++;
- }
-
- $total = $item['endValue'] - $item['startValue'];
- $progressValue = $item['currentValue'] - $item['startValue'];
-
- if ($total > 0) {
- $percentDone = round($progressValue / $total * 100, 2);
- } else {
- $percentDone = 0;
- }
-
- $totalPercent = $totalPercent + $percentDone;
- }
- }
-
- if ($goalAnalytics["numGoals"] > 0) {
- $goalAnalytics["avgPercentComplete"] = $totalPercent / $goalAnalytics["numGoals"];
- }
-
-
- if (session()->exists("current" . strtoupper(static::CANVAS_NAME) . "Canvas")) {
- $currentCanvasId = session("current" . strtoupper(static::CANVAS_NAME) . "Canvas");
- //Ensure canvas id is in the list of currentCanvases (could be old value after project select
-
- $found = false;
- foreach ($allCanvas as $row) {
- if ($currentCanvasId == $row['id']) {
- $found = true;
- break;
- }
- }
-
- if (!$found) {
- $currentCanvasId = -1;
- session(["current' . strtoupper(static::CANVAS_NAME) . 'Canvas" => '']);
- }
- } else {
- $currentCanvasId = -1;
- session(["current' . strtoupper(static::CANVAS_NAME) . 'Canvas" => '']);
- }
-
- if (count($allCanvas) > 0 && session("current" . strtoupper(static::CANVAS_NAME) . "Canvas") == '') {
- $currentCanvasId = $allCanvas[0]['id'];
- session(["current' . strtoupper(static::CANVAS_NAME) . 'Canvas" => $currentCanvasId]);
- }
-
- if (isset($_GET['id']) === true) {
- $currentCanvasId = (int)$_GET['id'];
- session(["current' . strtoupper(static::CANVAS_NAME) . 'Canvas" => $currentCanvasId]);
- }
-
- if (isset($_REQUEST['searchCanvas']) === true) {
- $currentCanvasId = (int)$_REQUEST['searchCanvas'];
- session(["current' . strtoupper(static::CANVAS_NAME) . 'Canvas" => $currentCanvasId]);
- return Frontcontroller::redirect(BASE_URL . '/' . static::CANVAS_NAME . 'canvas/showCanvas/');
- }
-
- // Add Canvas
- if (isset($_POST['newCanvas'])) {
- if (isset($_POST['canvastitle']) && !empty($_POST['canvastitle'])) {
- if (!$this->canvasRepo->existCanvas(session("currentProject"), $_POST['canvastitle'])) {
- $values = [
- 'title' => $_POST['canvastitle'],
- 'author' => session("userdata.id"),
- 'projectId' => session("currentProject"),
- ];
- $currentCanvasId = $this->canvasRepo->addCanvas($values);
- $allCanvas = $this->canvasRepo->getAllCanvas(session("currentProject"));
-
- $mailer = app()->make(Mailer::class);
- $this->projectService = app()->make(Projects::class);
- $users = $this->projectService->getUsersToNotify(session("currentProject"));
-
- $mailer->setSubject($this->language->__('notification.board_created'));
-
- $actual_link = CURRENT_URL;
- $message = sprintf(
- $this->language->__('email_notifications.canvas_created_message'),
- session("userdata.name"),
- "" . $values['title'] . ''
- );
- $mailer->setHtml($message);
-
- // New queuing messaging system
- $queue = app()->make(QueueRepo::class);
- $queue->queueMessageToUsers(
- $users,
- $message,
- $this->language->__('notification.board_created'),
- session("currentProject")
- );
-
- $this->tpl->setNotification($this->language->__('notification.board_created'), 'success');
-
- session(["current' . strtoupper(static::CANVAS_NAME) . 'Canvas" => $currentCanvasId]);
- return Frontcontroller::redirect(BASE_URL . '/' . static::CANVAS_NAME . 'canvas/showCanvas/');
- } else {
- $this->tpl->setNotification($this->language->__('notification.board_exists'), 'error');
- }
- } else {
- $this->tpl->setNotification($this->language->__('notification.please_enter_title'), 'error');
- }
- }
-
- // Edit Canvas
- if (isset($_POST['editCanvas']) && $currentCanvasId > 0) {
- if (isset($_POST['canvastitle']) && !empty($_POST['canvastitle'])) {
- if (!$this->canvasRepo->existCanvas(session("currentProject"), $_POST['canvastitle'])) {
- $values = array('title' => $_POST['canvastitle'], 'id' => $currentCanvasId);
- $currentCanvasId = $this->canvasRepo->updateCanvas($values);
-
- $this->tpl->setNotification($this->language->__('notification.board_edited'), 'success');
- return Frontcontroller::redirect(BASE_URL . '/' . static::CANVAS_NAME . 'canvas/showCanvas/');
- } else {
- $this->tpl->setNotification($this->language->__('notification.board_exists'), 'error');
- }
- } else {
- $this->tpl->setNotification($this->language->__('notification.please_enter_title'), 'error');
- }
- }
-
- // Clone canvas
- if (isset($_POST['cloneCanvas']) && $currentCanvasId > 0) {
- if (isset($_POST['canvastitle']) && !empty($_POST['canvastitle'])) {
- if (!$this->canvasRepo->existCanvas(session("currentProject"), $_POST['canvastitle'])) {
- $currentCanvasId = $this->canvasRepo->copyCanvas(
- session("currentProject"),
- $currentCanvasId,
- session("userdata.id"),
- $_POST['canvastitle']
- );
- $allCanvas = $this->canvasRepo->getAllCanvas(session("currentProject"));
-
- $this->tpl->setNotification($this->language->__('notification.board_copied'), 'success');
-
- session(["current' . strtoupper(static::CANVAS_NAME) . 'Canvas" => $currentCanvasId]);
- return Frontcontroller::redirect(BASE_URL . '/' . static::CANVAS_NAME . 'canvas/showCanvas/');
- } else {
- $this->tpl->setNotification($this->language->__('notification.board_exists'), 'error');
- }
- } else {
- $this->tpl->setNotification($this->language->__('notification.please_enter_title'), 'error');
- }
- }
-
- // Merge canvas
- if (isset($_POST['mergeCanvas']) && $currentCanvasId > 0) {
- if (isset($_POST['canvasid']) && $_POST['canvasid'] > 0) {
- $status = $this->canvasRepo->mergeCanvas($currentCanvasId, $_POST['canvasid']);
-
- if ($status) {
- $this->tpl->setNotification($this->language->__('notification.board_merged'), 'success');
- return Frontcontroller::redirect(BASE_URL . '/' . static::CANVAS_NAME . 'canvas/showCanvas/');
- } else {
- $this->tpl->setNotification($this->language->__('notification.merge_error'), 'error');
- }
- } else {
- $this->tpl->setNotification($this->language->__('notification.internal_error'), 'error');
- }
- }
-
- // Import canvas
- if (isset($_POST['importCanvas'])) {
- if (isset($_FILES['canvasfile']) && $_FILES['canvasfile']['error'] === 0) {
- $uploadfile = tempnam(sys_get_temp_dir(), 'leantime.') . '.xml';
-
- $status = move_uploaded_file($_FILES['canvasfile']['tmp_name'], $uploadfile);
- if ($status) {
- $services = app()->make(CanvasService::class);
- $importCanvasId = $services->import(
- $uploadfile,
- static::CANVAS_NAME . 'canvas',
- projectId: session("currentProject"),
- authorId: session("userdata.id")
- );
- unlink($uploadfile);
-
- if ($importCanvasId !== false) {
- $currentCanvasId = $importCanvasId;
- $allCanvas = $this->canvasRepo->getAllCanvas(session("currentProject"));
- session(["current' . strtoupper(static::CANVAS_NAME) . 'Canvas" => $currentCanvasId]);
-
- $mailer = app()->make(Mailer::class);
- $this->projectService = app()->make(Projects::class);
- $users = $this->projectService->getUsersToNotify(session("currentProject"));
- $canvas = $this->canvasRepo->getSingleCanvas($currentCanvasId);
- $mailer->setSubject($this->language->__('notification.board_imported'));
-
- $actual_link = CURRENT_URL;
- $message = sprintf(
- $this->language->__('email_notifications.canvas_imported_message'),
- session("userdata.name"),
- "" . $canvas[0]['title'] . ''
- );
- $mailer->setHtml($message);
-
- // New queuing messaging system
- $queue = app()->make(QueueRepo::class);
- $queue->queueMessageToUsers(
- $users,
- $message,
- $this->language->__('notification.board_imported'),
- session("currentProject")
- );
-
- $this->tpl->setNotification($this->language->__('notification.board_imported'), 'success');
- return Frontcontroller::redirect(BASE_URL . '/' . static::CANVAS_NAME . 'canvas/showCanvas/');
- } else {
- $this->tpl->setNotification($this->language->__('notification.board_import_failed'), 'error');
- }
- } else {
- $this->tpl->setNotification($this->language->__('notification.board_import_failed'), 'error');
- }
- }
- }
-
- $this->tpl->assign('currentCanvas', $currentCanvasId);
- $this->tpl->assign('goalStats', $goalAnalytics);
- $this->tpl->assign('canvasIcon', $this->canvasRepo->getIcon());
- $this->tpl->assign('canvasTypes', $this->canvasRepo->getCanvasTypes());
- $this->tpl->assign('statusLabels', $this->canvasRepo->getStatusLabels());
- $this->tpl->assign('relatesLabels', $this->canvasRepo->getRelatesLabels());
- $this->tpl->assign('dataLabels', $this->canvasRepo->getDataLabels());
- $this->tpl->assign('disclaimer', $this->canvasRepo->getDisclaimer());
- $this->tpl->assign('allCanvas', $allCanvas);
- $this->tpl->assign('canvasItems', $this->goalService->getCanvasItemsById($currentCanvasId));
- $this->tpl->assign('users', $this->projectService->getUsersAssignedToProject(session("currentProject")));
-
- if (!isset($_GET['raw'])) {
- return $this->tpl->display(static::CANVAS_NAME . 'canvas.dashboard');
- }
- }
+ public function get($params): Response
+ {
+
+ $result = $this->goalService->handleDashboardGetRequest($params);
+
+ $this->tpl->assign('currentCanvas', $result['currentCanvasId']);
+ $this->tpl->assign('goalStats', $result['goalAnalytics']);
+ $this->tpl->assign('canvasIcon', $result['canvasIcon']);
+ $this->tpl->assign('canvasTypes', $result['canvasTypes']);
+ $this->tpl->assign('statusLabels', $result['statusLabels']);
+ $this->tpl->assign('relatesLabels', $result['relatesLabels']);
+ $this->tpl->assign('dataLabels', $result['dataLabels']);
+ $this->tpl->assign('disclaimer', $result['disclaimer']);
+ $this->tpl->assign('allCanvas', $result['allCanvas']);
+ $this->tpl->assign('canvasItems', $result['canvasItems']);
+ $this->tpl->assign('users', $result['users']);
+
+ return $this->tpl->display(static::CANVAS_NAME . 'canvas.dashboard');
+ }
+
+
+ public function post($params): Response
+ {
+ $result = $this->goalService->handleDashboardPostRequest($params);
+
+ if ($result['redirect']) {
+ return Frontcontroller::redirect($result['redirectUrl']);
+ }
+
+ if ($result['notification']) {
+ $this->tpl->setNotification($result['notification']['message'], $result['notification']['type']);
+ }
+
+ return $this->tpl->display(static::CANVAS_NAME . 'canvas.dashboard');
+ }
}
}
diff --git a/app/Domain/Goalcanvas/Controllers/ShowCanvas.php b/app/Domain/Goalcanvas/Controllers/ShowCanvas.php
index 5fda1347a2..c9ccb904a3 100644
--- a/app/Domain/Goalcanvas/Controllers/ShowCanvas.php
+++ b/app/Domain/Goalcanvas/Controllers/ShowCanvas.php
@@ -14,6 +14,7 @@
use Leantime\Domain\Canvas\Services\Canvas as CanvasService;
use Illuminate\Support\Str;
use Leantime\Core\Frontcontroller;
+ use Symfony\Component\HttpFoundation\Response;
/**
*
@@ -46,216 +47,14 @@ public function init(Projects $projectService, Goalcanvas $goalService)
*
* @access public
*/
- public function run()
- {
-
- $allCanvas = $this->canvasRepo->getAllCanvas(session("currentProject"));
-
- //Create default canvas.
- if (!$allCanvas || count($allCanvas) == 0) {
- $values = [
- 'title' => $this->language->__("label.board"),
- 'author' => session("userdata.id"),
- 'projectId' => session("currentProject"),
- ];
- $currentCanvasId = $this->canvasRepo->addCanvas($values);
- $allCanvas = $this->canvasRepo->getAllCanvas(session("currentProject"));
- }
-
- if (session()->exists("current" . strtoupper(static::CANVAS_NAME) . "Canvas")) {
- $currentCanvasId = session("current" . strtoupper(static::CANVAS_NAME) . "Canvas");
- //Ensure canvas id is in the list of currentCanvases (could be old value after project select
-
- $found = false;
- foreach ($allCanvas as $row) {
- if ($currentCanvasId == $row['id']) {
- $found = true;
- break;
- }
- }
-
- if (!$found) {
- $currentCanvasId = -1;
- session(["current' . strtoupper(static::CANVAS_NAME) . 'Canvas" => '']);
- }
- } else {
- $currentCanvasId = -1;
- session(["current' . strtoupper(static::CANVAS_NAME) . 'Canvas" => '']);
- }
-
- if (count($allCanvas) > 0 && session("current" . strtoupper(static::CANVAS_NAME) . "Canvas") == '') {
- $currentCanvasId = $allCanvas[0]['id'];
- session(["current' . strtoupper(static::CANVAS_NAME) . 'Canvas" => $currentCanvasId]);
- }
-
- if (isset($_GET['id']) === true) {
- $currentCanvasId = (int)$_GET['id'];
- session(["current' . strtoupper(static::CANVAS_NAME) . 'Canvas" => $currentCanvasId]);
- }
-
- if (isset($_REQUEST['searchCanvas']) === true) {
- $currentCanvasId = (int)$_REQUEST['searchCanvas'];
- session(["current' . strtoupper(static::CANVAS_NAME) . 'Canvas" => $currentCanvasId]);
- return Frontcontroller::redirect(BASE_URL . '/' . static::CANVAS_NAME . 'canvas/showCanvas/');
- }
-
- // Add Canvas
- if (isset($_POST['newCanvas'])) {
- if (isset($_POST['canvastitle']) && !empty($_POST['canvastitle'])) {
- if (!$this->canvasRepo->existCanvas(session("currentProject"), $_POST['canvastitle'])) {
- $values = [
- 'title' => $_POST['canvastitle'],
- 'author' => session("userdata.id"),
- 'projectId' => session("currentProject"),
- ];
- $currentCanvasId = $this->canvasRepo->addCanvas($values);
- $allCanvas = $this->canvasRepo->getAllCanvas(session("currentProject"));
-
- $mailer = app()->make(Mailer::class);
- $users = $this->projectService->getUsersToNotify(session("currentProject"));
-
- $mailer->setSubject($this->language->__('notification.board_created'));
-
- $actual_link = CURRENT_URL;
- $message = sprintf(
- $this->language->__('email_notifications.canvas_created_message'),
- session("userdata.name"),
- "" . $values['title'] . ''
- );
- $mailer->setHtml($message);
-
- // New queuing messaging system
- $queue = app()->make(QueueRepo::class);
- $queue->queueMessageToUsers(
- $users,
- $message,
- $this->language->__('notification.board_created'),
- session("currentProject")
- );
-
- $this->tpl->setNotification($this->language->__('notification.board_created'), 'success');
-
- session(["current' . strtoupper(static::CANVAS_NAME) . 'Canvas" => $currentCanvasId]);
- return Frontcontroller::redirect(BASE_URL . '/' . static::CANVAS_NAME . 'canvas/showCanvas/');
- } else {
- $this->tpl->setNotification($this->language->__('notification.board_exists'), 'error');
- }
- } else {
- $this->tpl->setNotification($this->language->__('notification.please_enter_title'), 'error');
- }
- }
-
- // Edit Canvas
- if (isset($_POST['editCanvas']) && $currentCanvasId > 0) {
- if (isset($_POST['canvastitle']) && !empty($_POST['canvastitle'])) {
- if (!$this->canvasRepo->existCanvas(session("currentProject"), $_POST['canvastitle'])) {
- $values = array('title' => $_POST['canvastitle'], 'id' => $currentCanvasId);
- $currentCanvasId = $this->canvasRepo->updateCanvas($values);
-
- $this->tpl->setNotification($this->language->__('notification.board_edited'), 'success');
- return Frontcontroller::redirect(BASE_URL . '/' . static::CANVAS_NAME . 'canvas/showCanvas/');
- } else {
- $this->tpl->setNotification($this->language->__('notification.board_exists'), 'error');
- }
- } else {
- $this->tpl->setNotification($this->language->__('notification.please_enter_title'), 'error');
- }
- }
-
- // Clone canvas
- if (isset($_POST['cloneCanvas']) && $currentCanvasId > 0) {
- if (isset($_POST['canvastitle']) && !empty($_POST['canvastitle'])) {
- if (!$this->canvasRepo->existCanvas(session("currentProject"), $_POST['canvastitle'])) {
- $currentCanvasId = $this->canvasRepo->copyCanvas(
- session("currentProject"),
- $currentCanvasId,
- session("userdata.id"),
- $_POST['canvastitle']
- );
- $allCanvas = $this->canvasRepo->getAllCanvas(session("currentProject"));
-
- $this->tpl->setNotification($this->language->__('notification.board_copied'), 'success');
-
- session(["current' . strtoupper(static::CANVAS_NAME) . 'Canvas" => $currentCanvasId]);
- return Frontcontroller::redirect(BASE_URL . '/' . static::CANVAS_NAME . 'canvas/showCanvas/');
- } else {
- $this->tpl->setNotification($this->language->__('notification.board_exists'), 'error');
- }
- } else {
- $this->tpl->setNotification($this->language->__('notification.please_enter_title'), 'error');
- }
- }
-
- // Merge canvas
- if (isset($_POST['mergeCanvas']) && $currentCanvasId > 0) {
- if (isset($_POST['canvasid']) && $_POST['canvasid'] > 0) {
- $status = $this->canvasRepo->mergeCanvas($currentCanvasId, $_POST['canvasid']);
-
- if ($status) {
- $this->tpl->setNotification($this->language->__('notification.board_merged'), 'success');
- return Frontcontroller::redirect(BASE_URL . '/' . static::CANVAS_NAME . 'canvas/showCanvas/');
- } else {
- $this->tpl->setNotification($this->language->__('notification.merge_error'), 'error');
- }
- } else {
- $this->tpl->setNotification($this->language->__('notification.internal_error'), 'error');
- }
- }
-
- // Import canvas
- if (isset($_POST['importCanvas'])) {
- if (isset($_FILES['canvasfile']) && $_FILES['canvasfile']['error'] === 0) {
- $uploadfile = tempnam(sys_get_temp_dir(), 'leantime.') . '.xml';
- $status = move_uploaded_file($_FILES['canvasfile']['tmp_name'], $uploadfile);
- if ($status) {
- $services = app()->make(CanvasService::class);
- $importCanvasId = $services->import(
- $uploadfile,
- static::CANVAS_NAME . 'canvas',
- projectId: session("currentProject"),
- authorId: session("userdata.id")
- );
- unlink($uploadfile);
- if ($importCanvasId !== false) {
- $currentCanvasId = $importCanvasId;
- $allCanvas = $this->canvasRepo->getAllCanvas(session("currentProject"));
- session(["current' . strtoupper(static::CANVAS_NAME) . 'Canvas" => $currentCanvasId]);
-
- $mailer = app()->make(Mailer::class);
- $users = $this->projectService->getUsersToNotify(session("currentProject"));
- $canvas = $this->canvasRepo->getSingleCanvas($currentCanvasId);
- $mailer->setSubject($this->language->__('notification.board_imported'));
-
- $actual_link = CURRENT_URL;
- $message = sprintf(
- $this->language->__('email_notifications.canvas_imported_message'),
- session("userdata.name"),
- "" . $canvas[0]['title'] . ''
- );
- $mailer->setHtml($message);
-
- // New queuing messaging system
- $queue = app()->make(QueueRepo::class);
- $queue->queueMessageToUsers(
- $users,
- $message,
- $this->language->__('notification.board_imported'),
- session("currentProject")
- );
-
- $this->tpl->setNotification($this->language->__('notification.board_imported'), 'success');
- return Frontcontroller::redirect(BASE_URL . '/' . static::CANVAS_NAME . 'canvas/showCanvas/');
- } else {
- $this->tpl->setNotification($this->language->__('notification.board_import_failed'), 'error');
- }
- } else {
- $this->tpl->setNotification($this->language->__('notification.board_import_failed'), 'error');
- }
- }
- }
+ public function get($params): Response
+ {
+ $currentCanvasId = $this->goalService->getCurrentCanvasId($params);
+ $allCanvas = $this->goalService->getAllCanvas();
+
$this->tpl->assign('currentCanvas', $currentCanvasId);
$this->tpl->assign('canvasIcon', $this->canvasRepo->getIcon());
$this->tpl->assign('canvasTypes', $this->canvasRepo->getCanvasTypes());
@@ -266,10 +65,41 @@ public function run()
$this->tpl->assign('allCanvas', $allCanvas);
$this->tpl->assign('canvasItems', $this->goalService->getCanvasItemsById($currentCanvasId));
$this->tpl->assign('users', $this->projectService->getUsersAssignedToProject(session("currentProject")));
+
+ return $this->tpl->display(static::CANVAS_NAME . 'canvas.showCanvas');
+ }
- if (!isset($_GET['raw'])) {
- return $this->tpl->display(static::CANVAS_NAME . 'canvas.showCanvas');
+ public function post($params): Response
+ {
+ $action = $_POST['action'] ?? '';
+ $result = null;
+
+ switch ($action) {
+ case 'newCanvas':
+ $result = $this->goalService->createNewCanvas($_POST['canvastitle'] ?? '');
+ break;
+ case 'editCanvas':
+ $result = $this->goalService->editCanvas($_POST['canvastitle'] ?? '', $_POST['canvasid'] ?? -1);
+ break;
+ case 'cloneCanvas':
+ $result = $this->goalService->cloneCanvas($_POST['canvastitle'] ?? '', $_POST['canvasid'] ?? -1);
+ break;
+ case 'mergeCanvas':
+ $result = $this->goalService->mergeCanvas($_POST['canvasid'] ?? -1, $_POST['mergeCanvasId'] ?? -1);
+ break;
+ case 'importCanvas':
+ $result = $this->goalService->importCanvas($_FILES['canvasfile'] ?? null);
+ break;
+ }
+
+ if ($result['success']) {
+ $this->tpl->setNotification($result['message'], 'success');
+ return Frontcontroller::redirect(BASE_URL . '/' . static::CANVAS_NAME . 'canvas/showCanvas/');
+ } else {
+ $this->tpl->setNotification($result['message'], 'error');
}
+
+ return $this->get($params);
}
}
diff --git a/app/Domain/Goalcanvas/Services/Goalcanvas.php b/app/Domain/Goalcanvas/Services/Goalcanvas.php
index 8a274c7bb3..4e8539bc07 100644
--- a/app/Domain/Goalcanvas/Services/Goalcanvas.php
+++ b/app/Domain/Goalcanvas/Services/Goalcanvas.php
@@ -3,6 +3,12 @@
namespace Leantime\Domain\Goalcanvas\Services {
use Leantime\Domain\Goalcanvas\Repositories\Goalcanvas as GoalcanvaRepository;
+ use Leantime\Domain\Projects\Services\Projects;
+ use Leantime\core\Language;
+ use Leantime\Core\Mailer;
+ use Leantime\Domain\Queue\Repositories\Queue as QueueRepo;
+ use Leantime\Domain\Canvas\Services\Canvas as CanvasService;
+
/**
*
@@ -10,6 +16,14 @@
class Goalcanvas
{
private GoalcanvaRepository $goalRepository;
+ private ?Projects $projectService;
+
+ protected ?Language $language;
+ protected Mailer $mailer;
+
+ protected const CANVAS_NAME = 'goal';
+ protected QueueRepo $queueRepo;
+
public array $reportingSettings = [
"linkonly",
"linkAndReport",
@@ -19,9 +33,16 @@ class Goalcanvas
/**
* @param GoalcanvaRepository $goalRepository
*/
- public function __construct(GoalcanvaRepository $goalRepository)
- {
+ public function __construct(
+ GoalcanvaRepository $goalRepository,
+ ?Language $language = null
+ ) {
$this->goalRepository = $goalRepository;
+ $this->projectService = app()->make(Projects::class);
+ $this->language = $language;
+
+ $this->mailer = app()->make(Mailer::class);
+ $this->queueRepo = app()->make(QueueRepo::class);
}
/**
@@ -202,5 +223,488 @@ public function pollForUpdatedGoals(): array|false
return $goals;
}
+
+
+
+ // Goal Dashboard Get
+ public function handleDashboardGetRequest($params): array
+ {
+ $allCanvas = $this->goalRepository->getAllCanvas(session("currentProject"));
+
+ if (empty($allCanvas)) {
+ $allCanvas = $this->createDefaultCanvas();
+ }
+
+ $goalAnalytics = $this->calculateGoalAnalytics($allCanvas);
+ $currentCanvasId = $this->determineCurrentCanvasId($allCanvas, $params);
+
+ return [
+ 'currentCanvasId' => $currentCanvasId,
+ 'goalAnalytics' => $goalAnalytics,
+ 'canvasIcon' => $this->goalRepository->getIcon(),
+ 'canvasTypes' => $this->goalRepository->getCanvasTypes(),
+ 'statusLabels' => $this->goalRepository->getStatusLabels(),
+ 'relatesLabels' => $this->goalRepository->getRelatesLabels(),
+ 'dataLabels' => $this->goalRepository->getDataLabels(),
+ 'disclaimer' => $this->goalRepository->getDisclaimer(),
+ 'allCanvas' => $allCanvas,
+ 'canvasItems' => $this->goalRepository->getCanvasItemsById($currentCanvasId),
+ 'users' => $this->projectService->getUsersAssignedToProject(session("currentProject")),
+ ];
+ }
+
+ private function createDefaultCanvas(): array
+ {
+ $values = [
+ 'title' => $this->language->__("label.board"),
+ 'author' => session("userdata.id"),
+ 'projectId' => session("currentProject"),
+ ];
+ $this->goalRepository->addCanvas($values);
+ return $this->goalRepository->getAllCanvas(session("currentProject"));
+ }
+
+ private function calculateGoalAnalytics(array $allCanvas): array
+ {
+ $goalAnalytics = [
+ "numCanvases" => count($allCanvas),
+ "numGoals" => 0,
+ "goalsOnTrack" => 0,
+ "goalsAtRisk" => 0,
+ "goalsMiss" => 0,
+ "avgPercentComplete" => 0,
+ ];
+
+ $totalPercent = 0;
+ foreach ($allCanvas as $canvas) {
+ $canvasItems = $this->goalRepository->getCanvasItemsById($canvas["id"]);
+ foreach ($canvasItems as $item) {
+ $goalAnalytics["numGoals"]++;
+ $this->updateGoalStatus($goalAnalytics, $item);
+ $totalPercent += $this->calculateItemPercentage($item);
+ }
+ }
+
+ if ($goalAnalytics["numGoals"] > 0) {
+ $goalAnalytics["avgPercentComplete"] = $totalPercent / $goalAnalytics["numGoals"];
+ }
+
+ return $goalAnalytics;
+ }
+
+ private function updateGoalStatus(array &$goalAnalytics, array $item): void
+ {
+ switch ($item["status"]) {
+ case 'status_ontrack':
+ $goalAnalytics["goalsOnTrack"]++;
+ break;
+ case 'status_atrisk':
+ $goalAnalytics["goalsAtRisk"]++;
+ break;
+ case 'status_miss':
+ $goalAnalytics["goalsMiss"]++;
+ break;
+ }
+ }
+
+ private function calculateItemPercentage(array $item): float
+ {
+ $total = $item['endValue'] - $item['startValue'];
+ $progressValue = $item['currentValue'] - $item['startValue'];
+
+ return $total > 0 ? round($progressValue / $total * 100, 2) : 0;
+ }
+
+ private function determineCurrentCanvasId(array $allCanvas, array $params): int
+ {
+ $sessionKey = "current" . strtoupper(static::CANVAS_NAME) . "Canvas";
+
+ if (isset($params['id'])) {
+ $currentCanvasId = (int)$params['id'];
+ } elseif (isset($_REQUEST['searchCanvas'])) {
+ $currentCanvasId = (int)$_REQUEST['searchCanvas'];
+ } elseif (session()->exists($sessionKey)) {
+ $currentCanvasId = session($sessionKey);
+ $currentCanvasId = $this->validateCanvasId($currentCanvasId, $allCanvas);
+ } else {
+ $currentCanvasId = $allCanvas[0]['id'] ?? -1;
+ }
+
+ session([$sessionKey => $currentCanvasId]);
+
+ return $currentCanvasId;
+ }
+
+ private function validateCanvasId(int $canvasId, array $allCanvas): int
+ {
+ foreach ($allCanvas as $canvas) {
+ if ($canvasId == $canvas['id']) {
+ return $canvasId;
+ }
+ }
+ return -1;
+ }
+
+ // Goal Dashboard Post
+
+ public function handleDashboardPostRequest($params): array
+ {
+ $result = [
+ 'redirect' => false,
+ 'redirectUrl' => '',
+ 'notification' => null,
+ ];
+
+ $currentCanvasId = session("current" . strtoupper(static::CANVAS_NAME) . "Canvas") ?? -1;
+
+ if (isset($params['newCanvas'])) {
+ $result = $this->handleNewCanvas($params, $result);
+ } elseif (isset($params['editCanvas']) && $currentCanvasId > 0) {
+ $result = $this->handleEditCanvas($params, $currentCanvasId, $result);
+ } elseif (isset($params['cloneCanvas']) && $currentCanvasId > 0) {
+ $result = $this->handleCloneCanvas($params, $currentCanvasId, $result);
+ } elseif (isset($params['mergeCanvas']) && $currentCanvasId > 0) {
+ $result = $this->handleMergeCanvas($params, $currentCanvasId, $result);
+ } elseif (isset($params['importCanvas'])) {
+ $result = $this->handleImportCanvas($params, $result);
+ }
+
+ return $result;
+ }
+
+ private function handleNewCanvas($params, $result): array
+ {
+ if (!isset($params['canvastitle']) || empty($params['canvastitle'])) {
+ return $this->setNotification($result, 'notification.please_enter_title', 'error');
+ }
+
+ if ($this->goalRepository->existCanvas(session("currentProject"), $params['canvastitle'])) {
+ return $this->setNotification($result, 'notification.board_exists', 'error');
+ }
+
+ $values = [
+ 'title' => $params['canvastitle'],
+ 'author' => session("userdata.id"),
+ 'projectId' => session("currentProject"),
+ ];
+ $currentCanvasId = $this->goalRepository->addCanvas($values);
+
+ $this->sendCanvasNotification('notification.board_created', $values['title']);
+
+ session(["current" . strtoupper(static::CANVAS_NAME) . "Canvas" => $currentCanvasId]);
+ return $this->setRedirect($result, BASE_URL . '/' . static::CANVAS_NAME . 'canvas/showCanvas/');
+ }
+
+ private function handleEditCanvas($params, $currentCanvasId, $result): array
+ {
+ if (!isset($params['canvastitle']) || empty($params['canvastitle'])) {
+ return $this->setNotification($result, 'notification.please_enter_title', 'error');
+ }
+
+ if ($this->goalRepository->existCanvas(session("currentProject"), $params['canvastitle'])) {
+ return $this->setNotification($result, 'notification.board_exists', 'error');
+ }
+
+ $values = ['title' => $params['canvastitle'], 'id' => $currentCanvasId];
+ $this->goalRepository->updateCanvas($values);
+
+ return $this->setRedirect($result, BASE_URL . '/' . static::CANVAS_NAME . 'canvas/showCanvas/', 'notification.board_edited');
+ }
+
+ private function handleCloneCanvas($params, $currentCanvasId, $result): array
+ {
+ if (!isset($params['canvastitle']) || empty($params['canvastitle'])) {
+ return $this->setNotification($result, 'notification.please_enter_title', 'error');
+ }
+
+ if ($this->goalRepository->existCanvas(session("currentProject"), $params['canvastitle'])) {
+ return $this->setNotification($result, 'notification.board_exists', 'error');
+ }
+
+ $newCanvasId = $this->goalRepository->copyCanvas(
+ session("currentProject"),
+ $currentCanvasId,
+ session("userdata.id"),
+ $params['canvastitle']
+ );
+
+ session(["current" . strtoupper(static::CANVAS_NAME) . "Canvas" => $newCanvasId]);
+ return $this->setRedirect($result, BASE_URL . '/' . static::CANVAS_NAME . 'canvas/showCanvas/', 'notification.board_copied');
+ }
+
+ private function handleMergeCanvas($params, $currentCanvasId, $result): array
+ {
+ if (!isset($params['canvasid']) || $params['canvasid'] <= 0) {
+ return $this->setNotification($result, 'notification.internal_error', 'error');
+ }
+
+ $status = $this->goalRepository->mergeCanvas($currentCanvasId, $params['canvasid']);
+
+ if ($status) {
+ return $this->setRedirect($result, BASE_URL . '/' . static::CANVAS_NAME . 'canvas/showCanvas/', 'notification.board_merged');
+ } else {
+ return $this->setNotification($result, 'notification.merge_error', 'error');
+ }
+ }
+
+ private function handleImportCanvas($params, $result): array
+ {
+ if (!isset($_FILES['canvasfile']) || $_FILES['canvasfile']['error'] !== 0) {
+ return $this->setNotification($result, 'notification.board_import_failed', 'error');
+ }
+
+ $uploadfile = tempnam(sys_get_temp_dir(), 'leantime.') . '.xml';
+
+ if (!move_uploaded_file($_FILES['canvasfile']['tmp_name'], $uploadfile)) {
+ return $this->setNotification($result, 'notification.board_import_failed', 'error');
+ }
+
+ $services = app()->make(static::class);
+ $importCanvasId = $services->import(
+ $uploadfile,
+ static::CANVAS_NAME . 'canvas',
+ projectId: session("currentProject"),
+ authorId: session("userdata.id")
+ );
+ unlink($uploadfile);
+
+ if ($importCanvasId === false) {
+ return $this->setNotification($result, 'notification.board_import_failed', 'error');
+ }
+
+ $canvas = $this->goalRepository->getSingleCanvas($importCanvasId);
+ $this->sendCanvasNotification('notification.board_imported', $canvas[0]['title']);
+
+ session(["current" . strtoupper(static::CANVAS_NAME) . "Canvas" => $importCanvasId]);
+ return $this->setRedirect($result, BASE_URL . '/' . static::CANVAS_NAME . 'canvas/showCanvas/', 'notification.board_imported');
+ }
+
+ private function setNotification($result, $message, $type): array
+ {
+ $result['notification'] = [
+ 'message' => $this->language ? $this->language->__($message) : $message,
+ 'type' => $type
+ ];
+ return $result;
+ }
+
+ private function setRedirect($result, $url, $notificationMessage = null): array
+ {
+ $result['redirect'] = true;
+ $result['redirectUrl'] = $url;
+ if ($notificationMessage) {
+ $result['notification'] = [
+ 'message' => $this->language ? $this->language->__($notificationMessage) : $notificationMessage,
+ 'type' => 'success'
+ ];
+ }
+ return $result;
+ }
+
+ private function sendCanvasNotification($subject, $title): void
+ {
+ if (!$this->mailer || !$this->projectService || !$this->queueRepo) {
+ return;
+ }
+
+ $users = $this->projectService->getUsersToNotify(session("currentProject"));
+ $this->mailer->setSubject($this->language->__($subject));
+
+ $actual_link = CURRENT_URL;
+ $message = sprintf(
+ $this->language->__('email_notifications.canvas_created_message'),
+ session("userdata.name"),
+ "" . $title . ''
+ );
+ $this->mailer->setHtml($message);
+
+ $this->queueRepo->queueMessageToUsers(
+ $users,
+ $message,
+ $this->language->__($subject),
+ session("currentProject")
+ );
+ }
+
+
+ // Show canvas get data
+
+ public function getCurrentCanvasId($params)
+ {
+ $allCanvas = $this->getAllCanvas();
+ $currentCanvasId = $this->getStoredCanvasId();
+
+ if (empty($allCanvas)) {
+ $currentCanvasId = $this->createDefaultCanvas();
+ $allCanvas = $this->getAllCanvas();
+ } elseif ($currentCanvasId === -1 && !empty($allCanvas)) {
+ $currentCanvasId = $allCanvas[0]['id'];
+ }
+
+ if (isset($params['id'])) {
+ $currentCanvasId = (int)$params['id'];
+ }
+
+ if (isset($_REQUEST['searchCanvas'])) {
+ $currentCanvasId = (int)$_REQUEST['searchCanvas'];
+ // You might want to handle the redirect in the controller
+ }
+
+ $this->storeCurrentCanvasId($currentCanvasId);
+
+ return $currentCanvasId;
+ }
+
+ public function getAllCanvas()
+ {
+ return $this->goalRepository->getAllCanvas(session("currentProject"));
+ }
+
+
+ private function getStoredCanvasId()
+ {
+ $sessionKey = "current" . strtoupper(static::CANVAS_NAME) . "Canvas";
+ return session()->exists($sessionKey) ? session($sessionKey) : -1;
+ }
+
+ private function storeCurrentCanvasId($canvasId)
+ {
+ $sessionKey = "current" . strtoupper(static::CANVAS_NAME) . "Canvas";
+ session([$sessionKey => $canvasId]);
+ }
+
+ // Show canvas post data
+
+ public function createNewCanvas(string $title): array
+ {
+ if (empty($title)) {
+ return ['success' => false, 'message' => $this->language->__('notification.please_enter_title')];
+ }
+
+ if ($this->goalRepository->existCanvas(session("currentProject"), $title)) {
+ return ['success' => false, 'message' => $this->language->__('notification.board_exists')];
+ }
+
+ $values = [
+ 'title' => $title,
+ 'author' => session("userdata.id"),
+ 'projectId' => session("currentProject"),
+ ];
+ $canvasId = $this->goalRepository->addCanvas($values);
+
+ $this->notifyUsers('canvas_created', $title);
+
+ session(["current" . strtoupper(static::CANVAS_NAME) . "Canvas" => $canvasId]);
+ return ['success' => true, 'message' => $this->language->__('notification.board_created')];
+ }
+
+ public function editCanvas(string $title, int $canvasId): array
+ {
+ if (empty($title)) {
+ return ['success' => false, 'message' => $this->language->__('notification.please_enter_title')];
+ }
+
+ if ($this->goalRepository->existCanvas(session("currentProject"), $title)) {
+ return ['success' => false, 'message' => $this->language->__('notification.board_exists')];
+ }
+
+ $values = ['title' => $title, 'id' => $canvasId];
+ $this->goalRepository->updateCanvas($values);
+
+ return ['success' => true, 'message' => $this->language->__('notification.board_edited')];
+ }
+
+ public function cloneCanvas(string $title, int $canvasId): array
+ {
+ if (empty($title)) {
+ return ['success' => false, 'message' => $this->language->__('notification.please_enter_title')];
+ }
+
+ if ($this->goalRepository->existCanvas(session("currentProject"), $title)) {
+ return ['success' => false, 'message' => $this->language->__('notification.board_exists')];
+ }
+
+ $newCanvasId = $this->goalRepository->copyCanvas(
+ session("currentProject"),
+ $canvasId,
+ session("userdata.id"),
+ $title
+ );
+
+ session(["current" . strtoupper(static::CANVAS_NAME) . "Canvas" => $newCanvasId]);
+ return ['success' => true, 'message' => $this->language->__('notification.board_copied')];
+ }
+
+ public function mergeCanvas(int $canvasId, int $mergeCanvasId): array
+ {
+ if ($canvasId <= 0 || $mergeCanvasId <= 0) {
+ return ['success' => false, 'message' => $this->language->__('notification.internal_error')];
+ }
+
+ $status = $this->goalRepository->mergeCanvas($canvasId, $mergeCanvasId);
+
+ if ($status) {
+ return ['success' => true, 'message' => $this->language->__('notification.board_merged')];
+ } else {
+ return ['success' => false, 'message' => $this->language->__('notification.merge_error')];
+ }
+ }
+
+ public function importCanvas(?array $file): array
+ {
+ if (!$file || $file['error'] !== 0) {
+ return ['success' => false, 'message' => $this->language->__('notification.board_import_failed')];
+ }
+
+ $uploadfile = tempnam(sys_get_temp_dir(), 'leantime.') . '.xml';
+
+ if (!move_uploaded_file($file['tmp_name'], $uploadfile)) {
+ return ['success' => false, 'message' => $this->language->__('notification.board_import_failed')];
+ }
+
+ $services = app()->make(CanvasService::class);
+ $importCanvasId = $services->import(
+ $uploadfile,
+ static::CANVAS_NAME . 'canvas',
+ projectId: session("currentProject"),
+ authorId: session("userdata.id")
+ );
+ unlink($uploadfile);
+
+ if ($importCanvasId === false) {
+ return ['success' => false, 'message' => $this->language->__('notification.board_import_failed')];
+ }
+
+ session(["current" . strtoupper(static::CANVAS_NAME) . "Canvas" => $importCanvasId]);
+ $canvas = $this->goalRepository->getSingleCanvas($importCanvasId);
+ $this->notifyUsers('canvas_imported', $canvas[0]['title']);
+
+ return ['success' => true, 'message' => $this->language->__('notification.board_imported')];
+ }
+
+ private function notifyUsers(string $action, string $canvasTitle): void
+ {
+ $mailer = app()->make(Mailer::class);
+ $users = $this->projectService->getUsersToNotify(session("currentProject"));
+
+ $subject = $this->language->__("notification.board_{$action}");
+ $mailer->setSubject($subject);
+
+ $actual_link = CURRENT_URL;
+ $message = sprintf(
+ $this->language->__("email_notifications.canvas_{$action}_message"),
+ session("userdata.name"),
+ "" . $canvasTitle . ''
+ );
+ $mailer->setHtml($message);
+
+ $queue = app()->make(QueueRepo::class);
+ $queue->queueMessageToUsers(
+ $users,
+ $message,
+ $subject,
+ session("currentProject")
+ );
+ }
}
}