diff options
Diffstat (limited to 'app')
59 files changed, 745 insertions, 314 deletions
diff --git a/app/Action/TaskAssignColorSwimlane.php b/app/Action/TaskAssignColorSwimlane.php new file mode 100644 index 00000000..31f2d25a --- /dev/null +++ b/app/Action/TaskAssignColorSwimlane.php @@ -0,0 +1,99 @@ +<?php + +namespace Kanboard\Action; + +use Kanboard\Model\TaskModel; + +/** + * Assign a color to a task based on Swimlane + * + * @package Kanboard\Action + * @author Dave Almond + */ +class TaskAssignColorSwimlane extends Base +{ + /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Assign a color when the task is moved to a specific swimlane'); + } + + /** + * Get the list of compatible events + * + * @access public + * @return array + */ + public function getCompatibleEvents() + { + return array( + TaskModel::EVENT_CREATE, + TaskModel::EVENT_MOVE_SWIMLANE, + ); + } + + /** + * Get the required parameter for the action (defined by the user) + * + * @access public + * @return array + */ + public function getActionRequiredParameters() + { + return array( + 'swimlane_id' => t('Swimlane'), + 'color_id' => t('Color'), + ); + } + + /** + * Get the required parameter for the event + * + * @access public + * @return string[] + */ + public function getEventRequiredParameters() + { + return array( + 'task_id', + 'task' => array( + 'project_id', + 'swimlane_id', + ), + ); + } + + /** + * Execute the action (set the task color) + * + * @access public + * @param array $data Event data dictionary + * @return bool True if the action was executed or false when not executed + */ + public function doAction(array $data) + { + $values = array( + 'id' => $data['task_id'], + 'color_id' => $this->getParam('color_id'), + ); + + return $this->taskModificationModel->update($values, false); + } + + /** + * Check if the event data meet the action condition + * + * @access public + * @param array $data Event data dictionary + * @return bool + */ + public function hasRequiredCondition(array $data) + { + return $data['task']['swimlane_id'] == $this->getParam('swimlane_id'); + } +} diff --git a/app/Action/TaskAssignPrioritySwimlane.php b/app/Action/TaskAssignPrioritySwimlane.php new file mode 100644 index 00000000..7eaca7c8 --- /dev/null +++ b/app/Action/TaskAssignPrioritySwimlane.php @@ -0,0 +1,99 @@ +<?php + +namespace Kanboard\Action; + +use Kanboard\Model\TaskModel; + +/** + * Set a priority automatically according to the Swimlane + * + * @package Kanboard\Action + * @author Dave Almond + */ +class TaskAssignPrioritySwimlane extends Base +{ + /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Assign a priority when the task is moved to a specific swimlane'); + } + + /** + * Get the list of compatible events + * + * @access public + * @return array + */ + public function getCompatibleEvents() + { + return array( + TaskModel::EVENT_CREATE, + TaskModel::EVENT_MOVE_SWIMLANE, + ); + } + + /** + * Get the required parameter for the action (defined by the user) + * + * @access public + * @return array + */ + public function getActionRequiredParameters() + { + return array( + 'swimlane_id' => t('Swimlane'), + 'priority' => t('Priority'), + ); + } + + /** + * Get the required parameter for the event + * + * @access public + * @return string[] + */ + public function getEventRequiredParameters() + { + return array( + 'task_id', + 'task' => array( + 'project_id', + 'swimlane_id', + ), + ); + } + + /** + * Execute the action (set the priority) + * + * @access public + * @param array $data Event data dictionary + * @return bool True if the action was executed or false when not executed + */ + public function doAction(array $data) + { + $values = array( + 'id' => $data['task_id'], + 'priority' => $this->getParam('priority'), + ); + + return $this->taskModificationModel->update($values); + } + + /** + * Check if the event data meet the action condition + * + * @access public + * @param array $data Event data dictionary + * @return bool + */ + public function hasRequiredCondition(array $data) + { + return $data['task']['swimlane_id'] == $this->getParam('swimlane_id'); + } +} diff --git a/app/Controller/ActionController.php b/app/Controller/ActionController.php index 097640f6..c935125a 100644 --- a/app/Controller/ActionController.php +++ b/app/Controller/ActionController.php @@ -33,6 +33,7 @@ class ActionController extends BaseController 'colors_list' => $this->colorModel->getList(), 'categories_list' => $this->categoryModel->getList($project['id']), 'links_list' => $this->linkModel->getList(0, false), + 'swimlane_list' => $this->swimlaneModel->getList($project['id']), 'title' => t('Automatic actions') ))); } diff --git a/app/Controller/ActionCreationController.php b/app/Controller/ActionCreationController.php index 9b228f28..1629e68f 100644 --- a/app/Controller/ActionCreationController.php +++ b/app/Controller/ActionCreationController.php @@ -84,6 +84,7 @@ class ActionCreationController extends BaseController 'priorities_list' => $this->projectTaskPriorityModel->getPriorities($project), 'project' => $project, 'available_actions' => $this->actionManager->getAvailableActions(), + 'swimlane_list' => $this->swimlaneModel->getList($project['id']), 'events' => $this->actionManager->getCompatibleEvents($values['action_name']), ))); } diff --git a/app/Controller/BoardAjaxController.php b/app/Controller/BoardAjaxController.php index 9b721f06..ccd47667 100644 --- a/app/Controller/BoardAjaxController.php +++ b/app/Controller/BoardAjaxController.php @@ -4,6 +4,7 @@ namespace Kanboard\Controller; use Kanboard\Core\Controller\AccessForbiddenException; use Kanboard\Formatter\BoardFormatter; +use Kanboard\Model\UserMetadataModel; /** * Class BoardAjaxController @@ -88,7 +89,7 @@ class BoardAjaxController extends BaseController */ public function collapse() { - $this->changeDisplayMode(true); + $this->changeDisplayMode(1); } /** @@ -98,19 +99,19 @@ class BoardAjaxController extends BaseController */ public function expand() { - $this->changeDisplayMode(false); + $this->changeDisplayMode(0); } /** * Change display mode * * @access private - * @param boolean $mode + * @param int $mode */ private function changeDisplayMode($mode) { $project_id = $this->request->getIntegerParam('project_id'); - $this->userSession->setBoardDisplayMode($project_id, $mode); + $this->userMetadataCacheDecorator->set(UserMetadataModel::KEY_BOARD_COLLAPSED.$project_id, $mode); if ($this->request->isAjax()) { $this->response->html($this->renderBoard($project_id)); diff --git a/app/Controller/BoardTooltipController.php b/app/Controller/BoardTooltipController.php index 134d728e..79b9b509 100644 --- a/app/Controller/BoardTooltipController.php +++ b/app/Controller/BoardTooltipController.php @@ -2,6 +2,8 @@ namespace Kanboard\Controller; +use Kanboard\Model\UserMetadataModel; + /** * Board Tooltip * @@ -75,10 +77,11 @@ class BoardTooltipController extends BaseController public function comments() { $task = $this->getTask(); + $commentSortingDirection = $this->userMetadataCacheDecorator->get(UserMetadataModel::KEY_COMMENT_SORTING_DIRECTION, 'ASC'); $this->response->html($this->template->render('board/tooltip_comments', array( 'task' => $task, - 'comments' => $this->commentModel->getAll($task['id'], $this->userSession->getCommentSorting()) + 'comments' => $this->commentModel->getAll($task['id'], $commentSortingDirection) ))); } diff --git a/app/Controller/CommentController.php b/app/Controller/CommentController.php index 2a8c258a..c61a0602 100644 --- a/app/Controller/CommentController.php +++ b/app/Controller/CommentController.php @@ -4,6 +4,7 @@ namespace Kanboard\Controller; use Kanboard\Core\Controller\AccessForbiddenException; use Kanboard\Core\Controller\PageNotFoundException; +use Kanboard\Model\UserMetadataModel; /** * Comment Controller @@ -82,10 +83,10 @@ class CommentController extends BaseController $this->flash->failure(t('Unable to create your comment.')); } - return $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), 'comments'), true); + $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), 'comments'), true); + } else { + $this->create($values, $errors); } - - return $this->create($values, $errors); } /** @@ -183,9 +184,16 @@ class CommentController extends BaseController { $task = $this->getTask(); - $order = $this->userSession->getCommentSorting() === 'ASC' ? 'DESC' : 'ASC'; - $this->userSession->setCommentSorting($order); + $oldDirection = $this->userMetadataCacheDecorator->get(UserMetadataModel::KEY_COMMENT_SORTING_DIRECTION, 'ASC'); + $newDirection = $oldDirection === 'ASC' ? 'DESC' : 'ASC'; - $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), 'comments')); + $this->userMetadataCacheDecorator->set(UserMetadataModel::KEY_COMMENT_SORTING_DIRECTION, $newDirection); + + $this->response->redirect($this->helper->url->to( + 'TaskViewController', + 'show', + array('task_id' => $task['id'], 'project_id' => $task['project_id']), + 'comments' + )); } } diff --git a/app/Controller/TaskViewController.php b/app/Controller/TaskViewController.php index 36597457..31b9de11 100644 --- a/app/Controller/TaskViewController.php +++ b/app/Controller/TaskViewController.php @@ -4,6 +4,7 @@ namespace Kanboard\Controller; use Kanboard\Core\Controller\AccessForbiddenException; use Kanboard\Core\Controller\PageNotFoundException; +use Kanboard\Model\UserMetadataModel; /** * Task Controller @@ -61,13 +62,14 @@ class TaskViewController extends BaseController { $task = $this->getTask(); $subtasks = $this->subtaskModel->getAll($task['id']); + $commentSortingDirection = $this->userMetadataCacheDecorator->get(UserMetadataModel::KEY_COMMENT_SORTING_DIRECTION, 'ASC'); $this->response->html($this->helper->layout->task('task/show', array( 'task' => $task, 'project' => $this->projectModel->getById($task['project_id']), 'files' => $this->taskFileModel->getAllDocuments($task['id']), 'images' => $this->taskFileModel->getAllImages($task['id']), - 'comments' => $this->commentModel->getAll($task['id'], $this->userSession->getCommentSorting()), + 'comments' => $this->commentModel->getAll($task['id'], $commentSortingDirection), 'subtasks' => $subtasks, 'internal_links' => $this->taskLinkModel->getAllGroupedByLabel($task['id']), 'external_links' => $this->taskExternalLinkModel->getAll($task['id']), diff --git a/app/Controller/UserCredentialController.php b/app/Controller/UserCredentialController.php index 4021dc37..98fe967d 100644 --- a/app/Controller/UserCredentialController.php +++ b/app/Controller/UserCredentialController.php @@ -106,4 +106,21 @@ class UserCredentialController extends BaseController return $this->changeAuthentication($values, $errors); } + + /** + * Unlock user + */ + public function unlock() + { + $user = $this->getUser(); + $this->checkCSRFParam(); + + if ($this->userLockingModel->resetFailedLogin($user['username'])) { + $this->flash->success(t('User unlocked successfully.')); + } else { + $this->flash->failure(t('Unable to unlock the user.')); + } + + $this->response->redirect($this->helper->url->to('UserViewController', 'show', array('user_id' => $user['id']))); + } } diff --git a/app/Core/Base.php b/app/Core/Base.php index 68604785..3b7c5e66 100644 --- a/app/Core/Base.php +++ b/app/Core/Base.php @@ -18,6 +18,7 @@ use Pimple\Container; * @property \Kanboard\Core\Action\ActionManager $actionManager * @property \Kanboard\Core\ExternalLink\ExternalLinkManager $externalLinkManager * @property \Kanboard\Core\Cache\MemoryCache $memoryCache + * @property \Kanboard\Core\Cache\BaseCache $cacheDriver * @property \Kanboard\Core\Event\EventManager $eventManager * @property \Kanboard\Core\Group\GroupManager $groupManager * @property \Kanboard\Core\Http\Client $httpClient @@ -55,6 +56,7 @@ use Pimple\Container; * @property \Kanboard\Core\Helper $helper * @property \Kanboard\Core\Paginator $paginator * @property \Kanboard\Core\Template $template + * @property \Kanboard\Decorator\MetadataCacheDecorator $userMetadataCacheDecorator * @property \Kanboard\Model\ActionModel $actionModel * @property \Kanboard\Model\ActionParameterModel $actionParameterModel * @property \Kanboard\Model\AvatarFileModel $avatarFileModel diff --git a/app/Core/Cache/Base.php b/app/Core/Cache/BaseCache.php index d62b8507..b51c4c0c 100644 --- a/app/Core/Cache/Base.php +++ b/app/Core/Cache/BaseCache.php @@ -3,12 +3,12 @@ namespace Kanboard\Core\Cache; /** - * Base class for cache drivers + * Base Class for Cache Drivers * - * @package cache + * @package Kanboard\Core\Cache * @author Frederic Guillot */ -abstract class Base +abstract class BaseCache implements CacheInterface { /** * Proxy cache diff --git a/app/Core/Cache/CacheInterface.php b/app/Core/Cache/CacheInterface.php index d9e9747a..19bd6ef7 100644 --- a/app/Core/Cache/CacheInterface.php +++ b/app/Core/Cache/CacheInterface.php @@ -3,15 +3,15 @@ namespace Kanboard\Core\Cache; /** - * Cache Interface + * Interface CacheInterface * - * @package cache - * @author Frederic Guillot + * @package Kanboard\Core\Cache + * @author Frederic Guillot */ interface CacheInterface { /** - * Save a new value in the cache + * Store an item in the cache * * @access public * @param string $key @@ -20,7 +20,7 @@ interface CacheInterface public function set($key, $value); /** - * Fetch value from cache + * Retrieve an item from the cache by key * * @access public * @param string $key @@ -29,14 +29,14 @@ interface CacheInterface public function get($key); /** - * Clear all cache + * Remove all items from the cache * * @access public */ public function flush(); /** - * Remove cached value + * Remove an item from the cache * * @access public * @param string $key diff --git a/app/Core/Cache/FileCache.php b/app/Core/Cache/FileCache.php new file mode 100644 index 00000000..d477a1f3 --- /dev/null +++ b/app/Core/Cache/FileCache.php @@ -0,0 +1,98 @@ +<?php + +namespace Kanboard\Core\Cache; + +use Kanboard\Core\Tool; +use LogicException; + +/** + * Class FileCache + * + * @package Kanboard\Core\Cache + */ +class FileCache extends BaseCache +{ + /** + * Store an item in the cache + * + * @access public + * @param string $key + * @param string $value + */ + public function set($key, $value) + { + $this->createCacheFolder(); + file_put_contents($this->getFilenameFromKey($key), serialize($value)); + } + + /** + * Retrieve an item from the cache by key + * + * @access public + * @param string $key + * @return mixed Null when not found, cached value otherwise + */ + public function get($key) + { + $filename = $this->getFilenameFromKey($key); + + if (file_exists($filename)) { + return unserialize(file_get_contents($filename)); + } + + return null; + } + + /** + * Remove all items from the cache + * + * @access public + */ + public function flush() + { + $this->createCacheFolder(); + Tool::removeAllFiles(CACHE_DIR, false); + } + + /** + * Remove an item from the cache + * + * @access public + * @param string $key + */ + public function remove($key) + { + $filename = $this->getFilenameFromKey($key); + + if (file_exists($filename)) { + unlink($filename); + } + } + + /** + * Get absolute filename from the key + * + * @access protected + * @param string $key + * @return string + */ + protected function getFilenameFromKey($key) + { + return CACHE_DIR.DIRECTORY_SEPARATOR.$key; + } + + /** + * Create cache folder if missing + * + * @access protected + * @throws LogicException + */ + protected function createCacheFolder() + { + if (! is_dir(CACHE_DIR)) { + if (! mkdir(CACHE_DIR, 0755)) { + throw new LogicException('Unable to create cache directory: '.CACHE_DIR); + } + } + } +} diff --git a/app/Core/Cache/MemoryCache.php b/app/Core/Cache/MemoryCache.php index 39e3947b..4fb94728 100644 --- a/app/Core/Cache/MemoryCache.php +++ b/app/Core/Cache/MemoryCache.php @@ -3,12 +3,12 @@ namespace Kanboard\Core\Cache; /** - * Memory Cache + * Memory Cache Driver * - * @package cache + * @package Kanboard\Core\Cache * @author Frederic Guillot */ -class MemoryCache extends Base implements CacheInterface +class MemoryCache extends BaseCache { /** * Container @@ -19,7 +19,7 @@ class MemoryCache extends Base implements CacheInterface private $storage = array(); /** - * Save a new value in the cache + * Store an item in the cache * * @access public * @param string $key @@ -31,7 +31,7 @@ class MemoryCache extends Base implements CacheInterface } /** - * Fetch value from cache + * Retrieve an item from the cache by key * * @access public * @param string $key diff --git a/app/Core/Event/EventManager.php b/app/Core/Event/EventManager.php index 9ae43170..48a9d299 100644 --- a/app/Core/Event/EventManager.php +++ b/app/Core/Event/EventManager.php @@ -53,6 +53,7 @@ class EventManager TaskModel::EVENT_CREATE_UPDATE => t('Task creation or modification'), TaskModel::EVENT_ASSIGNEE_CHANGE => t('Task assignee change'), TaskModel::EVENT_DAILY_CRONJOB => t('Daily background job for tasks'), + TaskModel::EVENT_MOVE_SWIMLANE => t('Move a task to another swimlane'), ); $events = array_merge($events, $this->events); diff --git a/app/Core/Plugin/Installer.php b/app/Core/Plugin/Installer.php index 48c4d978..b3618aeb 100644 --- a/app/Core/Plugin/Installer.php +++ b/app/Core/Plugin/Installer.php @@ -2,9 +2,8 @@ namespace Kanboard\Core\Plugin; -use RecursiveDirectoryIterator; -use RecursiveIteratorIterator; use ZipArchive; +use Kanboard\Core\Tool; /** * Class Installer @@ -64,7 +63,7 @@ class Installer extends \Kanboard\Core\Base throw new PluginInstallerException(e('You don\'t have the permission to remove this plugin.')); } - $this->removeAllDirectories($pluginFolder); + Tool::removeAllFiles($pluginFolder); } /** @@ -137,26 +136,4 @@ class Installer extends \Kanboard\Core\Base unlink($zip->filename); $zip->close(); } - - /** - * Remove recursively a directory - * - * @access protected - * @param string $directory - */ - protected function removeAllDirectories($directory) - { - $it = new RecursiveDirectoryIterator($directory, RecursiveDirectoryIterator::SKIP_DOTS); - $files = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST); - - foreach ($files as $file) { - if ($file->isDir()) { - rmdir($file->getRealPath()); - } else { - unlink($file->getRealPath()); - } - } - - rmdir($directory); - } } diff --git a/app/Core/Tool.php b/app/Core/Tool.php index bfa6c955..9b8820eb 100644 --- a/app/Core/Tool.php +++ b/app/Core/Tool.php @@ -3,6 +3,8 @@ namespace Kanboard\Core; use Pimple\Container; +use RecursiveDirectoryIterator; +use RecursiveIteratorIterator; /** * Tool class @@ -13,6 +15,32 @@ use Pimple\Container; class Tool { /** + * Remove recursively a directory + * + * @static + * @access public + * @param string $directory + * @param bool $removeDirectory + */ + public static function removeAllFiles($directory, $removeDirectory = true) + { + $it = new RecursiveDirectoryIterator($directory, RecursiveDirectoryIterator::SKIP_DOTS); + $files = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST); + + foreach ($files as $file) { + if ($file->isDir()) { + rmdir($file->getRealPath()); + } else { + unlink($file->getRealPath()); + } + } + + if ($removeDirectory) { + rmdir($directory); + } + } + + /** * Build dependency injection container from an array * * @static diff --git a/app/Core/User/UserSession.php b/app/Core/User/UserSession.php index 9c63f07a..7917b223 100644 --- a/app/Core/User/UserSession.php +++ b/app/Core/User/UserSession.php @@ -179,50 +179,4 @@ class UserSession extends Base { $this->sessionStorage->filters[$project_id] = $filters; } - - /** - * Is board collapsed or expanded - * - * @access public - * @param integer $project_id - * @return boolean - */ - public function isBoardCollapsed($project_id) - { - return ! empty($this->sessionStorage->boardCollapsed[$project_id]) ? $this->sessionStorage->boardCollapsed[$project_id] : false; - } - - /** - * Set board display mode - * - * @access public - * @param integer $project_id - * @param boolean $is_collapsed - */ - public function setBoardDisplayMode($project_id, $is_collapsed) - { - $this->sessionStorage->boardCollapsed[$project_id] = $is_collapsed; - } - - /** - * Set comments sorting - * - * @access public - * @param string $order - */ - public function setCommentSorting($order) - { - $this->sessionStorage->commentSorting = $order; - } - - /** - * Get comments sorting direction - * - * @access public - * @return string - */ - public function getCommentSorting() - { - return empty($this->sessionStorage->commentSorting) ? 'ASC' : $this->sessionStorage->commentSorting; - } } diff --git a/app/Decorator/MetadataCacheDecorator.php b/app/Decorator/MetadataCacheDecorator.php new file mode 100644 index 00000000..0897b51c --- /dev/null +++ b/app/Decorator/MetadataCacheDecorator.php @@ -0,0 +1,96 @@ +<?php + +namespace Kanboard\Decorator; + +use Kanboard\Core\Cache\CacheInterface; +use Kanboard\Model\MetadataModel; + +/** + * Class MetadataCacheDecorator + * + * @package Kanboard\Decorator + * @author Frederic Guillot + */ +class MetadataCacheDecorator +{ + /** + * @var CacheInterface + */ + protected $cache; + + /** + * @var MetadataModel + */ + protected $metadataModel; + + /** + * @var string + */ + protected $cachePrefix; + + /** + * @var int + */ + protected $entityId; + + /** + * Constructor + * + * @param CacheInterface $cache + * @param MetadataModel $metadataModel + * @param string $cachePrefix + * @param integer $entityId + */ + public function __construct(CacheInterface $cache, MetadataModel $metadataModel, $cachePrefix, $entityId) + { + $this->cache = $cache; + $this->metadataModel = $metadataModel; + $this->cachePrefix = $cachePrefix; + $this->entityId = $entityId; + } + + /** + * Get metadata value by key + * + * @param string $key + * @param mixed $default + * @return mixed + */ + public function get($key, $default) + { + $metadata = $this->cache->get($this->getCacheKey()); + + if ($metadata === null) { + $metadata = $this->metadataModel->getAll($this->entityId); + $this->cache->set($this->getCacheKey(), $metadata); + } + + return isset($metadata[$key]) ? $metadata[$key] : $default; + } + + /** + * Set new metadata value + * + * @param $key + * @param $value + */ + public function set($key, $value) + { + $this->metadataModel->save($this->entityId, array( + $key => $value, + )); + + $metadata = $this->metadataModel->getAll($this->entityId); + $this->cache->set($this->getCacheKey(), $metadata); + } + + /** + * Get cache key + * + * @return string + */ + protected function getCacheKey() + { + return $this->cachePrefix.$this->entityId; + } +} diff --git a/app/Helper/BoardHelper.php b/app/Helper/BoardHelper.php index a86a6c18..f5df3db2 100644 --- a/app/Helper/BoardHelper.php +++ b/app/Helper/BoardHelper.php @@ -3,6 +3,7 @@ namespace Kanboard\Helper; use Kanboard\Core\Base; +use Kanboard\Model\UserMetadataModel; /** * Board Helper @@ -21,6 +22,6 @@ class BoardHelper extends Base */ public function isCollapsed($project_id) { - return $this->userSession->isBoardCollapsed($project_id); + return $this->userMetadataCacheDecorator->get(UserMetadataModel::KEY_BOARD_COLLAPSED.$project_id, 0) == 1; } } diff --git a/app/Locale/bs_BA/translations.php b/app/Locale/bs_BA/translations.php index 898e4d66..e17a3cdf 100644 --- a/app/Locale/bs_BA/translations.php +++ b/app/Locale/bs_BA/translations.php @@ -68,7 +68,6 @@ return array( 'Do you really want to remove this project: "%s"?' => 'Da li želiš da ukloniš projekat: "%s"?', 'Remove project' => 'Ukloni projekat', 'Edit the board for "%s"' => 'Uredi ploču za "%s"', - 'All projects' => 'Svi projekti', 'Add a new column' => 'Dodaj novu kolonu', 'Title' => 'Naslov', 'Assigned to %s' => 'Dodijeljen korisniku %s', @@ -88,7 +87,6 @@ return array( '(VACUUM command)' => '(Naredba VACUUM)', '(Gzip compressed Sqlite file)' => '(Sqlite baza spakovana Gzip-om)', 'Close a task' => 'Zatvori zadatak', - 'Edit a task' => 'Uredi zadatak', 'Column' => 'Kolona', 'Color' => 'Boja', 'Assignee' => 'Izvršilac', diff --git a/app/Locale/cs_CZ/translations.php b/app/Locale/cs_CZ/translations.php index 565f92f5..277ddecc 100644 --- a/app/Locale/cs_CZ/translations.php +++ b/app/Locale/cs_CZ/translations.php @@ -68,7 +68,6 @@ return array( 'Do you really want to remove this project: "%s"?' => 'Opravdu chcete vyjmout projekt: "%s"?', 'Remove project' => 'Vyjmout projekt', 'Edit the board for "%s"' => 'Editace nástěnky pro "%s" ', - 'All projects' => 'Všechny projekty', 'Add a new column' => 'Přidat nový sloupec', 'Title' => 'Název', 'Assigned to %s' => 'Přiřazeno uživateli: %s', @@ -88,7 +87,6 @@ return array( '(VACUUM command)' => '(Vyčištění)', '(Gzip compressed Sqlite file)' => '(Gzip )', 'Close a task' => 'Uzavřít úkol', - 'Edit a task' => 'Editovat úkol', 'Column' => 'Sloupec', 'Color' => 'Barva', 'Assignee' => 'Přiřazeno uživateli', diff --git a/app/Locale/da_DK/translations.php b/app/Locale/da_DK/translations.php index 0ff4253e..c4bf55ff 100644 --- a/app/Locale/da_DK/translations.php +++ b/app/Locale/da_DK/translations.php @@ -68,7 +68,6 @@ return array( 'Do you really want to remove this project: "%s"?' => 'Vil du virkelig fjerne dette projekt: "%s"?', 'Remove project' => 'Fjern projekt', 'Edit the board for "%s"' => 'Rediger boardet for "%s"', - 'All projects' => 'Alle Projekter', 'Add a new column' => 'Tilføj en ny kolonne', 'Title' => 'Titel', 'Assigned to %s' => 'Ansvarlig: %s', @@ -88,7 +87,6 @@ return array( '(VACUUM command)' => '(VACUUM kommando)', '(Gzip compressed Sqlite file)' => '(Gzip-komprimeret Sqlite fil)', 'Close a task' => 'Luk en opgave', - 'Edit a task' => 'Rediger en opgave', 'Column' => 'Kolonne', 'Color' => 'Farve', 'Assignee' => 'Ansvarlig', diff --git a/app/Locale/de_DE/translations.php b/app/Locale/de_DE/translations.php index 59de2956..a2a1c17a 100644 --- a/app/Locale/de_DE/translations.php +++ b/app/Locale/de_DE/translations.php @@ -68,7 +68,6 @@ return array( 'Do you really want to remove this project: "%s"?' => 'Soll dieses Projekt wirklich gelöscht werden: "%s"?', 'Remove project' => 'Projekt löschen', 'Edit the board for "%s"' => 'Pinnwand für "%s" bearbeiten', - 'All projects' => 'Alle Projekte', 'Add a new column' => 'Neue Spalte hinzufügen', 'Title' => 'Titel', 'Assigned to %s' => 'Zuständig: %s', @@ -88,7 +87,6 @@ return array( '(VACUUM command)' => '(VACUUM Befehl)', '(Gzip compressed Sqlite file)' => '(Gzip-komprimierte SQLite-Datei)', 'Close a task' => 'Aufgabe abschließen', - 'Edit a task' => 'Aufgabe bearbeiten', 'Column' => 'Spalte', 'Color' => 'Farbe', 'Assignee' => 'Zuständiger', diff --git a/app/Locale/el_GR/translations.php b/app/Locale/el_GR/translations.php index cf3bb588..30143ac5 100644 --- a/app/Locale/el_GR/translations.php +++ b/app/Locale/el_GR/translations.php @@ -68,7 +68,6 @@ return array( 'Do you really want to remove this project: "%s"?' => 'Αφαίρεση του έργου: « %s » ?', 'Remove project' => 'Αφαίρεση του έργου', 'Edit the board for "%s"' => 'Διόρθωση πίνακα από « %s »', - 'All projects' => 'Όλα τα έργα', 'Add a new column' => 'Πρόσθήκη στήλης', 'Title' => 'Τίτλος', 'Assigned to %s' => 'Ανατιθεμένο στον %s', @@ -88,7 +87,6 @@ return array( '(VACUUM command)' => '(VACUUM command)', '(Gzip compressed Sqlite file)' => '(Gzip compressed Sqlite file)', 'Close a task' => 'Κλείσιμο εργασίας', - 'Edit a task' => 'Διόρθωση εργασίας', 'Column' => 'Στήλη', 'Color' => 'Χρώμα', 'Assignee' => 'Ανατεθιμένο στον χρήστη', diff --git a/app/Locale/es_ES/translations.php b/app/Locale/es_ES/translations.php index 5a2c16c0..be603eeb 100644 --- a/app/Locale/es_ES/translations.php +++ b/app/Locale/es_ES/translations.php @@ -68,7 +68,6 @@ return array( 'Do you really want to remove this project: "%s"?' => '¿Realmente desea eliminar este proyecto: «%s»?', 'Remove project' => 'Eliminar el proyecto', 'Edit the board for "%s"' => 'Modificar el tablero para «%s»', - 'All projects' => 'Todos los proyectos', 'Add a new column' => 'Añadir una nueva columna', 'Title' => 'Título', 'Assigned to %s' => 'Asignada a %s', @@ -88,7 +87,6 @@ return array( '(VACUUM command)' => '(comando VACUUM)', '(Gzip compressed Sqlite file)' => '(archivo Sqlite comprimido en Gzip)', 'Close a task' => 'Cerrar una tarea', - 'Edit a task' => 'Modificar una tarea', 'Column' => 'Columna', 'Color' => 'Color', 'Assignee' => 'Responsable', diff --git a/app/Locale/fi_FI/translations.php b/app/Locale/fi_FI/translations.php index ed38fb56..7ce7fc5f 100644 --- a/app/Locale/fi_FI/translations.php +++ b/app/Locale/fi_FI/translations.php @@ -68,7 +68,6 @@ return array( 'Do you really want to remove this project: "%s"?' => 'Haluatko varmasti poistaa projektin: "%s"?', 'Remove project' => 'Poista projekti', 'Edit the board for "%s"' => 'Muokkaa taulua projektille "%s"', - 'All projects' => 'Kaikki projektit', 'Add a new column' => 'Lisää uusi sarake', 'Title' => 'Nimi', 'Assigned to %s' => 'Tekijä: %s', @@ -88,7 +87,6 @@ return array( '(VACUUM command)' => '(VACUUM-komento)', '(Gzip compressed Sqlite file)' => '(Gzip-pakattu Sqlite-tiedosto)', 'Close a task' => 'Sulje tehtävä', - 'Edit a task' => 'Muokkaa tehtävää', 'Column' => 'Sarake', 'Color' => 'Väri', 'Assignee' => 'Suorittaja', diff --git a/app/Locale/fr_FR/translations.php b/app/Locale/fr_FR/translations.php index e7184949..71b8ace5 100644 --- a/app/Locale/fr_FR/translations.php +++ b/app/Locale/fr_FR/translations.php @@ -68,7 +68,6 @@ return array( 'Do you really want to remove this project: "%s"?' => 'Voulez-vous vraiment supprimer ce projet : « %s » ?', 'Remove project' => 'Supprimer le projet', 'Edit the board for "%s"' => 'Modifier le tableau pour « %s »', - 'All projects' => 'Tous les projets', 'Add a new column' => 'Ajouter une nouvelle colonne', 'Title' => 'Titre', 'Assigned to %s' => 'Assigné à %s', @@ -88,7 +87,6 @@ return array( '(VACUUM command)' => '(Commande VACUUM)', '(Gzip compressed Sqlite file)' => '(Fichier Sqlite compressé en Gzip)', 'Close a task' => 'Fermer une tâche', - 'Edit a task' => 'Modifier une tâche', 'Column' => 'Colonne', 'Color' => 'Couleur', 'Assignee' => 'Personne assignée', diff --git a/app/Locale/hu_HU/translations.php b/app/Locale/hu_HU/translations.php index 32e34857..c5900fb5 100644 --- a/app/Locale/hu_HU/translations.php +++ b/app/Locale/hu_HU/translations.php @@ -68,7 +68,6 @@ return array( 'Do you really want to remove this project: "%s"?' => 'Valóban törölni akarja ezt a projektet: "%s"?', 'Remove project' => 'Projekt törlése', 'Edit the board for "%s"' => 'Tábla szerkesztése: "%s"', - 'All projects' => 'Minden projekt', 'Add a new column' => 'Új oszlop', 'Title' => 'Cím', 'Assigned to %s' => 'Felelős: %s', @@ -88,7 +87,6 @@ return array( '(VACUUM command)' => '(VACUUM parancs)', '(Gzip compressed Sqlite file)' => '(Gzip tömörített SQLite fájl)', 'Close a task' => 'Feladat lezárása', - 'Edit a task' => 'Feladat módosítása', 'Column' => 'Oszlop', 'Color' => 'Szín', 'Assignee' => 'Felelős', diff --git a/app/Locale/id_ID/translations.php b/app/Locale/id_ID/translations.php index 9ecb0121..22b6a75e 100644 --- a/app/Locale/id_ID/translations.php +++ b/app/Locale/id_ID/translations.php @@ -68,7 +68,6 @@ return array( 'Do you really want to remove this project: "%s"?' => 'Apakah anda yakin akan menghapus proyek ini : « %s » ?', 'Remove project' => 'Hapus proyek', 'Edit the board for "%s"' => 'Rubah papan untuk « %s »', - 'All projects' => 'Semua proyek', 'Add a new column' => 'Tambah kolom baru', 'Title' => 'Judul', 'Assigned to %s' => 'Ditugaskan ke %s', @@ -88,7 +87,6 @@ return array( '(VACUUM command)' => '(perintah VACUUM)', '(Gzip compressed Sqlite file)' => '(File Sqlite yang terkompress Gzip)', 'Close a task' => 'Tutup tugas', - 'Edit a task' => 'Edit tugas', 'Column' => 'Kolom', 'Color' => 'Warna', 'Assignee' => 'Orang yang ditugaskan', diff --git a/app/Locale/it_IT/translations.php b/app/Locale/it_IT/translations.php index b72ca181..1f6539b7 100644 --- a/app/Locale/it_IT/translations.php +++ b/app/Locale/it_IT/translations.php @@ -68,7 +68,6 @@ return array( 'Do you really want to remove this project: "%s"?' => 'Vuoi davvero eliminare il seguente progetto: "%s" ?', 'Remove project' => 'Cancella il progetto', 'Edit the board for "%s"' => 'Modifica la bacheca per "%s"', - 'All projects' => 'Tutti i progetti', 'Add a new column' => 'Aggiungi una nuova colonna', 'Title' => 'Titolo', 'Assigned to %s' => 'Assegnato a %s', @@ -88,7 +87,6 @@ return array( '(VACUUM command)' => '(Comando VACUUM)', '(Gzip compressed Sqlite file)' => '(File Sqlite compresso in Gzip)', 'Close a task' => 'Chiudi un task', - 'Edit a task' => 'Modifica un task', 'Column' => 'Colonna', 'Color' => 'Colore', 'Assignee' => 'Assegnatario', diff --git a/app/Locale/ja_JP/translations.php b/app/Locale/ja_JP/translations.php index d3a11fc8..24dae922 100644 --- a/app/Locale/ja_JP/translations.php +++ b/app/Locale/ja_JP/translations.php @@ -68,7 +68,6 @@ return array( 'Do you really want to remove this project: "%s"?' => 'プロジェクト「%s」を本当に削除しますか?', 'Remove project' => 'プロジェクトの削除', 'Edit the board for "%s"' => 'ボード「%s」を変更する', - 'All projects' => 'すべてのプロジェクト', 'Add a new column' => 'カラムの追加', 'Title' => 'タイトル', 'Assigned to %s' => '%sが担当', @@ -88,7 +87,6 @@ return array( '(VACUUM command)' => '(VACUUM コマンド)', '(Gzip compressed Sqlite file)' => '(GZip コマンドで圧縮された Sqlite ファイル)', 'Close a task' => 'タスクをクロースする', - 'Edit a task' => 'タスクを変更する', 'Column' => 'カラム', 'Color' => '色', 'Assignee' => '担当', diff --git a/app/Locale/ko_KR/translations.php b/app/Locale/ko_KR/translations.php index b8ec0c81..19b1f5fd 100644 --- a/app/Locale/ko_KR/translations.php +++ b/app/Locale/ko_KR/translations.php @@ -68,14 +68,13 @@ return array( 'Do you really want to remove this project: "%s"?' => '프로젝트를 삭제하시겠습니까: "%s"?', 'Remove project' => '프로젝트의 삭제', 'Edit the board for "%s"' => '"%s"를 위한 보드 수정', - 'All projects' => '모든 프로젝트', - 'Add a new column' => '칼럼의 추가', + 'Add a new column' => '컬럼의 추가', 'Title' => '제목', 'Assigned to %s' => '담당자 %s', - 'Remove a column' => '칼럼 삭제', - 'Remove a column from a board' => '보드에서 칼럼 삭제', + 'Remove a column' => '컬럼 삭제', + 'Remove a column from a board' => '보드에서 컬럼 삭제', 'Unable to remove this column.' => '(※)컬럼을 삭제할 수 없었습니다.', - 'Do you really want to remove this column: "%s"?' => '칼럼을 삭제하시겠습니까: "%s"?', + 'Do you really want to remove this column: "%s"?' => '컬럼을 삭제하시겠습니까: "%s"?', 'This action will REMOVE ALL TASKS associated to this column!' => '이 조작은 이 컬럼에 할당된 『 모든 할일을 삭제 』합니다!', 'Settings' => '설정', 'Application settings' => '애플리케이션의 설정', @@ -88,8 +87,7 @@ return array( '(VACUUM command)' => '(VACUUM명령)', '(Gzip compressed Sqlite file)' => '(GZip명령으로 압축된 Sqlite파일)', 'Close a task' => '할일 마치기', - 'Edit a task' => '할일 수정', - 'Column' => '칼럼', + 'Column' => '컬럼', 'Color' => '색', 'Assignee' => '담당자', 'Create another task' => '다른 할일 추가', @@ -98,7 +96,7 @@ return array( 'Do you really want to open this task: "%s"?' => '할일은 시작 하시겠습니까: "%s"?', 'Back to the board' => '보드로 돌아가기', 'There is nobody assigned' => '담당자가 없습니다', - 'Column on the board:' => '칼럼:', + 'Column on the board:' => '컬럼:', 'Close this task' => '할일 마치기', 'Open this task' => '할일을 열다', 'There is no description.' => '설명이 없다', @@ -190,12 +188,12 @@ return array( 'Assign the task to a specific user' => '할일 담당자를 할당', 'Assign the task to the person who does the action' => '액션을 일으킨 사용자를 담당자이자', 'Duplicate the task to another project' => ' 다른 프로젝트에 할일을 복제하는 ', - 'Move a task to another column' => '할일을 다른 칼럼에 이동하는 ', + 'Move a task to another column' => '할일을 다른 컬럼에 이동하는 ', 'Task modification' => '할일 변경', 'Task creation' => '할일을 만들', 'Closing a task' => '할일을 닫혔다', 'Assign a color to a specific user' => '색을 사용자에 할당', - 'Column title' => '칼럼의 제목', + 'Column title' => '컬럼의 제목', 'Position' => '위치', 'Duplicate to another project' => '다른 프로젝트에 복사', 'Duplicate' => '복사', @@ -362,7 +360,7 @@ return array( '%s updated the task %s' => '%s이 할일 %s을 갱신 하였습니다', '%s opened the task %s' => '%s이 할일 %s을 시작시켰습니다', '%s moved the task %s to the position #%d in the column "%s"' => '%s이 할일%s을 위치#%d컬럼%s로 옮겼습니다', - '%s moved the task %s to the column "%s"' => '%s이 할일 %s을 칼럼 "%s" 로 옮겼습니다', + '%s moved the task %s to the column "%s"' => '%s이 할일 %s을 컬럼 "%s" 로 옮겼습니다', '%s created the task %s' => '%s이 할일%s을 추가했습니다', '%s closed the task %s' => '%s이 할일%s을 마쳤습니다', '%s created a subtask for the task %s' => '%s이 할일%s의 서브 할일을 추가했습니다', @@ -383,7 +381,7 @@ return array( '%s opened the task #%d' => '%s이 할일#%d를 오픈했습니다', 'Activity' => '활동', 'Default values are "%s"' => '기본 값은 "%s" 입니다', - 'Default columns for new projects (Comma-separated)' => '새로운 프로젝트의 기본 칼럼 (콤마(,)로 분리됨)', + 'Default columns for new projects (Comma-separated)' => '새로운 프로젝트의 기본 컬럼 (콤마(,)로 분리됨)', 'Task assignee change' => '담당자의 변경', '%s changed the assignee of the task #%d to %s' => '%s이 할일 #%d의 담당을 %s로 변경합니다', '%s changed the assignee of the task %s to %s' => '%s이 할일 %s의 담당을 %s로 변경했습니다', @@ -428,7 +426,7 @@ return array( 'Create a comment from an external provider' => '외부 서비스로부터 의견을 작성한다', 'Project management' => '프로젝트 관리', 'My projects' => '내 프로젝트', - 'Columns' => '칼럼', + 'Columns' => '컬럼', 'Task' => '할일', 'Your are not member of any project.' => '어떤 프로젝트에도 속하지 않습니다.', 'Percentage' => '비중', @@ -486,16 +484,16 @@ return array( 'Application default' => '애플리케이션 기본', 'Language:' => '언어:', 'Timezone:' => '시간대:', - 'All columns' => '모든 칼럼', + 'All columns' => '모든 컬럼', 'Calendar' => '달력', 'Next' => '다음에 ', '#%d' => '#%d', 'All swimlanes' => '모든 스윔레인', 'All colors' => '모든 색', - 'Moved to column %s' => '"%s" 칼럼으로 이동', + 'Moved to column %s' => '"%s" 컬럼으로 이동', 'User dashboard' => '대시보드', 'Allow only one subtask in progress at the same time for a user' => '한 사용자에 대한 하나의 할일만 진행 중에 가능합니다', - 'Edit column "%s"' => '"%s" 칼럼 수정', + 'Edit column "%s"' => '"%s" 컬럼 수정', 'Select the new status of the subtask: "%s"' => '서브 할일의 새로운 상태 선택: "%s"', 'Subtask timesheet' => '서브 할일 타임시트', 'There is nothing to show.' => '기록이 없습니다', @@ -506,7 +504,7 @@ return array( 'Start' => '시작', 'End' => '종료', 'Task age in days' => '할일이 생긴 시간', - 'Days in this column' => '이 칼럼에 있는 시간', + 'Days in this column' => '이 컬럼에 있는 시간', '%dd' => '%d일', 'Add a new link' => ' 새로운 링크 추가', 'Do you really want to remove this link: "%s"?' => '링크를 삭제하시겠습니까: "%s"?', @@ -569,16 +567,16 @@ return array( // 'NZD - New Zealand Dollar' => '', // 'RSD - Serbian dinar' => '', // 'USD - US Dollar' => '', - 'Destination column' => '이동 후 칼럼', - 'Move the task to another column when assigned to a user' => '사용자의 할당을 하면 할일을 다른 칼럼에 이동', - 'Move the task to another column when assignee is cleared' => '사용자의 할당이 없어지면 할일을 다른 칼럼에 이동', - 'Source column' => '이동 전 칼럼', + 'Destination column' => '이동 후 컬럼', + 'Move the task to another column when assigned to a user' => '사용자의 할당을 하면 할일을 다른 컬럼에 이동', + 'Move the task to another column when assignee is cleared' => '사용자의 할당이 없어지면 할일을 다른 컬럼에 이동', + 'Source column' => '이동 전 컬럼', 'Transitions' => '이력', 'Executer' => '실행자', - 'Time spent in the column' => '칼럼에 있던 시간', + 'Time spent in the column' => '컬럼에 있던 시간', 'Task transitions' => '할일 천이', 'Task transitions export' => '할일 천이를 출력', - 'This report contains all column moves for each task with the date, the user and the time spent for each transition.' => '이 리포트는 할일의 칼럼 간 이동을 시간, 유저, 경과 시간과 함께 기록한 것입니다.', + 'This report contains all column moves for each task with the date, the user and the time spent for each transition.' => '이 리포트는 할일의 컬럼 간 이동을 시간, 유저, 경과 시간과 함께 기록한 것입니다.', 'Currency rates' => '환율', 'Rate' => '레이트', 'Change reference currency' => '현재의 기축 통화', @@ -599,7 +597,7 @@ return array( 'Check my code' => '코드 체크', 'Secret key: ' => '비밀키: ', 'Test your device' => '디바이스 테스트', - 'Assign a color when the task is moved to a specific column' => '상세 칼럼으로 이동할 할일의 색깔을 지정하세요', + 'Assign a color when the task is moved to a specific column' => '상세 컬럼으로 이동할 할일의 색깔을 지정하세요', '%s via Kanboard' => '%s via E-board', 'Burndown chart' => '번다운 차트', // 'This chart show the task complexity over the time (Work Remaining).' => '', @@ -639,8 +637,8 @@ return array( 'Timeframe to calculate new due date: ' => '종료날짜 계산 단위', // 'Trigger to generate recurrent task: ' => '', 'When task is closed' => '할일을 마쳤을때', - 'When task is moved from first column' => '할일이 첫번째 칼럼으로 옮겨졌을때', - 'When task is moved to last column' => '할일이 마지막 칼럼으로 옮겨졌을때', + 'When task is moved from first column' => '할일이 첫번째 컬럼으로 옮겨졌을때', + 'When task is moved to last column' => '할일이 마지막 컬럼으로 옮겨졌을때', 'Year(s)' => '년', 'Calendar settings' => '달력 설정', 'Project calendar view' => '프로젝트 달력 보기', @@ -661,8 +659,8 @@ return array( 'User that will receive the email' => '그 담당자가 이메일을 수신할 것입니다', 'Email subject' => '이메일 제목', 'Date' => '날짜', - 'Add a comment log when moving the task between columns' => '칼럼 중간의 할일이 이동할 때 의견 달기', - 'Move the task to another column when the category is changed' => '카테고리 변경시 할일을 다른 칼럼으로 이동', + 'Add a comment log when moving the task between columns' => '컬럼 중간의 할일이 이동할 때 의견 달기', + 'Move the task to another column when the category is changed' => '카테고리 변경시 할일을 다른 컬럼으로 이동', 'Send a task by email to someone' => '할일을 이메일로 보내기', 'Reopen a task' => '할일 다시 시작', 'Notification' => '알림', @@ -698,7 +696,7 @@ return array( 'Only for tasks created by me' => '내가 만든 일', 'Only for tasks created by me and assigned to me' => '내가 만들었거나 내가 담당자인 일', // '%%Y-%%m-%%d' => '', - 'Total for all columns' => '모든 칼럼', + 'Total for all columns' => '모든 컬럼', 'You need at least 2 days of data to show the chart.' => '차트를 보기 위하여 최소 2일의 데이터가 필요합니다', '<15m' => '<15분', '<30m' => '<30분', @@ -731,7 +729,7 @@ return array( 'Advanced search' => '검색 문법', 'Example of query: ' => '문법 예제 ', 'Search by project: ' => '프로젝트로 찾기 ', - 'Search by column: ' => '칼럼으로 찾기 ', + 'Search by column: ' => '컬럼으로 찾기 ', 'Search by assignee: ' => '담당자로 찾기 ', 'Search by color: ' => '색깔로 찾기 ', 'Search by category: ' => '카테고리로 찾기 ', @@ -739,18 +737,18 @@ return array( 'Search by due date: ' => '마감날짜로 찾기 ', 'Average time spent into each column' => '각 칼럼의 평균 소요시간', 'Average time spent' => '평균 소요시간', - 'This chart show the average time spent into each column for the last %d tasks.' => '마지막 %d 할일의 칼럼 평균 소요시간을 차트에 표시합니다', + 'This chart show the average time spent into each column for the last %d tasks.' => '마지막 %d 할일의 컬럼 평균 소요시간을 차트에 표시합니다', 'Average Lead and Cycle time' => '평균 Lead and Cycle 시간', 'Average lead time: ' => '평균 lead 시간', 'Average cycle time: ' => '평균 cycle 시간', 'Cycle Time' => '사이클 시간', 'Lead Time' => '리드 시간', 'This chart show the average lead and cycle time for the last %d tasks over the time.' => '마지막 %d 할일의 평균 리드와 사이클 시간을 차트에 표시합니다', - 'Average time into each column' => '각 칼럼의 평균 시간', + 'Average time into each column' => '각 컬럼의 평균 시간', 'Lead and cycle time' => '리드와 사이클 시간', 'Lead time: ' => '리드 시간: ', 'Cycle time: ' => '사이클 시간: ', - 'Time spent into each column' => '각 칼럼에서 걸린 시간', + 'Time spent into each column' => '각 컬럼에서 걸린 시간', 'The lead time is the duration between the task creation and the completion.' => '리드 시간은 할일의 생성부터 완료까지의 기간입니다', 'The cycle time is the duration between the start date and the completion.' => '사이클 시간은 할일의 시작일부터 완료까지의 기간입니다', 'If the task is not closed the current time is used instead of the completion date.' => '할일이 종료되지 않았다면, 완료 시간 대신 현재 시간이 사용됩니다', @@ -767,7 +765,7 @@ return array( 'Trigger automatically subtask time tracking' => '자동 서브 할일 시간 트래킹 트리거', 'Include closed tasks in the cumulative flow diagram' => '누적 플로우 다이어그램에 종료된 할일을 포함합니다', 'Current swimlane: %s' => '현재 스웜라인: %s', - 'Current column: %s' => '현재 칼럼: %s', + 'Current column: %s' => '현재 컬럼: %s', 'Current category: %s' => '현재 카테고리: %s', 'no category' => '카테고리 아님', 'Current assignee: %s' => '현재 할당자: %s', @@ -789,8 +787,8 @@ return array( 'People who are project managers' => '프로젝트 매니저', 'People who are project members' => '프로젝트 멤버', // 'NOK - Norwegian Krone' => '', - 'Show this column' => '칼럼 보이기', - 'Hide this column' => '칼럼 숨기기', + 'Show this column' => '컬럼 보이기', + 'Hide this column' => '컬럼 숨기기', 'open file' => '열기', 'End date' => '종료 날짜', 'Users overview' => '유저 전체보기', @@ -836,7 +834,7 @@ return array( 'Task updated #%d' => '할일 #%d이 갱신 되었습니다', 'Task #%d closed' => '할일 #%d를 마쳤습니다', 'Task #%d opened' => '할일 #%d가 시작되었습니다', - 'Column changed for task #%d' => '할일 #%d의 칼럼이 변경되었습니다', + 'Column changed for task #%d' => '할일 #%d의 컬럼이 변경되었습니다', 'New position for task #%d' => '할일 #%d이 새로운 위치에 등록되었습니다', 'Swimlane changed for task #%d' => '#%d 할일의 스웜라인이 변경됩니다', 'Assignee changed on task #%d' => '#%d 할일의 담당자가 변경됩니다', @@ -867,7 +865,7 @@ return array( 'Double Quote' => '이중 따옴표', 'Single Quote' => '따옴표', '%s attached a file to the task #%d' => '%s가 할일 #%d에 파일을 추가하였습니다', - 'There is no column or swimlane activated in your project!' => '프로젝트에 활성화된 칼럼이나 스웜라인이 없습니다', + 'There is no column or swimlane activated in your project!' => '프로젝트에 활성화된 컬럼이나 스웜라인이 없습니다', // 'Append filter (instead of replacement)' => '', 'Append/Replace' => '추가/변경', 'Append' => '추가', @@ -953,8 +951,8 @@ return array( 'Actual Time' => '실제 시간', 'Estimated vs actual time' => '예상 vs 실제 시간', // 'RUB - Russian Ruble' => '', - 'Assign the task to the person who does the action when the column is changed' => '칼럼이 변경되면 액션하지 않는 사람에게 할일을 할당합니다', - 'Close a task in a specific column' => '상세 칼럼의 할일을 종료합니다', + 'Assign the task to the person who does the action when the column is changed' => '컬럼이 변경되면 액션하지 않는 사람에게 할일을 할당합니다', + 'Close a task in a specific column' => '상세 컬럼의 할일을 종료합니다', 'Time-based One-time Password Algorithm' => '시간에 기반한 1회용 패스워드 알고리즘', 'Two-Factor Provider: ' => '이중 인증: ', 'Disable two-factor authentication' => '이중 인증 비활성화', @@ -972,10 +970,10 @@ return array( 'Creation' => '생성', 'Expiration' => '만료', 'Password reset history' => '비밀번호 초기화 기록', - 'All tasks of the column "%s" and the swimlane "%s" have been closed successfully.' => '칼럼 "%s"와 스웜라인 "%s"의 모든 할일이 성공적으로 종료되었습니다', - 'Do you really want to close all tasks of this column?' => '이 칼럼의 모든 할일을 종료 하시겠습니까?', - '%d task(s) in the column "%s" and the swimlane "%s" will be closed.' => '칼럼 "%s"와 스웜라인 "%s"의 할일 %d가 종료될 것입니다', - 'Close all tasks of this column' => '칼럼의 모든 할일 마치기', + 'All tasks of the column "%s" and the swimlane "%s" have been closed successfully.' => '컬럼 "%s"와 스웜라인 "%s"의 모든 할일이 성공적으로 종료되었습니다', + 'Do you really want to close all tasks of this column?' => '이 컬럼의 모든 할일을 종료 하시겠습니까?', + '%d task(s) in the column "%s" and the swimlane "%s" will be closed.' => '컬럼 "%s"와 스웜라인 "%s"의 할일 %d가 종료될 것입니다', + 'Close all tasks of this column' => '컬럼의 모든 할일 마치기', 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => '프로젝트 알림 방법으로 플러그인이 등록되지 않았습니다. 각각의 알림을 프로파일에서 설정하실 수 있습니다', 'My dashboard' => '대시보드', 'My profile' => '프로필', @@ -1027,7 +1025,7 @@ return array( 'Reference:' => '참고:', 'Complexity:' => '복합:', 'Swimlane:' => '스웜라인:', - 'Column:' => '칼럼:', + 'Column:' => '컬럼:', 'Position:' => '위치:', 'Creator:' => '생성자:', 'Time estimated:' => '예상 시간:', @@ -1070,11 +1068,11 @@ return array( 'Uploaded by %s' => '%s로 올리기', 'Filename' => '파일 이름', 'Size' => '크기', - 'Column created successfully.' => '칼럼이 성공적으로 생성되었습니다', - 'Another column with the same name exists in the project' => '프로젝트에 동일한 이름의 칼럼이 있습니다', + 'Column created successfully.' => '컬럼이 성공적으로 생성되었습니다', + 'Another column with the same name exists in the project' => '프로젝트에 동일한 이름의 컬럼이 있습니다', 'Default filters' => '기본 필터', - 'Your board doesn\'t have any columns!' => '보드에 칼럼이 존재하지 않습니다', - 'Change column position' => '칼럼 위치 변경', + 'Your board doesn\'t have any columns!' => '보드에 컬럼이 존재하지 않습니다', + 'Change column position' => '컬럼 위치 변경', 'Switch to the project overview' => '프로젝트 개요로 변경', 'User filters' => '사용자 필터', 'Category filters' => '카테고리 필터', @@ -1164,54 +1162,54 @@ return array( 'Email settings' => '이메일 설정', 'Email sender address' => '이메일 보낸이 주소', 'Email transport' => '이메일 전송', - // 'Webhook token' => '', + 'Webhook token' => 'Webhook토큰', 'Imports' => '가져오기', - // 'Project tags management' => '', - // 'Tag created successfully.' => '', - // 'Unable to create this tag.' => '', - // 'Tag updated successfully.' => '', - // 'Unable to update this tag.' => '', - // 'Tag removed successfully.' => '', - // 'Unable to remove this tag.' => '', - // 'Global tags management' => '', - // 'Tags' => '', - // 'Tags management' => '', - // 'Add new tag' => '', - // 'Edit a tag' => '', - // 'Project tags' => '', - // 'There is no specific tag for this project at the moment.' => '', - // 'Tag' => '', - // 'Remove a tag' => '', - // 'Do you really want to remove this tag: "%s"?' => '', - // 'Global tags' => '', - // 'There is no global tag at the moment.' => '', - // 'This field cannot be empty' => '', - // 'Close a task when there is no activity in an specific column' => '', - // '%s removed a subtask for the task #%d' => '', - // '%s removed a comment on the task #%d' => '', - // 'Comment removed on task #%d' => '', - // 'Subtask removed on task #%d' => '', - // 'Hide tasks in this column in the dashboard' => '', - // '%s removed a comment on the task %s' => '', - // '%s removed a subtask for the task %s' => '', - // 'Comment removed' => '', - // 'Subtask removed' => '', - // '%s set a new internal link for the task #%d' => '', - // '%s removed an internal link for the task #%d' => '', - // 'A new internal link for the task #%d have been defined' => '', - // 'Internal link removed for the task #%d' => '', - // '%s set a new internal link for the task %s' => '', - // '%s removed an internal link for the task %s' => '', - // 'Automatically set the due date on task creation' => '', - // 'Move the task to another column when closed' => '', - // 'Move the task to another column when not moved during a given period' => '', - // 'Dashboard for %s' => '', - // 'Tasks overview for %s' => '', - // 'Subtasks overview for %s' => '', - // 'Projects overview for %s' => '', - // 'Activity stream for %s' => '', - // 'Calendar for %s' => '', - // 'Notifications for %s' => '', - // 'Subtasks export' => '', - // 'Tasks exportation' => '', + 'Project tags management' => '프로젝트 태그 관리', + 'Tag created successfully.' => '태그가 성공적으로 생성되었습니다.', + 'Unable to create this tag.' => '태그를 생성할 수 없습니다.', + 'Tag updated successfully.' => '태그가 성공적으로 수정되었습니다.', + 'Unable to update this tag.' => '태그를 수정할 수 없습니다.', + 'Tag removed successfully.' => '태그가 성공적으로 삭제되었습니다.', + 'Unable to remove this tag.' => '태그를 삭제할 수 없습니다.', + 'Global tags management' => '전역 태그 관리', + 'Tags' => '태그', + 'Tags management' => '태그 관리', + 'Add new tag' => '태그 추가', + 'Edit a tag' => '태그 수정', + 'Project tags' => '프로젝트 태그', + 'There is no specific tag for this project at the moment.' => '현재 이 프로젝트에는 태그가 없습니다.', + 'Tag' => '태그', + 'Remove a tag' => '태그 삭제', + 'Do you really want to remove this tag: "%s"?' => '태그를 삭제하시겠습니까: "%s"?', + 'Global tags' => '전역 태그', + 'There is no global tag at the moment.' => '현재 전역 태그가 없습니다.', + 'This field cannot be empty' => '이 필드는 비워둘 수 없습니다', + 'Close a task when there is no activity in an specific column' => '활동이 없는 컬럼의 할일 마치기', + '%s removed a subtask for the task #%d' => '%s가 할일 #%d의 서브 할일을 삭제하였습니다', + '%s removed a comment on the task #%d' => '%s가 할일 #%d의 댓글을 삭제하였습니다', + 'Comment removed on task #%d' => '할일 #%d의 댓글이 삭제되었습니다', + 'Subtask removed on task #%d' => '할일 #%d의 서브 할일이 삭제되었습니다', + 'Hide tasks in this column in the dashboard' => '대시보드 컬럼의 할일 숨기기', + '%s removed a comment on the task %s' => '%s가 할일 %s의 댓글을 삭제하였습니다', + '%s removed a subtask for the task %s' => '%s가 할일 %s의 서브 할일을 삭제하였습니다', + 'Comment removed' => '댓글이 삭제되었습니다', + 'Subtask removed' => '서브 할일이 삭제되었습니다', + '%s set a new internal link for the task #%d' => '%s가 할일 #%d의 새로운 내부 링크를 설정하였습니다', + '%s removed an internal link for the task #%d' => '%s가 할일 #%d의 새로운 내부 링크를 삭제하였습니다', + 'A new internal link for the task #%d have been defined' => '할일 #%d의 새로운 내부 링크가 정의되었습니다', + 'Internal link removed for the task #%d' => '할일 #%d의 새로운 내부 링크가 삭제되었습니다', + '%s set a new internal link for the task %s' => '%s가 할일 %s의 새로운 내부 링크를 설정하였습니다', + '%s removed an internal link for the task %s' => '%s가 할일 %s의 새로운 내부 링크를 삭제하였습니다', + 'Automatically set the due date on task creation' => '할일 생성시 마감일이 자동으로 설정되었습니다', + 'Move the task to another column when closed' => '할일을 마치면 다른 컬럼으로 이동시키기', + 'Move the task to another column when not moved during a given period' => '주어진 기간동안 이동하지 않으면 할일을 다른 컬럼으로 이동시키기', + 'Dashboard for %s' => '%s의 대시보드', + 'Tasks overview for %s' => '%s의 할일 개요', + 'Subtasks overview for %s' => '%s의 서브 할일 개요', + 'Projects overview for %s' => '%s의 프로젝트 개요', + 'Activity stream for %s' => '%s의 활동기록', + 'Calendar for %s' => '%s의 달력', + 'Notifications for %s' => '%s의 알림', + 'Subtasks export' => '서브할일 내보내기', + 'Tasks exportation' => '할일 내보내기', ); diff --git a/app/Locale/my_MY/translations.php b/app/Locale/my_MY/translations.php index 79baadf7..661fe5ac 100644 --- a/app/Locale/my_MY/translations.php +++ b/app/Locale/my_MY/translations.php @@ -68,7 +68,6 @@ return array( 'Do you really want to remove this project: "%s"?' => 'Anda yakin mahu menghapus projek ini : « %s » ?', 'Remove project' => 'Hapus projek', 'Edit the board for "%s"' => 'Ubah papan untuk « %s »', - 'All projects' => 'Semua projek', 'Add a new column' => 'Tambah kolom baru', 'Title' => 'Judul', 'Assigned to %s' => 'Ditugaskan ke %s', @@ -88,7 +87,6 @@ return array( '(VACUUM command)' => '(perintah VACUUM)', '(Gzip compressed Sqlite file)' => '(File Sqlite yang termampat Gzip)', 'Close a task' => 'Tutup tugas', - 'Edit a task' => 'Sunting tugas', 'Column' => 'Kolom', 'Color' => 'Warna', 'Assignee' => 'Orang yang ditugaskan', diff --git a/app/Locale/nb_NO/translations.php b/app/Locale/nb_NO/translations.php index 3a0c3353..86fb33a9 100644 --- a/app/Locale/nb_NO/translations.php +++ b/app/Locale/nb_NO/translations.php @@ -68,7 +68,6 @@ return array( 'Do you really want to remove this project: "%s"?' => 'Vil du fjerne dette prosjektet: "%s"?', 'Remove project' => 'Fjern prosjekt', 'Edit the board for "%s"' => 'Endre prosjektsiden for "%s"', - 'All projects' => 'Alle prosjekter', 'Add a new column' => 'Legg til en ny kolonne', 'Title' => 'Tittel', 'Assigned to %s' => 'Tildelt: %s', @@ -88,7 +87,6 @@ return array( '(VACUUM command)' => '(VACUUM kommando)', '(Gzip compressed Sqlite file)' => '(Gzip-komprimert Sqlite fil)', 'Close a task' => 'Lukk en oppgave', - 'Edit a task' => 'Endre en oppgave', 'Column' => 'Kolonne', 'Color' => 'Farge', 'Assignee' => 'Tildelt', diff --git a/app/Locale/nl_NL/translations.php b/app/Locale/nl_NL/translations.php index 5a026092..43bd32d3 100644 --- a/app/Locale/nl_NL/translations.php +++ b/app/Locale/nl_NL/translations.php @@ -68,7 +68,6 @@ return array( 'Do you really want to remove this project: "%s"?' => 'Weet u zeker dat u dit project wil verwijderen : « %s » ?', 'Remove project' => 'Project verwijderen', 'Edit the board for "%s"' => 'Bord bewerken voor « %s »', - 'All projects' => 'Alle projecten', 'Add a new column' => 'Kolom toevoegen', 'Title' => 'Titel', 'Assigned to %s' => 'Toegewezen aan %s', @@ -88,7 +87,6 @@ return array( '(VACUUM command)' => '(VACUUM commando)', '(Gzip compressed Sqlite file)' => '(Gzip ingepakt Sqlite bestand)', 'Close a task' => 'Taak sluiten', - 'Edit a task' => 'Taak bewerken', 'Column' => 'Kolom', 'Color' => 'Kleur', 'Assignee' => 'Toegewezene', diff --git a/app/Locale/pl_PL/translations.php b/app/Locale/pl_PL/translations.php index af3bcd4e..c19ebbbe 100644 --- a/app/Locale/pl_PL/translations.php +++ b/app/Locale/pl_PL/translations.php @@ -68,7 +68,6 @@ return array( 'Do you really want to remove this project: "%s"?' => 'Na pewno chcesz usunąć projekt: "%s"?', 'Remove project' => 'Usuń projekt', 'Edit the board for "%s"' => 'Edytuj tablicę dla "%s"', - 'All projects' => 'Wszystkie projekty', 'Add a new column' => 'Dodaj nową kolumnę', 'Title' => 'Nazwa', 'Assigned to %s' => 'Przypisane do %s', @@ -88,7 +87,6 @@ return array( '(VACUUM command)' => '(komenda VACUUM)', '(Gzip compressed Sqlite file)' => '(baza danych spakowana Gzip)', 'Close a task' => 'Zakończ zadanie', - 'Edit a task' => 'Edytuj zadanie', 'Column' => 'Kolumna', 'Color' => 'Kolor', 'Assignee' => 'Odpowiedzialny', diff --git a/app/Locale/pt_BR/translations.php b/app/Locale/pt_BR/translations.php index 2772d8bb..f4ed4f62 100644 --- a/app/Locale/pt_BR/translations.php +++ b/app/Locale/pt_BR/translations.php @@ -68,7 +68,6 @@ return array( 'Do you really want to remove this project: "%s"?' => 'Você realmente deseja remover este projeto: "%s"?', 'Remove project' => 'Remover projeto', 'Edit the board for "%s"' => 'Editar o board para "%s"', - 'All projects' => 'Todos os projetos', 'Add a new column' => 'Adicionar uma nova coluna', 'Title' => 'Título', 'Assigned to %s' => 'Designado para %s', @@ -88,7 +87,6 @@ return array( '(VACUUM command)' => '(Comando VACUUM)', '(Gzip compressed Sqlite file)' => '(Arquivo Sqlite comprimido com Gzip)', 'Close a task' => 'Finalizar uma tarefa', - 'Edit a task' => 'Editar uma tarefa', 'Column' => 'Coluna', 'Color' => 'Cor', 'Assignee' => 'Designação', diff --git a/app/Locale/pt_PT/translations.php b/app/Locale/pt_PT/translations.php index ebc26cd7..1925eef2 100644 --- a/app/Locale/pt_PT/translations.php +++ b/app/Locale/pt_PT/translations.php @@ -68,7 +68,6 @@ return array( 'Do you really want to remove this project: "%s"?' => 'Tem a certeza que quer remover este projecto: "%s" ?', 'Remove project' => 'Remover projecto', 'Edit the board for "%s"' => 'Editar o quadro para "%s"', - 'All projects' => 'Todos os projectos', 'Add a new column' => 'Adicionar uma nova coluna', 'Title' => 'Título', 'Assigned to %s' => 'Designado para %s', @@ -88,7 +87,6 @@ return array( '(VACUUM command)' => '(Comando VACUUM)', '(Gzip compressed Sqlite file)' => '(Arquivo Sqlite comprimido com Gzip)', 'Close a task' => 'Finalizar uma tarefa', - 'Edit a task' => 'Editar uma tarefa', 'Column' => 'Coluna', 'Color' => 'Cor', 'Assignee' => 'Assignado', diff --git a/app/Locale/ru_RU/translations.php b/app/Locale/ru_RU/translations.php index f3ec5af7..74563ad4 100644 --- a/app/Locale/ru_RU/translations.php +++ b/app/Locale/ru_RU/translations.php @@ -68,7 +68,6 @@ return array( 'Do you really want to remove this project: "%s"?' => 'Вы точно хотите удалить проект: "%s"?', 'Remove project' => 'Удалить проект', 'Edit the board for "%s"' => 'Изменить доску для "%s"', - 'All projects' => 'Все проекты', 'Add a new column' => 'Добавить новую колонку', 'Title' => 'Название', 'Assigned to %s' => 'Назначено %s', @@ -88,7 +87,6 @@ return array( '(VACUUM command)' => '(Команда VACUUM)', '(Gzip compressed Sqlite file)' => '(Сжать GZip файл SQLite)', 'Close a task' => 'Закрыть задачу', - 'Edit a task' => 'Изменить задачу', 'Column' => 'Колонка', 'Color' => 'Цвет', 'Assignee' => 'Назначена', diff --git a/app/Locale/sr_Latn_RS/translations.php b/app/Locale/sr_Latn_RS/translations.php index 7e28e9a9..18dbbc65 100644 --- a/app/Locale/sr_Latn_RS/translations.php +++ b/app/Locale/sr_Latn_RS/translations.php @@ -68,7 +68,6 @@ return array( 'Do you really want to remove this project: "%s"?' => 'Da li želiš da ukloniš projekat: "%s"?', 'Remove project' => 'Ukloni projekat', 'Edit the board for "%s"' => 'Izmeni tablu za "%s"', - 'All projects' => 'Svi projekti', 'Add a new column' => 'Dodaj novu kolonu', 'Title' => 'Naslov', 'Assigned to %s' => 'Dodeljen korisniku %s', @@ -88,7 +87,6 @@ return array( '(VACUUM command)' => '(komanda VACUUM)', '(Gzip compressed Sqlite file)' => '(Sqlite baza spakovana Gzip-om)', 'Close a task' => 'Zatvori zadatak', - 'Edit a task' => 'Izmeni zadatak', 'Column' => 'Kolona', 'Color' => 'Boja', 'Assignee' => 'Dodeli', diff --git a/app/Locale/sv_SE/translations.php b/app/Locale/sv_SE/translations.php index 5ad2938c..f7d1a4e4 100644 --- a/app/Locale/sv_SE/translations.php +++ b/app/Locale/sv_SE/translations.php @@ -68,7 +68,6 @@ return array( 'Do you really want to remove this project: "%s"?' => 'Vill du verkligen ta bort projektet: "%s" ?', 'Remove project' => 'Ta bort projekt', 'Edit the board for "%s"' => 'Ändra tavlan för "%s"', - 'All projects' => 'Alla projekt', 'Add a new column' => 'Lägg till ny kolumn', 'Title' => 'Titel', 'Assigned to %s' => 'Tilldelad %s', @@ -88,7 +87,6 @@ return array( '(VACUUM command)' => '(Vacuum kommando)', '(Gzip compressed Sqlite file)' => '(Gzip komprimera Sqlite filen)', 'Close a task' => 'Stäng en uppgift', - 'Edit a task' => 'Ändra en uppgift', 'Column' => 'Kolumn', 'Color' => 'Färg', 'Assignee' => 'Uppdragsinnehavare', diff --git a/app/Locale/th_TH/translations.php b/app/Locale/th_TH/translations.php index 2aee696b..825dab93 100644 --- a/app/Locale/th_TH/translations.php +++ b/app/Locale/th_TH/translations.php @@ -42,11 +42,11 @@ return array( 'Sign in' => 'เข้าสู่ระบบ', 'Users' => 'ผู้ใช้', 'No user' => 'ไม่มีผู้ใช้', - 'Forbidden' => 'ไม่อนุญาติ', - 'Access Forbidden' => 'ไม่อนุญาติให้เข้า', + 'Forbidden' => 'ไม่อนุญาต', + 'Access Forbidden' => 'ไม่อนุญาตให้เข้า', 'Edit user' => 'แก้ไขผู้ใช้', 'Logout' => 'ออกจากระบบ', - 'Bad username or password' => 'ชื่อผู้ใช่หรือรหัสผ่านผิด', + 'Bad username or password' => 'ชื่อผู้ใช้หรือรหัสผ่านผิด', 'Edit project' => 'แก้ไขโปรเจค', 'Name' => 'ชื่อ', 'Projects' => 'โปรเจค', @@ -68,7 +68,6 @@ return array( 'Do you really want to remove this project: "%s"?' => 'คุณต้องการเอาโปรเจค « %s » ออกใช่หรือไม่?', 'Remove project' => 'ลบโปรเจค', 'Edit the board for "%s"' => 'แก้ไขบอร์ดสำหรับ « %s »', - 'All projects' => 'โปรเจคทั้งหมด', 'Add a new column' => 'เพิ่มคอลัมน์ใหม่', 'Title' => 'หัวเรื่อง', 'Assigned to %s' => 'กำหนดให้ %s', @@ -88,7 +87,6 @@ return array( '(VACUUM command)' => '(VACUUM command)', '(Gzip compressed Sqlite file)' => '(Gzip compressed Sqlite file)', 'Close a task' => 'ปิดงาน', - 'Edit a task' => 'แก้ไขงาน', 'Column' => 'คอลัมน์', 'Color' => 'สี', 'Assignee' => 'กำหนดให้', @@ -213,7 +211,7 @@ return array( 'Last logins' => 'เข้าใช้ล่าสุด', 'Login date' => 'วันที่เข้าใข้', 'Authentication method' => 'วิธีการยืนยันตัวตน', - 'IP address' => 'ไอพี แอดเดรส', + 'IP address' => 'ที่อยู่ไอพี', 'User agent' => 'User agent', 'Persistent connections' => 'Persistent connections', 'No session.' => 'No session.', @@ -230,35 +228,35 @@ return array( 'Description' => 'คำอธิบาย', '%d comments' => '%d ความคิดเห็น', '%d comment' => '%d ความคิดเห็น', - 'Email address invalid' => 'อีเมลผิด', - 'Your external account is not linked anymore to your profile.' => 'บัญชีภายนอกของคุณไม่ได้เชื่อมโยงอีกต่อไปในโปรไฟล์ของคุณ', + 'Email address invalid' => 'ที่อยู่อีเมลไม่ถูกต้อง', + 'Your external account is not linked anymore to your profile.' => 'บัญชีภายนอกของคุณไม่ได้เชื่อมโยงมายังโปรไฟล์ของคุณอีกต่อ', 'Unable to unlink your external account.' => 'ไม่สามารถยกเลิกการเชื่อมโยงบัญชีภายนอกของคุณ', 'External authentication failed' => 'การตรวจสอบภายนอกล้มเหลว', - 'Your external account is linked to your profile successfully.' => 'บัญชีภายนอกของคุณลิงค์กับโปรไฟล์ของคุณเรียบร้อย', + 'Your external account is linked to your profile successfully.' => 'ทำการเชื่อมโยงบัญชีภายนอกของคุณกับโปรไฟล์ของคุณเรียบร้อย', 'Email' => 'อีเมล', 'Task removed successfully.' => 'ลบงานเรียบร้อยแล้ว', 'Unable to remove this task.' => 'ไม่สามารถลบงานนี้', - 'Remove a task' => 'ลบงาาน', + 'Remove a task' => 'ลบงาน', 'Do you really want to remove this task: "%s"?' => 'คุณต้องการลบงาน "%s" ออกใช่หรือไม่?', 'Assign automatically a color based on a category' => 'กำหนดสีอัตโนมัติขึ้นอยู่กับหมวด', 'Assign automatically a category based on a color' => 'กำหนดหมวดอัตโนมัติขึ้นอยู่กับสี', 'Task creation or modification' => 'สร้างหรือแก้ไขงาน', - 'Category' => 'หมวด', - 'Category:' => 'หมวด:', - 'Categories' => 'หมวด', - 'Your category have been created successfully.' => 'สร้างหมวดเรียบร้อยแล้ว', - 'Unable to create your category.' => 'ไม่สามารถสร้างหมวดได้', + 'Category' => 'หมวดหมู่', + 'Category:' => 'หมวดหมู่:', + 'Categories' => 'หมวดหมู่', + 'Your category have been created successfully.' => 'สร้างหมวดหมู่เรียบร้อยแล้ว', + 'Unable to create your category.' => 'ไม่สามารถสร้างหมวดหมู่ได้', 'Your category have been updated successfully.' => 'ปรับปรุงหมวดเรียบร้อยแล้ว', - 'Unable to update your category.' => 'ไม่สามารถปรับปรุงหมวดได้', - 'Remove a category' => 'ลบหมวด', + 'Unable to update your category.' => 'ไม่สามารถปรับปรุงหมวดหมู่ได้', + 'Remove a category' => 'ลบหมวดหมู่', 'Category removed successfully.' => 'ลบหมวดเรียบร้อยแล้ว', - 'Unable to remove this category.' => 'ไม่สามารถลบหมวดได้', - 'Category modification for the project "%s"' => 'แก้ไขหมวดสำหรับโปรเจค "%s"', - 'Category Name' => 'ชื่อหมวด', - 'Add a new category' => 'เพิ่มหมวดใหม่', - 'Do you really want to remove this category: "%s"?' => 'คุณต้องการลบหมวด "%s" ใช่หรือไม่?', - 'All categories' => 'หมวดทั้งหมด', - 'No category' => 'ไม่มีหมวด', + 'Unable to remove this category.' => 'ไม่สามารถลบหมวดหมู่ได้', + 'Category modification for the project "%s"' => 'แก้ไขหมวดหมู่สำหรับโปรเจค "%s"', + 'Category Name' => 'ชื่อหมวดหมู่', + 'Add a new category' => 'เพิ่มหมวดหมู่ใหม่', + 'Do you really want to remove this category: "%s"?' => 'คุณต้องการลบหมวดหมู่ "%s" ใช่หรือไม่?', + 'All categories' => 'หมวดหมู่ทั้งหมด', + 'No category' => 'ไม่มีหมวดหมู่', 'The name is required' => 'ต้องการชื่อ', 'Remove a file' => 'ลบไฟล์', 'Unable to remove this file.' => 'ไม่สามารถลบไฟล์ได้', @@ -294,7 +292,7 @@ return array( 'Unable to update your sub-task.' => 'ไม่สามารถปรับปรุงานย่อยได้', 'Unable to create your sub-task.' => 'ไม่สามารถสร้างงานย่อยได้', 'Sub-task added successfully.' => 'เพิ่มงานย่อยเรียบร้อยแล้ว', - 'Maximum size: ' => 'ขนาดสูงสุด:', + 'Maximum size: ' => 'ขนาดไฟล์สูงสุด:', 'Unable to upload the file.' => 'ไม่สามารถอัพโหลดไฟล์ได้', 'Display another project' => 'แสดงโปรเจคอื่น', 'Created by %s' => 'สร้างโดย %s', @@ -355,38 +353,38 @@ return array( 'Password modification' => 'แก้ไขรหัสผ่าน', 'External authentications' => 'การยืนยันภายนอก', 'Never connected.' => 'ไม่เชื่อมต่อ', - 'No external authentication enabled.' => 'ไม่เปิดการใช้งานการยืนยันภายนอก', - 'Password modified successfully.' => 'แก้ไขรหัสผ่านเรียบร้อยแล้ว', + 'No external authentication enabled.' => 'ปิดการใช้งานการยืนยันภายนอก', + 'Password modified successfully.' => 'แก้ไขรหัสผ่านเรียบร้อย', 'Unable to change the password.' => 'ไม่สามารถเปลี่ยนรหัสผ่านได้', - 'Change category' => 'เปลี่ยนหมวด', - '%s updated the task %s' => '%s ปรับปรุงงานแล้ว %s', - '%s opened the task %s' => '%s เปิดงานแล้ว %s', - '%s moved the task %s to the position #%d in the column "%s"' => '%s ย้ายงานแล้ว %s ไปตำแหน่ง #%d ในคอลัมน์ "%s"', - '%s moved the task %s to the column "%s"' => '%s ย้ายงานแล้ว %s ไปคอลัมน์ "%s"', - '%s created the task %s' => '%s สร้างงานแล้ว %s', - '%s closed the task %s' => '%s ปิดงานแล้ว %s', - '%s created a subtask for the task %s' => '%s สร้างงานย่อยสำหรับงานแล้ว %s', - '%s updated a subtask for the task %s' => '%s ปรับปรุงงานย่อยสำหรับงานแล้ว %s', - 'Assigned to %s with an estimate of %s/%sh' => 'กำหนดให้ %s โดยประมาณแล้ว %s/%sh', - 'Not assigned, estimate of %sh' => 'ไม่กำหนดแล้ว, ประมาณเวลาที่ใช้ %s ชั่วโมง', - '%s updated a comment on the task %s' => '%s ปรับปรุงความคิดเห็นในงานแล้ว %s', - '%s commented the task %s' => '%s แสดงความคิดเห็นของงานแล้ว %s', + 'Change category' => 'เปลี่ยนหมวดหมู่', + '%s updated the task %s' => '%s ได้ปรับปรุงงาน %s', + '%s opened the task %s' => '%s ได้สร้างงาน %s', + '%s moved the task %s to the position #%d in the column "%s"' => '%s ได้ย้ายงาน %s ไปยังตำแหน่ง #%d ในคอลัมน์ "%s"', + '%s moved the task %s to the column "%s"' => '%s ได้ย้ายงาน %s ไปยังคอลัมน์ "%s"', + '%s created the task %s' => '%s ได้สร้างงาน %s', + '%s closed the task %s' => '%s ได้ปิดงาน %s', + '%s created a subtask for the task %s' => '%s ได้สร้างงานย่อยสำหรับงาน %s', + '%s updated a subtask for the task %s' => '%s ได้ปรับปรุงงานย่อยสำหรับงาน %s', + 'Assigned to %s with an estimate of %s/%sh' => 'มอบหมายให้ %s โดยประมาณเวลาที่ใช้ %s/%sh', + 'Not assigned, estimate of %sh' => 'ไม่ระบุผู้รับผิดชอบ, ประมาณเวลาที่ใช้ %s ชั่วโมง', + '%s updated a comment on the task %s' => '%s ได้ปรับปรุงความคิดเห็นในงาน %s', + '%s commented the task %s' => '%s ได้แสดงความคิดเห็นในงาน %s', '%s\'s activity' => 'กิจกรรม %s', 'RSS feed' => 'RSS feed', - '%s updated a comment on the task #%d' => '%s ปรับปรุงความคิดเห็นบนงานแล้ว #%d', - '%s commented on the task #%d' => '%s แสดงความคิดเห็นบนงานแล้ว #%d', - '%s updated a subtask for the task #%d' => '%s ปรับปรุงงานย่อยสำหรับงานแล้ว #%d', - '%s created a subtask for the task #%d' => '%s สร้างงานย่อยสำหรับงานแล้ว #%d', - '%s updated the task #%d' => '%s ปรับปรุงงานแล้ว #%d', - '%s created the task #%d' => '%s สร้างงานแล้ว #%d', - '%s closed the task #%d' => '%s ปิดงานแล้ว #%d', - '%s opened the task #%d' => '%s เปิดงานแล้ว #%d', + '%s updated a comment on the task #%d' => '%s ได้ปรับปรุงความคิดเห็นในงาน #%d', + '%s commented on the task #%d' => '%s ได้แสดงความคิดเห็นบนงาน #%d', + '%s updated a subtask for the task #%d' => '%s ได้ปรับปรุงงานย่อยสำหรับงาน #%d', + '%s created a subtask for the task #%d' => '%s ได้สร้างงานย่อยสำหรับงาน #%d', + '%s updated the task #%d' => '%s ได้ปรับปรุงงาน #%d', + '%s created the task #%d' => '%s ได้สร้างงาน #%d', + '%s closed the task #%d' => '%s ได้ปิดงาน #%d', + '%s opened the task #%d' => '%s ได้เปิดงาน #%d', 'Activity' => 'กิจกรรม', 'Default values are "%s"' => 'ค่าเริ่มต้น "%s"', 'Default columns for new projects (Comma-separated)' => 'คอลัมน์เริ่มต้นสำหรับโปรเจคใหม่ (Comma-separated)', 'Task assignee change' => 'เปลี่ยนการกำหนดบุคคลของงาน', - '%s changed the assignee of the task #%d to %s' => '%s เปลี่ยนผู้รับผิดชอบของงาน #%d เป็น %s', - '%s changed the assignee of the task %s to %s' => '%s เปลี่ยนผู้รับผิดชอบของงาน %s เป็น %s', + '%s changed the assignee of the task #%d to %s' => '%s ได้เปลี่ยนผู้รับผิดชอบงาน #%d เป็น %s', + '%s changed the assignee of the task %s to %s' => '%s ได้เปลี่ยนผู้รับผิดชอบงาน %s เป็น %s', 'New password for the user "%s"' => 'รหัสผ่านใหม่สำหรับผู้ใช้ "%s"', 'Choose an event' => 'เลือกเหตุการณ์', 'Create a task from an external provider' => 'สร้างงานจากบริการภายนอก', @@ -401,8 +399,8 @@ return array( // 'Webhook settings' => '', // 'Reset token' => '', // 'API endpoint:' => '', - 'Refresh interval for private board' => 'ระยะรีเฟรชบอร์ดส่วนตัว', - 'Refresh interval for public board' => 'ระยะรีเฟรชบอร์ดสาธารณะ', + 'Refresh interval for private board' => 'ระยะเวลารีเฟรชบอร์ดส่วนตัว', + 'Refresh interval for public board' => 'ระยะเวลารีเฟรชบอร์ดสาธารณะ', 'Task highlight period' => 'ช่วงเวลาไฮไลต์งาน', 'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => 'ช่วงเวลา (เป็นวินาที) ใช้ในการตัดสินใจว่าเป็นการแก้ไขเร็วๆ นี้ (0 ไม่ใช้งาน, ค่าเริ่มต้น 2 วัน)', 'Frequency in second (60 seconds by default)' => 'ความถี่ (ค่าเริ่มต้นทุก 60 วินาที) ', @@ -430,7 +428,7 @@ return array( 'My projects' => 'โปรเจคของฉัน', 'Columns' => 'คอลัมน์', 'Task' => 'งาน', - 'Your are not member of any project.' => 'คุณไม่ได้เป็นสมาชิกของโปรเจค', + 'Your are not member of any project.' => 'คุณไม่ได้เป็นสมาชิกของโปรเจคใดๆ', 'Percentage' => 'เปอร์เซ็นต์', 'Number of tasks' => 'จำนวนงาน', 'Task distribution' => 'การกระจายงาน', @@ -438,18 +436,18 @@ return array( 'Subtask' => 'งานย่อย', 'My subtasks' => 'งานย่อยของฉัน', 'User repartition' => 'การแบ่งงานของผู้ใช้', - 'Clone this project' => 'เลียนแบบโปรเจคนี้', + 'Clone this project' => 'สำเนาโปรเจคนี้', 'Column removed successfully.' => 'ลบคอลัมน์สำเร็จ', - 'Not enough data to show the graph.' => 'ไม่มีข้อมูลแสดงเป็นกราฟ', + 'Not enough data to show the graph.' => 'ไม่มีข้อมูลเพียงพอสำหรับการแสดงกราฟ', 'Previous' => 'ก่อนหน้า', 'The id must be an integer' => 'ไอดีต้องเป็นตัวเลขจำนวนเต็ม', - 'The project id must be an integer' => 'ไอดีโปรเจคต้องเป็นตัวเลข', - 'The status must be an integer' => 'สถานะต้องเป็นตัวเลข', + 'The project id must be an integer' => 'ไอดีโปรเจคต้องเป็นตัวเลขเท่านั้น', + 'The status must be an integer' => 'สถานะต้องเป็นตัวเลขเท่านั้น', 'The subtask id is required' => 'ต้องการงานย่อย', - 'The subtask id must be an integer' => 'ไอดีงานย่อยต้องเป็นตัวเลข', + 'The subtask id must be an integer' => 'ไอดีงานย่อยต้องเป็นตัวเลขเท่านั้น', 'The task id is required' => 'ต้องการไอดีงาน', - 'The task id must be an integer' => 'ไอดีงานต้องเป็นตัวเลข', - 'The user id must be an integer' => 'ไอดีผู้ใช้ต้องเป็นตัวเลข', + 'The task id must be an integer' => 'ไอดีงานต้องเป็นตัวเลขเท่านั้น', + 'The user id must be an integer' => 'ไอดีผู้ใช้ต้องเป็นตัวเลขเท่านั้น', 'This value is required' => 'ต้องการค่านี้', 'This value must be numeric' => 'ค่านี้ต้องเป็นตัวเลข', 'Unable to create this task.' => 'ไม่สามารถสร้างงานนี้', @@ -478,7 +476,7 @@ return array( 'Default categories for new projects (Comma-separated)' => 'ค่าเริ่มต้นหมวดสำหรับโปรเจคใหม่ (Comma-separated)', 'Integrations' => 'การใช้ร่วมกัน', 'Integration with third-party services' => 'การใช้งานร่วมกับบริการ third-party', - 'Subtask Id' => 'รหัสงานย่อย', + 'Subtask Id' => 'ไอดีของงานย่อย', 'Subtasks' => 'งานย่อย', 'Subtasks Export' => 'ส่งออก งานย่อย', 'Task Title' => 'ชื่องาน', @@ -511,7 +509,7 @@ return array( 'Add a new link' => 'เพิ่มลิงค์ใหม่', 'Do you really want to remove this link: "%s"?' => 'คุณต้องการลบลิงค์นี้: "%s"?', 'Do you really want to remove this link with task #%d?' => 'คุณต้องการลบลิงค์นี้ของงาน #%d?', - 'Field required' => 'ต้องใส่', + 'Field required' => 'จำเป็นต้องใส่', 'Link added successfully.' => 'เพิ่มลิงค์เรียบร้อยแล้ว', 'Link updated successfully.' => 'ปรับปรุงลิงค์เรียบร้อยแล้ว', 'Link removed successfully.' => 'ลบลิงค์เรียบร้อยแล้ว', @@ -931,11 +929,11 @@ return array( 'Remove this user' => 'เอาผู้ใช้คนนี้ออก', 'Permissions' => 'การอนุญาตใช้งาน', 'Allowed Users' => 'การอนุญาตผู้ใช้', - 'No user have been allowed specifically.' => 'ไม่มีผู้ใช้ได้รับอนุญาติเป็นพิเศษ', + 'No user have been allowed specifically.' => 'ไม่มีผู้ใช้ได้รับอนุญาตเป็นพิเศษ', 'Role' => 'บทบาท', 'Enter user name...' => 'พิมพ์ชื่อผู้ใช้...', 'Allowed Groups' => 'อนุญาตกลุ่ม', - 'No group have been allowed specifically.' => 'ไม่มีกลุ่มได้รับอนุญาติเป็นพิเศษ', + 'No group have been allowed specifically.' => 'ไม่มีกลุ่มได้รับอนุญาตเป็นพิเศษ', 'Group' => 'กลุ่ม', 'Group Name' => 'ชื่อกลุ่ม', 'Enter group name...' => 'พิมพ์ชื่อกลุ่ม...', diff --git a/app/Locale/tr_TR/translations.php b/app/Locale/tr_TR/translations.php index 69642b58..7eb5c2aa 100644 --- a/app/Locale/tr_TR/translations.php +++ b/app/Locale/tr_TR/translations.php @@ -68,7 +68,6 @@ return array( 'Do you really want to remove this project: "%s"?' => 'Bu projeyi gerçekten silmek istiyor musunuz: "%s"?', 'Remove project' => 'Projeyi sil', 'Edit the board for "%s"' => 'Tabloyu "%s" için güncelle', - 'All projects' => 'Tüm projeler', 'Add a new column' => 'Yeni sütun ekle', 'Title' => 'Başlık', 'Assigned to %s' => '%s kullanıcısına atanmış', @@ -88,7 +87,6 @@ return array( '(VACUUM command)' => '(VACUUM komutu)', '(Gzip compressed Sqlite file)' => '(Gzip ile sıkıştırılmış Sqlite dosyası)', 'Close a task' => 'Bir görevi kapat', - 'Edit a task' => 'Bir görevi düzenle', 'Column' => 'Sütun', 'Color' => 'Renk', 'Assignee' => 'Atanan', diff --git a/app/Locale/zh_CN/translations.php b/app/Locale/zh_CN/translations.php index b4e9c063..f28434d2 100644 --- a/app/Locale/zh_CN/translations.php +++ b/app/Locale/zh_CN/translations.php @@ -68,7 +68,6 @@ return array( 'Do you really want to remove this project: "%s"?' => '确定要移除项目"%s"吗?', 'Remove project' => '移除项目', 'Edit the board for "%s"' => '为"%s"修改看板', - 'All projects' => '所有项目', 'Add a new column' => '添加新栏目', 'Title' => '标题', 'Assigned to %s' => '指派给 %s', @@ -88,7 +87,6 @@ return array( '(VACUUM command)' => '(VACUUM 指令)', '(Gzip compressed Sqlite file)' => '(用Gzip压缩的Sqlite文件)', 'Close a task' => '关闭一个任务', - 'Edit a task' => '修改一个任务', 'Column' => '栏目', 'Color' => '颜色', 'Assignee' => '负责人', diff --git a/app/Model/ActionParameterModel.php b/app/Model/ActionParameterModel.php index 9895da0f..cdac396e 100644 --- a/app/Model/ActionParameterModel.php +++ b/app/Model/ActionParameterModel.php @@ -157,6 +157,9 @@ class ActionParameterModel extends Base case 'user_id': case 'owner_id': return $this->projectPermissionModel->isAssignable($project_id, $value) ? $value : false; + case 'swimlane_id': + $column = $this->swimlaneModel->getById($value); + return empty($column) ? false : $this->swimlaneModel->getIdByName($project_id, $column['name']) ?: false; default: return $value; } diff --git a/app/Model/UserMetadataModel.php b/app/Model/UserMetadataModel.php index e931d3ba..42fe4c6d 100644 --- a/app/Model/UserMetadataModel.php +++ b/app/Model/UserMetadataModel.php @@ -10,6 +10,9 @@ namespace Kanboard\Model; */ class UserMetadataModel extends MetadataModel { + const KEY_COMMENT_SORTING_DIRECTION = 'comment.sorting.direction'; + const KEY_BOARD_COLLAPSED = 'board.collapsed.'; + /** * Get the table * diff --git a/app/ServiceProvider/ActionProvider.php b/app/ServiceProvider/ActionProvider.php index 946fbf41..d46562b7 100644 --- a/app/ServiceProvider/ActionProvider.php +++ b/app/ServiceProvider/ActionProvider.php @@ -36,6 +36,8 @@ use Kanboard\Action\TaskOpen; use Kanboard\Action\TaskUpdateStartDate; use Kanboard\Action\TaskCloseNoActivity; use Kanboard\Action\TaskCloseNoActivityColumn; +use Kanboard\Action\TaskAssignColorSwimlane; +use Kanboard\Action\TaskAssignPrioritySwimlane; /** * Action Provider @@ -86,6 +88,8 @@ class ActionProvider implements ServiceProviderInterface $container['actionManager']->register(new TaskOpen($container)); $container['actionManager']->register(new TaskUpdateStartDate($container)); $container['actionManager']->register(new TaskAssignDueDateOnCreation($container)); + $container['actionManager']->register(new TaskAssignColorSwimlane($container)); + $container['actionManager']->register(new TaskAssignPrioritySwimlane($container)); return $container; } diff --git a/app/ServiceProvider/AuthenticationProvider.php b/app/ServiceProvider/AuthenticationProvider.php index 978bc05b..adff1e63 100644 --- a/app/ServiceProvider/AuthenticationProvider.php +++ b/app/ServiceProvider/AuthenticationProvider.php @@ -151,7 +151,7 @@ class AuthenticationProvider implements ServiceProviderInterface $acl->add('UserCreationController', '*', Role::APP_ADMIN); $acl->add('UserListController', '*', Role::APP_ADMIN); $acl->add('UserStatusController', '*', Role::APP_ADMIN); - $acl->add('UserCredentialController', array('changeAuthentication', 'saveAuthentication'), Role::APP_ADMIN); + $acl->add('UserCredentialController', array('changeAuthentication', 'saveAuthentication', 'unlock'), Role::APP_ADMIN); return $acl; } diff --git a/app/ServiceProvider/CacheProvider.php b/app/ServiceProvider/CacheProvider.php new file mode 100644 index 00000000..fac44d53 --- /dev/null +++ b/app/ServiceProvider/CacheProvider.php @@ -0,0 +1,51 @@ +<?php + +namespace Kanboard\ServiceProvider; + +use Kanboard\Core\Cache\FileCache; +use Kanboard\Core\Cache\MemoryCache; +use Kanboard\Decorator\MetadataCacheDecorator; +use Pimple\Container; +use Pimple\ServiceProviderInterface; + +/** + * Cache Provider + * + * @package Kanboard\ServiceProvider + * @author Frederic Guillot + */ +class CacheProvider implements ServiceProviderInterface +{ + /** + * Register providers + * + * @access public + * @param \Pimple\Container $container + * @return \Pimple\Container + */ + public function register(Container $container) + { + $container['memoryCache'] = function() { + return new MemoryCache(); + }; + + if (CACHE_DRIVER === 'file') { + $container['cacheDriver'] = function() { + return new FileCache(); + }; + } else { + $container['cacheDriver'] = $container['memoryCache']; + } + + $container['userMetadataCacheDecorator'] = function($c) { + return new MetadataCacheDecorator( + $c['cacheDriver'], + $c['userMetadataModel'], + 'user.metadata.', + $c['userSession']->getId() + ); + }; + + return $container; + } +} diff --git a/app/ServiceProvider/ClassProvider.php b/app/ServiceProvider/ClassProvider.php index aab41c74..d837500a 100644 --- a/app/ServiceProvider/ClassProvider.php +++ b/app/ServiceProvider/ClassProvider.php @@ -140,9 +140,6 @@ class ClassProvider implements ServiceProviderInterface 'Response', 'RememberMeCookie', ), - 'Core\Cache' => array( - 'MemoryCache', - ), 'Core\Plugin' => array( 'Hook', ), diff --git a/app/Template/action/index.php b/app/Template/action/index.php index 085ea3ad..7768a0b6 100644 --- a/app/Template/action/index.php +++ b/app/Template/action/index.php @@ -54,6 +54,8 @@ <?= $this->text->in($param_value, $categories_list) ?> <?php elseif ($this->text->contains($param_name, 'link_id')): ?> <?= $this->text->in($param_value, $links_list) ?> + <?php elseif ($this->text->contains($param_name, 'swimlane_id')): ?> + <?= $this->text->in($param_value, $swimlane_list) ?> <?php else: ?> <?= $this->text->e($param_value) ?> <?php endif ?> diff --git a/app/Template/action_creation/params.php b/app/Template/action_creation/params.php index fa892177..c9608f21 100644 --- a/app/Template/action_creation/params.php +++ b/app/Template/action_creation/params.php @@ -41,6 +41,9 @@ <?php elseif ($this->text->contains($param_name, 'duration')): ?> <?= $this->form->label($param_desc, $param_name) ?> <?= $this->form->number('params['.$param_name.']', $values) ?> + <?php elseif ($this->text->contains($param_name, 'swimlane_id')): ?> + <?= $this->form->label($param_desc, $param_name) ?> + <?= $this->form->select('params['.$param_name.']', $swimlane_list, $values) ?> <?php else: ?> <?= $this->form->label($param_desc, $param_name) ?> <?= $this->form->text('params['.$param_name.']', $values) ?> diff --git a/app/Template/board/task_footer.php b/app/Template/board/task_footer.php index bc34363c..650fe559 100644 --- a/app/Template/board/task_footer.php +++ b/app/Template/board/task_footer.php @@ -81,8 +81,10 @@ </span> <?php endif ?> - <?php if (! empty($task['time_estimated'])): ?> - <span class="task-time-estimated" title="<?= t('Time estimated') ?>"><?= $this->text->e($task['time_estimated']).'h' ?></span> + <?php if (! empty($task['time_estimated']) || ! empty($task['time_spent'])): ?> + <span class="task-time-estimated" title="<?= t('Time spent and estimated') ?>"> + <?= $this->text->e($task['time_spent']) ?>/<?= $this->text->e($task['time_estimated']) ?>h + </span> <?php endif ?> <?php if ($task['is_milestone'] == 1): ?> diff --git a/app/Template/dashboard/notifications.php b/app/Template/dashboard/notifications.php index a189d74f..4fb59e24 100644 --- a/app/Template/dashboard/notifications.php +++ b/app/Template/dashboard/notifications.php @@ -15,13 +15,27 @@ <table class="table-striped table-scrolling table-small"> <tr> + <th class="column-20"><?= t('Project') ?></th> <th><?= t('Notification') ?></th> - <th class="column-20"><?= t('Date') ?></th> + <th class="column-15"><?= t('Date') ?></th> <th class="column-15"><?= t('Action') ?></th> </tr> <?php foreach ($notifications as $notification): ?> <tr> <td> + <?php if (isset($notification['event_data']['task']['project_name'])): ?> + <?= $this->url->link( + $this->text->e($notification['event_data']['task']['project_name']), + 'BoardViewController', + 'show', + array('project_id' => $notification['event_data']['task']['project_id']) + ) + ?> + <?php elseif (isset($notification['event_data']['project_name'])): ?> + <?= $this->text->e($notification['event_data']['project_name']) ?> + <?php endif ?> + </td> + <td> <?php if ($this->text->contains($notification['event_name'], 'subtask')): ?> <i class="fa fa-tasks fa-fw"></i> <?php elseif ($this->text->contains($notification['event_name'], 'task.move')): ?> diff --git a/app/Template/project_list/show.php b/app/Template/project_list/show.php index 8e4c3e6a..4f7c2e83 100644 --- a/app/Template/project_list/show.php +++ b/app/Template/project_list/show.php @@ -1,12 +1,14 @@ <section id="main"> <div class="page-header"> <ul> + <?= $this->hook->render('template:project-list:menu:before', array('project' => $project)) ?> <?php if ($this->user->hasAccess('ProjectUserOverviewController', 'managers')): ?> <li><i class="fa fa-user fa-fw"></i><?= $this->url->link(t('Users overview'), 'ProjectUserOverviewController', 'managers') ?></li> <?php endif ?> <?php if ($this->user->hasAccess('ProjectGanttController', 'show')): ?> <li><i class="fa fa-sliders fa-fw"></i><?= $this->url->link(t('Projects Gantt chart'), 'ProjectGanttController', 'show') ?></li> <?php endif ?> + <?= $this->hook->render('template:project-list:menu:after', array('project' => $project)) ?> </ul> </div> <?php if ($paginator->isEmpty()): ?> diff --git a/app/Template/user_view/show.php b/app/Template/user_view/show.php index fc11f8a1..2f5a73af 100644 --- a/app/Template/user_view/show.php +++ b/app/Template/user_view/show.php @@ -18,6 +18,11 @@ <li><?= t('Number of failed login:') ?> <strong><?= $user['nb_failed_login'] ?></strong></li> <?php if ($user['lock_expiration_date'] != 0): ?> <li><?= t('Account locked until:') ?> <strong><?= $this->dt->datetime($user['lock_expiration_date']) ?></strong></li> + <?php if ($this->user->isAdmin()): ?> + <li> + <?= $this->url->link(t('Unlock this user'), 'UserCredentialController', 'unlock', array('user_id' => $user['id']), true) ?> + </li> + <?php endif ?> <?php endif ?> </ul> diff --git a/app/common.php b/app/common.php index 15fd7a75..e5490c11 100644 --- a/app/common.php +++ b/app/common.php @@ -35,6 +35,7 @@ $container->register(new Kanboard\ServiceProvider\MailProvider()); $container->register(new Kanboard\ServiceProvider\HelperProvider()); $container->register(new Kanboard\ServiceProvider\SessionProvider()); $container->register(new Kanboard\ServiceProvider\LoggingProvider()); +$container->register(new Kanboard\ServiceProvider\CacheProvider()); $container->register(new Kanboard\ServiceProvider\DatabaseProvider()); $container->register(new Kanboard\ServiceProvider\AuthenticationProvider()); $container->register(new Kanboard\ServiceProvider\NotificationProvider()); diff --git a/app/constants.php b/app/constants.php index 40b88fe9..3adb0835 100644 --- a/app/constants.php +++ b/app/constants.php @@ -12,6 +12,12 @@ defined('DATA_DIR') or define('DATA_DIR', ROOT_DIR.DIRECTORY_SEPARATOR.'data'); // Files directory (attachments) defined('FILES_DIR') or define('FILES_DIR', DATA_DIR.DIRECTORY_SEPARATOR.'files'); +// Available cache drivers are "file" and "memory" +defined('CACHE_DRIVER') or define('CACHE_DRIVER', 'memory'); + +// Cache folder (file driver) +defined('CACHE_DIR') or define('CACHE_DIR', DATA_DIR.DIRECTORY_SEPARATOR.'cache'); + // Plugins settings defined('PLUGINS_DIR') or define('PLUGINS_DIR', ROOT_DIR.DIRECTORY_SEPARATOR.'plugins'); defined('PLUGIN_API_URL') or define('PLUGIN_API_URL', 'https://kanboard.net/plugins.json'); |