diff options
Diffstat (limited to 'app')
44 files changed, 450 insertions, 160 deletions
diff --git a/app/Controller/Board.php b/app/Controller/Board.php index a552b9cf..5851bd26 100644 --- a/app/Controller/Board.php +++ b/app/Controller/Board.php @@ -27,7 +27,7 @@ class Board extends Base } // Display the board with a specific layout - $this->response->html($this->template->layout('board/public_view', array( + $this->response->html($this->template->layout('board/view_public', array( 'project' => $project, 'swimlanes' => $this->board->getBoard($project['id']), 'title' => $project['name'], @@ -49,7 +49,7 @@ class Board extends Base { $params = $this->getProjectFilters('board', 'show'); - $this->response->html($this->template->layout('board/private_view', array( + $this->response->html($this->template->layout('board/view_private', array( 'categories_list' => $this->category->getList($params['project']['id'], false), 'users_list' => $this->projectPermission->getMemberList($params['project']['id'], false), 'swimlanes' => $this->taskFilter->search($params['filters']['search'])->getBoard($params['project']['id']), @@ -136,7 +136,7 @@ class Board extends Base } $values = $this->request->getJson(); - $this->userSession->setFilters($project_id, $values['search']); + $this->userSession->setFilters($project_id, empty($values['search']) ? '' : $values['search']); $this->response->html($this->renderBoard($project_id)); } diff --git a/app/Controller/Config.php b/app/Controller/Config.php index 790bdcd3..1ae390c8 100644 --- a/app/Controller/Config.php +++ b/app/Controller/Config.php @@ -78,6 +78,19 @@ class Config extends Base } /** + * Display the plugin page + * + * @access public + */ + public function plugins() + { + $this->response->html($this->layout('config/plugins', array( + 'plugins' => $this->pluginLoader->plugins, + 'title' => t('Settings').' > '.t('Plugins'), + ))); + } + + /** * Display the application settings page * * @access public diff --git a/app/Controller/Taskstatus.php b/app/Controller/Taskstatus.php index a47d9da3..9260b658 100644 --- a/app/Controller/Taskstatus.php +++ b/app/Controller/Taskstatus.php @@ -18,62 +18,58 @@ class Taskstatus extends Base public function close() { $task = $this->getTask(); + $this->changeStatus($task, 'close', t('Task closed successfully.'), t('Unable to close this task.')); + $this->renderTemplate($task, 'task_status/close'); + } + + /** + * Open a task + * + * @access public + */ + public function open() + { + $task = $this->getTask(); $redirect = $this->request->getStringParam('redirect'); + $this->changeStatus($task, 'open', t('Task opened successfully.'), t('Unable to open this task.')); + $this->renderTemplate($task, 'task_status/open'); + } + + private function changeStatus(array $task, $method, $success_message, $failure_message) + { if ($this->request->getStringParam('confirmation') === 'yes') { $this->checkCSRFParam(); - if ($this->taskStatus->close($task['id'])) { - $this->session->flash(t('Task closed successfully.')); + if ($this->taskStatus->$method($task['id'])) { + $this->session->flash($success_message); } else { - $this->session->flashError(t('Unable to close this task.')); + $this->session->flashError($failure_message); } - if ($redirect === 'board') { + if ($this->request->getStringParam('redirect') === 'board') { $this->response->redirect($this->helper->url->to('board', 'show', array('project_id' => $task['project_id']))); } $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']))); } + } + + private function renderTemplate(array $task, $template) + { + $redirect = $this->request->getStringParam('redirect'); if ($this->request->isAjax()) { - $this->response->html($this->template->render('task_status/close', array( + $this->response->html($this->template->render($template, array( 'task' => $task, 'redirect' => $redirect, ))); } - $this->response->html($this->taskLayout('task_status/close', array( + $this->response->html($this->taskLayout($template, array( 'task' => $task, 'redirect' => $redirect, ))); } - - /** - * Open a task - * - * @access public - */ - public function open() - { - $task = $this->getTask(); - - if ($this->request->getStringParam('confirmation') === 'yes') { - - $this->checkCSRFParam(); - - if ($this->taskStatus->open($task['id'])) { - $this->session->flash(t('Task opened successfully.')); - } else { - $this->session->flashError(t('Unable to open this task.')); - } - - $this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id']))); - } - - $this->response->html($this->taskLayout('task_status/open', array( - 'task' => $task, - ))); - } } diff --git a/app/Core/Base.php b/app/Core/Base.php index fe42ba09..b919d551 100644 --- a/app/Core/Base.php +++ b/app/Core/Base.php @@ -23,6 +23,7 @@ use Pimple\Container; * @property \Core\ObjectStorage\ObjectStorageInterface $objectStorage * @property \Core\Cache\Cache $memoryCache * @property \Core\Plugin\Hook $hook + * @property \Core\Plugin\Loader $pluginLoader * @property \Integration\BitbucketWebhook $bitbucketWebhook * @property \Integration\GithubWebhook $githubWebhook * @property \Integration\GitlabWebhook $gitlabWebhook diff --git a/app/Core/Plugin/Base.php b/app/Core/Plugin/Base.php index 580d41ad..a72a0cd6 100644 --- a/app/Core/Plugin/Base.php +++ b/app/Core/Plugin/Base.php @@ -44,4 +44,69 @@ abstract class Base extends \Core\Base call_user_func($callback, $container); }); } + + /** + * Get plugin name + * + * This method should be overrided by your Plugin class + * + * @access public + * @return string + */ + public function getPluginName() + { + return ucfirst(substr(get_called_class(), 7, -7)); + } + + /** + * Get plugin description + * + * This method should be overrided by your Plugin class + * + * @access public + * @return string + */ + public function getPluginDescription() + { + return ''; + } + + /** + * Get plugin author + * + * This method should be overrided by your Plugin class + * + * @access public + * @return string + */ + public function getPluginAuthor() + { + return '?'; + } + + /** + * Get plugin version + * + * This method should be overrided by your Plugin class + * + * @access public + * @return string + */ + public function getPluginVersion() + { + return '?'; + } + + /** + * Get plugin homepage + * + * This method should be overrided by your Plugin class + * + * @access public + * @return string + */ + public function getPluginHomepage() + { + return ''; + } } diff --git a/app/Core/Plugin/Loader.php b/app/Core/Plugin/Loader.php index 04b2bfff..9a884dae 100644 --- a/app/Core/Plugin/Loader.php +++ b/app/Core/Plugin/Loader.php @@ -22,6 +22,14 @@ class Loader extends \Core\Base const TABLE_SCHEMA = 'plugin_schema_versions'; /** + * Plugin instances + * + * @access public + * @var array + */ + public $plugins = array(); + + /** * Scan plugin folder and load plugins * * @access public @@ -55,6 +63,7 @@ class Loader extends \Core\Base Tool::buildDic($this->container, $instance->getClasses()); $instance->initialize(); + $this->plugins[] = $instance; } /** diff --git a/app/Locale/cs_CZ/translations.php b/app/Locale/cs_CZ/translations.php index 6c5cf0fb..fad94fb0 100644 --- a/app/Locale/cs_CZ/translations.php +++ b/app/Locale/cs_CZ/translations.php @@ -1012,4 +1012,10 @@ return array( // 'Table of contents' => '', // 'Gantt' => '', // 'Help with project permissions' => '', + // 'Author' => '', + // 'Version' => '', + // 'Plugins' => '', + // 'There is no plugin loaded.' => '', + // 'Set maximum column height' => '', + // 'Remove maximum column height' => '', ); diff --git a/app/Locale/da_DK/translations.php b/app/Locale/da_DK/translations.php index d0fa1a18..cc721b84 100644 --- a/app/Locale/da_DK/translations.php +++ b/app/Locale/da_DK/translations.php @@ -1012,4 +1012,10 @@ return array( // 'Table of contents' => '', // 'Gantt' => '', // 'Help with project permissions' => '', + // 'Author' => '', + // 'Version' => '', + // 'Plugins' => '', + // 'There is no plugin loaded.' => '', + // 'Set maximum column height' => '', + // 'Remove maximum column height' => '', ); diff --git a/app/Locale/de_DE/translations.php b/app/Locale/de_DE/translations.php index 71a1d7eb..361b6d74 100644 --- a/app/Locale/de_DE/translations.php +++ b/app/Locale/de_DE/translations.php @@ -1012,4 +1012,10 @@ return array( // 'Table of contents' => '', // 'Gantt' => '', // 'Help with project permissions' => '', + // 'Author' => '', + // 'Version' => '', + // 'Plugins' => '', + // 'There is no plugin loaded.' => '', + // 'Set maximum column height' => '', + // 'Remove maximum column height' => '', ); diff --git a/app/Locale/es_ES/translations.php b/app/Locale/es_ES/translations.php index 3a80d2fb..0d0f1456 100644 --- a/app/Locale/es_ES/translations.php +++ b/app/Locale/es_ES/translations.php @@ -1012,4 +1012,10 @@ return array( 'Table of contents' => 'Tabla de contenido', 'Gantt' => 'Gantt', 'Help with project permissions' => 'Ayuda con permisos del proyecto', + // 'Author' => '', + // 'Version' => '', + // 'Plugins' => '', + // 'There is no plugin loaded.' => '', + // 'Set maximum column height' => '', + // 'Remove maximum column height' => '', ); diff --git a/app/Locale/fi_FI/translations.php b/app/Locale/fi_FI/translations.php index e8940ba9..3dc02236 100644 --- a/app/Locale/fi_FI/translations.php +++ b/app/Locale/fi_FI/translations.php @@ -1012,4 +1012,10 @@ return array( // 'Table of contents' => '', // 'Gantt' => '', // 'Help with project permissions' => '', + // 'Author' => '', + // 'Version' => '', + // 'Plugins' => '', + // 'There is no plugin loaded.' => '', + // 'Set maximum column height' => '', + // 'Remove maximum column height' => '', ); diff --git a/app/Locale/fr_FR/translations.php b/app/Locale/fr_FR/translations.php index 4c149b9a..368e6917 100644 --- a/app/Locale/fr_FR/translations.php +++ b/app/Locale/fr_FR/translations.php @@ -1014,4 +1014,10 @@ return array( 'Table of contents' => 'Table des matières', 'Gantt' => 'Gantt', 'Help with project permissions' => 'Aide avec les permissions des projets', + 'Author' => 'Auteur', + 'Version' => 'Version', + 'Plugins' => 'Extensions', + 'There is no plugin loaded.' => 'Il n\'y a aucune extension chargée.', + 'Set maximum column height' => 'Définir la hauteur max. des colonnes', + 'Remove maximum column height' => 'Enlever la hauteur max. des colonnes', ); diff --git a/app/Locale/hu_HU/translations.php b/app/Locale/hu_HU/translations.php index 0bb99954..d729c51a 100644 --- a/app/Locale/hu_HU/translations.php +++ b/app/Locale/hu_HU/translations.php @@ -1012,4 +1012,10 @@ return array( // 'Table of contents' => '', // 'Gantt' => '', // 'Help with project permissions' => '', + // 'Author' => '', + // 'Version' => '', + // 'Plugins' => '', + // 'There is no plugin loaded.' => '', + // 'Set maximum column height' => '', + // 'Remove maximum column height' => '', ); diff --git a/app/Locale/id_ID/translations.php b/app/Locale/id_ID/translations.php index 1945e60b..d7042ebc 100644 --- a/app/Locale/id_ID/translations.php +++ b/app/Locale/id_ID/translations.php @@ -1012,4 +1012,10 @@ return array( 'Table of contents' => 'Daftar isi', 'Gantt' => 'Gantt', 'Help with project permissions' => 'Bantuan dengan izin proyek', + // 'Author' => '', + // 'Version' => '', + // 'Plugins' => '', + // 'There is no plugin loaded.' => '', + // 'Set maximum column height' => '', + // 'Remove maximum column height' => '', ); diff --git a/app/Locale/it_IT/translations.php b/app/Locale/it_IT/translations.php index 5d6d33f6..9edeae60 100644 --- a/app/Locale/it_IT/translations.php +++ b/app/Locale/it_IT/translations.php @@ -1012,4 +1012,10 @@ return array( // 'Table of contents' => '', // 'Gantt' => '', // 'Help with project permissions' => '', + // 'Author' => '', + // 'Version' => '', + // 'Plugins' => '', + // 'There is no plugin loaded.' => '', + // 'Set maximum column height' => '', + // 'Remove maximum column height' => '', ); diff --git a/app/Locale/ja_JP/translations.php b/app/Locale/ja_JP/translations.php index b46ec1c4..18fdcd7f 100644 --- a/app/Locale/ja_JP/translations.php +++ b/app/Locale/ja_JP/translations.php @@ -1012,4 +1012,10 @@ return array( // 'Table of contents' => '', // 'Gantt' => '', // 'Help with project permissions' => '', + // 'Author' => '', + // 'Version' => '', + // 'Plugins' => '', + // 'There is no plugin loaded.' => '', + // 'Set maximum column height' => '', + // 'Remove maximum column height' => '', ); diff --git a/app/Locale/nb_NO/translations.php b/app/Locale/nb_NO/translations.php index 8ee800e6..c8425a20 100755 --- a/app/Locale/nb_NO/translations.php +++ b/app/Locale/nb_NO/translations.php @@ -1012,4 +1012,10 @@ return array( 'Table of contents' => 'Innholdsfortegnelse', 'Gantt' => 'Gantt', 'Help with project permissions' => 'Hjelp med prosjekttilganger', + // 'Author' => '', + // 'Version' => '', + // 'Plugins' => '', + // 'There is no plugin loaded.' => '', + // 'Set maximum column height' => '', + // 'Remove maximum column height' => '', ); diff --git a/app/Locale/nl_NL/translations.php b/app/Locale/nl_NL/translations.php index 7c623914..3fd90af8 100644 --- a/app/Locale/nl_NL/translations.php +++ b/app/Locale/nl_NL/translations.php @@ -1012,4 +1012,10 @@ return array( // 'Table of contents' => '', // 'Gantt' => '', // 'Help with project permissions' => '', + // 'Author' => '', + // 'Version' => '', + // 'Plugins' => '', + // 'There is no plugin loaded.' => '', + // 'Set maximum column height' => '', + // 'Remove maximum column height' => '', ); diff --git a/app/Locale/pl_PL/translations.php b/app/Locale/pl_PL/translations.php index e7683d9a..adcfab56 100644 --- a/app/Locale/pl_PL/translations.php +++ b/app/Locale/pl_PL/translations.php @@ -1012,4 +1012,10 @@ return array( // 'Table of contents' => '', // 'Gantt' => '', // 'Help with project permissions' => '', + // 'Author' => '', + // 'Version' => '', + // 'Plugins' => '', + // 'There is no plugin loaded.' => '', + // 'Set maximum column height' => '', + // 'Remove maximum column height' => '', ); diff --git a/app/Locale/pt_BR/translations.php b/app/Locale/pt_BR/translations.php index 57cfe761..9dd005ab 100644 --- a/app/Locale/pt_BR/translations.php +++ b/app/Locale/pt_BR/translations.php @@ -1012,4 +1012,10 @@ return array( 'Table of contents' => 'Índice', 'Gantt' => 'Gantt', 'Help with project permissions' => 'Ajuda com as permissões dos projetos', + // 'Author' => '', + // 'Version' => '', + // 'Plugins' => '', + // 'There is no plugin loaded.' => '', + // 'Set maximum column height' => '', + // 'Remove maximum column height' => '', ); diff --git a/app/Locale/pt_PT/translations.php b/app/Locale/pt_PT/translations.php index cb2fc53e..7e8019d8 100644 --- a/app/Locale/pt_PT/translations.php +++ b/app/Locale/pt_PT/translations.php @@ -1012,4 +1012,10 @@ return array( 'Table of contents' => 'Tabela de conteúdos', 'Gantt' => 'Gantt', 'Help with project permissions' => 'Ajuda com permissões de projecto', + // 'Author' => '', + // 'Version' => '', + // 'Plugins' => '', + // 'There is no plugin loaded.' => '', + // 'Set maximum column height' => '', + // 'Remove maximum column height' => '', ); diff --git a/app/Locale/ru_RU/translations.php b/app/Locale/ru_RU/translations.php index 53303506..e4fce0e1 100644 --- a/app/Locale/ru_RU/translations.php +++ b/app/Locale/ru_RU/translations.php @@ -1012,4 +1012,10 @@ return array( 'Table of contents' => 'Сожержание', 'Gantt' => 'Гантт', 'Help with project permissions' => 'Помощь с правами доступа по проекту', + // 'Author' => '', + // 'Version' => '', + // 'Plugins' => '', + // 'There is no plugin loaded.' => '', + // 'Set maximum column height' => '', + // 'Remove maximum column height' => '', ); diff --git a/app/Locale/sr_Latn_RS/translations.php b/app/Locale/sr_Latn_RS/translations.php index 562b8f22..3bd30e0c 100644 --- a/app/Locale/sr_Latn_RS/translations.php +++ b/app/Locale/sr_Latn_RS/translations.php @@ -1012,4 +1012,10 @@ return array( // 'Table of contents' => '', // 'Gantt' => '', // 'Help with project permissions' => '', + // 'Author' => '', + // 'Version' => '', + // 'Plugins' => '', + // 'There is no plugin loaded.' => '', + // 'Set maximum column height' => '', + // 'Remove maximum column height' => '', ); diff --git a/app/Locale/sv_SE/translations.php b/app/Locale/sv_SE/translations.php index c37759c7..3dce551c 100644 --- a/app/Locale/sv_SE/translations.php +++ b/app/Locale/sv_SE/translations.php @@ -1012,4 +1012,10 @@ return array( // 'Table of contents' => '', // 'Gantt' => '', // 'Help with project permissions' => '', + // 'Author' => '', + // 'Version' => '', + // 'Plugins' => '', + // 'There is no plugin loaded.' => '', + // 'Set maximum column height' => '', + // 'Remove maximum column height' => '', ); diff --git a/app/Locale/th_TH/translations.php b/app/Locale/th_TH/translations.php index 1fdb5d34..1c0a1371 100644 --- a/app/Locale/th_TH/translations.php +++ b/app/Locale/th_TH/translations.php @@ -1012,4 +1012,10 @@ return array( // 'Table of contents' => '', // 'Gantt' => '', // 'Help with project permissions' => '', + // 'Author' => '', + // 'Version' => '', + // 'Plugins' => '', + // 'There is no plugin loaded.' => '', + // 'Set maximum column height' => '', + // 'Remove maximum column height' => '', ); diff --git a/app/Locale/tr_TR/translations.php b/app/Locale/tr_TR/translations.php index 44f973d1..f88e369d 100644 --- a/app/Locale/tr_TR/translations.php +++ b/app/Locale/tr_TR/translations.php @@ -1012,4 +1012,10 @@ return array( // 'Table of contents' => '', // 'Gantt' => '', // 'Help with project permissions' => '', + // 'Author' => '', + // 'Version' => '', + // 'Plugins' => '', + // 'There is no plugin loaded.' => '', + // 'Set maximum column height' => '', + // 'Remove maximum column height' => '', ); diff --git a/app/Locale/zh_CN/translations.php b/app/Locale/zh_CN/translations.php index 5ad5e9c8..c224f825 100644 --- a/app/Locale/zh_CN/translations.php +++ b/app/Locale/zh_CN/translations.php @@ -1012,4 +1012,10 @@ return array( // 'Table of contents' => '', // 'Gantt' => '', // 'Help with project permissions' => '', + // 'Author' => '', + // 'Version' => '', + // 'Plugins' => '', + // 'There is no plugin loaded.' => '', + // 'Set maximum column height' => '', + // 'Remove maximum column height' => '', ); diff --git a/app/Model/Board.php b/app/Model/Board.php index b1032e90..0e2cbaaa 100644 --- a/app/Model/Board.php +++ b/app/Model/Board.php @@ -252,16 +252,24 @@ class Board extends Base $swimlanes[$i]['columns'] = $columns; $swimlanes[$i]['nb_columns'] = $nb_columns; $swimlanes[$i]['nb_tasks'] = 0; + $swimlanes[$i]['nb_swimlanes'] = $ilen; for ($j = 0; $j < $nb_columns; $j++) { $column_id = $columns[$j]['id']; $swimlane_id = $swimlanes[$i]['id']; + if (! isset($swimlanes[0]['columns'][$j]['nb_column_tasks'])) { + $swimlanes[0]['columns'][$j]['nb_column_tasks'] = 0; + $swimlanes[0]['columns'][$j]['total_score'] = 0; + } + $swimlanes[$i]['columns'][$j]['tasks'] = $callback === null ? $this->taskFinder->getTasksByColumnAndSwimlane($project_id, $column_id, $swimlane_id) : $callback($project_id, $column_id, $swimlane_id); $swimlanes[$i]['columns'][$j]['nb_tasks'] = count($swimlanes[$i]['columns'][$j]['tasks']); $swimlanes[$i]['columns'][$j]['score'] = $this->getColumnSum($swimlanes[$i]['columns'][$j]['tasks'], 'score'); $swimlanes[$i]['nb_tasks'] += $swimlanes[$i]['columns'][$j]['nb_tasks']; + $swimlanes[0]['columns'][$j]['nb_column_tasks'] += $swimlanes[$i]['columns'][$j]['nb_tasks']; + $swimlanes[0]['columns'][$j]['total_score'] += $swimlanes[$i]['columns'][$j]['score']; } } diff --git a/app/ServiceProvider/ClassProvider.php b/app/ServiceProvider/ClassProvider.php index 78a089ee..a89b78bb 100644 --- a/app/ServiceProvider/ClassProvider.php +++ b/app/ServiceProvider/ClassProvider.php @@ -2,6 +2,7 @@ namespace ServiceProvider; +use Core\Plugin\Loader; use Core\ObjectStorage\FileStorage; use Core\Paginator; use Core\OAuth2; @@ -117,5 +118,7 @@ class ClassProvider implements ServiceProviderInterface $container['objectStorage'] = function() { return new FileStorage(FILES_DIR); }; + + $container['pluginLoader'] = new Loader($container); } } diff --git a/app/Template/board/table_column.php b/app/Template/board/table_column.php new file mode 100644 index 00000000..da8db52d --- /dev/null +++ b/app/Template/board/table_column.php @@ -0,0 +1,51 @@ +<!-- column titles --> +<?php ?> +<tr> + <?php foreach ($swimlane['columns'] as $column): ?> + <th class="board-column-header board-column-header-<?= $column['id'] ?>" data-column-id="<?= $column['id'] ?>"> + + <!-- column in collapsed mode --> + <div class="board-column-collapsed"> + <span title="<?= t('Task count') ?>" class="board-column-header-task-count" title="<?= t('Show this column') ?>"> + <span id="task-number-column-<?= $column['id'] ?>"><?= $column['nb_column_tasks'] ?></span> + </span> + </div> + + <!-- column in expanded mode --> + <div class="board-column-expanded"> + <?php if (! $not_editable): ?> + <div class="board-add-icon"> + <?= $this->url->link('+', 'taskcreation', 'create', array('project_id' => $column['project_id'], 'column_id' => $column['id'], 'swimlane_id' => $swimlane['id']), false, 'popover', t('Add a new task')) ?> + </div> + <?php endif ?> + + <span class="board-column-title" data-column-id="<?= $column['id'] ?>" title="<?= t('Hide this column') ?>"> + <?= $this->e($column['title']) ?> + </span> + + <?php if (! $not_editable && ! empty($column['description'])): ?> + <span class="tooltip pull-right" title='<?= $this->e($this->text->markdown($column['description'])) ?>'> + <i class="fa fa-info-circle"></i> + </span> + <?php endif ?> + + <?php if (! empty($column['score'])): ?> + <span class="pull-right" title="<?= t('Score') ?>"> + <?= $column['total_score'] ?> + </span> + <?php endif ?> + + <span title="<?= t('Total number of tasks in this column across all swimlanes') ?>" class="board-column-header-task-count"> + (<span id="task-number-column-<?= $column['id'] ?>"><?= $column['nb_column_tasks'] ?></span>) + </span> + + <?php if ($column['task_limit']): ?> + <span title="<?= t('Task limit') ?>"> + (<span id="task-number-column-<?= $column['id'] ?>"><?= $this->e($column['task_limit']) ?></span>) + </span> + <?php endif ?> + </div> + + </th> + <?php endforeach ?> +</tr> diff --git a/app/Template/board/table_container.php b/app/Template/board/table_container.php index 98b40eb4..83587c44 100644 --- a/app/Template/board/table_container.php +++ b/app/Template/board/table_container.php @@ -13,18 +13,37 @@ > <?php endif ?> - <?php foreach ($swimlanes as $swimlane): ?> + <?php foreach ($swimlanes as $index => $swimlane): ?> <?php if (empty($swimlane['columns'])): ?> <p class="alert alert-error"><?= t('There is no column in your project!') ?></p> <?php break ?> <?php else: ?> - <?= $this->render('board/table_swimlane', array( - 'project' => $project, - 'swimlane' => $swimlane, - 'board_highlight_period' => $board_highlight_period, - 'hide_swimlane' => count($swimlanes) === 1, - 'not_editable' => isset($not_editable), - )) ?> + <?php if ($index === 0): ?> + <?= $this->render('board/table_column', array( + 'swimlane' => $swimlane, + 'not_editable' => isset($not_editable), + )) ?> + <?php endif ?> + + <?php if (! ($swimlane['nb_tasks'] === 0 && isset($not_editable))): ?> + + <?php if ($swimlane['nb_swimlanes'] > 1): ?> + <?= $this->render('board/table_swimlane', array( + 'project' => $project, + 'swimlane' => $swimlane, + 'not_editable' => isset($not_editable), + )) ?> + <?php endif ?> + + <?= $this->render('board/table_tasks', array( + 'project' => $project, + 'swimlane' => $swimlane, + 'not_editable' => isset($not_editable), + 'board_highlight_period' => $board_highlight_period, + )) ?> + + <?php endif ?> + <?php endif ?> <?php endforeach ?> </table> diff --git a/app/Template/board/table_swimlane.php b/app/Template/board/table_swimlane.php index 1caa920d..dd38fc97 100644 --- a/app/Template/board/table_swimlane.php +++ b/app/Template/board/table_swimlane.php @@ -1,104 +1,26 @@ +<!-- swimlane --> <tr id="swimlane-<?= $swimlane['id'] ?>"> - <!-- swimlane toggle --> - <?php if (! $hide_swimlane): ?> - <th class="board-swimlane-header"> - <?php if (! $not_editable): ?> - <a href="#" class="board-swimlane-toggle" data-swimlane-id="<?= $swimlane['id'] ?>"> - <i class="fa fa-minus-circle hide-icon-swimlane-<?= $swimlane['id'] ?>"></i> - <i class="fa fa-plus-circle show-icon-swimlane-<?= $swimlane['id'] ?>" style="display: none"></i> - </a> - - <?php if (! empty($swimlane['description'])): ?> - <span - title="<?= t('Description') ?>" - class="tooltip" - data-href="<?= $this->url->href('board', 'swimlane', array('swimlane_id' => $swimlane['id'], 'project_id' => $project['id'])) ?>"> - <i class="fa fa-info-circle"></i> - </span> - <?php endif ?> - - <span title="<?= t('Task count') ?>" class="board-column-header-task-count swimlane-task-count-<?= $swimlane['id'] ?>"> - (<?= $swimlane['nb_tasks'] ?>) - </span> - - <span class="board-swimlane-toggle-title show-icon-swimlane-<?= $swimlane['id'] ?>"><?= $this->e($swimlane['name']) ?></span> - <?php endif ?> - </th> - <?php endif ?> - - <!-- column header title --> - <?php foreach ($swimlane['columns'] as $column): ?> - <th class="board-column-header board-column-header-<?= $column['id'] ?>" data-column-id="<?= $column['id'] ?>"> - <div class="board-column-collapsed"> - <span title="<?= t('Task count') ?>" class="board-column-header-task-count" title="<?= t('Show this column') ?>"> - <span id="task-number-column-<?= $column['id'] ?>"><?= $column['nb_tasks'] ?></span> - </span> - </div> - <div class="board-column-expanded"> - <?php if (! $not_editable): ?> - <div class="board-add-icon"> - <?= $this->url->link('+', 'taskcreation', 'create', array('project_id' => $column['project_id'], 'column_id' => $column['id'], 'swimlane_id' => $swimlane['id']), false, 'popover', t('Add a new task')) ?> - </div> - <?php endif ?> - - <span class="board-column-title" data-column-id="<?= $column['id'] ?>" title="<?= t('Hide this column') ?>"> - <?= $this->e($column['title']) ?> + <th class="board-swimlane-header" colspan="<?= $swimlane['nb_columns'] ?>"> + <?php if (! $not_editable): ?> + <a href="#" class="board-swimlane-toggle" data-swimlane-id="<?= $swimlane['id'] ?>"> + <i class="fa fa-chevron-circle-up hide-icon-swimlane-<?= $swimlane['id'] ?>" title="<?= t('Collapse swimlane') ?>"></i> + <i class="fa fa-chevron-circle-down show-icon-swimlane-<?= $swimlane['id'] ?>" title="<?= t('Expand swimlane') ?>" style="display: none"></i> + </a> + <?php endif ?> + + <?= $this->e($swimlane['name']) ?> + + <?php if (! $not_editable && ! empty($swimlane['description'])): ?> + <span + title="<?= t('Description') ?>" + class="tooltip" + data-href="<?= $this->url->href('board', 'swimlane', array('swimlane_id' => $swimlane['id'], 'project_id' => $project['id'])) ?>"> + <i class="fa fa-info-circle"></i> </span> + <?php endif ?> - <?php if (! $not_editable && ! empty($column['description'])): ?> - <span class="tooltip pull-right" title='<?= $this->e($this->text->markdown($column['description'])) ?>'> - <i class="fa fa-info-circle"></i> - </span> - <?php endif ?> - - <?php if (! empty($column['score'])): ?> - <span class="pull-right" title="<?= t('Score') ?>"> - <?= $column['score'] ?> - </span> - <?php endif ?> - - <?php if ($column['task_limit']): ?> - <span title="<?= t('Task limit') ?>"> - (<span id="task-number-column-<?= $column['id'] ?>"><?= $column['nb_tasks'] ?></span>/<?= $this->e($column['task_limit']) ?>) - </span> - <?php else: ?> - <span title="<?= t('Task count') ?>" class="board-column-header-task-count"> - (<span id="task-number-column-<?= $column['id'] ?>"><?= $column['nb_tasks'] ?></span>) - </span> - <?php endif ?> - </div> + <span title="<?= t('Task count') ?>" class="board-column-header-task-count swimlane-task-count-<?= $swimlane['id'] ?>"> + (<?= $swimlane['nb_tasks'] ?>) + </span> </th> - <?php endforeach ?> </tr> -<tr class="board-swimlane swimlane-row-<?= $swimlane['id'] ?>"> - - <!-- swimlane title --> - <?php if (! $hide_swimlane): ?> - <th class="board-swimlane-title"> - <?= $this->e($swimlane['name']) ?> - </th> - <?php endif ?> - - <!-- task list --> - <?php foreach ($swimlane['columns'] as $column): ?> - <td class="board-column-<?= $column['id'] ?> <?= $column['task_limit'] && $column['nb_tasks'] > $column['task_limit'] ? 'board-task-list-limit' : '' ?>"> - <div class="board-task-list board-column-expanded" data-column-id="<?= $column['id'] ?>" data-swimlane-id="<?= $swimlane['id'] ?>" data-task-limit="<?= $column['task_limit'] ?>"> - <?php foreach ($column['tasks'] as $task): ?> - <?= $this->render($not_editable ? 'board/task_public' : 'board/task_private', array( - 'project' => $project, - 'task' => $task, - 'board_highlight_period' => $board_highlight_period, - 'not_editable' => $not_editable, - )) ?> - <?php endforeach ?> - </div> - <div class="board-column-collapsed"> - <div class="board-rotation-wrapper"> - <div class="board-column-title board-rotation" data-column-id="<?= $column['id'] ?>" title="<?= t('Show this column') ?>"> - <?= $this->e($column['title']) ?> - </div> - </div> - </div> - </td> - <?php endforeach ?> -</tr>
\ No newline at end of file diff --git a/app/Template/board/table_tasks.php b/app/Template/board/table_tasks.php new file mode 100644 index 00000000..edb4d323 --- /dev/null +++ b/app/Template/board/table_tasks.php @@ -0,0 +1,31 @@ +<!-- task row --> +<tr class="board-swimlane swimlane-row-<?= $swimlane['id'] ?>"> + <?php foreach ($swimlane['columns'] as $column): ?> + <td class=" + board-column-<?= $column['id'] ?> + <?= $column['task_limit'] > 0 && $column['nb_tasks'] > $column['task_limit'] ? 'board-task-list-limit' : '' ?> + "> + + <!-- tasks list --> + <div class="board-task-list board-column-expanded" data-column-id="<?= $column['id'] ?>" data-swimlane-id="<?= $swimlane['id'] ?>" data-task-limit="<?= $column['task_limit'] ?>"> + <?php foreach ($column['tasks'] as $task): ?> + <?= $this->render($not_editable ? 'board/task_public' : 'board/task_private', array( + 'project' => $project, + 'task' => $task, + 'board_highlight_period' => $board_highlight_period, + 'not_editable' => $not_editable, + )) ?> + <?php endforeach ?> + </div> + + <!-- column in collapsed mode (rotated text) --> + <div class="board-column-collapsed"> + <div class="board-rotation-wrapper"> + <div class="board-column-title board-rotation" data-column-id="<?= $column['id'] ?>" title="<?= t('Show this column') ?>"> + <i class="fa fa-chevron-circle-up tooltip" title="<?= $this->e($column['title']) ?>"></i> <?= $this->e($column['title']) ?> + </div> + </div> + </div> + </td> + <?php endforeach ?> +</tr> diff --git a/app/Template/board/task_menu.php b/app/Template/board/task_menu.php index 1434a1a0..3eb35705 100644 --- a/app/Template/board/task_menu.php +++ b/app/Template/board/task_menu.php @@ -8,6 +8,10 @@ <li><i class="fa fa-comment-o fa-fw"></i> <?= $this->url->link(t('Add a comment'), 'comment', 'create', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'popover') ?></li> <li><i class="fa fa-code-fork fa-fw"></i> <?= $this->url->link(t('Add a link'), 'tasklink', 'create', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'popover') ?></li> <li><i class="fa fa-camera fa-fw"></i> <?= $this->url->link(t('Add a screenshot'), 'board', 'screenshot', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'popover') ?></li> - <li><i class="fa fa-close fa-fw"></i> <?= $this->url->link(t('Close this task'), 'taskstatus', 'close', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'redirect' => 'board'), false, 'popover') ?></li> + <?php if ($task['is_active'] == 1): ?> + <li><i class="fa fa-close fa-fw"></i> <?= $this->url->link(t('Close this task'), 'taskstatus', 'close', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'redirect' => 'board'), false, 'popover') ?></li> + <?php else: ?> + <li><i class="fa fa-check-square-o fa-fw"></i> <?= $this->url->link(t('Open this task'), 'taskstatus', 'open', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'redirect' => 'board'), false, 'popover') ?></li> + <?php endif ?> </ul> </span>
\ No newline at end of file diff --git a/app/Template/board/task_private.php b/app/Template/board/task_private.php index a6c8a9e1..da993fdd 100644 --- a/app/Template/board/task_private.php +++ b/app/Template/board/task_private.php @@ -9,10 +9,11 @@ data-task-url="<?= $this->url->href('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>"> <div class="task-board-sort-handle" style="display: none;"><i class="fa fa-arrows-alt"></i></div> - <?= $this->render('board/task_menu', array('task' => $task)) ?> - <?php if ($this->board->isCollapsed($project['id'])): ?> + <?php if ($this->board->isCollapsed($task['project_id'])): ?> <div class="task-board-collapsed"> + <?= $this->render('board/task_menu', array('task' => $task)) ?> + <?php if (! empty($task['assignee_username'])): ?> <span title="<?= $this->e($task['assignee_name'] ?: $task['assignee_username']) ?>"> <?= $this->e($this->user->getInitials($task['assignee_name'] ?: $task['assignee_username'])) ?> @@ -22,6 +23,7 @@ </div> <?php else: ?> <div class="task-board-expanded"> + <?= $this->render('board/task_menu', array('task' => $task)) ?> <?php if ($task['reference']): ?> <span class="task-board-reference" title="<?= t('Reference') ?>"> @@ -29,9 +31,10 @@ </span> <?php endif ?> + <?php if (! empty($task['owner_id'])): ?> <span class="task-board-user <?= $this->user->isCurrentUser($task['owner_id']) ? 'task-board-current-user' : '' ?>"> <?= $this->url->link( - (! empty($task['owner_id']) ? ($task['assignee_name'] ?: $task['assignee_username']) : t('Nobody assigned')), + $task['assignee_name'] ?: $task['assignee_username'], 'board', 'changeAssignee', array('task_id' => $task['id'], 'project_id' => $task['project_id']), @@ -40,6 +43,7 @@ t('Change assignee') ) ?> </span> + <?php endif ?> <?php if ($task['is_active'] == 1): ?> <div class="task-board-days"> diff --git a/app/Template/board/private_view.php b/app/Template/board/view_private.php index d4c2c651..d4c2c651 100644 --- a/app/Template/board/private_view.php +++ b/app/Template/board/view_private.php diff --git a/app/Template/board/public_view.php b/app/Template/board/view_public.php index aea72031..aea72031 100644 --- a/app/Template/board/public_view.php +++ b/app/Template/board/view_public.php diff --git a/app/Template/config/plugins.php b/app/Template/config/plugins.php new file mode 100644 index 00000000..fea48d58 --- /dev/null +++ b/app/Template/config/plugins.php @@ -0,0 +1,30 @@ +<div class="page-header"> + <h2><?= t('Plugins') ?></h2> +</div> + +<?php if (empty($plugins)): ?> + <p class="alert"><?= t('There is no plugin loaded.') ?></p> +<?php else: ?> + <table class="table-stripped"> + <tr> + <th class="column-20"><?= t('Name') ?></th> + <th class="column-20"><?= t('Author') ?></th> + <th class="column-10"><?= t('Version') ?></th> + <th><?= t('Description') ?></th> + </tr> + + <?php foreach($plugins as $plugin): ?> + <tr> + <td> + <?php if ($plugin->getPluginHomepage()): ?> + <a href="<?= $plugin->getPluginHomepage() ?>" target="_blank" rel="noreferrer"><?= $this->e($plugin->getPluginName()) ?></a> + <?php else: ?> + <?= $this->e($plugin->getPluginName()) ?> + <?php endif ?> + </td> + <td><?= $this->e($plugin->getPluginAuthor()) ?></td> + <td><?= $this->e($plugin->getPluginVersion()) ?></td> + <td><?= $this->e($plugin->getPluginDescription()) ?></td> + </tr> + <?php endforeach ?> +<?php endif ?>
\ No newline at end of file diff --git a/app/Template/config/sidebar.php b/app/Template/config/sidebar.php index ed4f01e7..4195cde1 100644 --- a/app/Template/config/sidebar.php +++ b/app/Template/config/sidebar.php @@ -4,6 +4,9 @@ <li <?= $this->app->getRouterAction() === 'index' ? 'class="active"' : '' ?>> <?= $this->url->link(t('About'), 'config', 'index') ?> </li> + <li <?= $this->app->getRouterAction() === 'plugins' ? 'class="active"' : '' ?>> + <?= $this->url->link(t('Plugins'), 'config', 'plugins') ?> + </li> <li <?= $this->app->getRouterAction() === 'application' ? 'class="active"' : '' ?>> <?= $this->url->link(t('Application settings'), 'config', 'application') ?> </li> diff --git a/app/Template/project/filters.php b/app/Template/project/filters.php index fa50b36a..5b9ac472 100644 --- a/app/Template/project/filters.php +++ b/app/Template/project/filters.php @@ -21,6 +21,14 @@ <i class="fa fa-arrows-h fa-fw"></i> <a href="#" class="filter-toggle-scrolling" title="<?= t('Keyboard shortcut: "%s"', 'c') ?>"><?= t('Horizontal scrolling') ?></a> </span> </li> + <li> + <span class="filter-max-height" style="display: none"> + <i class="fa fa-arrows-v fa-fw"></i> <a href="#" class="filter-toggle-height"><?= t('Set maximum column height') ?></a> + </span> + <span class="filter-min-height"> + <i class="fa fa-arrows-v fa-fw"></i> <a href="#" class="filter-toggle-height"><?= t('Remove maximum column height') ?></a> + </span> + </li> <?php endif ?> <?= $this->render('project/dropdown', array('project' => $project)) ?> </ul> @@ -59,10 +67,9 @@ <div class="dropdown filters"> <i class="fa fa-caret-down"></i> <a href="#" class="dropdown-menu"><?= t('Users') ?></a> <ul> - <li><a href="#" class="filter-helper" data-filter="status:open"><?= t('All users') ?></a></li> - <li><a href="#" class="filter-helper" data-filter="status:open assignee:nobody"><?= t('Not assigned') ?></a></li> + <li><a href="#" class="filter-helper" data-append-filter="assignee:nobody"><?= t('Not assigned') ?></a></li> <?php foreach ($users_list as $user): ?> - <li><a href="#" class="filter-helper" data-filter='status:open assignee:"<?= $this->e($user) ?>"'><?= $this->e($user) ?></a></li> + <li><a href="#" class="filter-helper" data-append-filter='assignee:"<?= $this->e($user) ?>"'><?= $this->e($user) ?></a></li> <?php endforeach ?> </ul> </div> @@ -72,10 +79,9 @@ <div class="dropdown filters"> <i class="fa fa-caret-down"></i> <a href="#" class="dropdown-menu"><?= t('Categories') ?></a> <ul> - <li><a href="#" class="filter-helper" data-filter="status:open"><?= t('All categories') ?></a></li> - <li><a href="#" class="filter-helper" data-filter="status:open category:none"><?= t('No category') ?></a></li> + <li><a href="#" class="filter-helper" data-append-filter="category:none"><?= t('No category') ?></a></li> <?php foreach ($categories_list as $category): ?> - <li><a href="#" class="filter-helper" data-filter='status:open category:"<?= $this->e($category) ?>"'><?= $this->e($category) ?></a></li> + <li><a href="#" class="filter-helper" data-append-filter='category:"<?= $this->e($category) ?>"'><?= $this->e($category) ?></a></li> <?php endforeach ?> </ul> </div> diff --git a/app/Template/swimlane/index.php b/app/Template/swimlane/index.php index 797d2ca2..41ba788b 100644 --- a/app/Template/swimlane/index.php +++ b/app/Template/swimlane/index.php @@ -50,7 +50,7 @@ <?= $this->form->hidden('id', $default_swimlane) ?> <?= $this->form->label(t('Rename'), 'default_swimlane') ?> - <?= $this->form->text('default_swimlane', $default_swimlane, array(), array('autofocus', 'required', 'maxlength="50"')) ?><br/> + <?= $this->form->text('default_swimlane', $default_swimlane, array(), array('required', 'maxlength="50"')) ?><br/> <?= $this->form->checkbox('show_default_swimlane', t('Show default swimlane'), 1, isset($default_swimlane['show_default_swimlane']) && $default_swimlane['show_default_swimlane'] == 1) ?> diff --git a/app/Template/task_status/close.php b/app/Template/task_status/close.php index 4de3dcb2..d32863bd 100644 --- a/app/Template/task_status/close.php +++ b/app/Template/task_status/close.php @@ -4,7 +4,7 @@ <div class="confirm"> <p class="alert alert-info"> - <?= t('Do you really want to close the task "%s" as well as all subtasks?', $this->e($task['title'])) ?> + <?= t('Do you really want to close the task "%s" as well as all subtasks?', $task['title']) ?> </p> <div class="form-actions"> diff --git a/app/Template/task_status/open.php b/app/Template/task_status/open.php index 0043fdae..615b2464 100644 --- a/app/Template/task_status/open.php +++ b/app/Template/task_status/open.php @@ -4,12 +4,12 @@ <div class="confirm"> <p class="alert alert-info"> - <?= t('Do you really want to open this task: "%s"?', $this->e($task['title'])) ?> + <?= t('Do you really want to open this task: "%s"?', $task['title']) ?> </p> <div class="form-actions"> - <?= $this->url->link(t('Yes'), 'taskstatus', 'open', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'confirmation' => 'yes'), true, 'btn btn-red') ?> + <?= $this->url->link(t('Yes'), 'taskstatus', 'open', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'confirmation' => 'yes', 'redirect' => $redirect), true, 'btn btn-red') ?> <?= t('or') ?> - <?= $this->url->link(t('cancel'), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?> + <?= $this->url->link(t('cancel'), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?> </div> </div>
\ No newline at end of file diff --git a/app/common.php b/app/common.php index dcd571bc..e63d82bb 100644 --- a/app/common.php +++ b/app/common.php @@ -33,5 +33,4 @@ if (ENABLE_URL_REWRITE) { require __DIR__.'/routes.php'; } -$plugin = new Core\Plugin\Loader($container); -$plugin->scan(); +$container['pluginLoader']->scan(); |