Merge remote-tracking branch 'refs/remotes/upstream/master'

Conflicts:
	app/Locale/de_DE/translations.php
This commit is contained in:
85pando 2016-02-05 10:28:40 +01:00
commit 791d13c87b
280 changed files with 7983 additions and 4826 deletions

View File

@ -5,9 +5,11 @@ Original author and main developer: Frédéric Guillot (fguillot)
Contributors:
- [85pando](https://github.com/85pando)
- Alex Butum
- [Aleix Pol](https://github.com/aleixpol)
- [Ally Raza](https://github.com/alirz23)
- [Angystardust](https://github.com/angystardust)
- [Anjar Febrianto](https://github.com/Lasut)
- [Ashbike](https://github.com/ashbike)
- [Ashish Kulkarni](https://github.com/ashkulz)
@ -21,6 +23,7 @@ Contributors:
- [Crash5](https://github.com/crash5)
- [Creador30](https://github.com/creador30)
- [Cynthia Pereira](https://github.com/cynthiapereira)
- [d4rk5eed](https://github.com/d4rk5eed)
- [Damian](https://github.com/dromek)
- [Daniel Raknes](https://github.com/danielraknes)
- [David-Norris](https://github.com/David-Norris)
@ -40,6 +43,7 @@ Contributors:
- [Jan Dittrich](https://github.com/jdittrich)
- [Janne Mäntyharju](https://github.com/JanneMantyharju)
- [Jean-François Magnier](https://github.com/lefakir)
- [Jeff Guillou](https://github.com/jf-guillou)
- [Jesusaplsoft](https://github.com/jesusaplsoft)
- [Jesús Marín](https://github.com/alu0100502114)
- [Jules Verhaeren](https://github.com/julesverhaeren)
@ -91,6 +95,7 @@ Contributors:
- [Sebastien Pacilly](https://github.com/spacilly)
- [Sebastian Reese](https://github.com/ReeseSebastian)
- [Semyon Novikov](https://github.com/semka)
- [StavrosKa](https://github.com/StavrosKa)
- [Sylvain Veyrié](https://github.com/turb)
- [Thomas Lutz](https://github.com/phoen1x)
- [Timo](https://github.com/BlueTeck)
@ -98,10 +103,12 @@ Contributors:
- [Tomáš Votruba](https://github.com/TomasVotruba)
- [Toomyem](https://github.com/Toomyem)
- [Tony G. Bolaño](https://github.com/tonybolanyo)
- [Trapulo](https://github.com/Trapulo)
- [Torsten](https://github.com/misterfu)
- [Troloo](https://github.com/troloo)
- [Typz](https://github.com/Typz)
- [Vedovator](https://github.com/vedovator)
- [Vitaliy S. Orlov](https://github.com/orlov0562)
- [Vladimir Babin](https://github.com/Chiliec)
- [Yannick Ihmels](https://github.com/ihmels)
- [Ybarc](https://github.com/ybarc)

View File

@ -1,10 +1,38 @@
Version 1.0.25 (unreleased)
--------------
Breaking changes:
* Core functionalities moved to external plugins:
- Google Auth: https://github.com/kanboard/plugin-google-auth
- Github Auth: https://github.com/kanboard/plugin-github-auth
- Gitlab Auth: https://github.com/kanboard/plugin-gitlab-auth
New features:
* When creating a new project, have the possibility to select another project to duplicate
* Add a "Me" button to assignee form element
* Add external links for tasks with plugin api
* Add project owner (Directly Responsible Individual)
* Add configurable task priority
* Add Greek translation
* Add automatic actions to close tasks with no activity
* Add automatic actions to send an email when there is no activity on a task
* Regroup all daily background tasks in one command: "cronjob"
Improvements:
* Do not refresh the whole page when changing subtask status (work in progress)
* Add dropdown menu with inline popup for all task actions
* Change sidebar style
* Change task summary layout
* Use inline popup for subtasks modification
* Move homepage menus to the user dropdown
* Have a new task assigned to the creator by default instead of "no assignee"
* Show progress for task links in board tooltips
* Simplify code to handle ajax popover and redirects
* Simplify layout and templates generation
* Move task form elements to Task helper
Version 1.0.24
--------------

View File

@ -1,12 +1,12 @@
BUILD_DIR = /tmp
CSS_APP = $(addprefix assets/css/src/, $(addsuffix .css, base links title table form button alert tooltip header board task comment subtask markdown listing activity dashboard pagination popover confirm sidebar responsive dropdown screenshot filters gantt))
CSS_APP = $(addprefix assets/css/src/, $(addsuffix .css, base links title table form button alert tooltip header board task comment subtask markdown listing activity dashboard pagination popover confirm sidebar responsive dropdown screenshot filters gantt project))
CSS_PRINT = $(addprefix assets/css/src/, $(addsuffix .css, print links table board task comment subtask markdown))
CSS_VENDOR = $(addprefix assets/css/vendor/, $(addsuffix .css, jquery-ui.min jquery-ui-timepicker-addon.min chosen.min fullcalendar.min font-awesome.min c3.min))
JS_APP = $(addprefix assets/js/src/, $(addsuffix .js, Popover Dropdown Tooltip Markdown Sidebar Search App Screenshot Calendar Board Swimlane Gantt Task Project TaskRepartitionChart UserRepartitionChart CumulativeFlowDiagram BurndownChart AvgTimeColumnChart TaskTimeColumnChart LeadCycleTimeChart CompareHoursColumnChart Router))
JS_APP = $(addprefix assets/js/src/, $(addsuffix .js, Popover Dropdown Tooltip Markdown Search App Screenshot Calendar Board Swimlane Gantt Task Project TaskRepartitionChart UserRepartitionChart CumulativeFlowDiagram BurndownChart AvgTimeColumnChart TaskTimeColumnChart LeadCycleTimeChart CompareHoursColumnChart Router))
JS_VENDOR = $(addprefix assets/js/vendor/, $(addsuffix .js, jquery-1.11.3.min jquery-ui.min jquery-ui-timepicker-addon.min jquery.ui.touch-punch.min chosen.jquery.min moment.min fullcalendar.min mousetrap.min mousetrap-global-bind.min jquery.textcomplete))
JS_LANG = $(addprefix assets/js/vendor/lang/, $(addsuffix .js, cs da de es fi fr hu id it ja nl nb pl pt pt-br ru sv sr th tr zh-cn))
JS_LANG = $(addprefix assets/js/vendor/lang/, $(addsuffix .js, cs da de es el fi fr hu id it ja nl nb pl pt pt-br ru sv sr th tr zh-cn))
all: css js

View File

@ -125,7 +125,7 @@ abstract class Base extends \Kanboard\Core\Base
$params[] = $key.'='.var_export($value, true);
}
return $this->getName().'('.implode('|', $params).'])';
return $this->getName().'('.implode('|', $params).')';
}
/**

View File

@ -0,0 +1,95 @@
<?php
namespace Kanboard\Action;
use Kanboard\Model\Task;
/**
* Close automatically a task after when inactive
*
* @package action
* @author Frederic Guillot
*/
class TaskCloseNoActivity extends Base
{
/**
* Get automatic action description
*
* @access public
* @return string
*/
public function getDescription()
{
return t('Close a task when there is no activity');
}
/**
* Get the list of compatible events
*
* @access public
* @return array
*/
public function getCompatibleEvents()
{
return array(Task::EVENT_DAILY_CRONJOB);
}
/**
* Get the required parameter for the action (defined by the user)
*
* @access public
* @return array
*/
public function getActionRequiredParameters()
{
return array(
'duration' => t('Duration in days')
);
}
/**
* Get the required parameter for the event
*
* @access public
* @return string[]
*/
public function getEventRequiredParameters()
{
return array('tasks');
}
/**
* Execute the action (close the task)
*
* @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)
{
$results = array();
$max = $this->getParam('duration') * 86400;
foreach ($data['tasks'] as $task) {
$duration = time() - $task['date_modification'];
if ($duration > $max) {
$results[] = $this->taskStatus->close($task['id']);
}
}
return in_array(true, $results, true);
}
/**
* 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 count($data['tasks']) > 0;
}
}

View File

@ -0,0 +1,124 @@
<?php
namespace Kanboard\Action;
use Kanboard\Model\Task;
/**
* Email a task with no activity
*
* @package action
* @author Frederic Guillot
*/
class TaskEmailNoActivity extends Base
{
/**
* Get automatic action description
*
* @access public
* @return string
*/
public function getDescription()
{
return t('Send email when there is no activity on a task');
}
/**
* Get the list of compatible events
*
* @access public
* @return array
*/
public function getCompatibleEvents()
{
return array(
Task::EVENT_DAILY_CRONJOB,
);
}
/**
* Get the required parameter for the action (defined by the user)
*
* @access public
* @return array
*/
public function getActionRequiredParameters()
{
return array(
'user_id' => t('User that will receive the email'),
'subject' => t('Email subject'),
'duration' => t('Duration in days'),
);
}
/**
* Get the required parameter for the event
*
* @access public
* @return string[]
*/
public function getEventRequiredParameters()
{
return array('tasks');
}
/**
* 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 count($data['tasks']) > 0;
}
/**
* Execute the action (move the task to another column)
*
* @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)
{
$results = array();
$max = $this->getParam('duration') * 86400;
$user = $this->user->getById($this->getParam('user_id'));
if (! empty($user['email'])) {
foreach ($data['tasks'] as $task) {
$duration = time() - $task['date_modification'];
if ($duration > $max) {
$results[] = $this->sendEmail($task['id'], $user);
}
}
}
return in_array(true, $results, true);
}
/**
* Send email
*
* @access private
* @param integer $task_id
* @param array $user
* @return boolean
*/
private function sendEmail($task_id, array $user)
{
$task = $this->taskFinder->getDetails($task_id);
$this->emailClient->send(
$user['email'],
$user['name'] ?: $user['username'],
$this->getParam('subject'),
$this->template->render('notification/task_create', array('task' => $task, 'application_url' => $this->config->get('application_url')))
);
return true;
}
}

View File

@ -21,6 +21,11 @@ class User extends \Kanboard\Core\Base
return $this->user->getById($user_id);
}
public function getUserByName($username)
{
return $this->user->getByUsername($username);
}
public function getAllUsers()
{
return $this->user->getAll();

View File

@ -1,143 +0,0 @@
<?php
namespace Kanboard\Auth;
use Kanboard\Core\Base;
use Kanboard\Core\Security\OAuthAuthenticationProviderInterface;
use Kanboard\User\GithubUserProvider;
/**
* Github Authentication Provider
*
* @package auth
* @author Frederic Guillot
*/
class GithubAuth extends Base implements OAuthAuthenticationProviderInterface
{
/**
* User properties
*
* @access protected
* @var \Kanboard\User\GithubUserProvider
*/
protected $userInfo = null;
/**
* OAuth2 instance
*
* @access protected
* @var \Kanboard\Core\Http\OAuth2
*/
protected $service;
/**
* OAuth2 code
*
* @access protected
* @var string
*/
protected $code = '';
/**
* Get authentication provider name
*
* @access public
* @return string
*/
public function getName()
{
return 'Github';
}
/**
* Authenticate the user
*
* @access public
* @return boolean
*/
public function authenticate()
{
$profile = $this->getProfile();
if (! empty($profile)) {
$this->userInfo = new GithubUserProvider($profile);
return true;
}
return false;
}
/**
* Set Code
*
* @access public
* @param string $code
* @return GithubAuth
*/
public function setCode($code)
{
$this->code = $code;
return $this;
}
/**
* Get user object
*
* @access public
* @return GithubUserProvider
*/
public function getUser()
{
return $this->userInfo;
}
/**
* Get configured OAuth2 service
*
* @access public
* @return \Kanboard\Core\Http\OAuth2
*/
public function getService()
{
if (empty($this->service)) {
$this->service = $this->oauth->createService(
GITHUB_CLIENT_ID,
GITHUB_CLIENT_SECRET,
$this->helper->url->to('oauth', 'github', array(), '', true),
GITHUB_OAUTH_AUTHORIZE_URL,
GITHUB_OAUTH_TOKEN_URL,
array()
);
}
return $this->service;
}
/**
* Get Github profile
*
* @access public
* @return array
*/
public function getProfile()
{
$this->getService()->getAccessToken($this->code);
return $this->httpClient->getJson(
GITHUB_API_URL.'user',
array($this->getService()->getAuthorizationHeader())
);
}
/**
* Unlink user
*
* @access public
* @param integer $userId
* @return bool
*/
public function unlink($userId)
{
return $this->user->update(array('id' => $userId, 'github_id' => ''));
}
}

View File

@ -1,143 +0,0 @@
<?php
namespace Kanboard\Auth;
use Kanboard\Core\Base;
use Kanboard\Core\Security\OAuthAuthenticationProviderInterface;
use Kanboard\User\GitlabUserProvider;
/**
* Gitlab Authentication Provider
*
* @package auth
* @author Frederic Guillot
*/
class GitlabAuth extends Base implements OAuthAuthenticationProviderInterface
{
/**
* User properties
*
* @access private
* @var \Kanboard\User\GitlabUserProvider
*/
private $userInfo = null;
/**
* OAuth2 instance
*
* @access protected
* @var \Kanboard\Core\Http\OAuth2
*/
protected $service;
/**
* OAuth2 code
*
* @access protected
* @var string
*/
protected $code = '';
/**
* Get authentication provider name
*
* @access public
* @return string
*/
public function getName()
{
return 'Gitlab';
}
/**
* Authenticate the user
*
* @access public
* @return boolean
*/
public function authenticate()
{
$profile = $this->getProfile();
if (! empty($profile)) {
$this->userInfo = new GitlabUserProvider($profile);
return true;
}
return false;
}
/**
* Set Code
*
* @access public
* @param string $code
* @return GitlabAuth
*/
public function setCode($code)
{
$this->code = $code;
return $this;
}
/**
* Get user object
*
* @access public
* @return GitlabUserProvider
*/
public function getUser()
{
return $this->userInfo;
}
/**
* Get configured OAuth2 service
*
* @access public
* @return \Kanboard\Core\Http\OAuth2
*/
public function getService()
{
if (empty($this->service)) {
$this->service = $this->oauth->createService(
GITLAB_CLIENT_ID,
GITLAB_CLIENT_SECRET,
$this->helper->url->to('oauth', 'gitlab', array(), '', true),
GITLAB_OAUTH_AUTHORIZE_URL,
GITLAB_OAUTH_TOKEN_URL,
array()
);
}
return $this->service;
}
/**
* Get Gitlab profile
*
* @access public
* @return array
*/
public function getProfile()
{
$this->getService()->getAccessToken($this->code);
return $this->httpClient->getJson(
GITLAB_API_URL.'user',
array($this->getService()->getAuthorizationHeader())
);
}
/**
* Unlink user
*
* @access public
* @param integer $userId
* @return bool
*/
public function unlink($userId)
{
return $this->user->update(array('id' => $userId, 'gitlab_id' => ''));
}
}

View File

@ -1,143 +0,0 @@
<?php
namespace Kanboard\Auth;
use Kanboard\Core\Base;
use Kanboard\Core\Security\OAuthAuthenticationProviderInterface;
use Kanboard\User\GoogleUserProvider;
/**
* Google Authentication Provider
*
* @package auth
* @author Frederic Guillot
*/
class GoogleAuth extends Base implements OAuthAuthenticationProviderInterface
{
/**
* User properties
*
* @access protected
* @var \Kanboard\User\GoogleUserProvider
*/
protected $userInfo = null;
/**
* OAuth2 instance
*
* @access protected
* @var \Kanboard\Core\Http\OAuth2
*/
protected $service;
/**
* OAuth2 code
*
* @access protected
* @var string
*/
protected $code = '';
/**
* Get authentication provider name
*
* @access public
* @return string
*/
public function getName()
{
return 'Google';
}
/**
* Authenticate the user
*
* @access public
* @return boolean
*/
public function authenticate()
{
$profile = $this->getProfile();
if (! empty($profile)) {
$this->userInfo = new GoogleUserProvider($profile);
return true;
}
return false;
}
/**
* Set Code
*
* @access public
* @param string $code
* @return GoogleAuth
*/
public function setCode($code)
{
$this->code = $code;
return $this;
}
/**
* Get user object
*
* @access public
* @return GoogleUserProvider
*/
public function getUser()
{
return $this->userInfo;
}
/**
* Get configured OAuth2 service
*
* @access public
* @return \Kanboard\Core\Http\OAuth2
*/
public function getService()
{
if (empty($this->service)) {
$this->service = $this->oauth->createService(
GOOGLE_CLIENT_ID,
GOOGLE_CLIENT_SECRET,
$this->helper->url->to('oauth', 'google', array(), '', true),
'https://accounts.google.com/o/oauth2/auth',
'https://accounts.google.com/o/oauth2/token',
array('https://www.googleapis.com/auth/userinfo.email', 'https://www.googleapis.com/auth/userinfo.profile')
);
}
return $this->service;
}
/**
* Get Google profile
*
* @access public
* @return array
*/
public function getProfile()
{
$this->getService()->getAccessToken($this->code);
return $this->httpClient->getJson(
'https://www.googleapis.com/oauth2/v1/userinfo',
array($this->getService()->getAuthorizationHeader())
);
}
/**
* Unlink user
*
* @access public
* @param integer $userId
* @return bool
*/
public function unlink($userId)
{
return $this->user->update(array('id' => $userId, 'google_id' => ''));
}
}

View File

@ -11,18 +11,19 @@ use Symfony\Component\Console\Command\Command;
* @package console
* @author Frederic Guillot
*
* @property \Kanboard\Model\Notification $notification
* @property \Kanboard\Model\Project $project
* @property \Kanboard\Model\ProjectPermission $projectPermission
* @property \Kanboard\Model\ProjectAnalytic $projectAnalytic
* @property \Kanboard\Model\ProjectDailyColumnStats $projectDailyColumnStats
* @property \Kanboard\Model\ProjectDailyStats $projectDailyStats
* @property \Kanboard\Model\SubtaskExport $subtaskExport
* @property \Kanboard\Model\OverdueNotification $overdueNotification
* @property \Kanboard\Model\Task $task
* @property \Kanboard\Model\TaskExport $taskExport
* @property \Kanboard\Model\TaskFinder $taskFinder
* @property \Kanboard\Model\Transition $transition
* @property \Kanboard\Model\Notification $notification
* @property \Kanboard\Model\Project $project
* @property \Kanboard\Model\ProjectPermission $projectPermission
* @property \Kanboard\Model\ProjectAnalytic $projectAnalytic
* @property \Kanboard\Model\ProjectDailyColumnStats $projectDailyColumnStats
* @property \Kanboard\Model\ProjectDailyStats $projectDailyStats
* @property \Kanboard\Model\SubtaskExport $subtaskExport
* @property \Kanboard\Model\OverdueNotification $overdueNotification
* @property \Kanboard\Model\Task $task
* @property \Kanboard\Model\TaskExport $taskExport
* @property \Kanboard\Model\TaskFinder $taskFinder
* @property \Kanboard\Model\Transition $transition
* @property \Symfony\Component\EventDispatcher\EventDispatcher $dispatcher
*/
abstract class Base extends Command
{

32
app/Console/Cronjob.php Normal file
View File

@ -0,0 +1,32 @@
<?php
namespace Kanboard\Console;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Output\NullOutput;
class Cronjob extends Base
{
private $commands = array(
'projects:daily-stats',
'notification:overdue-tasks',
'trigger:tasks',
);
protected function configure()
{
$this
->setName('cronjob')
->setDescription('Execute daily cronjob');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
foreach ($this->commands as $command) {
$job = $this->getApplication()->find($command);
$job->run(new ArrayInput(array('command' => $command)), new NullOutput());
}
}
}

View File

@ -0,0 +1,51 @@
<?php
namespace Kanboard\Console;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Kanboard\Model\Task;
use Kanboard\Event\TaskListEvent;
class TaskTrigger extends Base
{
protected function configure()
{
$this
->setName('trigger:tasks')
->setDescription('Trigger scheduler event for all tasks');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
foreach ($this->getProjectIds() as $project_id) {
$tasks = $this->taskFinder->getAll($project_id);
$nb_tasks = count($tasks);
if ($nb_tasks > 0) {
$output->writeln('Trigger task event: project_id='.$project_id.', nb_tasks='.$nb_tasks);
$this->sendEvent($tasks, $project_id);
}
}
}
private function getProjectIds()
{
$listeners = $this->dispatcher->getListeners(Task::EVENT_DAILY_CRONJOB);
$project_ids = array();
foreach ($listeners as $listener) {
$project_ids[] = $listener[0]->getProjectId();
}
return array_unique($project_ids);
}
private function sendEvent(array &$tasks, $project_id)
{
$event = new TaskListEvent(array('project_id' => $project_id));
$event->setTasks($tasks);
$this->dispatcher->dispatch(Task::EVENT_DAILY_CRONJOB, $event);
}
}

View File

@ -20,7 +20,7 @@ class Action extends Base
$project = $this->getProject();
$actions = $this->action->getAllByProject($project['id']);
$this->response->html($this->projectLayout('action/index', array(
$this->response->html($this->helper->layout->project('action/index', array(
'values' => array('project_id' => $project['id']),
'project' => $project,
'actions' => $actions,
@ -51,7 +51,7 @@ class Action extends Base
$this->response->redirect($this->helper->url->to('action', 'index', array('project_id' => $project['id'])));
}
$this->response->html($this->projectLayout('action/event', array(
$this->response->html($this->helper->layout->project('action/event', array(
'values' => $values,
'project' => $project,
'events' => $this->actionManager->getCompatibleEvents($values['action_name']),
@ -83,7 +83,7 @@ class Action extends Base
$projects_list = $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId());
unset($projects_list[$project['id']]);
$this->response->html($this->projectLayout('action/params', array(
$this->response->html($this->helper->layout->project('action/params', array(
'values' => $values,
'action_params' => $action_params,
'columns_list' => $this->board->getColumnsList($project['id']),
@ -138,7 +138,7 @@ class Action extends Base
{
$project = $this->getProject();
$this->response->html($this->projectLayout('action/remove', array(
$this->response->html($this->helper->layout->project('action/remove', array(
'action' => $this->action->getById($this->request->getIntegerParam('action_id')),
'available_events' => $this->eventManager->getAll(),
'available_actions' => $this->actionManager->getAvailableActions(),

View File

@ -19,8 +19,7 @@ class Activity extends Base
{
$project = $this->getProject();
$this->response->html($this->template->layout('activity/project', array(
'board_selector' => $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId()),
$this->response->html($this->helper->layout->app('activity/project', array(
'events' => $this->projectActivity->getProject($project['id']),
'project' => $project,
'title' => t('%s\'s activity', $project['name'])
@ -36,7 +35,7 @@ class Activity extends Base
{
$task = $this->getTask();
$this->response->html($this->taskLayout('activity/task', array(
$this->response->html($this->helper->layout->task('activity/task', array(
'title' => $task['title'],
'task' => $task,
'events' => $this->projectActivity->getTask($task['id']),

View File

@ -1,6 +1,7 @@
<?php
namespace Kanboard\Controller;
use Kanboard\Model\Task as TaskModel;
/**
@ -11,22 +12,6 @@ use Kanboard\Model\Task as TaskModel;
*/
class Analytic extends Base
{
/**
* Common layout for analytic views
*
* @access private
* @param string $template Template name
* @param array $params Template parameters
* @return string
*/
private function layout($template, array $params)
{
$params['board_selector'] = $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId());
$params['content_for_sublayout'] = $this->template->render($template, $params);
return $this->template->layout('analytic/layout', $params);
}
/**
* Show average Lead and Cycle time
*
@ -37,7 +22,7 @@ class Analytic extends Base
$project = $this->getProject();
list($from, $to) = $this->getDates();
$this->response->html($this->layout('analytic/lead_cycle_time', array(
$this->response->html($this->helper->layout->analytic('analytic/lead_cycle_time', array(
'values' => array(
'from' => $from,
'to' => $to,
@ -69,7 +54,7 @@ class Analytic extends Base
->setQuery($query)
->calculate();
$this->response->html($this->layout('analytic/compare_hours', array(
$this->response->html($this->helper->layout->analytic('analytic/compare_hours', array(
'project' => $project,
'paginator' => $paginator,
'metrics' => $this->estimatedTimeComparisonAnalytic->build($project['id']),
@ -86,7 +71,7 @@ class Analytic extends Base
{
$project = $this->getProject();
$this->response->html($this->layout('analytic/avg_time_columns', array(
$this->response->html($this->helper->layout->analytic('analytic/avg_time_columns', array(
'project' => $project,
'metrics' => $this->averageTimeSpentColumnAnalytic->build($project['id']),
'title' => t('Average time spent into each column for "%s"', $project['name']),
@ -102,7 +87,7 @@ class Analytic extends Base
{
$project = $this->getProject();
$this->response->html($this->layout('analytic/tasks', array(
$this->response->html($this->helper->layout->analytic('analytic/tasks', array(
'project' => $project,
'metrics' => $this->taskDistributionAnalytic->build($project['id']),
'title' => t('Task repartition for "%s"', $project['name']),
@ -118,7 +103,7 @@ class Analytic extends Base
{
$project = $this->getProject();
$this->response->html($this->layout('analytic/users', array(
$this->response->html($this->helper->layout->analytic('analytic/users', array(
'project' => $project,
'metrics' => $this->userDistributionAnalytic->build($project['id']),
'title' => t('User repartition for "%s"', $project['name']),
@ -160,7 +145,7 @@ class Analytic extends Base
$display_graph = $this->projectDailyColumnStats->countDays($project['id'], $from, $to) >= 2;
$this->response->html($this->layout($template, array(
$this->response->html($this->helper->layout->analytic($template, array(
'values' => array(
'from' => $from,
'to' => $to,

View File

@ -12,22 +12,6 @@ use Kanboard\Model\Subtask as SubtaskModel;
*/
class App extends Base
{
/**
* Common layout for dashboard views
*
* @access private
* @param string $template Template name
* @param array $params Template parameters
* @return string
*/
private function layout($template, array $params)
{
$params['board_selector'] = $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId());
$params['content_for_sublayout'] = $this->template->render($template, $params);
return $this->template->layout('app/layout', $params);
}
/**
* Get project pagination
*
@ -101,7 +85,7 @@ class App extends Base
{
$user = $this->getUser();
$this->response->html($this->layout('app/overview', array(
$this->response->html($this->helper->layout->dashboard('app/overview', array(
'title' => t('Dashboard'),
'project_paginator' => $this->getProjectPaginator($user['id'], 'index', 10),
'task_paginator' => $this->getTaskPaginator($user['id'], 'index', 10),
@ -119,7 +103,7 @@ class App extends Base
{
$user = $this->getUser();
$this->response->html($this->layout('app/tasks', array(
$this->response->html($this->helper->layout->dashboard('app/tasks', array(
'title' => t('My tasks'),
'paginator' => $this->getTaskPaginator($user['id'], 'tasks', 50),
'user' => $user,
@ -135,7 +119,7 @@ class App extends Base
{
$user = $this->getUser();
$this->response->html($this->layout('app/subtasks', array(
$this->response->html($this->helper->layout->dashboard('app/subtasks', array(
'title' => t('My subtasks'),
'paginator' => $this->getSubtaskPaginator($user['id'], 'subtasks', 50),
'user' => $user,
@ -151,7 +135,7 @@ class App extends Base
{
$user = $this->getUser();
$this->response->html($this->layout('app/projects', array(
$this->response->html($this->helper->layout->dashboard('app/projects', array(
'title' => t('My projects'),
'paginator' => $this->getProjectPaginator($user['id'], 'projects', 25),
'user' => $user,
@ -167,7 +151,7 @@ class App extends Base
{
$user = $this->getUser();
$this->response->html($this->layout('app/activity', array(
$this->response->html($this->helper->layout->dashboard('app/activity', array(
'title' => t('My activity stream'),
'events' => $this->projectActivity->getProjects($this->projectPermission->getActiveProjectIds($user['id']), 100),
'user' => $user,
@ -181,7 +165,7 @@ class App extends Base
*/
public function calendar()
{
$this->response->html($this->layout('app/calendar', array(
$this->response->html($this->helper->layout->dashboard('app/calendar', array(
'title' => t('My calendar'),
'user' => $this->getUser(),
)));
@ -196,7 +180,7 @@ class App extends Base
{
$user = $this->getUser();
$this->response->html($this->layout('app/notifications', array(
$this->response->html($this->helper->layout->dashboard('app/notifications', array(
'title' => t('My notifications'),
'notifications' => $this->userUnreadNotification->getAll($user['id']),
'user' => $user,

View File

@ -21,7 +21,7 @@ class Auth extends Base
$this->response->redirect($this->helper->url->to('app', 'index'));
}
$this->response->html($this->template->layout('auth/index', array(
$this->response->html($this->helper->layout->app('auth/index', array(
'captcha' => ! empty($values['username']) && $this->userLocking->hasCaptcha($values['username']),
'errors' => $errors,
'values' => $values,

View File

@ -131,7 +131,7 @@ abstract class Base extends \Kanboard\Core\Base
*/
protected function notfound($no_layout = false)
{
$this->response->html($this->template->layout('app/notfound', array(
$this->response->html($this->helper->layout->app('app/notfound', array(
'title' => t('Page not found'),
'no_layout' => $no_layout,
)));
@ -149,7 +149,7 @@ abstract class Base extends \Kanboard\Core\Base
$this->response->text('Access Forbidden', 403);
}
$this->response->html($this->template->layout('app/forbidden', array(
$this->response->html($this->helper->layout->app('app/forbidden', array(
'title' => t('Access Forbidden'),
'no_layout' => $no_layout,
)));
@ -179,43 +179,6 @@ abstract class Base extends \Kanboard\Core\Base
}
}
/**
* Common layout for task views
*
* @access protected
* @param string $template Template name
* @param array $params Template parameters
* @return string
*/
protected function taskLayout($template, array $params)
{
$content = $this->template->render($template, $params);
$params['task_content_for_layout'] = $content;
$params['title'] = $params['task']['project_name'].' &gt; '.$params['task']['title'];
$params['board_selector'] = $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId());
return $this->template->layout('task/layout', $params);
}
/**
* Common layout for project views
*
* @access protected
* @param string $template Template name
* @param array $params Template parameters
* @return string
*/
protected function projectLayout($template, array $params, $sidebar_template = 'project/sidebar')
{
$content = $this->template->render($template, $params);
$params['project_content_for_layout'] = $content;
$params['title'] = $params['project']['name'] === $params['title'] ? $params['title'] : $params['project']['name'].' &gt; '.$params['title'];
$params['board_selector'] = $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId());
$params['sidebar_template'] = $sidebar_template;
return $this->template->layout('project/layout', $params);
}
/**
* Common method to get a task for task views
*
@ -251,8 +214,7 @@ abstract class Base extends \Kanboard\Core\Base
$project = $this->project->getByIdWithOwner($project_id);
if (empty($project)) {
$this->flash->failure(t('Project not found.'));
$this->response->redirect($this->helper->url->to('project', 'index'));
$this->notfound();
}
return $project;
@ -279,6 +241,23 @@ abstract class Base extends \Kanboard\Core\Base
return $user;
}
/**
* Get the current subtask
*
* @access protected
* @return array
*/
protected function getSubtask()
{
$subtask = $this->subtask->getById($this->request->getIntegerParam('subtask_id'));
if (empty($subtask)) {
$this->notfound();
}
return $subtask;
}
/**
* Common method to get project filters
*
@ -319,7 +298,8 @@ abstract class Base extends \Kanboard\Core\Base
* @param array &$project
* @return string
*/
protected function getProjectDescription(array &$project) {
protected function getProjectDescription(array &$project)
{
if ($project['owner_id'] > 0) {
$description = t('Project owner: ').'**'.$this->template->e($project['owner_name'] ?: $project['owner_username']).'**'.PHP_EOL.PHP_EOL;

View File

@ -27,7 +27,7 @@ class Board extends Base
}
// Display the board with a specific layout
$this->response->html($this->template->layout('board/view_public', array(
$this->response->html($this->helper->layout->app('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/view_private', array(
$this->response->html($this->helper->layout->app('board/view_private', array(
'categories_list' => $this->category->getList($params['project']['id'], false),
'users_list' => $this->projectUserRole->getAssignableUsersList($params['project']['id'], false),
'custom_filters_list' => $this->customFilter->getAll($params['project']['id'], $this->userSession->getId()),

View File

@ -19,7 +19,21 @@ class BoardTooltip extends Base
{
$task = $this->getTask();
$this->response->html($this->template->render('board/tooltip_tasklinks', array(
'links' => $this->taskLink->getAll($task['id']),
'links' => $this->taskLink->getAllGroupedByLabel($task['id']),
'task' => $task,
)));
}
/**
* Get links on mouseover
*
* @access public
*/
public function externallinks()
{
$task = $this->getTask();
$this->response->html($this->template->render('board/tooltip_external_links', array(
'links' => $this->taskExternalLink->getAll($task['id']),
'task' => $task,
)));
}

View File

@ -20,7 +20,7 @@ class Calendar extends Base
*/
public function show()
{
$this->response->html($this->template->layout('calendar/show', array(
$this->response->html($this->helper->layout->app('calendar/show', array(
'check_interval' => $this->config->get('board_private_refresh_interval'),
) + $this->getProjectFilters('calendar', 'show')));
}

View File

@ -38,7 +38,7 @@ class Category extends Base
{
$project = $this->getProject();
$this->response->html($this->projectLayout('category/index', array(
$this->response->html($this->helper->layout->project('category/index', array(
'categories' => $this->category->getList($project['id'], false),
'values' => $values + array('project_id' => $project['id']),
'errors' => $errors,
@ -81,7 +81,7 @@ class Category extends Base
$project = $this->getProject();
$category = $this->getCategory($project['id']);
$this->response->html($this->projectLayout('category/edit', array(
$this->response->html($this->helper->layout->project('category/edit', array(
'values' => empty($values) ? $category : $values,
'errors' => $errors,
'project' => $project,
@ -123,7 +123,7 @@ class Category extends Base
$project = $this->getProject();
$category = $this->getCategory($project['id']);
$this->response->html($this->projectLayout('category/remove', array(
$this->response->html($this->helper->layout->project('category/remove', array(
'project' => $project,
'category' => $category,
'title' => t('Remove a category')

View File

@ -26,7 +26,7 @@ class Column extends Base
$values['task_limit['.$column['id'].']'] = $column['task_limit'] ?: null;
}
$this->response->html($this->projectLayout('column/index', array(
$this->response->html($this->helper->layout->project('column/index', array(
'errors' => $errors,
'values' => $values + array('project_id' => $project['id']),
'columns' => $columns,
@ -75,7 +75,7 @@ class Column extends Base
$project = $this->getProject();
$column = $this->board->getColumn($this->request->getIntegerParam('column_id'));
$this->response->html($this->projectLayout('column/edit', array(
$this->response->html($this->helper->layout->project('column/edit', array(
'errors' => $errors,
'values' => $values ?: $column,
'project' => $project,
@ -136,7 +136,7 @@ class Column extends Base
{
$project = $this->getProject();
$this->response->html($this->projectLayout('column/remove', array(
$this->response->html($this->helper->layout->project('column/remove', array(
'column' => $this->board->getColumn($this->request->getIntegerParam('column_id')),
'project' => $project,
'title' => t('Remove a column from a board')

View File

@ -21,13 +21,11 @@ class Comment extends Base
$comment = $this->comment->getById($this->request->getIntegerParam('comment_id'));
if (empty($comment)) {
$this->notfound();
return $this->notfound();
}
if (! $this->userSession->isAdmin() && $comment['user_id'] != $this->userSession->getId()) {
$this->response->html($this->template->layout('comment/forbidden', array(
'title' => t('Access Forbidden')
)));
return $this->forbidden();
}
return $comment;
@ -41,7 +39,6 @@ class Comment extends Base
public function create(array $values = array(), array $errors = array())
{
$task = $this->getTask();
$ajax = $this->request->isAjax() || $this->request->getIntegerParam('ajax');
if (empty($values)) {
$values = array(
@ -50,16 +47,7 @@ class Comment extends Base
);
}
if ($ajax) {
$this->response->html($this->template->render('comment/create', array(
'values' => $values,
'errors' => $errors,
'task' => $task,
'ajax' => $ajax,
)));
}
$this->response->html($this->taskLayout('comment/create', array(
$this->response->html($this->helper->layout->task('comment/create', array(
'values' => $values,
'errors' => $errors,
'task' => $task,
@ -76,7 +64,6 @@ class Comment extends Base
{
$task = $this->getTask();
$values = $this->request->getValues();
$ajax = $this->request->isAjax() || $this->request->getIntegerParam('ajax');
list($valid, $errors) = $this->commentValidator->validateCreation($values);
@ -87,11 +74,7 @@ class Comment extends Base
$this->flash->failure(t('Unable to create your comment.'));
}
if ($ajax) {
$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']), 'comments'));
return $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), 'comments'), true);
}
$this->create($values, $errors);
@ -107,7 +90,7 @@ class Comment extends Base
$task = $this->getTask();
$comment = $this->getComment();
$this->response->html($this->taskLayout('comment/edit', array(
$this->response->html($this->helper->layout->task('comment/edit', array(
'values' => empty($values) ? $comment : $values,
'errors' => $errors,
'comment' => $comment,
@ -124,7 +107,7 @@ class Comment extends Base
public function update()
{
$task = $this->getTask();
$comment = $this->getComment();
$this->getComment();
$values = $this->request->getValues();
list($valid, $errors) = $this->commentValidator->validateModification($values);
@ -136,7 +119,7 @@ class Comment extends Base
$this->flash->failure(t('Unable to update your comment.'));
}
$this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), 'comment-'.$comment['id']));
return $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), false);
}
$this->edit($values, $errors);
@ -152,7 +135,7 @@ class Comment extends Base
$task = $this->getTask();
$comment = $this->getComment();
$this->response->html($this->taskLayout('comment/remove', array(
$this->response->html($this->helper->layout->task('comment/remove', array(
'comment' => $comment,
'task' => $task,
'title' => t('Remove a comment')

View File

@ -10,24 +10,6 @@ namespace Kanboard\Controller;
*/
class Config extends Base
{
/**
* Common layout for config views
*
* @access private
* @param string $template Template name
* @param array $params Template parameters
* @return string
*/
private function layout($template, array $params)
{
$params['board_selector'] = $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId());
$params['values'] = $this->config->getAll();
$params['errors'] = array();
$params['config_content_for_layout'] = $this->template->render($template, $params);
return $this->template->layout('config/layout', $params);
}
/**
* Common method between pages
*
@ -72,7 +54,7 @@ class Config extends Base
*/
public function index()
{
$this->response->html($this->layout('config/about', array(
$this->response->html($this->helper->layout->config('config/about', array(
'db_size' => $this->config->getDatabaseSize(),
'title' => t('Settings').' &gt; '.t('About'),
)));
@ -85,7 +67,7 @@ class Config extends Base
*/
public function plugins()
{
$this->response->html($this->layout('config/plugins', array(
$this->response->html($this->helper->layout->config('config/plugins', array(
'plugins' => $this->pluginLoader->plugins,
'title' => t('Settings').' &gt; '.t('Plugins'),
)));
@ -100,7 +82,7 @@ class Config extends Base
{
$this->common('application');
$this->response->html($this->layout('config/application', array(
$this->response->html($this->helper->layout->config('config/application', array(
'languages' => $this->config->getLanguages(),
'timezones' => $this->config->getTimezones(),
'date_formats' => $this->dateParser->getAvailableFormats(),
@ -117,7 +99,7 @@ class Config extends Base
{
$this->common('project');
$this->response->html($this->layout('config/project', array(
$this->response->html($this->helper->layout->config('config/project', array(
'colors' => $this->color->getList(),
'default_columns' => implode(', ', $this->board->getDefaultColumns()),
'title' => t('Settings').' &gt; '.t('Project settings'),
@ -133,7 +115,7 @@ class Config extends Base
{
$this->common('board');
$this->response->html($this->layout('config/board', array(
$this->response->html($this->helper->layout->config('config/board', array(
'title' => t('Settings').' &gt; '.t('Board settings'),
)));
}
@ -147,7 +129,7 @@ class Config extends Base
{
$this->common('calendar');
$this->response->html($this->layout('config/calendar', array(
$this->response->html($this->helper->layout->config('config/calendar', array(
'title' => t('Settings').' &gt; '.t('Calendar settings'),
)));
}
@ -161,7 +143,7 @@ class Config extends Base
{
$this->common('integrations');
$this->response->html($this->layout('config/integrations', array(
$this->response->html($this->helper->layout->config('config/integrations', array(
'title' => t('Settings').' &gt; '.t('Integrations'),
)));
}
@ -175,7 +157,7 @@ class Config extends Base
{
$this->common('webhook');
$this->response->html($this->layout('config/webhook', array(
$this->response->html($this->helper->layout->config('config/webhook', array(
'title' => t('Settings').' &gt; '.t('Webhook settings'),
)));
}
@ -187,7 +169,7 @@ class Config extends Base
*/
public function api()
{
$this->response->html($this->layout('config/api', array(
$this->response->html($this->helper->layout->config('config/api', array(
'title' => t('Settings').' &gt; '.t('API'),
)));
}

View File

@ -10,22 +10,6 @@ namespace Kanboard\Controller;
*/
class Currency extends Base
{
/**
* Common layout for config views
*
* @access private
* @param string $template Template name
* @param array $params Template parameters
* @return string
*/
private function layout($template, array $params)
{
$params['board_selector'] = $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId());
$params['config_content_for_layout'] = $this->template->render($template, $params);
return $this->template->layout('config/layout', $params);
}
/**
* Display all currency rates and form
*
@ -33,7 +17,7 @@ class Currency extends Base
*/
public function index(array $values = array(), array $errors = array())
{
$this->response->html($this->layout('currency/index', array(
$this->response->html($this->helper->layout->config('currency/index', array(
'config_values' => array('application_currency' => $this->config->get('application_currency')),
'values' => $values,
'errors' => $errors,

View File

@ -21,7 +21,7 @@ class Customfilter extends Base
{
$project = $this->getProject();
$this->response->html($this->projectLayout('custom_filter/index', array(
$this->response->html($this->helper->layout->project('custom_filter/index', array(
'values' => $values + array('project_id' => $project['id']),
'errors' => $errors,
'project' => $project,
@ -90,7 +90,7 @@ class Customfilter extends Base
$this->checkPermission($project, $filter);
$this->response->html($this->projectLayout('custom_filter/edit', array(
$this->response->html($this->helper->layout->project('custom_filter/edit', array(
'values' => empty($values) ? $filter : $values,
'errors' => $errors,
'project' => $project,

View File

@ -52,8 +52,6 @@ class Doc extends Base
}
}
$this->response->html($this->template->layout('doc/show', $this->readFile($filename) + array(
'board_selector' => $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId()),
)));
$this->response->html($this->helper->layout->app('doc/show', $this->readFile($filename)));
}
}

View File

@ -27,7 +27,7 @@ class Export extends Base
$this->response->csv($data);
}
$this->response->html($this->projectLayout('export/'.$action, array(
$this->response->html($this->helper->layout->project('export/'.$action, array(
'values' => array(
'controller' => 'export',
'action' => $action,

View File

@ -23,17 +23,11 @@ class File extends Base
if ($this->request->isPost() && $this->file->uploadScreenshot($task['project_id'], $task['id'], $this->request->getValue('screenshot')) !== false) {
$this->flash->success(t('Screenshot uploaded successfully.'));
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'])));
return $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), true);
}
$this->response->html($this->taskLayout('file/screenshot', array(
$this->response->html($this->helper->layout->task('file/screenshot', array(
'task' => $task,
'redirect' => 'task',
)));
}
@ -46,7 +40,7 @@ class File extends Base
{
$task = $this->getTask();
$this->response->html($this->taskLayout('file/new', array(
$this->response->html($this->helper->layout->task('file/new', array(
'task' => $task,
'max_size' => ini_get('upload_max_filesize'),
)));
@ -65,7 +59,7 @@ class File extends Base
$this->flash->failure(t('Unable to upload the file.'));
}
$this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])));
$this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), true);
}
/**
@ -184,7 +178,7 @@ class File extends Base
$task = $this->getTask();
$file = $this->file->getById($this->request->getIntegerParam('file_id'));
$this->response->html($this->taskLayout('file/remove', array(
$this->response->html($this->helper->layout->task('file/remove', array(
'task' => $task,
'file' => $file,
)));

View File

@ -23,10 +23,9 @@ class Gantt extends Base
$project_ids = $this->projectPermission->getActiveProjectIds($this->userSession->getId());
}
$this->response->html($this->template->layout('gantt/projects', array(
$this->response->html($this->helper->layout->app('gantt/projects', array(
'projects' => $this->projectGanttFormatter->filter($project_ids)->format(),
'title' => t('Gantt chart for all projects'),
'board_selector' => $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId()),
)));
}
@ -65,7 +64,7 @@ class Gantt extends Base
$filter->getQuery()->asc('column_position')->asc(TaskModel::TABLE.'.position');
}
$this->response->html($this->template->layout('gantt/project', $params + array(
$this->response->html($this->helper->layout->app('gantt/project', $params + array(
'users_list' => $this->projectUserRole->getAssignableUsersList($params['project']['id'], false),
'sorting' => $sorting,
'tasks' => $filter->format(),
@ -102,19 +101,22 @@ class Gantt extends Base
{
$project = $this->getProject();
$values = $values + array(
'project_id' => $project['id'],
'column_id' => $this->board->getFirstColumn($project['id']),
'position' => 1
);
$values = $this->hook->merge('controller:task:form:default', $values, array('default_values' => $values));
$this->response->html($this->template->render('gantt/task_creation', array(
'project' => $project,
'errors' => $errors,
'values' => $values + array(
'project_id' => $project['id'],
'column_id' => $this->board->getFirstColumn($project['id']),
'position' => 1
),
'values' => $values,
'users_list' => $this->projectUserRole->getAssignableUsersList($project['id'], true, false, true),
'colors_list' => $this->color->getList(),
'categories_list' => $this->category->getList($project['id']),
'swimlanes_list' => $this->swimlane->getList($project['id'], false, true),
'date_format' => $this->config->get('application_date_format'),
'date_formats' => $this->dateParser->getAvailableFormats(),
'title' => $project['name'].' &gt; '.t('New task')
)));
}

View File

@ -24,8 +24,7 @@ class Group extends Base
->setQuery($this->group->getQuery())
->calculate();
$this->response->html($this->template->layout('group/index', array(
'board_selector' => $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId()),
$this->response->html($this->helper->layout->app('group/index', array(
'title' => t('Groups').' ('.$paginator->getTotal().')',
'paginator' => $paginator,
)));
@ -48,8 +47,7 @@ class Group extends Base
->setQuery($this->groupMember->getQuery($group_id))
->calculate();
$this->response->html($this->template->layout('group/users', array(
'board_selector' => $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId()),
$this->response->html($this->helper->layout->app('group/users', array(
'title' => t('Members of %s', $group['name']).' ('.$paginator->getTotal().')',
'paginator' => $paginator,
'group' => $group,
@ -63,8 +61,7 @@ class Group extends Base
*/
public function create(array $values = array(), array $errors = array())
{
$this->response->html($this->template->layout('group/create', array(
'board_selector' => $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId()),
$this->response->html($this->helper->layout->app('group/create', array(
'errors' => $errors,
'values' => $values,
'title' => t('New group')
@ -104,8 +101,7 @@ class Group extends Base
$values = $this->group->getById($this->request->getIntegerParam('group_id'));
}
$this->response->html($this->template->layout('group/edit', array(
'board_selector' => $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId()),
$this->response->html($this->helper->layout->app('group/edit', array(
'errors' => $errors,
'values' => $values,
'title' => t('Edit group')
@ -148,8 +144,7 @@ class Group extends Base
$values['group_id'] = $group_id;
}
$this->response->html($this->template->layout('group/associate', array(
'board_selector' => $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId()),
$this->response->html($this->helper->layout->app('group/associate', array(
'users' => $this->user->prepareList($this->groupMember->getNotMembers($group_id)),
'group' => $group,
'errors' => $errors,
@ -191,7 +186,7 @@ class Group extends Base
$group = $this->group->getById($group_id);
$user = $this->user->getById($user_id);
$this->response->html($this->template->layout('group/dissociate', array(
$this->response->html($this->helper->layout->app('group/dissociate', array(
'group' => $group,
'user' => $user,
'title' => t('Remove user from group "%s"', $group['name']),
@ -228,7 +223,7 @@ class Group extends Base
$group_id = $this->request->getIntegerParam('group_id');
$group = $this->group->getById($group_id);
$this->response->html($this->template->layout('group/remove', array(
$this->response->html($this->helper->layout->app('group/remove', array(
'group' => $group,
'title' => t('Remove group'),
)));

View File

@ -11,22 +11,6 @@ namespace Kanboard\Controller;
*/
class Link extends Base
{
/**
* Common layout for config views
*
* @access private
* @param string $template Template name
* @param array $params Template parameters
* @return string
*/
private function layout($template, array $params)
{
$params['board_selector'] = $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId());
$params['config_content_for_layout'] = $this->template->render($template, $params);
return $this->template->layout('config/layout', $params);
}
/**
* Get the current link
*
@ -51,7 +35,7 @@ class Link extends Base
*/
public function index(array $values = array(), array $errors = array())
{
$this->response->html($this->layout('link/index', array(
$this->response->html($this->helper->layout->config('link/index', array(
'links' => $this->link->getMergedList(),
'values' => $values,
'errors' => $errors,
@ -91,7 +75,7 @@ class Link extends Base
$link = $this->getLink();
$link['label'] = t($link['label']);
$this->response->html($this->layout('link/edit', array(
$this->response->html($this->helper->layout->config('link/edit', array(
'values' => $values ?: $link,
'errors' => $errors,
'labels' => $this->link->getList($link['id']),
@ -131,7 +115,7 @@ class Link extends Base
{
$link = $this->getLink();
$this->response->html($this->layout('link/remove', array(
$this->response->html($this->helper->layout->config('link/remove', array(
'link' => $link,
'title' => t('Remove a link')
)));

View File

@ -30,7 +30,7 @@ class Listing extends Base
->setQuery($query)
->calculate();
$this->response->html($this->template->layout('listing/show', $params + array(
$this->response->html($this->helper->layout->app('listing/show', $params + array(
'paginator' => $paginator,
)));
}

View File

@ -10,36 +10,6 @@ namespace Kanboard\Controller;
*/
class Oauth extends Base
{
/**
* Link or authenticate a Google account
*
* @access public
*/
public function google()
{
$this->step1('Google');
}
/**
* Link or authenticate a Github account
*
* @access public
*/
public function github()
{
$this->step1('Github');
}
/**
* Link or authenticate a Gitlab account
*
* @access public
*/
public function gitlab()
{
$this->step1('Gitlab');
}
/**
* Unlink external account
*
@ -65,7 +35,7 @@ class Oauth extends Base
* @access private
* @param string $provider
*/
private function step1($provider)
protected function step1($provider)
{
$code = $this->request->getStringParam('code');
@ -79,11 +49,11 @@ class Oauth extends Base
/**
* Link or authenticate the user
*
* @access private
* @access protected
* @param string $provider
* @param string $code
*/
private function step2($provider, $code)
protected function step2($provider, $code)
{
$this->authenticationManager->getProvider($provider)->setCode($code);
@ -97,10 +67,10 @@ class Oauth extends Base
/**
* Link the account
*
* @access private
* @access protected
* @param string $provider
*/
private function link($provider)
protected function link($provider)
{
$authProvider = $this->authenticationManager->getProvider($provider);
@ -117,15 +87,15 @@ class Oauth extends Base
/**
* Authenticate the account
*
* @access private
* @access protected
* @param string $provider
*/
private function authenticate($provider)
protected function authenticate($provider)
{
if ($this->authenticationManager->oauthAuthentication($provider)) {
$this->response->redirect($this->helper->url->to('app', 'index'));
} else {
$this->response->html($this->template->layout('auth/index', array(
$this->response->html($this->helper->layout->app('auth/index', array(
'errors' => array('login' => t('External authentication failed')),
'values' => array(),
'no_layout' => true,

View File

@ -17,7 +17,7 @@ class PasswordReset extends Base
{
$this->checkActivation();
$this->response->html($this->template->layout('password_reset/create', array(
$this->response->html($this->helper->layout->app('password_reset/create', array(
'errors' => $errors,
'values' => $values,
'no_layout' => true,
@ -53,7 +53,7 @@ class PasswordReset extends Base
$user_id = $this->passwordReset->getUserIdByToken($token);
if ($user_id !== false) {
$this->response->html($this->template->layout('password_reset/change', array(
$this->response->html($this->helper->layout->app('password_reset/change', array(
'token' => $token,
'errors' => $errors,
'values' => $values,

View File

@ -32,8 +32,7 @@ class Project extends Base
->setQuery($this->project->getQueryColumnStats($project_ids))
->calculate();
$this->response->html($this->template->layout('project/index', array(
'board_selector' => $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId()),
$this->response->html($this->helper->layout->app('project/index', array(
'paginator' => $paginator,
'nb_projects' => $nb_projects,
'title' => t('Projects').' ('.$nb_projects.')'
@ -49,7 +48,7 @@ class Project extends Base
{
$project = $this->getProject();
$this->response->html($this->projectLayout('project/show', array(
$this->response->html($this->helper->layout->project('project/show', array(
'project' => $project,
'stats' => $this->project->getTaskStats($project['id']),
'title' => $project['name'],
@ -78,7 +77,7 @@ class Project extends Base
$this->response->redirect($this->helper->url->to('project', 'share', array('project_id' => $project['id'])));
}
$this->response->html($this->projectLayout('project/share', array(
$this->response->html($this->helper->layout->project('project/share', array(
'project' => $project,
'title' => t('Public access'),
)));
@ -99,7 +98,7 @@ class Project extends Base
$this->response->redirect($this->helper->url->to('project', 'integrations', array('project_id' => $project['id'])));
}
$this->response->html($this->projectLayout('project/integrations', array(
$this->response->html($this->helper->layout->project('project/integrations', array(
'project' => $project,
'title' => t('Integrations'),
'webhook_token' => $this->config->get('webhook_token'),
@ -124,7 +123,7 @@ class Project extends Base
$this->response->redirect($this->helper->url->to('project', 'notifications', array('project_id' => $project['id'])));
}
$this->response->html($this->projectLayout('project/notifications', array(
$this->response->html($this->helper->layout->project('project/notifications', array(
'notifications' => $this->projectNotification->readSettings($project['id']),
'types' => $this->projectNotificationType->getTypes(),
'project' => $project,
@ -153,7 +152,7 @@ class Project extends Base
$this->response->redirect($this->helper->url->to('project', 'index'));
}
$this->response->html($this->projectLayout('project/remove', array(
$this->response->html($this->helper->layout->project('project/remove', array(
'project' => $project,
'title' => t('Remove project')
)));
@ -171,17 +170,18 @@ class Project extends Base
$project = $this->getProject();
if ($this->request->getStringParam('duplicate') === 'yes') {
$values = array_keys($this->request->getValues());
if ($this->projectDuplication->duplicate($project['id'], $values) !== false) {
$project_id = $this->projectDuplication->duplicate($project['id'], array_keys($this->request->getValues()), $this->userSession->getId());
if ($project_id !== false) {
$this->flash->success(t('Project cloned successfully.'));
} else {
$this->flash->failure(t('Unable to clone this project.'));
}
$this->response->redirect($this->helper->url->to('project', 'index'));
$this->response->redirect($this->helper->url->to('project', 'show', array('project_id' => $project_id)));
}
$this->response->html($this->projectLayout('project/duplicate', array(
$this->response->html($this->helper->layout->project('project/duplicate', array(
'project' => $project,
'title' => t('Clone this project')
)));
@ -208,7 +208,7 @@ class Project extends Base
$this->response->redirect($this->helper->url->to('project', 'show', array('project_id' => $project['id'])));
}
$this->response->html($this->projectLayout('project/disable', array(
$this->response->html($this->helper->layout->project('project/disable', array(
'project' => $project,
'title' => t('Project activation')
)));
@ -235,62 +235,9 @@ class Project extends Base
$this->response->redirect($this->helper->url->to('project', 'show', array('project_id' => $project['id'])));
}
$this->response->html($this->projectLayout('project/enable', array(
$this->response->html($this->helper->layout->project('project/enable', array(
'project' => $project,
'title' => t('Project activation')
)));
}
/**
* Display a form to create a new project
*
* @access public
*/
public function create(array $values = array(), array $errors = array())
{
$is_private = isset($values['is_private']) && $values['is_private'] == 1;
$this->response->html($this->template->layout('project/new', array(
'board_selector' => $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId()),
'values' => $values,
'errors' => $errors,
'is_private' => $is_private,
'title' => $is_private ? t('New private project') : t('New project'),
)));
}
/**
* Display a form to create a private project
*
* @access public
*/
public function createPrivate(array $values = array(), array $errors = array())
{
$values['is_private'] = 1;
$this->create($values, $errors);
}
/**
* Validate and save a new project
*
* @access public
*/
public function save()
{
$values = $this->request->getValues();
list($valid, $errors) = $this->projectValidator->validateCreation($values);
if ($valid) {
$project_id = $this->project->create($values, $this->userSession->getId(), true);
if ($project_id > 0) {
$this->flash->success(t('Your project have been created successfully.'));
$this->response->redirect($this->helper->url->to('project', 'show', array('project_id' => $project_id)));
}
$this->flash->failure(t('Unable to create your project.'));
}
$this->create($values, $errors);
}
}

View File

@ -0,0 +1,125 @@
<?php
namespace Kanboard\Controller;
/**
* Project Creation Controller
*
* @package controller
* @author Frederic Guillot
*/
class ProjectCreation extends Base
{
/**
* Display a form to create a new project
*
* @access public
*/
public function create(array $values = array(), array $errors = array())
{
$is_private = isset($values['is_private']) && $values['is_private'] == 1;
$projects_list = array(0 => t('Do not duplicate anything')) + $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId());
$this->response->html($this->helper->layout->app('project_creation/create', array(
'values' => $values,
'errors' => $errors,
'is_private' => $is_private,
'projects_list' => $projects_list,
'title' => $is_private ? t('New private project') : t('New project'),
)));
}
/**
* Display a form to create a private project
*
* @access public
*/
public function createPrivate(array $values = array(), array $errors = array())
{
$values['is_private'] = 1;
$this->create($values, $errors);
}
/**
* Validate and save a new project
*
* @access public
*/
public function save()
{
$values = $this->request->getValues();
list($valid, $errors) = $this->projectValidator->validateCreation($values);
if ($valid) {
$project_id = $this->createOrDuplicate($values);
if ($project_id > 0) {
$this->flash->success(t('Your project have been created successfully.'));
return $this->response->redirect($this->helper->url->to('project', 'show', array('project_id' => $project_id)));
}
$this->flash->failure(t('Unable to create your project.'));
}
$this->create($values, $errors);
}
/**
* Create or duplicate a project
*
* @access private
* @param array $values
* @return boolean|integer
*/
private function createOrDuplicate(array $values)
{
if ($values['src_project_id'] == 0) {
return $this->createNewProject($values);
}
return $this->duplicateNewProject($values);
}
/**
* Save a new project
*
* @access private
* @param array $values
* @return boolean|integer
*/
private function createNewProject(array $values)
{
$project = array(
'name' => $values['name'],
'is_private' => $values['is_private'],
);
return $this->project->create($project, $this->userSession->getId(), true);
}
/**
* Creatte from another project
*
* @access private
* @param array $values
* @return boolean|integer
*/
private function duplicateNewProject(array $values)
{
$selection = array();
foreach ($this->projectDuplication->getOptionalSelection() as $item) {
if (isset($values[$item]) && $values[$item] == 1) {
$selection[] = $item;
}
}
return $this->projectDuplication->duplicate(
$values['src_project_id'],
$selection,
$this->userSession->getId(),
$values['name'],
$values['is_private'] == 1
);
}
}

View File

@ -89,11 +89,11 @@ class ProjectEdit extends Base
{
if ($redirect === 'edit') {
if (isset($values['is_private'])) {
if (! $this->helper->user->hasProjectAccess('project', 'create', $project['id'])) {
if (! $this->helper->user->hasProjectAccess('ProjectCreation', 'create', $project['id'])) {
unset($values['is_private']);
}
} elseif ($project['is_private'] == 1 && ! isset($values['is_private'])) {
if ($this->helper->user->hasProjectAccess('project', 'create', $project['id'])) {
if ($this->helper->user->hasProjectAccess('ProjectCreation', 'create', $project['id'])) {
$values += array('is_private' => 0);
}
}
@ -114,7 +114,7 @@ class ProjectEdit extends Base
{
$project = $this->getProject();
$this->response->html($this->projectLayout($template, array(
$this->response->html($this->helper->layout->project($template, array(
'owners' => $this->projectUserRole->getAssignableUsersList($project['id'], true),
'values' => empty($values) ? $project : $values,
'errors' => $errors,

View File

@ -12,6 +12,24 @@ use Kanboard\Core\Security\Role;
*/
class ProjectPermission extends Base
{
/**
* Permissions are only available for team projects
*
* @access protected
* @param integer $project_id Default project id
* @return array
*/
protected function getProject($project_id = 0)
{
$project = parent::getProject($project_id);
if ($project['is_private'] == 1) {
$this->forbidden();
}
return $project;
}
/**
* Show all permissions
*
@ -25,7 +43,7 @@ class ProjectPermission extends Base
$values['role'] = Role::PROJECT_MEMBER;
}
$this->response->html($this->projectLayout('project_permission/index', array(
$this->response->html($this->helper->layout->project('project_permission/index', array(
'project' => $project,
'users' => $this->projectUserRole->getUsers($project['id']),
'groups' => $this->projectGroupRole->getGroups($project['id']),
@ -62,6 +80,7 @@ class ProjectPermission extends Base
*/
public function addUser()
{
$project = $this->getProject();
$values = $this->request->getValues();
if ($this->projectUserRole->addUser($values['project_id'], $values['user_id'], $values['role'])) {
@ -70,7 +89,7 @@ class ProjectPermission extends Base
$this->flash->failure(t('Unable to update this project.'));
}
$this->response->redirect($this->helper->url->to('ProjectPermission', 'index', array('project_id' => $values['project_id'])));
$this->response->redirect($this->helper->url->to('ProjectPermission', 'index', array('project_id' => $project['id'])));
}
/**
@ -81,19 +100,16 @@ class ProjectPermission extends Base
public function removeUser()
{
$this->checkCSRFParam();
$project = $this->getProject();
$user_id = $this->request->getIntegerParam('user_id');
$values = array(
'project_id' => $this->request->getIntegerParam('project_id'),
'user_id' => $this->request->getIntegerParam('user_id'),
);
if ($this->projectUserRole->removeUser($values['project_id'], $values['user_id'])) {
if ($this->projectUserRole->removeUser($project['id'], $user_id)) {
$this->flash->success(t('Project updated successfully.'));
} else {
$this->flash->failure(t('Unable to update this project.'));
}
$this->response->redirect($this->helper->url->to('ProjectPermission', 'index', array('project_id' => $values['project_id'])));
$this->response->redirect($this->helper->url->to('ProjectPermission', 'index', array('project_id' => $project['id'])));
}
/**
@ -103,10 +119,10 @@ class ProjectPermission extends Base
*/
public function changeUserRole()
{
$project_id = $this->request->getIntegerParam('project_id');
$project = $this->getProject();
$values = $this->request->getJson();
if (! empty($project_id) && ! empty($values) && $this->projectUserRole->changeUserRole($project_id, $values['id'], $values['role'])) {
if (! empty($project) && ! empty($values) && $this->projectUserRole->changeUserRole($project['id'], $values['id'], $values['role'])) {
$this->response->json(array('status' => 'ok'));
} else {
$this->response->json(array('status' => 'error'));
@ -120,19 +136,20 @@ class ProjectPermission extends Base
*/
public function addGroup()
{
$project = $this->getProject();
$values = $this->request->getValues();
if (empty($values['group_id']) && ! empty($values['external_id'])) {
$values['group_id'] = $this->group->create($values['name'], $values['external_id']);
}
if ($this->projectGroupRole->addGroup($values['project_id'], $values['group_id'], $values['role'])) {
if ($this->projectGroupRole->addGroup($project['id'], $values['group_id'], $values['role'])) {
$this->flash->success(t('Project updated successfully.'));
} else {
$this->flash->failure(t('Unable to update this project.'));
}
$this->response->redirect($this->helper->url->to('ProjectPermission', 'index', array('project_id' => $values['project_id'])));
$this->response->redirect($this->helper->url->to('ProjectPermission', 'index', array('project_id' => $project['id'])));
}
/**
@ -143,19 +160,16 @@ class ProjectPermission extends Base
public function removeGroup()
{
$this->checkCSRFParam();
$project = $this->getProject();
$group_id = $this->request->getIntegerParam('group_id');
$values = array(
'project_id' => $this->request->getIntegerParam('project_id'),
'group_id' => $this->request->getIntegerParam('group_id'),
);
if ($this->projectGroupRole->removeGroup($values['project_id'], $values['group_id'])) {
if ($this->projectGroupRole->removeGroup($project['id'], $group_id)) {
$this->flash->success(t('Project updated successfully.'));
} else {
$this->flash->failure(t('Unable to update this project.'));
}
$this->response->redirect($this->helper->url->to('ProjectPermission', 'index', array('project_id' => $values['project_id'])));
$this->response->redirect($this->helper->url->to('ProjectPermission', 'index', array('project_id' => $project['id'])));
}
/**
@ -165,10 +179,10 @@ class ProjectPermission extends Base
*/
public function changeGroupRole()
{
$project_id = $this->request->getIntegerParam('project_id');
$project = $this->getProject();
$values = $this->request->getJson();
if (! empty($project_id) && ! empty($values) && $this->projectGroupRole->changeGroupRole($project_id, $values['id'], $values['role'])) {
if (! empty($project) && ! empty($values) && $this->projectGroupRole->changeGroupRole($project['id'], $values['id'], $values['role'])) {
$this->response->json(array('status' => 'ok'));
} else {
$this->response->json(array('status' => 'error'));

View File

@ -14,23 +14,6 @@ use Kanboard\Core\Security\Role;
*/
class Projectuser extends Base
{
/**
* Common layout for users overview views
*
* @access private
* @param string $template Template name
* @param array $params Template parameters
* @return string
*/
private function layout($template, array $params)
{
$params['board_selector'] = $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId());
$params['content_for_sublayout'] = $this->template->render($template, $params);
$params['filter'] = array('user_id' => $params['user_id']);
return $this->template->layout('project_user/layout', $params);
}
private function common()
{
$user_id = $this->request->getIntegerParam('user_id', UserModel::EVERYBODY_ID);
@ -62,7 +45,7 @@ class Projectuser extends Base
->setQuery($query)
->calculate();
$this->response->html($this->layout('project_user/roles', array(
$this->response->html($this->helper->layout->projectUser('project_user/roles', array(
'paginator' => $paginator,
'title' => $title,
'user_id' => $user_id,
@ -88,7 +71,7 @@ class Projectuser extends Base
->setQuery($query)
->calculate();
$this->response->html($this->layout('project_user/tasks', array(
$this->response->html($this->helper->layout->projectUser('project_user/tasks', array(
'paginator' => $paginator,
'title' => $title,
'user_id' => $user_id,

View File

@ -36,8 +36,7 @@ class Search extends Base
$nb_tasks = $paginator->getTotal();
}
$this->response->html($this->template->layout('search/index', array(
'board_selector' => $projects,
$this->response->html($this->helper->layout->app('search/index', array(
'values' => array(
'search' => $search,
'controller' => 'search',

View File

@ -2,8 +2,6 @@
namespace Kanboard\Controller;
use Kanboard\Model\Subtask as SubtaskModel;
/**
* Subtask controller
*
@ -13,20 +11,20 @@ use Kanboard\Model\Subtask as SubtaskModel;
class Subtask extends Base
{
/**
* Get the current subtask
*
* @access private
* @return array
* Show list of subtasks
*/
private function getSubtask()
public function show()
{
$subtask = $this->subtask->getById($this->request->getIntegerParam('subtask_id'));
$task = $this->getTask();
if (empty($subtask)) {
$this->notfound();
}
return $subtask;
$this->response->html($this->helper->layout->task('subtask/show', array(
'users_list' => $this->projectUserRole->getAssignableUsersList($task['project_id']),
'task' => $task,
'project' => $this->getProject(),
'subtasks' => $this->subtask->getAll($task['id']),
'editable' => true,
'redirect' => 'subtask',
)));
}
/**
@ -45,7 +43,7 @@ class Subtask extends Base
);
}
$this->response->html($this->taskLayout('subtask/create', array(
$this->response->html($this->helper->layout->task('subtask/create', array(
'values' => $values,
'errors' => $errors,
'users_list' => $this->projectUserRole->getAssignableUsersList($task['project_id']),
@ -73,10 +71,10 @@ class Subtask extends Base
}
if (isset($values['another_subtask']) && $values['another_subtask'] == 1) {
$this->response->redirect($this->helper->url->to('subtask', 'create', array('project_id' => $task['project_id'], 'task_id' => $task['id'], 'another_subtask' => 1)));
return $this->create(array('project_id' => $task['project_id'], 'task_id' => $task['id'], 'another_subtask' => 1));
}
$this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id']), 'subtasks'));
return $this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id']), 'subtasks'), true);
}
$this->create($values, $errors);
@ -92,7 +90,7 @@ class Subtask extends Base
$task = $this->getTask();
$subtask = $this->getSubTask();
$this->response->html($this->taskLayout('subtask/edit', array(
$this->response->html($this->helper->layout->task('subtask/edit', array(
'values' => empty($values) ? $subtask : $values,
'errors' => $errors,
'users_list' => $this->projectUserRole->getAssignableUsersList($task['project_id']),
@ -122,7 +120,7 @@ class Subtask extends Base
$this->flash->failure(t('Unable to update your sub-task.'));
}
$this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id']), 'subtasks'));
return $this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id'])), true);
}
$this->edit($values, $errors);
@ -138,7 +136,7 @@ class Subtask extends Base
$task = $this->getTask();
$subtask = $this->getSubtask();
$this->response->html($this->taskLayout('subtask/remove', array(
$this->response->html($this->helper->layout->task('subtask/remove', array(
'subtask' => $subtask,
'task' => $task,
)));
@ -161,97 +159,7 @@ class Subtask extends Base
$this->flash->failure(t('Unable to remove this sub-task.'));
}
$this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id']), 'subtasks'));
}
/**
* Change status to the next status: Toto -> In Progress -> Done
*
* @access public
*/
public function toggleStatus()
{
$task = $this->getTask();
$subtask = $this->getSubtask();
$redirect = $this->request->getStringParam('redirect', 'task');
$this->subtask->toggleStatus($subtask['id']);
if ($redirect === 'board') {
$this->sessionStorage->hasSubtaskInProgress = $this->subtask->hasSubtaskInProgress($this->userSession->getId());
$this->response->html($this->template->render('board/tooltip_subtasks', array(
'subtasks' => $this->subtask->getAll($task['id']),
'task' => $task,
)));
}
$this->toggleRedirect($task, $redirect);
}
/**
* Handle subtask restriction (popover)
*
* @access public
*/
public function subtaskRestriction()
{
$task = $this->getTask();
$subtask = $this->getSubtask();
$this->response->html($this->template->render('subtask/restriction_change_status', array(
'status_list' => array(
SubtaskModel::STATUS_TODO => t('Todo'),
SubtaskModel::STATUS_DONE => t('Done'),
),
'subtask_inprogress' => $this->subtask->getSubtaskInProgress($this->userSession->getId()),
'subtask' => $subtask,
'task' => $task,
'redirect' => $this->request->getStringParam('redirect'),
)));
}
/**
* Change status of the in progress subtask and the other subtask
*
* @access public
*/
public function changeRestrictionStatus()
{
$task = $this->getTask();
$subtask = $this->getSubtask();
$values = $this->request->getValues();
// Change status of the previous in progress subtask
$this->subtask->update(array(
'id' => $values['id'],
'status' => $values['status'],
));
// Set the current subtask to in pogress
$this->subtask->update(array(
'id' => $subtask['id'],
'status' => SubtaskModel::STATUS_INPROGRESS,
));
$this->toggleRedirect($task, $values['redirect']);
}
/**
* Redirect to the right page
*
* @access private
*/
private function toggleRedirect(array $task, $redirect)
{
switch ($redirect) {
case 'board':
$this->response->redirect($this->helper->url->to('board', 'show', array('project_id' => $task['project_id'])));
case 'dashboard':
$this->response->redirect($this->helper->url->to('app', 'index'));
default:
$this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), 'subtasks'));
}
$this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id'])), true);
}
/**
@ -267,8 +175,9 @@ class Subtask extends Base
$subtask_id = $this->request->getIntegerParam('subtask_id');
$direction = $this->request->getStringParam('direction');
$method = $direction === 'up' ? 'moveUp' : 'moveDown';
$redirect = $this->request->getStringParam('redirect', 'task');
$this->subtask->$method($task_id, $subtask_id);
$this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $project_id, 'task_id' => $task_id), 'subtasks'));
$this->response->redirect($this->helper->url->to($redirect, 'show', array('project_id' => $project_id, 'task_id' => $task_id), 'subtasks'));
}
}

View File

@ -0,0 +1,61 @@
<?php
namespace Kanboard\Controller;
use Kanboard\Model\Subtask as SubtaskModel;
/**
* Subtask Restriction
*
* @package controller
* @author Frederic Guillot
*/
class SubtaskRestriction extends Base
{
/**
* Show popup
*
* @access public
*/
public function popover()
{
$task = $this->getTask();
$subtask = $this->getSubtask();
$this->response->html($this->template->render('subtask_restriction/popover', array(
'status_list' => array(
SubtaskModel::STATUS_TODO => t('Todo'),
SubtaskModel::STATUS_DONE => t('Done'),
),
'subtask_inprogress' => $this->subtask->getSubtaskInProgress($this->userSession->getId()),
'subtask' => $subtask,
'task' => $task,
)));
}
/**
* Change status of the in progress subtask and the other subtask
*
* @access public
*/
public function update()
{
$task = $this->getTask();
$subtask = $this->getSubtask();
$values = $this->request->getValues();
// Change status of the previous "in progress" subtask
$this->subtask->update(array(
'id' => $values['id'],
'status' => $values['status'],
));
// Set the current subtask to "in progress"
$this->subtask->update(array(
'id' => $subtask['id'],
'status' => SubtaskModel::STATUS_INPROGRESS,
));
$this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id'])), true);
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace Kanboard\Controller;
/**
* Subtask Status
*
* @package controller
* @author Frederic Guillot
*/
class SubtaskStatus extends Base
{
/**
* Change status to the next status: Toto -> In Progress -> Done
*
* @access public
*/
public function change()
{
$task = $this->getTask();
$subtask = $this->getSubtask();
$status = $this->subtask->toggleStatus($subtask['id']);
$subtask['status'] = $status;
$this->response->html($this->helper->subtask->toggleStatus($subtask, $task['project_id']));
}
}

View File

@ -40,7 +40,7 @@ class Swimlane extends Base
{
$project = $this->getProject();
$this->response->html($this->projectLayout('swimlane/index', array(
$this->response->html($this->helper->layout->project('swimlane/index', array(
'default_swimlane' => $this->swimlane->getDefault($project['id']),
'active_swimlanes' => $this->swimlane->getAllByStatus($project['id'], SwimlaneModel::ACTIVE),
'inactive_swimlanes' => $this->swimlane->getAllByStatus($project['id'], SwimlaneModel::INACTIVE),
@ -108,7 +108,7 @@ class Swimlane extends Base
$project = $this->getProject();
$swimlane = $this->getSwimlane($project['id']);
$this->response->html($this->projectLayout('swimlane/edit', array(
$this->response->html($this->helper->layout->project('swimlane/edit', array(
'values' => empty($values) ? $swimlane : $values,
'errors' => $errors,
'project' => $project,
@ -150,7 +150,7 @@ class Swimlane extends Base
$project = $this->getProject();
$swimlane = $this->getSwimlane($project['id']);
$this->response->html($this->projectLayout('swimlane/remove', array(
$this->response->html($this->helper->layout->project('swimlane/remove', array(
'project' => $project,
'swimlane' => $swimlane,
'title' => t('Remove a swimlane')

View File

@ -30,7 +30,7 @@ class Task extends Base
$this->notfound(true);
}
$this->response->html($this->template->layout('task/public', array(
$this->response->html($this->helper->layout->app('task/public', array(
'project' => $project,
'comments' => $this->comment->getAll($task['id']),
'subtasks' => $this->subtask->getAll($task['id']),
@ -64,7 +64,7 @@ class Task extends Base
$this->dateParser->format($values, array('date_started'), 'Y-m-d H:i');
$this->response->html($this->taskLayout('task/show', array(
$this->response->html($this->helper->layout->task('task/show', array(
'project' => $this->project->getById($task['project_id']),
'files' => $this->file->getAllDocuments($task['id']),
'images' => $this->file->getAllImages($task['id']),
@ -95,7 +95,7 @@ class Task extends Base
{
$task = $this->getTask();
$this->response->html($this->taskLayout('task/analytics', array(
$this->response->html($this->helper->layout->task('task/analytics', array(
'title' => $task['title'],
'task' => $task,
'lead_time' => $this->taskAnalytic->getLeadTime($task),
@ -121,7 +121,7 @@ class Task extends Base
->setQuery($this->subtaskTimeTracking->getTaskQuery($task['id']))
->calculateOnlyIf($this->request->getStringParam('pagination') === 'subtasks');
$this->response->html($this->taskLayout('task/time_tracking_details', array(
$this->response->html($this->helper->layout->task('task/time_tracking_details', array(
'task' => $task,
'subtask_paginator' => $subtask_paginator,
)));
@ -136,7 +136,7 @@ class Task extends Base
{
$task = $this->getTask();
$this->response->html($this->taskLayout('task/transitions', array(
$this->response->html($this->helper->layout->task('task/transitions', array(
'task' => $task,
'transitions' => $this->transition->getAllByTask($task['id']),
)));
@ -167,7 +167,7 @@ class Task extends Base
$this->response->redirect($this->helper->url->to('board', 'show', array('project_id' => $task['project_id'])));
}
$this->response->html($this->taskLayout('task/remove', array(
$this->response->html($this->helper->layout->task('task/remove', array(
'task' => $task,
)));
}

View File

@ -0,0 +1,185 @@
<?php
namespace Kanboard\Controller;
use Kanboard\Core\ExternalLink\ExternalLinkProviderNotFound;
/**
* Task External Link Controller
*
* @package controller
* @author Frederic Guillot
*/
class TaskExternalLink extends Base
{
/**
* Creation form
*
* @access public
*/
public function show()
{
$task = $this->getTask();
$this->response->html($this->helper->layout->task('task_external_link/show', array(
'links' => $this->taskExternalLink->getAll($task['id']),
'task' => $task,
'title' => t('List of external links'),
)));
}
/**
* First creation form
*
* @access public
*/
public function find(array $values = array(), array $errors = array())
{
$task = $this->getTask();
$this->response->html($this->helper->layout->task('task_external_link/find', array(
'values' => $values,
'errors' => $errors,
'task' => $task,
'types' => $this->externalLinkManager->getTypes(),
)));
}
/**
* Second creation form
*
* @access public
*/
public function create()
{
try {
$task = $this->getTask();
$values = $this->request->getValues();
$provider = $this->externalLinkManager->setUserInput($values)->find();
$link = $provider->getLink();
$this->response->html($this->helper->layout->task('task_external_link/create', array(
'values' => array(
'title' => $link->getTitle(),
'url' => $link->getUrl(),
'link_type' => $provider->getType(),
),
'dependencies' => $provider->getDependencies(),
'errors' => array(),
'task' => $task,
)));
} catch (ExternalLinkProviderNotFound $e) {
$errors = array('text' => array(t('Unable to fetch link information.')));
$this->find($values, $errors);
}
}
/**
* Save link
*
* @access public
*/
public function save()
{
$task = $this->getTask();
$values = $this->request->getValues();
list($valid, $errors) = $this->externalLinkValidator->validateCreation($values);
if ($valid && $this->taskExternalLink->create($values)) {
$this->flash->success(t('Link added successfully.'));
return $this->response->redirect($this->helper->url->to('TaskExternalLink', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), true);
}
$this->edit($values, $errors);
}
/**
* Edit form
*
* @access public
*/
public function edit(array $values = array(), array $errors = array())
{
$task = $this->getTask();
$link_id = $this->request->getIntegerParam('link_id');
if ($link_id > 0) {
$values = $this->taskExternalLink->getById($link_id);
}
if (empty($values)) {
return $this->notfound();
}
$provider = $this->externalLinkManager->getProvider($values['link_type']);
$this->response->html($this->helper->layout->task('task_external_link/edit', array(
'values' => $values,
'errors' => $errors,
'task' => $task,
'dependencies' => $provider->getDependencies(),
)));
}
/**
* Update link
*
* @access public
*/
public function update()
{
$task = $this->getTask();
$values = $this->request->getValues();
list($valid, $errors) = $this->externalLinkValidator->validateModification($values);
if ($valid && $this->taskExternalLink->update($values)) {
$this->flash->success(t('Link updated successfully.'));
return $this->response->redirect($this->helper->url->to('TaskExternalLink', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), true);
}
$this->edit($values, $errors);
}
/**
* Confirmation dialog before removing a link
*
* @access public
*/
public function confirm()
{
$task = $this->getTask();
$link_id = $this->request->getIntegerParam('link_id');
$link = $this->taskExternalLink->getById($link_id);
if (empty($link)) {
return $this->notfound();
}
$this->response->html($this->helper->layout->task('task_external_link/remove', array(
'link' => $link,
'task' => $task,
)));
}
/**
* Remove a link
*
* @access public
*/
public function remove()
{
$this->checkCSRFParam();
$task = $this->getTask();
if ($this->taskExternalLink->remove($this->request->getIntegerParam('link_id'))) {
$this->flash->success(t('Link removed successfully.'));
} else {
$this->flash->failure(t('Unable to remove this link.'));
}
$this->response->redirect($this->helper->url->to('TaskExternalLink', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])));
}
}

View File

@ -20,7 +20,7 @@ class TaskImport extends Base
{
$project = $this->getProject();
$this->response->html($this->projectLayout('task_import/step1', array(
$this->response->html($this->helper->layout->project('task_import/step1', array(
'project' => $project,
'values' => $values,
'errors' => $errors,

View File

@ -0,0 +1,61 @@
<?php
namespace Kanboard\Controller;
/**
* Task Recurrence controller
*
* @package controller
* @author Frederic Guillot
*/
class TaskRecurrence extends Base
{
/**
* Edit recurrence form
*
* @access public
*/
public function edit(array $values = array(), array $errors = array())
{
$task = $this->getTask();
if (empty($values)) {
$values = $task;
}
$this->response->html($this->helper->layout->task('task_recurrence/edit', array(
'values' => $values,
'errors' => $errors,
'task' => $task,
'recurrence_status_list' => $this->task->getRecurrenceStatusList(),
'recurrence_trigger_list' => $this->task->getRecurrenceTriggerList(),
'recurrence_timeframe_list' => $this->task->getRecurrenceTimeframeList(),
'recurrence_basedate_list' => $this->task->getRecurrenceBasedateList(),
)));
}
/**
* Update recurrence form
*
* @access public
*/
public function update()
{
$task = $this->getTask();
$values = $this->request->getValues();
list($valid, $errors) = $this->taskValidator->validateEditRecurrence($values);
if ($valid) {
if ($this->taskModification->update($values)) {
$this->flash->success(t('Task updated successfully.'));
} else {
$this->flash->failure(t('Unable to update your task.'));
}
$this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id'])), true);
}
$this->edit($values, $errors);
}
}

View File

@ -18,22 +18,21 @@ class Taskcreation extends Base
public function create(array $values = array(), array $errors = array())
{
$project = $this->getProject();
$method = $this->request->isAjax() ? 'render' : 'layout';
$swimlanes_list = $this->swimlane->getList($project['id'], false, true);
if (empty($values)) {
$values = array(
'swimlane_id' => $this->request->getIntegerParam('swimlane_id', key($swimlanes_list)),
'column_id' => $this->request->getIntegerParam('column_id'),
'color_id' => $this->request->getStringParam('color_id', $this->color->getDefaultColor()),
'owner_id' => $this->request->getIntegerParam('owner_id'),
'another_task' => $this->request->getIntegerParam('another_task'),
'color_id' => $this->color->getDefaultColor(),
'owner_id' => $this->userSession->getId(),
);
$values = $this->hook->merge('controller:task:form:default', $values, array('default_values' => $values));
}
$this->response->html($this->template->$method('task_creation/form', array(
$this->response->html($this->template->render('task_creation/form', array(
'project' => $project,
'ajax' => $this->request->isAjax(),
'errors' => $errors,
'values' => $values + array('project_id' => $project['id']),
'columns_list' => $this->board->getColumnsList($project['id']),
@ -41,8 +40,6 @@ class Taskcreation extends Base
'colors_list' => $this->color->getList(),
'categories_list' => $this->category->getList($project['id']),
'swimlanes_list' => $swimlanes_list,
'date_format' => $this->config->get('application_date_format'),
'date_formats' => $this->dateParser->getAvailableFormats(),
'title' => $project['name'].' &gt; '.t('New task')
)));
}
@ -61,25 +58,26 @@ class Taskcreation extends Base
if ($valid && $this->taskCreation->create($values)) {
$this->flash->success(t('Task created successfully.'));
$this->afterSave($project, $values);
} else {
$this->flash->failure(t('Unable to create your task.'));
return $this->afterSave($project, $values);
}
$this->flash->failure(t('Unable to create your task.'));
$this->create($values, $errors);
}
private function afterSave(array $project, array &$values)
{
if (isset($values['another_task']) && $values['another_task'] == 1) {
unset($values['title']);
unset($values['description']);
if (! $this->request->isAjax()) {
$this->response->redirect($this->helper->url->to('taskcreation', 'create', $values));
}
} else {
$this->response->redirect($this->helper->url->to('board', 'show', array('project_id' => $project['id'])));
return $this->create(array(
'owner_id' => $values['owner_id'],
'color_id' => $values['color_id'],
'category_id' => isset($values['category_id']) ? $values['category_id'] : 0,
'column_id' => $values['column_id'],
'swimlane_id' => isset($values['swimlane_id']) ? $values['swimlane_id'] : 0,
'another_task' => 1,
));
}
$this->response->redirect($this->helper->url->to('board', 'show', array('project_id' => $project['id'])));
}
}

View File

@ -2,8 +2,6 @@
namespace Kanboard\Controller;
use Kanboard\Model\Project as ProjectModel;
/**
* Task Duplication controller
*
@ -30,11 +28,11 @@ class Taskduplication extends Base
$this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task_id)));
} else {
$this->flash->failure(t('Unable to create this task.'));
$this->response->redirect($this->helper->url->to('taskduplication', 'duplicate', array('project_id' => $task['project_id'], 'task_id' => $task['id'])));
$this->response->redirect($this->helper->url->to('taskduplication', 'duplicate', array('project_id' => $task['project_id'], 'task_id' => $task['id'])), true);
}
}
$this->response->html($this->taskLayout('task_duplication/duplicate', array(
$this->response->html($this->helper->layout->task('task_duplication/duplicate', array(
'task' => $task,
)));
}
@ -109,7 +107,7 @@ class Taskduplication extends Base
private function chooseDestination(array $task, $template)
{
$values = array();
$projects_list = $this->projectUserRole->getProjectsByUser($this->userSession->getId(), array(ProjectModel::ACTIVE));
$projects_list = $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId());
unset($projects_list[$task['project_id']]);
@ -130,7 +128,7 @@ class Taskduplication extends Base
$users_list = array();
}
$this->response->html($this->taskLayout($template, array(
$this->response->html($this->helper->layout->task($template, array(
'values' => $values,
'task' => $task,
'projects_list' => $projects_list,

View File

@ -22,12 +22,31 @@ class Tasklink extends Base
$link = $this->taskLink->getById($this->request->getIntegerParam('link_id'));
if (empty($link)) {
$this->notfound();
return $this->notfound();
}
return $link;
}
/**
* Show links
*
* @access public
*/
public function show()
{
$task = $this->getTask();
$project = $this->project->getById($task['project_id']);
$this->response->html($this->helper->layout->task('tasklink/show', array(
'links' => $this->taskLink->getAllGroupedByLabel($task['id']),
'task' => $task,
'project' => $project,
'editable' => true,
'is_public' => false,
)));
}
/**
* Creation form
*
@ -36,20 +55,8 @@ class Tasklink extends Base
public function create(array $values = array(), array $errors = array())
{
$task = $this->getTask();
$ajax = $this->request->isAjax() || $this->request->getIntegerParam('ajax');
if ($ajax && empty($errors)) {
$this->response->html($this->template->render('tasklink/create', array(
'values' => $values,
'errors' => $errors,
'task' => $task,
'labels' => $this->link->getList(0, false),
'title' => t('Add a new link'),
'ajax' => $ajax,
)));
}
$this->response->html($this->taskLayout('tasklink/create', array(
$this->response->html($this->helper->layout->task('tasklink/create', array(
'values' => $values,
'errors' => $errors,
'task' => $task,
@ -67,19 +74,13 @@ class Tasklink extends Base
{
$task = $this->getTask();
$values = $this->request->getValues();
$ajax = $this->request->isAjax() || $this->request->getIntegerParam('ajax');
list($valid, $errors) = $this->taskLinkValidator->validateCreation($values);
if ($valid) {
if ($this->taskLink->create($values['task_id'], $values['opposite_task_id'], $values['link_id'])) {
$this->flash->success(t('Link added successfully.'));
if ($ajax) {
$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'])).'#links');
return $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])).'#links', true);
}
$errors = array('title' => array(t('The exact same link already exists')));
@ -105,7 +106,7 @@ class Tasklink extends Base
$values['title'] = '#'.$opposite_task['id'].' - '.$opposite_task['title'];
}
$this->response->html($this->taskLayout('tasklink/edit', array(
$this->response->html($this->helper->layout->task('tasklink/edit', array(
'values' => $values,
'errors' => $errors,
'task_link' => $task_link,
@ -130,7 +131,7 @@ class Tasklink extends Base
if ($valid) {
if ($this->taskLink->update($values['id'], $values['task_id'], $values['opposite_task_id'], $values['link_id'])) {
$this->flash->success(t('Link updated successfully.'));
$this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])).'#links');
return $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])).'#links');
}
$this->flash->failure(t('Unable to update your link.'));
@ -149,7 +150,7 @@ class Tasklink extends Base
$task = $this->getTask();
$link = $this->getTaskLink();
$this->response->html($this->taskLayout('tasklink/remove', array(
$this->response->html($this->helper->layout->task('tasklink/remove', array(
'link' => $link,
'task' => $task,
)));

View File

@ -48,46 +48,44 @@ class Taskmodification extends Base
*
* @access public
*/
public function description()
public function description(array $values = array(), array $errors = array())
{
$task = $this->getTask();
$ajax = $this->request->isAjax() || $this->request->getIntegerParam('ajax');
if ($this->request->isPost()) {
$values = $this->request->getValues();
list($valid, $errors) = $this->taskValidator->validateDescriptionCreation($values);
if ($valid) {
if ($this->taskModification->update($values)) {
$this->flash->success(t('Task updated successfully.'));
} else {
$this->flash->failure(t('Unable to update your task.'));
}
if ($ajax) {
$this->response->redirect($this->helper->url->to('board', 'show', array('project_id' => $task['project_id'])));
} else {
$this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id'])));
}
}
} else {
$values = $task;
$errors = array();
if (empty($values)) {
$values = array('id' => $task['id'], 'description' => $task['description']);
}
$params = array(
$this->response->html($this->helper->layout->task('task_modification/edit_description', array(
'values' => $values,
'errors' => $errors,
'task' => $task,
'ajax' => $ajax,
);
)));
}
if ($ajax) {
$this->response->html($this->template->render('task_modification/edit_description', $params));
} else {
$this->response->html($this->taskLayout('task_modification/edit_description', $params));
/**
* Update description
*
* @access public
*/
public function updateDescription()
{
$task = $this->getTask();
$values = $this->request->getValues();
list($valid, $errors) = $this->taskValidator->validateDescriptionCreation($values);
if ($valid) {
if ($this->taskModification->update($values)) {
$this->flash->success(t('Task updated successfully.'));
} else {
$this->flash->failure(t('Unable to update your task.'));
}
return $this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id'])), true);
}
$this->description($values, $errors);
}
/**
@ -99,15 +97,15 @@ class Taskmodification extends Base
{
$task = $this->getTask();
$project = $this->project->getById($task['project_id']);
$ajax = $this->request->isAjax();
if (empty($values)) {
$values = $task;
$values = $this->hook->merge('controller:task:form:default', $values, array('default_values' => $values));
}
$this->dateParser->format($values, array('date_due'));
$params = array(
$this->response->html($this->helper->layout->task('task_modification/edit_task', array(
'project' => $project,
'values' => $values,
'errors' => $errors,
@ -117,16 +115,7 @@ class Taskmodification extends Base
'categories_list' => $this->category->getList($task['project_id']),
'date_format' => $this->config->get('application_date_format'),
'date_formats' => $this->dateParser->getAvailableFormats(),
'ajax' => $ajax,
);
if ($ajax) {
$html = $this->template->render('task_modification/edit_task', $params);
} else {
$html = $this->taskLayout('task_modification/edit_task', $params);
}
$this->response->html($html);
)));
}
/**
@ -143,56 +132,10 @@ class Taskmodification extends Base
if ($valid && $this->taskModification->update($values)) {
$this->flash->success(t('Task updated successfully.'));
if ($this->request->isAjax()) {
$this->response->redirect($this->helper->url->to('board', 'show', array('project_id' => $task['project_id'])));
} else {
$this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id'])));
}
return $this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id'])), true);
} else {
$this->flash->failure(t('Unable to update your task.'));
$this->edit($values, $errors);
}
}
/**
* Edit recurrence form
*
* @access public
*/
public function recurrence()
{
$task = $this->getTask();
if ($this->request->isPost()) {
$values = $this->request->getValues();
list($valid, $errors) = $this->taskValidator->validateEditRecurrence($values);
if ($valid) {
if ($this->taskModification->update($values)) {
$this->flash->success(t('Task updated successfully.'));
} else {
$this->flash->failure(t('Unable to update your task.'));
}
$this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id'])));
}
} else {
$values = $task;
$errors = array();
}
$params = array(
'values' => $values,
'errors' => $errors,
'task' => $task,
'recurrence_status_list' => $this->task->getRecurrenceStatusList(),
'recurrence_trigger_list' => $this->task->getRecurrenceTriggerList(),
'recurrence_timeframe_list' => $this->task->getRecurrenceTimeframeList(),
'recurrence_basedate_list' => $this->task->getRecurrenceBasedateList(),
);
$this->response->html($this->taskLayout('task_modification/edit_recurrence', $params));
}
}

View File

@ -17,9 +17,7 @@ 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');
$this->changeStatus('close', 'task_status/close', t('Task closed successfully.'), t('Unable to close this task.'));
}
/**
@ -29,13 +27,22 @@ class Taskstatus extends Base
*/
public function open()
{
$task = $this->getTask();
$this->changeStatus($task, 'open', t('Task opened successfully.'), t('Unable to open this task.'));
$this->renderTemplate($task, 'task_status/open');
$this->changeStatus('open', 'task_status/open', t('Task opened successfully.'), t('Unable to open this task.'));
}
private function changeStatus(array $task, $method, $success_message, $failure_message)
/**
* Common method to change status
*
* @access private
* @param string $method
* @param string $template
* @param string $success_message
* @param string $failure_message
*/
private function changeStatus($method, $template, $success_message, $failure_message)
{
$task = $this->getTask();
if ($this->request->getStringParam('confirmation') === 'yes') {
$this->checkCSRFParam();
@ -45,28 +52,11 @@ class Taskstatus extends Base
$this->flash->failure($failure_message);
}
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($template, array(
'task' => $task,
'redirect' => $redirect,
)));
return $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), true);
}
$this->response->html($this->taskLayout($template, array(
$this->response->html($this->helper->layout->task($template, array(
'task' => $task,
'redirect' => $redirect,
)));
}
}

View File

@ -33,7 +33,7 @@ class Twofactor extends User
$this->checkCurrentUser($user);
unset($this->sessionStorage->twoFactorSecret);
$this->response->html($this->layout('twofactor/index', array(
$this->response->html($this->helper->layout->user('twofactor/index', array(
'user' => $user,
'provider' => $this->authenticationManager->getPostAuthenticationProvider()->getName(),
)));
@ -60,7 +60,7 @@ class Twofactor extends User
$provider->setSecret($this->sessionStorage->twoFactorSecret);
}
$this->response->html($this->layout('twofactor/show', array(
$this->response->html($this->helper->layout->user('twofactor/show', array(
'user' => $user,
'secret' => $this->sessionStorage->twoFactorSecret,
'qrcode_url' => $provider->getQrCodeUrl($label),
@ -165,7 +165,7 @@ class Twofactor extends User
$this->sessionStorage->twoFactorBeforeCodeCalled = true;
}
$this->response->html($this->template->layout('twofactor/check', array(
$this->response->html($this->helper->layout->app('twofactor/check', array(
'title' => t('Check two factor authentication code'),
)));
}
@ -191,7 +191,7 @@ class Twofactor extends User
$this->response->redirect($this->helper->url->to('user', 'show', array('user_id' => $user['id'])));
}
$this->response->html($this->layout('twofactor/disable', array(
$this->response->html($this->helper->layout->user('twofactor/disable', array(
'user' => $user,
)));
}

View File

@ -14,27 +14,6 @@ use Kanboard\Core\Security\Role;
*/
class User extends Base
{
/**
* Common layout for user views
*
* @access protected
* @param string $template Template name
* @param array $params Template parameters
* @return string
*/
protected function layout($template, array $params)
{
$content = $this->template->render($template, $params);
$params['user_content_for_layout'] = $content;
$params['board_selector'] = $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId());
if (isset($params['user'])) {
$params['title'] = ($params['user']['name'] ?: $params['user']['username']).' (#'.$params['user']['id'].')';
}
return $this->template->layout('user/layout', $params);
}
/**
* List all users
*
@ -50,8 +29,7 @@ class User extends Base
->calculate();
$this->response->html(
$this->template->layout('user/index', array(
'board_selector' => $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId()),
$this->helper->layout->app('user/index', array(
'title' => t('Users').' ('.$paginator->getTotal().')',
'paginator' => $paginator,
)));
@ -71,8 +49,7 @@ class User extends Base
}
$this->response->html(
$this->template->layout('user/profile', array(
'board_selector' => $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId()),
$this->helper->layout->app('user/profile', array(
'title' => $user['name'] ?: $user['username'],
'user' => $user,
)
@ -88,11 +65,10 @@ class User extends Base
{
$is_remote = $this->request->getIntegerParam('remote') == 1 || (isset($values['is_ldap_user']) && $values['is_ldap_user'] == 1);
$this->response->html($this->template->layout($is_remote ? 'user/create_remote' : 'user/create_local', array(
$this->response->html($this->helper->layout->app($is_remote ? 'user/create_remote' : 'user/create_local', array(
'timezones' => $this->config->getTimezones(true),
'languages' => $this->config->getLanguages(true),
'roles' => $this->role->getApplicationRoles(),
'board_selector' => $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId()),
'projects' => $this->project->getList(),
'errors' => $errors,
'values' => $values + array('role' => Role::APP_USER),
@ -142,7 +118,7 @@ class User extends Base
public function show()
{
$user = $this->getUser();
$this->response->html($this->layout('user/show', array(
$this->response->html($this->helper->layout->user('user/show', array(
'user' => $user,
'timezones' => $this->config->getTimezones(true),
'languages' => $this->config->getLanguages(true),
@ -166,7 +142,7 @@ class User extends Base
->setQuery($this->subtaskTimeTracking->getUserQuery($user['id']))
->calculateOnlyIf($this->request->getStringParam('pagination') === 'subtasks');
$this->response->html($this->layout('user/timesheet', array(
$this->response->html($this->helper->layout->user('user/timesheet', array(
'subtask_paginator' => $subtask_paginator,
'user' => $user,
)));
@ -180,7 +156,7 @@ class User extends Base
public function passwordReset()
{
$user = $this->getUser();
$this->response->html($this->layout('user/password_reset', array(
$this->response->html($this->helper->layout->user('user/password_reset', array(
'tokens' => $this->passwordReset->getAll($user['id']),
'user' => $user,
)));
@ -194,7 +170,7 @@ class User extends Base
public function last()
{
$user = $this->getUser();
$this->response->html($this->layout('user/last', array(
$this->response->html($this->helper->layout->user('user/last', array(
'last_logins' => $this->lastLogin->getAll($user['id']),
'user' => $user,
)));
@ -208,7 +184,7 @@ class User extends Base
public function sessions()
{
$user = $this->getUser();
$this->response->html($this->layout('user/sessions', array(
$this->response->html($this->helper->layout->user('user/sessions', array(
'sessions' => $this->rememberMeSession->getAll($user['id']),
'user' => $user,
)));
@ -243,7 +219,7 @@ class User extends Base
$this->response->redirect($this->helper->url->to('user', 'notifications', array('user_id' => $user['id'])));
}
$this->response->html($this->layout('user/notifications', array(
$this->response->html($this->helper->layout->user('user/notifications', array(
'projects' => $this->projectUserRole->getProjectsByUser($user['id'], array(ProjectModel::ACTIVE)),
'notifications' => $this->userNotification->readSettings($user['id']),
'types' => $this->userNotificationType->getTypes(),
@ -268,7 +244,7 @@ class User extends Base
$this->response->redirect($this->helper->url->to('user', 'integrations', array('user_id' => $user['id'])));
}
$this->response->html($this->layout('user/integrations', array(
$this->response->html($this->helper->layout->user('user/integrations', array(
'user' => $user,
'values' => $this->userMetadata->getall($user['id']),
)));
@ -282,7 +258,7 @@ class User extends Base
public function external()
{
$user = $this->getUser();
$this->response->html($this->layout('user/external', array(
$this->response->html($this->helper->layout->user('user/external', array(
'last_logins' => $this->lastLogin->getAll($user['id']),
'user' => $user,
)));
@ -310,7 +286,7 @@ class User extends Base
$this->response->redirect($this->helper->url->to('user', 'share', array('user_id' => $user['id'])));
}
$this->response->html($this->layout('user/share', array(
$this->response->html($this->helper->layout->user('user/share', array(
'user' => $user,
'title' => t('Public access'),
)));
@ -342,7 +318,7 @@ class User extends Base
}
}
$this->response->html($this->layout('user/password', array(
$this->response->html($this->helper->layout->user('user/password', array(
'values' => $values,
'errors' => $errors,
'user' => $user,
@ -384,7 +360,7 @@ class User extends Base
}
}
$this->response->html($this->layout('user/edit', array(
$this->response->html($this->helper->layout->user('user/edit', array(
'values' => $values,
'errors' => $errors,
'user' => $user,
@ -422,7 +398,7 @@ class User extends Base
}
}
$this->response->html($this->layout('user/authentication', array(
$this->response->html($this->helper->layout->user('user/authentication', array(
'values' => $values,
'errors' => $errors,
'user' => $user,
@ -450,7 +426,7 @@ class User extends Base
$this->response->redirect($this->helper->url->to('user', 'index'));
}
$this->response->html($this->layout('user/remove', array(
$this->response->html($this->helper->layout->user('user/remove', array(
'user' => $user,
)));
}

View File

@ -18,7 +18,7 @@ class UserImport extends Base
*/
public function step1(array $values = array(), array $errors = array())
{
$this->response->html($this->template->layout('user_import/step1', array(
$this->response->html($this->helper->layout->app('user_import/step1', array(
'values' => $values,
'errors' => $errors,
'max_size' => ini_get('upload_max_filesize'),

View File

@ -16,6 +16,7 @@ use Pimple\Container;
* @property \Kanboard\Analytic\AverageLeadCycleTimeAnalytic $averageLeadCycleTimeAnalytic
* @property \Kanboard\Analytic\AverageTimeSpentColumnAnalytic $averageTimeSpentColumnAnalytic
* @property \Kanboard\Core\Action\ActionManager $actionManager
* @property \Kanboard\Core\ExternalLink\ExternalLinkManager $externalLinkManager
* @property \Kanboard\Core\Cache\MemoryCache $memoryCache
* @property \Kanboard\Core\Event\EventManager $eventManager
* @property \Kanboard\Core\Group\GroupManager $groupManager
@ -97,6 +98,7 @@ use Pimple\Container;
* @property \Kanboard\Model\TaskCreation $taskCreation
* @property \Kanboard\Model\TaskDuplication $taskDuplication
* @property \Kanboard\Model\TaskExport $taskExport
* @property \Kanboard\Model\TaskExternalLink $taskExternalLink
* @property \Kanboard\Model\TaskImport $taskImport
* @property \Kanboard\Model\TaskFinder $taskFinder
* @property \Kanboard\Model\TaskFilter $taskFilter
@ -132,6 +134,7 @@ use Pimple\Container;
* @property \Kanboard\Validator\SubtaskValidator $subtaskValidator
* @property \Kanboard\Validator\SwimlaneValidator $swimlaneValidator
* @property \Kanboard\Validator\TaskLinkValidator $taskLinkValidator
* @property \Kanboard\Validator\TaskExternalLinkValidator $taskExternalLinkValidator
* @property \Kanboard\Validator\TaskValidator $taskValidator
* @property \Kanboard\Validator\UserValidator $userValidator
* @property \Psr\Log\LoggerInterface $logger

View File

@ -52,6 +52,7 @@ class EventManager
Task::EVENT_CLOSE => t('Closing a task'),
Task::EVENT_CREATE_UPDATE => t('Task creation or modification'),
Task::EVENT_ASSIGNEE_CHANGE => t('Task assignee change'),
Task::EVENT_DAILY_CRONJOB => t('Daily background job for tasks'),
);
$events = array_merge($events, $this->events);

View File

@ -0,0 +1,36 @@
<?php
namespace Kanboard\Core\ExternalLink;
/**
* External Link Interface
*
* @package externalLink
* @author Frederic Guillot
*/
interface ExternalLinkInterface
{
/**
* Get link title
*
* @access public
* @return string
*/
public function getTitle();
/**
* Get link URL
*
* @access public
* @return string
*/
public function getUrl();
/**
* Set link URL
*
* @access public
* @param string $url
*/
public function setUrl($url);
}

View File

@ -0,0 +1,173 @@
<?php
namespace Kanboard\Core\ExternalLink;
use Kanboard\Core\Base;
/**
* External Link Manager
*
* @package externalLink
* @author Frederic Guillot
*/
class ExternalLinkManager extends Base
{
/**
* Automatic type value
*
* @var string
*/
const TYPE_AUTO = 'auto';
/**
* Registered providers
*
* @access private
* @var array
*/
private $providers = array();
/**
* Type chosen by the user
*
* @access private
* @var string
*/
private $userInputType = '';
/**
* Text entered by the user
*
* @access private
* @var string
*/
private $userInputText = '';
/**
* Register a new provider
*
* Providers are registered in a LIFO queue
*
* @access public
* @param ExternalLinkProviderInterface $provider
* @return ExternalLinkManager
*/
public function register(ExternalLinkProviderInterface $provider)
{
array_unshift($this->providers, $provider);
return $this;
}
/**
* Get provider
*
* @access public
* @param string $type
* @throws ExternalLinkProviderNotFound
* @return ExternalLinkProviderInterface
*/
public function getProvider($type)
{
foreach ($this->providers as $provider) {
if ($provider->getType() === $type) {
return $provider;
}
}
throw new ExternalLinkProviderNotFound('Unable to find link provider: '.$type);
}
/**
* Get link types
*
* @access public
* @return array
*/
public function getTypes()
{
$types = array();
foreach ($this->providers as $provider) {
$types[$provider->getType()] = $provider->getName();
}
asort($types);
return array(self::TYPE_AUTO => t('Auto')) + $types;
}
/**
* Get dependency label from a provider
*
* @access public
* @param string $type
* @param string $dependency
* @return string
*/
public function getDependencyLabel($type, $dependency)
{
$provider = $this->getProvider($type);
$dependencies = $provider->getDependencies();
return isset($dependencies[$dependency]) ? $dependencies[$dependency] : $dependency;
}
/**
* Find a provider that match
*
* @access public
* @throws ExternalLinkProviderNotFound
* @return ExternalLinkProviderInterface
*/
public function find()
{
if ($this->userInputType === self::TYPE_AUTO) {
$provider = $this->findProvider();
} else {
$provider = $this->getProvider($this->userInputType);
$provider->setUserTextInput($this->userInputText);
if (! $provider->match()) {
throw new ExternalLinkProviderNotFound('Unable to parse URL with selected provider');
}
}
if ($provider === null) {
throw new ExternalLinkProviderNotFound('Unable to find link information from provided information');
}
return $provider;
}
/**
* Set form values
*
* @access public
* @param array $values
* @return ExternalLinkManager
*/
public function setUserInput(array $values)
{
$this->userInputType = empty($values['type']) ? self::TYPE_AUTO : $values['type'];
$this->userInputText = empty($values['text']) ? '' : trim($values['text']);
return $this;
}
/**
* Find a provider that user input
*
* @access private
* @return ExternalLinkProviderInterface
*/
private function findProvider()
{
foreach ($this->providers as $provider) {
$provider->setUserTextInput($this->userInputText);
if ($provider->match()) {
return $provider;
}
}
return null;
}
}

View File

@ -0,0 +1,71 @@
<?php
namespace Kanboard\Core\ExternalLink;
/**
* External Link Provider Interface
*
* @package externalLink
* @author Frederic Guillot
*/
interface ExternalLinkProviderInterface
{
/**
* Get provider name (label)
*
* @access public
* @return string
*/
public function getName();
/**
* Get link type (will be saved in the database)
*
* @access public
* @return string
*/
public function getType();
/**
* Get a dictionary of supported dependency types by the provider
*
* Example:
*
* [
* 'related' => t('Related'),
* 'child' => t('Child'),
* 'parent' => t('Parent'),
* 'self' => t('Self'),
* ]
*
* The dictionary key is saved in the database.
*
* @access public
* @return array
*/
public function getDependencies();
/**
* Set text entered by the user
*
* @access public
* @param string $input
*/
public function setUserTextInput($input);
/**
* Return true if the provider can parse correctly the user input
*
* @access public
* @return boolean
*/
public function match();
/**
* Get the link found with the properties
*
* @access public
* @return ExternalLinkInterface
*/
public function getLink();
}

View File

@ -0,0 +1,15 @@
<?php
namespace Kanboard\Core\ExternalLink;
use Exception;
/**
* External Link Provider Not Found Exception
*
* @package externalLink
* @author Frederic Guillot
*/
class ExternalLinkProviderNotFound extends Exception
{
}

View File

@ -20,6 +20,7 @@ use Pimple\Container;
* @property \Helper\Text $text
* @property \Helper\Url $url
* @property \Helper\User $user
* @property \Helper\Layout $layout
*/
class Helper
{

View File

@ -33,6 +33,19 @@ class Client extends Base
*/
const HTTP_USER_AGENT = 'Kanboard';
/**
* Send a GET HTTP request
*
* @access public
* @param string $url
* @param string[] $headers
* @return string
*/
public function get($url, array $headers = array())
{
return $this->doRequest('GET', $url, '', $headers);
}
/**
* Send a GET HTTP request and parse JSON response
*

View File

@ -68,11 +68,12 @@ class Response extends Base
*
* @access public
* @param string $url Redirection URL
* @param boolean $self If Ajax request and true: refresh the current page
*/
public function redirect($url)
public function redirect($url, $self = false)
{
if ($this->request->getServerVariable('HTTP_X_REQUESTED_WITH') === 'XMLHttpRequest') {
header('X-Ajax-Redirect: '.$url);
if ($this->request->isAjax()) {
header('X-Ajax-Redirect: '.($self ? 'self' : $url));
} else {
header('Location: '.$url);
}

View File

@ -7,7 +7,7 @@ use Symfony\Component\EventDispatcher\Event as BaseEvent;
class GenericEvent extends BaseEvent implements ArrayAccess
{
private $container = array();
protected $container = array();
public function __construct(array $values = array())
{

View File

@ -0,0 +1,11 @@
<?php
namespace Kanboard\Event;
class TaskListEvent extends GenericEvent
{
public function setTasks(array &$tasks)
{
$this->container['tasks'] =& $tasks;
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace Kanboard\ExternalLink;
use Kanboard\Core\ExternalLink\ExternalLinkInterface;
/**
* Attachment Link
*
* @package externalLink
* @author Frederic Guillot
*/
class AttachmentLink extends BaseLink implements ExternalLinkInterface
{
/**
* Get link title
*
* @access public
* @return string
*/
public function getTitle()
{
$path = parse_url($this->url, PHP_URL_PATH);
return basename($path);
}
}

View File

@ -0,0 +1,117 @@
<?php
namespace Kanboard\ExternalLink;
use Kanboard\Core\ExternalLink\ExternalLinkProviderInterface;
/**
* Attachment Link Provider
*
* @package externalLink
* @author Frederic Guillot
*/
class AttachmentLinkProvider extends BaseLinkProvider implements ExternalLinkProviderInterface
{
/**
* File extensions that are not attachments
*
* @access protected
* @var array
*/
protected $extensions = array(
'html',
'htm',
'xhtml',
'php',
'jsp',
'do',
'action',
'asp',
'aspx',
'cgi',
);
/**
* Get provider name
*
* @access public
* @return string
*/
public function getName()
{
return t('Attachment');
}
/**
* Get link type
*
* @access public
* @return string
*/
public function getType()
{
return 'attachment';
}
/**
* Get a dictionary of supported dependency types by the provider
*
* @access public
* @return array
*/
public function getDependencies()
{
return array(
'related' => t('Related'),
);
}
/**
* Return true if the provider can parse correctly the user input
*
* @access public
* @return boolean
*/
public function match()
{
if (preg_match('/^https?:\/\/.*\.([^\/]+)$/', $this->userInput, $matches)) {
return $this->isValidExtension($matches[1]);
}
return false;
}
/**
* Get the link found with the properties
*
* @access public
* @return ExternalLinkInterface
*/
public function getLink()
{
$link = new AttachmentLink($this->container);
$link->setUrl($this->userInput);
return $link;
}
/**
* Check file extension
*
* @access protected
* @param string $extension
* @return boolean
*/
protected function isValidExtension($extension)
{
$extension = strtolower($extension);
foreach ($this->extensions as $ext) {
if ($extension === $ext) {
return false;
}
}
return true;
}
}

View File

@ -0,0 +1,44 @@
<?php
namespace Kanboard\ExternalLink;
use Kanboard\Core\Base;
/**
* Base Link
*
* @package externalLink
* @author Frederic Guillot
*/
abstract class BaseLink extends Base
{
/**
* URL
*
* @access protected
* @var string
*/
protected $url = '';
/**
* Get link URL
*
* @access public
* @return string
*/
public function getUrl()
{
return $this->url;
}
/**
* Set link URL
*
* @access public
* @param string $url
*/
public function setUrl($url)
{
$this->url = $url;
}
}

View File

@ -0,0 +1,33 @@
<?php
namespace Kanboard\ExternalLink;
use Kanboard\Core\Base;
/**
* Base Link Provider
*
* @package externalLink
* @author Frederic Guillot
*/
abstract class BaseLinkProvider extends Base
{
/**
* User input
*
* @access protected
* @var string
*/
protected $userInput = '';
/**
* Set text entered by the user
*
* @access public
* @param string $input
*/
public function setUserTextInput($input)
{
$this->userInput = trim($input);
}
}

View File

@ -0,0 +1,37 @@
<?php
namespace Kanboard\ExternalLink;
use Kanboard\Core\ExternalLink\ExternalLinkInterface;
/**
* Web Link
*
* @package externalLink
* @author Frederic Guillot
*/
class WebLink extends BaseLink implements ExternalLinkInterface
{
/**
* Get link title
*
* @access public
* @return string
*/
public function getTitle()
{
$html = $this->httpClient->get($this->url);
if (preg_match('/<title>(.*)<\/title>/siU', $html, $matches)) {
return trim($matches[1]);
}
$components = parse_url($this->url);
if (! empty($components['host']) && ! empty($components['path'])) {
return $components['host'].$components['path'];
}
return t('Title not found');
}
}

View File

@ -0,0 +1,77 @@
<?php
namespace Kanboard\ExternalLink;
use Kanboard\Core\ExternalLink\ExternalLinkProviderInterface;
/**
* Web Link Provider
*
* @package externalLink
* @author Frederic Guillot
*/
class WebLinkProvider extends BaseLinkProvider implements ExternalLinkProviderInterface
{
/**
* Get provider name
*
* @access public
* @return string
*/
public function getName()
{
return t('Web Link');
}
/**
* Get link type
*
* @access public
* @return string
*/
public function getType()
{
return 'weblink';
}
/**
* Get a dictionary of supported dependency types by the provider
*
* @access public
* @return array
*/
public function getDependencies()
{
return array(
'related' => t('Related'),
);
}
/**
* Return true if the provider can parse correctly the user input
*
* @access public
* @return boolean
*/
public function match()
{
$startWithHttp = strpos($this->userInput, 'http://') === 0 || strpos($this->userInput, 'https://') === 0;
$validUrl = filter_var($this->userInput, FILTER_VALIDATE_URL);
return $startWithHttp && $validUrl;
}
/**
* Get the link found with the properties
*
* @access public
* @return ExternalLinkInterface
*/
public function getLink()
{
$link = new WebLink($this->container);
$link->setUrl($this->userInput);
return $link;
}
}

171
app/Helper/Layout.php Normal file
View File

@ -0,0 +1,171 @@
<?php
namespace Kanboard\Helper;
use Kanboard\Core\Base;
/**
* Layout helpers
*
* @package helper
* @author Frederic Guillot
*/
class Layout extends Base
{
/**
* Render a template without the layout if Ajax request
*
* @access public
* @param string $template Template name
* @param array $params Template parameters
* @return string
*/
public function app($template, array $params = array())
{
if ($this->request->isAjax()) {
return $this->template->render($template, $params);
}
if (! isset($params['no_layout']) && ! isset($params['board_selector'])) {
$params['board_selector'] = $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId());
}
return $this->template->layout($template, $params);
}
/**
* Common layout for user views
*
* @access public
* @param string $template Template name
* @param array $params Template parameters
* @return string
*/
public function user($template, array $params)
{
if (isset($params['user'])) {
$params['title'] = '#'.$params['user']['id'].' '.($params['user']['name'] ?: $params['user']['username']);
}
return $this->subLayout('user/layout', 'user/sidebar', $template, $params);
}
/**
* Common layout for task views
*
* @access public
* @param string $template Template name
* @param array $params Template parameters
* @return string
*/
public function task($template, array $params)
{
$params['title'] = $params['task']['title'];
return $this->subLayout('task/layout', 'task/sidebar', $template, $params);
}
/**
* Common layout for project views
*
* @access public
* @param string $template
* @param array $params
* @param string $sidebar
* @return string
*/
public function project($template, array $params, $sidebar = 'project/sidebar')
{
if (empty($params['title'])) {
$params['title'] = $params['project']['name'];
} elseif ($params['project']['name'] !== $params['title']) {
$params['title'] = $params['project']['name'].' &gt; '.$params['title'];
}
return $this->subLayout('project/layout', $sidebar, $template, $params);
}
/**
* Common layout for project user views
*
* @access public
* @param string $template
* @param array $params
* @return string
*/
public function projectUser($template, array $params)
{
$params['filter'] = array('user_id' => $params['user_id']);
return $this->subLayout('project_user/layout', 'project_user/sidebar', $template, $params);
}
/**
* Common layout for config views
*
* @access public
* @param string $template
* @param array $params
* @return string
*/
public function config($template, array $params)
{
if (! isset($params['values'])) {
$params['values'] = $this->config->getAll();
}
if (! isset($params['errors'])) {
$params['errors'] = array();
}
return $this->subLayout('config/layout', 'config/sidebar', $template, $params);
}
/**
* Common layout for dashboard views
*
* @access public
* @param string $template
* @param array $params
* @return string
*/
public function dashboard($template, array $params)
{
return $this->subLayout('app/layout', 'app/sidebar', $template, $params);
}
/**
* Common layout for analytic views
*
* @access public
* @param string $template
* @param array $params
* @return string
*/
public function analytic($template, array $params)
{
return $this->subLayout('analytic/layout', 'analytic/sidebar', $template, $params);
}
/**
* Common method to generate a sublayout
*
* @access public
* @param string $sublayout
* @param string $sidebar
* @param string $template
* @param array $params
* @return string
*/
public function subLayout($sublayout, $sidebar, $template, array $params = array())
{
$content = $this->template->render($template, $params);
if ($this->request->isAjax()) {
return $content;
}
$params['content_for_sublayout'] = $content;
$params['sidebar_template'] = $sidebar;
return $this->app($sublayout, $params);
}
}

View File

@ -10,37 +10,82 @@ namespace Kanboard\Helper;
*/
class Subtask extends \Kanboard\Core\Base
{
public function getTitle(array $subtask)
{
if ($subtask['status'] == 0) {
$html = '<i class="fa fa-square-o fa-fw"></i>';
} elseif ($subtask['status'] == 1) {
$html = '<i class="fa fa-gears fa-fw"></i>';
} else {
$html = '<i class="fa fa-check-square-o fa-fw"></i>';
}
return $html.$this->helper->e($subtask['title']);
}
/**
* Get the link to toggle subtask status
*
* @access public
* @param array $subtask
* @param string $redirect
* @param integer $project_id
* @return string
*/
public function toggleStatus(array $subtask, $redirect, $project_id = 0)
public function toggleStatus(array $subtask, $project_id)
{
if ($project_id > 0 && ! $this->helper->user->hasProjectAccess('subtask', 'edit', $project_id)) {
return trim($this->template->render('subtask/icons', array('subtask' => $subtask))) . $this->helper->e($subtask['title']);
if (! $this->helper->user->hasProjectAccess('subtask', 'edit', $project_id)) {
return $this->getTitle($subtask);
}
$params = array('task_id' => $subtask['task_id'], 'subtask_id' => $subtask['id']);
if ($subtask['status'] == 0 && isset($this->sessionStorage->hasSubtaskInProgress) && $this->sessionStorage->hasSubtaskInProgress) {
return $this->helper->url->link(
trim($this->template->render('subtask/icons', array('subtask' => $subtask))) . $this->helper->e($subtask['title']),
'subtask',
'subtaskRestriction',
array('task_id' => $subtask['task_id'], 'subtask_id' => $subtask['id'], 'redirect' => $redirect),
false,
'popover task-board-popover'
);
return $this->helper->url->link($this->getTitle($subtask), 'SubtaskRestriction', 'popover', $params, false, 'popover');
}
return $this->helper->url->link(
trim($this->template->render('subtask/icons', array('subtask' => $subtask))) . $this->helper->e($subtask['title']),
'subtask',
'toggleStatus',
array('task_id' => $subtask['task_id'], 'subtask_id' => $subtask['id'], 'redirect' => $redirect)
);
return $this->helper->url->link($this->getTitle($subtask), 'SubtaskStatus', 'change', $params, false, 'ajax-replace');
}
public function selectTitle(array $values, array $errors = array(), array $attributes = array())
{
$attributes = array_merge(array('tabindex="1"', 'required', 'maxlength="255"'), $attributes);
$html = $this->helper->form->label(t('Title'), 'title');
$html .= $this->helper->form->text('title', $values, $errors, $attributes);
return $html;
}
public function selectAssignee(array $users, array $values, array $errors = array(), array $attributes = array())
{
$attributes = array_merge(array('tabindex="2"'), $attributes);
$html = $this->helper->form->label(t('Assignee'), 'user_id');
$html .= $this->helper->form->select('user_id', $users, $values, $errors, $attributes);
$html .= '&nbsp;<a href="#" class="assign-me" data-target-id="form-user_id" data-current-id="'.$this->userSession->getId().'" title="'.t('Assign to me').'">'.t('Me').'</a>';
return $html;
}
public function selectTimeEstimated(array $values, array $errors = array(), array $attributes = array())
{
$attributes = array_merge(array('tabindex="3"'), $attributes);
$html = $this->helper->form->label(t('Original estimate'), 'time_estimated');
$html .= $this->helper->form->numeric('time_estimated', $values, $errors, $attributes);
$html .= ' '.t('hours');
return $html;
}
public function selectTimeSpent(array $values, array $errors = array(), array $attributes = array())
{
$attributes = array_merge(array('tabindex="4"'), $attributes);
$html = $this->helper->form->label(t('Time spent'), 'time_spent');
$html .= $this->helper->form->numeric('time_spent', $values, $errors, $attributes);
$html .= ' '.t('hours');
return $html;
}
}

View File

@ -12,6 +12,14 @@ use Kanboard\Core\Base;
*/
class Task extends Base
{
/**
* Local cache for project columns
*
* @access private
* @var array
*/
private $columns = array();
public function getColors()
{
return $this->color->getList();
@ -37,6 +45,53 @@ class Task extends Base
return $this->taskPermission->canRemoveTask($task);
}
public function selectAssignee(array $users, array $values, array $errors = array(), array $attributes = array())
{
$attributes = array_merge(array('tabindex="3"'), $attributes);
$html = $this->helper->form->label(t('Assignee'), 'owner_id');
$html .= $this->helper->form->select('owner_id', $users, $values, $errors, $attributes);
$html .= '&nbsp;<a href="#" class="assign-me" data-target-id="form-owner_id" data-current-id="'.$this->userSession->getId().'" title="'.t('Assign to me').'">'.t('Me').'</a>';
return $html;
}
public function selectCategory(array $categories, array $values, array $errors = array(), array $attributes = array(), $allow_one_item = false)
{
$attributes = array_merge(array('tabindex="4"'), $attributes);
$html = '';
if (! (! $allow_one_item && count($categories) === 1 && key($categories) == 0)) {
$html .= $this->helper->form->label(t('Category'), 'category_id');
$html .= $this->helper->form->select('category_id', $categories, $values, $errors, $attributes);
}
return $html;
}
public function selectSwimlane(array $swimlanes, array $values, array $errors = array(), array $attributes = array())
{
$attributes = array_merge(array('tabindex="5"'), $attributes);
$html = '';
if (! (count($swimlanes) === 1 && key($swimlanes) == 0)) {
$html .= $this->helper->form->label(t('Swimlane'), 'swimlane_id');
$html .= $this->helper->form->select('swimlane_id', $swimlanes, $values, $errors, $attributes);
}
return $html;
}
public function selectColumn(array $columns, array $values, array $errors = array(), array $attributes = array())
{
$attributes = array_merge(array('tabindex="6"'), $attributes);
$html = $this->helper->form->label(t('Column'), 'column_id');
$html .= $this->helper->form->select('column_id', $columns, $values, $errors, $attributes);
return $html;
}
public function selectPriority(array $project, array $values)
{
$html = '';
@ -53,6 +108,61 @@ class Task extends Base
return $html;
}
public function selectScore(array $values, array $errors = array(), array $attributes = array())
{
$attributes = array_merge(array('tabindex="8"'), $attributes);
$html = $this->helper->form->label(t('Complexity'), 'score');
$html .= $this->helper->form->number('score', $values, $errors, $attributes);
return $html;
}
public function selectTimeEstimated(array $values, array $errors = array(), array $attributes = array())
{
$attributes = array_merge(array('tabindex="9"'), $attributes);
$html = $this->helper->form->label(t('Original estimate'), 'time_estimated');
$html .= $this->helper->form->numeric('time_estimated', $values, $errors, $attributes);
$html .= ' '.t('hours');
return $html;
}
public function selectTimeSpent(array $values, array $errors = array(), array $attributes = array())
{
$attributes = array_merge(array('tabindex="10"'), $attributes);
$html = $this->helper->form->label(t('Time spent'), 'time_spent');
$html .= $this->helper->form->numeric('time_spent', $values, $errors, $attributes);
$html .= ' '.t('hours');
return $html;
}
public function selectStartDate(array $values, array $errors = array(), array $attributes = array())
{
$placeholder = $this->helper->text->in($this->config->get('application_date_format'), $this->dateParser->getAvailableFormats());
$attributes = array_merge(array('tabindex="11"', 'placeholder="'.$placeholder.'"'), $attributes);
$html = $this->helper->form->label(t('Start Date'), 'date_started');
$html .= $this->helper->form->text('date_started', $values, $errors, $attributes, 'form-date');
return $html;
}
public function selectDueDate(array $values, array $errors = array(), array $attributes = array())
{
$placeholder = $this->helper->text->in($this->config->get('application_date_format'), $this->dateParser->getAvailableFormats());
$attributes = array_merge(array('tabindex="12"', 'placeholder="'.$placeholder.'"'), $attributes);
$html = $this->helper->form->label(t('Due Date'), 'date_due');
$html .= $this->helper->form->text('date_due', $values, $errors, $attributes, 'form-date');
$html .= '<div class="form-help">'.t('Others formats accepted: %s and %s', date('Y-m-d'), date('Y_m_d')).'</div>';
return $html;
}
public function formatPriority(array $project, array $task)
{
$html = '';
@ -65,4 +175,13 @@ class Task extends Base
return $html;
}
public function getProgress($task)
{
if (! isset($this->columns[$task['project_id']])) {
$this->columns[$task['project_id']] = $this->board->getColumnsList($task['project_id']);
}
return $this->task->getProgress($task, $this->columns[$task['project_id']]);
}
}

View File

@ -260,9 +260,6 @@ return array(
'External authentication failed' => 'Vanjska autentikacija nije uspostavljena',
'Your external account is linked to your profile successfully.' => 'Uspješno uspostavljena vanjska autentikacija',
'Email' => 'E-mail',
'Link my Google Account' => 'Poveži sa Google nalogom',
'Unlink my Google Account' => 'Ukini vezu sa Google nalogom',
'Login with my Google Account' => 'Prijavi se preko Google naloga',
'Project not found.' => 'Projekat nije pronađen.',
'Task removed successfully.' => 'Zadatak uspješno uklonjen.',
'Unable to remove this task.' => 'Nemoguće uklanjanje zadatka.',
@ -327,9 +324,6 @@ return array(
'Maximum size: ' => 'Maksimalna veličina: ',
'Unable to upload the file.' => 'Nije moguće snimiti fajl.',
'Display another project' => 'Prikaži drugi projekat',
'Login with my Github Account' => 'Prijavi me s mojim Github korisničkim računom',
'Link my Github Account' => 'Poveži s mojim Github korisničkim računom',
'Unlink my Github Account' => 'Odbavi vez s mojim Github korisničkim računom',
'Created by %s' => 'Kreirao %s',
'Last modified on %B %e, %Y at %k:%M %p' => 'Posljednja izmjena %e %B %Y o %k:%M',
'Tasks Export' => 'Izvoz zadataka',
@ -395,8 +389,6 @@ return array(
'Change password' => 'Promijeni šifru',
'Password modification' => 'Izmjena šifre',
'External authentications' => 'Vanjske autentikacije',
'Google Account' => 'Google korisnički račun',
'Github Account' => 'Github korisnički račun',
'Never connected.' => 'Bez konekcija.',
'No account linked.' => 'Bez povezanih korisničkih računa.',
'Account linked.' => 'Korisnički račun povezan.',
@ -846,10 +838,6 @@ return array(
'This chart show the average lead and cycle time for the last %d tasks over the time.' => 'Ovaj grafik pokazuje prosjek vremena vođenja i vremenskog ciklusa za posljednjih %d zadataka tokom vremena.',
'Average time into each column' => 'Prosječno vrijeme u svakoj koloni',
'Lead and cycle time' => 'Vrijeme vođenja i vremenski ciklus',
'Google Authentication' => 'Google autentifikacija',
'Help on Google authentication' => 'Pomoć na Google autentifikacija',
'Github Authentication' => 'Github autentifikacija',
'Help on Github authentication' => 'Pomoć na Github autentifikacija',
'Lead time: ' => 'Vrijeme vođenja: ',
'Cycle time: ' => 'Vremenski ciklus: ',
'Time spent into each column' => 'Utrošeno vrijeme u svakoj koloni',
@ -858,8 +846,6 @@ return array(
'If the task is not closed the current time is used instead of the completion date.' => 'Ako zadatak nije zatvoren trenutno vrijeme je iskorišteno umjesto datuma završetka.',
'Set automatically the start date' => 'Automatski postavi početno vrijeme',
'Edit Authentication' => 'Uredi autentifikaciju',
'Google Id' => 'Google Id',
'Github Id' => 'Github Id',
'Remote user' => 'Vanjski korisnik',
'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => 'Vanjski korisnik ne čuva šifru u Kanboard bazi, npr: LDAP, Google i Github korisnički računi.',
'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => 'Ako ste označili kvadratić "Zabrani prijavnu formu", unos pristupnih podataka u prijavnoj formi će biti ignorisan.',
@ -917,14 +903,7 @@ return array(
'Link type' => 'Tip veze',
'Change task color when using a specific task link' => 'Promijeni boju zadatka kada se koristi određena veza na zadatku',
'Task link creation or modification' => 'Veza na zadatku je napravljena ili izmijenjena',
'Login with my Gitlab Account' => 'Prijava s mojim Gitlab korisničkim računom',
'Milestone' => 'Prekretnica',
'Gitlab Authentication' => 'Gitlab autentifikacija',
'Help on Gitlab authentication' => 'Pomoć na Gitlab autentifikacija',
'Gitlab Id' => 'Gitlab Id',
'Gitlab Account' => 'Gitlab korisnički račun',
'Link my Gitlab Account' => 'Veza s mojim Gitlab korisničkim računom',
'Unlink my Gitlab Account' => 'Prekini vezu s mojim Gitlab korisničkim računom',
'Documentation: %s' => 'Dokumentacija: %s',
'Switch to the Gantt chart view' => 'Promijeni u gantogram pregled',
'Reset the search/filter box' => 'Vrati na početno pretragu/filtere',
@ -1118,4 +1097,37 @@ return array(
// 'Highest priority' => '',
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
// 'Priority: %d' => '',
// 'Close a task when there is no activity' => '',
// 'Duration in days' => '',
// 'Send email when there is no activity on a task' => '',
// 'List of external links' => '',
// 'Unable to fetch link information.' => '',
// 'Daily background job for tasks' => '',
// 'Auto' => '',
// 'Related' => '',
// 'Attachment' => '',
// 'Title not found' => '',
// 'Web Link' => '',
// 'External links' => '',
// 'Add external link' => '',
// 'Type' => '',
// 'Dependency' => '',
// 'View internal links' => '',
// 'View external links' => '',
// 'Add internal link' => '',
// 'Add a new external link' => '',
// 'Edit external link' => '',
// 'External link' => '',
// 'Copy and paste your link here...' => '',
// 'URL' => '',
// 'There is no external link for the moment.' => '',
// 'Internal links' => '',
// 'There is no internal link for the moment.' => '',
// 'Assign to me' => '',
// 'Me' => '',
// 'Do not duplicate anything' => '',
// 'Projects management' => '',
// 'Users management' => '',
// 'Groups management' => '',
// 'Create from another project' => '',
);

View File

@ -260,9 +260,6 @@ return array(
// 'External authentication failed' => '',
// 'Your external account is linked to your profile successfully.' => '',
'Email' => 'E-Mail',
'Link my Google Account' => 'Propojit s Google účtem',
'Unlink my Google Account' => 'Odpojit Google účet',
'Login with my Google Account' => 'Přihlášení pomocí Google účtu',
'Project not found.' => 'Projekt nebyl nalezen.',
'Task removed successfully.' => 'Úkol byl úspěšně odebrán.',
'Unable to remove this task.' => 'Tento úkol nelze odebrat.',
@ -327,9 +324,6 @@ return array(
'Maximum size: ' => 'Maximální velikost: ',
'Unable to upload the file.' => 'Soubor nelze nahrát.',
'Display another project' => 'Zobrazit jiný projekt',
// 'Login with my Github Account' => '',
// 'Link my Github Account' => '',
// 'Unlink my Github Account' => '',
'Created by %s' => 'Vytvořeno uživatelem %s',
'Last modified on %B %e, %Y at %k:%M %p' => 'Poslední úprava dne %d.%m.%Y v čase %H:%M',
'Tasks Export' => 'Export úkolů',
@ -395,8 +389,6 @@ return array(
'Change password' => 'Změnit heslo',
'Password modification' => 'Změna hesla',
'External authentications' => 'Vzdálená autorizace',
'Google Account' => 'Google účet',
'Github Account' => 'github účet',
'Never connected.' => 'Zatím nikdy nespojen.',
'No account linked.' => 'Žádné propojení účtu.',
'Account linked.' => 'Propojení účtu',
@ -846,10 +838,6 @@ return array(
'This chart show the average lead and cycle time for the last %d tasks over the time.' => 'Graf ukazuje průměrnou dodací lhůtu a dobu cyklu pro posledních %d úkolů v průběhu času',
'Average time into each column' => 'Průměrná doba v každé fázi',
'Lead and cycle time' => 'Dodací lhůta a doba cyklu',
'Google Authentication' => 'Ověřování pomocí služby Google',
'Help on Google authentication' => 'Nápověda k ověřování pomocí služby Google',
'Github Authentication' => 'Ověřování pomocí služby Github',
'Help on Github authentication' => 'Nápověda k ověřování pomocí služby Github',
'Lead time: ' => 'Dodací lhůta: ',
'Cycle time: ' => 'Doba cyklu: ',
'Time spent into each column' => 'Čas strávený v každé fázi',
@ -858,8 +846,6 @@ return array(
'If the task is not closed the current time is used instead of the completion date.' => 'Jestliže není úkol uzavřen, místo termínu dokončení je použit aktuální čas.',
'Set automatically the start date' => 'Nastavit automaticky počáteční datum',
'Edit Authentication' => 'Upravit ověřování',
'Google Id' => 'Google ID',
'Github Id' => 'Github ID',
'Remote user' => 'Vzdálený uživatel',
'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => 'Hesla vzdáleným uživatelům se neukládají do databáze Kanboard. Naříklad: LDAP, Google a Github účty.',
'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => 'Pokud zaškrtnete políčko "Zakázat přihlašovací formulář", budou pověření zadané do přihlašovacího formuláře ignorovány.',
@ -917,14 +903,7 @@ return array(
// 'Link type' => '',
// 'Change task color when using a specific task link' => '',
// 'Task link creation or modification' => '',
// 'Login with my Gitlab Account' => '',
// 'Milestone' => '',
// 'Gitlab Authentication' => '',
// 'Help on Gitlab authentication' => '',
// 'Gitlab Id' => '',
// 'Gitlab Account' => '',
// 'Link my Gitlab Account' => '',
// 'Unlink my Gitlab Account' => '',
// 'Documentation: %s' => '',
// 'Switch to the Gantt chart view' => '',
// 'Reset the search/filter box' => '',
@ -1118,4 +1097,37 @@ return array(
// 'Highest priority' => '',
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
// 'Priority: %d' => '',
// 'Close a task when there is no activity' => '',
// 'Duration in days' => '',
// 'Send email when there is no activity on a task' => '',
// 'List of external links' => '',
// 'Unable to fetch link information.' => '',
// 'Daily background job for tasks' => '',
// 'Auto' => '',
// 'Related' => '',
// 'Attachment' => '',
// 'Title not found' => '',
// 'Web Link' => '',
// 'External links' => '',
// 'Add external link' => '',
// 'Type' => '',
// 'Dependency' => '',
// 'View internal links' => '',
// 'View external links' => '',
// 'Add internal link' => '',
// 'Add a new external link' => '',
// 'Edit external link' => '',
// 'External link' => '',
// 'Copy and paste your link here...' => '',
// 'URL' => '',
// 'There is no external link for the moment.' => '',
// 'Internal links' => '',
// 'There is no internal link for the moment.' => '',
// 'Assign to me' => '',
// 'Me' => '',
// 'Do not duplicate anything' => '',
// 'Projects management' => '',
// 'Users management' => '',
// 'Groups management' => '',
// 'Create from another project' => '',
);

View File

@ -260,9 +260,6 @@ return array(
// 'External authentication failed' => '',
// 'Your external account is linked to your profile successfully.' => '',
'Email' => 'E-Mail',
'Link my Google Account' => 'Forbind min Google-konto',
'Unlink my Google Account' => 'Fjern forbindelsen til min Google-konto',
'Login with my Google Account' => 'Login med min Google-konto',
'Project not found.' => 'Projekt ikke fundet.',
'Task removed successfully.' => 'Opgaven er fjernet.',
'Unable to remove this task.' => 'Opgaven kunne ikke fjernes.',
@ -327,9 +324,6 @@ return array(
'Maximum size: ' => 'Maksimum størrelse: ',
'Unable to upload the file.' => 'Filen kunne ikke uploades.',
'Display another project' => 'Vis et andet projekt...',
'Login with my Github Account' => 'Login med min Github-konto',
'Link my Github Account' => 'Forbind min Github-konto',
'Unlink my Github Account' => 'Fjern forbindelsen til min Github-konto',
'Created by %s' => 'Oprettet af %s',
'Last modified on %B %e, %Y at %k:%M %p' => 'Sidst redigeret %d.%m.%Y - %H:%M',
'Tasks Export' => 'Opgave eksport',
@ -395,8 +389,6 @@ return array(
'Change password' => 'Skift adgangskode',
'Password modification' => 'Adgangskode ændring',
'External authentications' => 'Ekstern autentificering',
'Google Account' => 'Google-konto',
'Github Account' => 'Github-konto',
'Never connected.' => 'Aldrig forbundet.',
'No account linked.' => 'Ingen kontoer forfundet.',
'Account linked.' => 'Konto forbundet.',
@ -846,10 +838,6 @@ return array(
// 'This chart show the average lead and cycle time for the last %d tasks over the time.' => '',
// 'Average time into each column' => '',
// 'Lead and cycle time' => '',
// 'Google Authentication' => '',
// 'Help on Google authentication' => '',
// 'Github Authentication' => '',
// 'Help on Github authentication' => '',
// 'Lead time: ' => '',
// 'Cycle time: ' => '',
// 'Time spent into each column' => '',
@ -858,8 +846,6 @@ return array(
// 'If the task is not closed the current time is used instead of the completion date.' => '',
// 'Set automatically the start date' => '',
// 'Edit Authentication' => '',
// 'Google Id' => '',
// 'Github Id' => '',
// 'Remote user' => '',
// 'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => '',
// 'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => '',
@ -917,14 +903,7 @@ return array(
// 'Link type' => '',
// 'Change task color when using a specific task link' => '',
// 'Task link creation or modification' => '',
// 'Login with my Gitlab Account' => '',
// 'Milestone' => '',
// 'Gitlab Authentication' => '',
// 'Help on Gitlab authentication' => '',
// 'Gitlab Id' => '',
// 'Gitlab Account' => '',
// 'Link my Gitlab Account' => '',
// 'Unlink my Gitlab Account' => '',
// 'Documentation: %s' => '',
// 'Switch to the Gantt chart view' => '',
// 'Reset the search/filter box' => '',
@ -1118,4 +1097,37 @@ return array(
// 'Highest priority' => '',
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
// 'Priority: %d' => '',
// 'Close a task when there is no activity' => '',
// 'Duration in days' => '',
// 'Send email when there is no activity on a task' => '',
// 'List of external links' => '',
// 'Unable to fetch link information.' => '',
// 'Daily background job for tasks' => '',
// 'Auto' => '',
// 'Related' => '',
// 'Attachment' => '',
// 'Title not found' => '',
// 'Web Link' => '',
// 'External links' => '',
// 'Add external link' => '',
// 'Type' => '',
// 'Dependency' => '',
// 'View internal links' => '',
// 'View external links' => '',
// 'Add internal link' => '',
// 'Add a new external link' => '',
// 'Edit external link' => '',
// 'External link' => '',
// 'Copy and paste your link here...' => '',
// 'URL' => '',
// 'There is no external link for the moment.' => '',
// 'Internal links' => '',
// 'There is no internal link for the moment.' => '',
// 'Assign to me' => '',
// 'Me' => '',
// 'Do not duplicate anything' => '',
// 'Projects management' => '',
// 'Users management' => '',
// 'Groups management' => '',
// 'Create from another project' => '',
);

View File

@ -20,7 +20,7 @@ return array(
'Red' => 'Rot',
'Orange' => 'Orange',
'Grey' => 'Grau',
'Brown' => 'Bran',
'Brown' => 'Braun',
'Deep Orange' => 'Dunkelorange',
'Dark Grey' => 'Dunkelgrau',
'Pink' => 'Pink',
@ -28,7 +28,7 @@ return array(
'Cyan' => 'Cyan',
'Lime' => 'Limette',
'Light Green' => 'Hellgrün',
'Amber' => 'Braun (Amber)',
'Amber' => 'Bernstein',
'Save' => 'Speichern',
'Login' => 'Anmelden',
'Official website:' => 'Offizielle Webseite:',
@ -96,7 +96,7 @@ return array(
'Edit a task' => 'Aufgabe bearbeiten',
'Column' => 'Spalte',
'Color' => 'Farbe',
'Assignee' => 'Zuständig',
'Assignee' => 'Zuständiger',
'Create another task' => 'Weitere Aufgabe erstellen',
'New task' => 'Neue Aufgabe',
'Open a task' => 'Öffne eine Aufgabe',
@ -260,9 +260,6 @@ return array(
'External authentication failed' => 'Externe Authentifizierung fehlgeschlagen',
'Your external account is linked to your profile successfully.' => 'Dein externer Account wurde erfolgreich mit deinem Profil verbunden',
'Email' => 'E-Mail',
'Link my Google Account' => 'Verbinde meinen Google-Account',
'Unlink my Google Account' => 'Verbindung mit meinem Google-Account trennen',
'Login with my Google Account' => 'Anmelden mit meinem Google-Account',
'Project not found.' => 'Das Projekt wurde nicht gefunden.',
'Task removed successfully.' => 'Aufgabe erfolgreich gelöscht.',
'Unable to remove this task.' => 'Löschen der Aufgabe nicht möglich.',
@ -327,9 +324,6 @@ return array(
'Maximum size: ' => 'Maximalgröße: ',
'Unable to upload the file.' => 'Hochladen der Datei nicht möglich.',
'Display another project' => 'Zu Projekt wechseln',
'Login with my Github Account' => 'Anmelden mit meinem Github-Account',
'Link my Github Account' => 'Mit meinem Github-Account verbinden',
'Unlink my Github Account' => 'Verbindung mit meinem Github-Account trennen',
'Created by %s' => 'Erstellt durch %s',
'Last modified on %B %e, %Y at %k:%M %p' => 'Letzte Änderung am %d.%m.%Y um %H:%M',
'Tasks Export' => 'Aufgaben exportieren',
@ -395,8 +389,6 @@ return array(
'Change password' => 'Passwort ändern',
'Password modification' => 'Passwortänderung',
'External authentications' => 'Externe Authentisierungsmethoden',
'Google Account' => 'Google-Account',
'Github Account' => 'Github-Account',
'Never connected.' => 'Noch nie verbunden.',
'No account linked.' => 'Kein Account verbunden.',
'Account linked.' => 'Account verbunden',
@ -846,10 +838,6 @@ return array(
'This chart show the average lead and cycle time for the last %d tasks over the time.' => 'Das Diagramm zeigt die durchschnittliche Durchlauf- und Zykluszeit der letzten %d Aufgaben über die Zeit an.',
'Average time into each column' => 'Durchschnittzeit in jeder Spalte',
'Lead and cycle time' => 'Durchlauf- und Zykluszeit',
'Google Authentication' => 'Google-Authentifizierung',
'Help on Google authentication' => 'Hilfe bei Google-Authentifizierung',
'Github Authentication' => 'Github-Authentifizierung',
'Help on Github authentication' => 'Hilfe bei Github-Authentifizierung',
'Lead time: ' => 'Durchlaufzeit:',
'Cycle time: ' => 'Zykluszeit:',
'Time spent into each column' => 'zeit verbracht in jeder Spalte',
@ -858,8 +846,6 @@ return array(
'If the task is not closed the current time is used instead of the completion date.' => 'Wenn die Aufgabe nicht geschlossen ist, wird die aktuelle Zeit statt der Fertigstellung verwendet.',
'Set automatically the start date' => 'Setze Startdatum automatisch',
'Edit Authentication' => 'Authentifizierung bearbeiten',
'Google Id' => 'Google Id',
'Github Id' => 'Github Id',
'Remote user' => 'Remote-Benutzer',
'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => 'Remote-Benutzer haben kein Passwort in der Kanboard Datenbank, Beispiel LDAP, Goole und Github Accounts',
'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => 'Wenn die Box "Verbiete Login-Formular" angeschaltet ist, werden Eingaben in das Login Formular ignoriert.',
@ -917,14 +903,7 @@ return array(
'Link type' => 'Verbindungstyp',
'Change task color when using a specific task link' => 'Aufgabefarbe ändern bei bestimmter Aufgabenverbindung',
'Task link creation or modification' => 'Aufgabenverbindung erstellen oder bearbeiten',
'Login with my Gitlab Account' => 'Mit Gitlab Account einloggen',
'Milestone' => 'Meilenstein',
'Gitlab Authentication' => 'Gitlab-Authentifizierung',
'Help on Gitlab authentication' => 'Hilfe bei Gitlab-Authentifizierung',
'Gitlab Id' => 'Gitlab Id',
'Gitlab Account' => 'Gitlab Account',
'Link my Gitlab Account' => 'Verknüpfe mein Gitlab Account',
'Unlink my Gitlab Account' => 'Trenne meinen Gitlab Account',
'Documentation: %s' => 'Dokumentation: %s',
'Switch to the Gantt chart view' => 'Zur Gantt-Diagramm Ansicht wechseln',
'Reset the search/filter box' => 'Suche/Filter-Box zurücksetzen',
@ -1096,26 +1075,59 @@ return array(
'Creation' => 'Erstellung',
'Expiration' => 'Ablauf',
'Password reset history' => 'Verlauf Passwortrücksetzung',
// 'All tasks of the column "%s" and the swimlane "%s" have been closed successfully.' => '',
// '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.' => '',
// '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' => '',
// 'Project owner: ' => '',
// 'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => '',
// 'Project owner' => '',
// 'Those dates are useful for the project Gantt chart.' => '',
// 'Private projects do not have users and groups management.' => '',
// 'There is no project member.' => '',
// 'Priority' => '',
// 'Task priority' => '',
// 'General' => '',
// 'Dates' => '',
// 'Default priority' => '',
// 'Lowest priority' => '',
// 'Highest priority' => '',
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
// 'Priority: %d' => '',
'All tasks of the column "%s" and the swimlane "%s" have been closed successfully.' => 'Alle Aufgaben der Spalte "%s" und der Swimlane "%s" wurden erfolgreich geschlossen',
'Do you really want to close all tasks of this column?' => 'Wollen Sie wirklich alle Aufgaben in dieser Spalte schließen?',
'%d task(s) in the column "%s" and the swimlane "%s" will be closed.' => '%d Aufgabe(n) in der Spalte "%s" und in der Swimlane "%s" werden geschlossen.',
'Close all tasks of this column' => 'Alle Aufgaben in dieser Spalte schließen',
'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => 'Kein Plugin hat eine Projekt-Benachrichtigungsmethode registriert. Sie können individuelle Meldungen in Ihrem Benutzerprofil konfigurieren',
'My dashboard' => 'Mein Dashboard',
'My profile' => 'Mein Profil',
'Project owner: ' => 'Projekt-Besitzer:',
'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => 'Die Projekt-Kennung ist optional und muss alphanumerisch sein, beispielsweise: MYPROJECT.',
'Project owner' => 'Projekt-Besitzer',
'Those dates are useful for the project Gantt chart.' => 'Diese Daten sind nützlich für das Gantt-Diagramm.',
'Private projects do not have users and groups management.' => 'Private Projekte haben kein Benutzer- und Gruppen-Management.',
'There is no project member.' => 'Es gibt kein Projekt-Mitglied.',
'Priority' => 'Priorität',
'Task priority' => 'Aufgaben-Priorität',
'General' => 'Allgemein',
'Dates' => 'Daten',
'Default priority' => 'Standard-Priorität',
'Lowest priority' => 'Niedrigste Priorität',
'Highest priority' => 'Höchste Priorität',
'If you put zero to the low and high priority, this feature will be disabled.' => 'Wenn Sie Null bei höchster und niedrigster Priorität eintragen, wird diese Funktion deaktiviert.',
'Priority: %d' => 'Priorität: %d',
'Close a task when there is no activity' => 'Schliesse eine Aufgabe, wenn keine Aktivitäten vorhanden sind',
'Duration in days' => 'Dauer in Tagen',
'Send email when there is no activity on a task' => 'Versende eine Email, wenn keine Aktivitäten an einer Aufgabe vorhanden sind',
'List of external links' => 'Liste der externen Verbindungen',
'Unable to fetch link information.' => 'Kann keine Informationen über Verbindungen holen',
'Daily background job for tasks' => 'Tägliche Hintergrundarbeit für Aufgaben',
'Auto' => 'Auto',
'Related' => 'Verbunden',
'Attachment' => 'Anhang',
'Title not found' => 'Titel nicht gefunden',
'Web Link' => 'Weblink',
'External links' => 'Externe Verbindungen',
'Add external link' => 'Externe Verbindung hinzufügen',
'Type' => 'Typ',
'Dependency' => 'Abhängigkeit',
'View internal links' => 'Zeige interne Verbindungen',
'View external links' => 'Zeige externe Verbindungen',
'Add internal link' => 'Füge interne Verbindung hinzu',
'Add a new external link' => 'Füge eine neue externe Verbindung hinzu',
'Edit external link' => 'Externe Verbindung bearbeiten',
'External link' => 'Externe Verbindung',
'Copy and paste your link here...' => 'Kopieren Sie Ihren Link hier...',
'URL' => 'URL',
'There is no external link for the moment.' => 'Es gibt im Moment keine externe Verbindung.',
'Internal links' => 'Interne Verbindungen',
'There is no internal link for the moment.' => 'Es gibt im Moment keine interne Verbindung.',
'Assign to me' => 'Mir zuweisen',
'Me' => 'Mich',
'Do not duplicate anything' => 'Nichts duplizieren',
'Projects management' => 'Projektmanagement',
'Users management' => 'Benutzermanagement',
'Groups management' => 'Gruppenmanagement',
'Create from another project' => 'Von einem anderen Projekt erstellen',
);

File diff suppressed because it is too large Load Diff

View File

@ -260,9 +260,6 @@ return array(
'External authentication failed' => 'Falló la autenticación externa',
'Your external account is linked to your profile successfully.' => 'Su cuenta externa se ha vinculado exitosamente con su perfil.',
'Email' => 'Correo',
'Link my Google Account' => 'Vincular con mi Cuenta en Google',
'Unlink my Google Account' => 'Desvincular de mi Cuenta en Google',
'Login with my Google Account' => 'Ingresar con mi Cuenta de Google',
'Project not found.' => 'Proyecto no hallado.',
'Task removed successfully.' => 'Tarea suprimida correctamente.',
'Unable to remove this task.' => 'No pude suprimir esta tarea.',
@ -327,9 +324,6 @@ return array(
'Maximum size: ' => 'Tamaño máximo',
'Unable to upload the file.' => 'No pude cargar el fichero.',
'Display another project' => 'Mostrar otro proyecto',
'Login with my Github Account' => 'Ingresar con mi cuenta de Github',
'Link my Github Account' => 'Vincular mi cuenta de Github',
'Unlink my Github Account' => 'Desvincular mi cuenta de Github',
'Created by %s' => 'Creado por %s',
'Last modified on %B %e, %Y at %k:%M %p' => 'Última modificación %e de %B de %Y a las %k:%M %p',
'Tasks Export' => 'Exportar tareas',
@ -395,8 +389,6 @@ return array(
'Change password' => 'Cambiar contraseña',
'Password modification' => 'Modificacion de contraseña',
'External authentications' => 'Autenticación externa',
'Google Account' => 'Cuenta de Google',
'Github Account' => 'Cuenta de Github',
'Never connected.' => 'Nunca se ha conectado.',
'No account linked.' => 'Sin vínculo con cuenta.',
'Account linked.' => 'Vinculada con Cuenta.',
@ -846,10 +838,6 @@ return array(
'This chart show the average lead and cycle time for the last %d tasks over the time.' => 'Esta gráfica muestra el plazo medio de entrega y de ciclo para las %d últimas tareas transcurridas.',
'Average time into each column' => 'Tiempo medio en cada columna',
'Lead and cycle time' => 'Plazo de entrega y de ciclo',
'Google Authentication' => 'Autenticación de Google',
'Help on Google authentication' => 'Ayuda con la aAutenticación de Google',
'Github Authentication' => 'Autenticación de Github',
'Help on Github authentication' => 'Ayuda con la autenticación de Github',
'Lead time: ' => 'Plazo de entrega: ',
'Cycle time: ' => 'Tiempo de Ciclo: ',
'Time spent into each column' => 'Tiempo empleado en cada columna',
@ -858,8 +846,6 @@ return array(
'If the task is not closed the current time is used instead of the completion date.' => 'Si la tarea no se cierra, se usa la fecha actual en lugar de la de terminación.',
'Set automatically the start date' => 'Poner la fecha de inicio de forma automática',
'Edit Authentication' => 'Editar autenticación',
'Google Id' => 'Id de Google',
'Github Id' => 'Id de Github',
'Remote user' => 'Usuario remoto',
'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => 'Los usuarios remotos no almacenan sus contraseñas en la base de datos Kanboard, por ejemplo: cuentas de LDAP, Google y Github',
'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => 'Si marcas la caja de edición "Desactivar formulario de ingreso", se ignoran las credenciales entradas en el formulario de ingreso.',
@ -917,14 +903,7 @@ return array(
'Link type' => 'Tipo de enlace',
'Change task color when using a specific task link' => 'Cambiar colo de la tarea al usar un enlace específico a tarea',
'Task link creation or modification' => 'Creación o modificación de enlace a tarea',
'Login with my Gitlab Account' => 'Ingresar usando mi Cuenta en Gitlab',
'Milestone' => 'Hito',
'Gitlab Authentication' => 'Autenticación Gitlab',
'Help on Gitlab authentication' => 'Ayuda con autenticación Gitlab',
'Gitlab Id' => 'Id de Gitlab',
'Gitlab Account' => 'Cuenta de Gitlab',
'Link my Gitlab Account' => 'Enlazar con mi Cuenta en Gitlab',
'Unlink my Gitlab Account' => 'Desenlazar con mi Cuenta en Gitlab',
'Documentation: %s' => 'Documentación: %s',
'Switch to the Gantt chart view' => 'Conmutar a vista de diagrama de Gantt',
'Reset the search/filter box' => 'Limpiar la caja del filtro de búsqueda',
@ -1118,4 +1097,37 @@ return array(
// 'Highest priority' => '',
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
// 'Priority: %d' => '',
// 'Close a task when there is no activity' => '',
// 'Duration in days' => '',
// 'Send email when there is no activity on a task' => '',
// 'List of external links' => '',
// 'Unable to fetch link information.' => '',
// 'Daily background job for tasks' => '',
// 'Auto' => '',
// 'Related' => '',
// 'Attachment' => '',
// 'Title not found' => '',
// 'Web Link' => '',
// 'External links' => '',
// 'Add external link' => '',
// 'Type' => '',
// 'Dependency' => '',
// 'View internal links' => '',
// 'View external links' => '',
// 'Add internal link' => '',
// 'Add a new external link' => '',
// 'Edit external link' => '',
// 'External link' => '',
// 'Copy and paste your link here...' => '',
// 'URL' => '',
// 'There is no external link for the moment.' => '',
// 'Internal links' => '',
// 'There is no internal link for the moment.' => '',
// 'Assign to me' => '',
// 'Me' => '',
// 'Do not duplicate anything' => '',
// 'Projects management' => '',
// 'Users management' => '',
// 'Groups management' => '',
// 'Create from another project' => '',
);

View File

@ -260,9 +260,6 @@ return array(
// 'External authentication failed' => '',
// 'Your external account is linked to your profile successfully.' => '',
'Email' => 'Sähköposti',
'Link my Google Account' => 'Linkitä Google-tili',
'Unlink my Google Account' => 'Poista Google-tilin linkitys',
'Login with my Google Account' => 'Kirjaudu Google tunnuksella',
'Project not found.' => 'Projektia ei löytynyt.',
'Task removed successfully.' => 'Tehtävä poistettiin onnistuneesti.',
'Unable to remove this task.' => 'Tehtävän poistaminen epäonnistui.',
@ -327,9 +324,6 @@ return array(
'Maximum size: ' => 'Maksimikoko: ',
'Unable to upload the file.' => 'Tiedoston lataus epäonnistui.',
'Display another project' => 'Näytä toinen projekti',
'Login with my Github Account' => 'Kirjaudu sisään Github-tililläni',
'Link my Github Account' => 'Liitä Github-tilini',
'Unlink my Github Account' => 'Poista liitos Github-tiliini',
'Created by %s' => 'Luonut: %s',
'Last modified on %B %e, %Y at %k:%M %p' => 'Viimeksi muokattu %B %e, %Y kello %H:%M',
'Tasks Export' => 'Tehtävien vienti',
@ -395,8 +389,6 @@ return array(
'Change password' => 'Vaihda salasana',
'Password modification' => 'Salasanan vaihto',
'External authentications' => 'Muut tunnistautumistavat',
'Google Account' => 'Google-tili',
'Github Account' => 'Github-tili',
'Never connected.' => 'Ei koskaan liitetty.',
'No account linked.' => 'Tiliä ei ole liitetty.',
'Account linked.' => 'Tili on liitetty.',
@ -846,10 +838,6 @@ return array(
// 'This chart show the average lead and cycle time for the last %d tasks over the time.' => '',
// 'Average time into each column' => '',
// 'Lead and cycle time' => '',
// 'Google Authentication' => '',
// 'Help on Google authentication' => '',
// 'Github Authentication' => '',
// 'Help on Github authentication' => '',
// 'Lead time: ' => '',
// 'Cycle time: ' => '',
// 'Time spent into each column' => '',
@ -858,8 +846,6 @@ return array(
// 'If the task is not closed the current time is used instead of the completion date.' => '',
// 'Set automatically the start date' => '',
// 'Edit Authentication' => '',
// 'Google Id' => '',
// 'Github Id' => '',
// 'Remote user' => '',
// 'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => '',
// 'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => '',
@ -917,14 +903,7 @@ return array(
// 'Link type' => '',
// 'Change task color when using a specific task link' => '',
// 'Task link creation or modification' => '',
// 'Login with my Gitlab Account' => '',
// 'Milestone' => '',
// 'Gitlab Authentication' => '',
// 'Help on Gitlab authentication' => '',
// 'Gitlab Id' => '',
// 'Gitlab Account' => '',
// 'Link my Gitlab Account' => '',
// 'Unlink my Gitlab Account' => '',
// 'Documentation: %s' => '',
// 'Switch to the Gantt chart view' => '',
// 'Reset the search/filter box' => '',
@ -1118,4 +1097,37 @@ return array(
// 'Highest priority' => '',
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
// 'Priority: %d' => '',
// 'Close a task when there is no activity' => '',
// 'Duration in days' => '',
// 'Send email when there is no activity on a task' => '',
// 'List of external links' => '',
// 'Unable to fetch link information.' => '',
// 'Daily background job for tasks' => '',
// 'Auto' => '',
// 'Related' => '',
// 'Attachment' => '',
// 'Title not found' => '',
// 'Web Link' => '',
// 'External links' => '',
// 'Add external link' => '',
// 'Type' => '',
// 'Dependency' => '',
// 'View internal links' => '',
// 'View external links' => '',
// 'Add internal link' => '',
// 'Add a new external link' => '',
// 'Edit external link' => '',
// 'External link' => '',
// 'Copy and paste your link here...' => '',
// 'URL' => '',
// 'There is no external link for the moment.' => '',
// 'Internal links' => '',
// 'There is no internal link for the moment.' => '',
// 'Assign to me' => '',
// 'Me' => '',
// 'Do not duplicate anything' => '',
// 'Projects management' => '',
// 'Users management' => '',
// 'Groups management' => '',
// 'Create from another project' => '',
);

View File

@ -260,9 +260,6 @@ return array(
'External authentication failed' => 'Lauthentification externe a échoué',
'Your external account is linked to your profile successfully.' => 'Votre compte externe est désormais lié à votre profil.',
'Email' => 'Email',
'Link my Google Account' => 'Lier mon compte Google',
'Unlink my Google Account' => 'Ne plus utiliser mon compte Google',
'Login with my Google Account' => 'Se connecter avec mon compte Google',
'Project not found.' => 'Projet introuvable.',
'Task removed successfully.' => 'Tâche supprimée avec succès.',
'Unable to remove this task.' => 'Impossible de supprimer cette tâche.',
@ -327,9 +324,6 @@ return array(
'Maximum size: ' => 'Taille maximum : ',
'Unable to upload the file.' => 'Impossible de transférer le fichier.',
'Display another project' => 'Afficher un autre projet',
'Login with my Github Account' => 'Se connecter avec mon compte Github',
'Link my Github Account' => 'Lier mon compte Github',
'Unlink my Github Account' => 'Ne plus utiliser mon compte Github',
'Created by %s' => 'Créé par %s',
'Last modified on %B %e, %Y at %k:%M %p' => 'Modifié le %d/%m/%Y à %H:%M',
'Tasks Export' => 'Exportation des tâches',
@ -397,8 +391,6 @@ return array(
'Change password' => 'Changer le mot de passe',
'Password modification' => 'Changement de mot de passe',
'External authentications' => 'Authentifications externes',
'Google Account' => 'Compte Google',
'Github Account' => 'Compte Github',
'Never connected.' => 'Jamais connecté.',
'No account linked.' => 'Aucun compte attaché.',
'Account linked.' => 'Compte attaché.',
@ -848,10 +840,6 @@ return array(
'This chart show the average lead and cycle time for the last %d tasks over the time.' => 'Ce graphique montre la durée moyenne du lead et cycle time pour les %d dernières tâches.',
'Average time into each column' => 'Temps moyen dans chaque colonne',
'Lead and cycle time' => 'Lead et cycle time',
'Google Authentication' => 'Authentification Google',
'Help on Google authentication' => 'Aide sur l\'authentification Google',
'Github Authentication' => 'Authentification Github',
'Help on Github authentication' => 'Aide sur l\'authentification Github',
'Lead time: ' => 'Lead time : ',
'Cycle time: ' => 'Temps de cycle : ',
'Time spent into each column' => 'Temps passé dans chaque colonne',
@ -860,8 +848,6 @@ return array(
'If the task is not closed the current time is used instead of the completion date.' => 'Si la tâche n\'est pas fermée, l\'heure courante est utilisée à la place de la date de complétion.',
'Set automatically the start date' => 'Définir automatiquement la date de début',
'Edit Authentication' => 'Modifier l\'authentification',
'Google Id' => 'Identifiant Google',
'Github Id' => 'Identifiant Github',
'Remote user' => 'Utilisateur distant',
'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => 'Les utilisateurs distants ne stockent pas leur mot de passe dans la base de données de Kanboard, exemples : comptes LDAP, Github ou Google.',
'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => 'Si vous cochez la case « Interdire le formulaire d\'authentification », les identifiants entrés dans le formulaire d\'authentification seront ignorés.',
@ -919,14 +905,7 @@ return array(
'Link type' => 'Type de lien',
'Change task color when using a specific task link' => 'Changer la couleur de la tâche lorsqu\'un lien spécifique est utilisé',
'Task link creation or modification' => 'Création ou modification d\'un lien sur une tâche',
'Login with my Gitlab Account' => 'Se connecter avec mon compte Gitlab',
'Milestone' => 'Étape importante',
'Gitlab Authentication' => 'Authentification Gitlab',
'Help on Gitlab authentication' => 'Aide sur l\'authentification Gitlab',
'Gitlab Id' => 'Identifiant Gitlab',
'Gitlab Account' => 'Compte Gitlab',
'Link my Gitlab Account' => 'Lier mon compte Gitlab',
'Unlink my Gitlab Account' => 'Ne plus utiliser mon compte Gitlab',
'Documentation: %s' => 'Documentation : %s',
'Switch to the Gantt chart view' => 'Passer à la vue en diagramme de Gantt',
'Reset the search/filter box' => 'Réinitialiser le champ de recherche',
@ -1121,4 +1100,37 @@ return array(
'Highest priority' => 'Priorité haute',
'If you put zero to the low and high priority, this feature will be disabled.' => 'Si vous mettez zéro pour la priorité basse et haute, cette fonctionnalité sera désactivée.',
'Priority: %d' => 'Priorité : %d',
'Close a task when there is no activity' => 'Fermer une tâche sans activité',
'Duration in days' => 'Durée en jours',
'Send email when there is no activity on a task' => 'Envoyer un email lorsqu\'il n\'y a pas d\'activité sur une tâche',
'List of external links' => 'Liste des liens externes',
'Unable to fetch link information.' => 'Impossible de récupérer les informations sur le lien.',
'Daily background job for tasks' => 'Tâche planifée quotidienne pour les tâches',
'Auto' => 'Auto',
'Related' => 'Relié',
'Attachment' => 'Pièce-jointe',
'Title not found' => 'Titre non trouvé',
'Web Link' => 'Lien web',
'External links' => 'Liens externes',
'Add external link' => 'Ajouter un lien externe',
'Type' => 'Type',
'Dependency' => 'Dépendance',
'View internal links' => 'Voir les liens internes',
'View external links' => 'Voir les liens externes',
'Add internal link' => 'Ajouter un lien interne',
'Add a new external link' => 'Ajouter un nouveau lien externe',
'Edit external link' => 'Modifier un lien externe',
'External link' => 'Lien externe',
'Copy and paste your link here...' => 'Copier-coller vôtre lien ici...',
'URL' => 'URL',
'There is no external link for the moment.' => 'Il n\'y a pas de lien externe pour le moment.',
'Internal links' => 'Liens internes',
'There is no internal link for the moment.' => 'Il n\'y a pas de lien interne pour le moment.',
'Assign to me' => 'Assigner à moi',
'Me' => 'Moi',
'Do not duplicate anything' => 'Ne rien dupliquer',
'Projects management' => 'Gestion des projets',
'Users management' => 'Gestion des utilisateurs',
'Groups management' => 'Gestion des groupes',
'Create from another project' => 'Créer depuis un autre projet',
);

View File

@ -260,9 +260,6 @@ return array(
// 'External authentication failed' => '',
// 'Your external account is linked to your profile successfully.' => '',
'Email' => 'E-mail',
'Link my Google Account' => 'Kapcsold össze a Google fiókkal',
'Unlink my Google Account' => 'Válaszd le a Google fiókomat',
'Login with my Google Account' => 'Jelentkezzen be Google fiókkal',
'Project not found.' => 'A projekt nem található.',
'Task removed successfully.' => 'Feladat sikeresen törölve.',
'Unable to remove this task.' => 'A feladatot nem lehet törölni.',
@ -327,9 +324,6 @@ return array(
'Maximum size: ' => 'Maximális méret: ',
'Unable to upload the file.' => 'Fájl feltöltése nem lehetséges.',
'Display another project' => 'Másik projekt megjelenítése',
'Login with my Github Account' => 'Jelentkezzen be Github fiókkal',
'Link my Github Account' => 'Github fiók csatolása',
'Unlink my Github Account' => 'Github fiók leválasztása',
'Created by %s' => 'Készítette: %s',
'Last modified on %B %e, %Y at %k:%M %p' => 'Utolsó módosítás: %Y. %m. %d. %H:%M',
'Tasks Export' => 'Feladatok exportálása',
@ -395,8 +389,6 @@ return array(
'Change password' => 'Jelszó módosítása',
'Password modification' => 'Jelszó módosítása',
'External authentications' => 'Külső azonosítás',
'Google Account' => 'Google fiók',
'Github Account' => 'Github fiók',
'Never connected.' => 'Sosem csatlakozva.',
'No account linked.' => 'Nincs csatlakoztatott fiók.',
'Account linked.' => 'Fiók csatlakoztatva.',
@ -846,10 +838,6 @@ return array(
// 'This chart show the average lead and cycle time for the last %d tasks over the time.' => '',
// 'Average time into each column' => '',
// 'Lead and cycle time' => '',
// 'Google Authentication' => '',
// 'Help on Google authentication' => '',
// 'Github Authentication' => '',
// 'Help on Github authentication' => '',
// 'Lead time: ' => '',
// 'Cycle time: ' => '',
// 'Time spent into each column' => '',
@ -858,8 +846,6 @@ return array(
// 'If the task is not closed the current time is used instead of the completion date.' => '',
// 'Set automatically the start date' => '',
// 'Edit Authentication' => '',
// 'Google Id' => '',
// 'Github Id' => '',
// 'Remote user' => '',
// 'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => '',
// 'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => '',
@ -917,14 +903,7 @@ return array(
// 'Link type' => '',
// 'Change task color when using a specific task link' => '',
// 'Task link creation or modification' => '',
// 'Login with my Gitlab Account' => '',
// 'Milestone' => '',
// 'Gitlab Authentication' => '',
// 'Help on Gitlab authentication' => '',
// 'Gitlab Id' => '',
// 'Gitlab Account' => '',
// 'Link my Gitlab Account' => '',
// 'Unlink my Gitlab Account' => '',
// 'Documentation: %s' => '',
// 'Switch to the Gantt chart view' => '',
// 'Reset the search/filter box' => '',
@ -1118,4 +1097,37 @@ return array(
// 'Highest priority' => '',
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
// 'Priority: %d' => '',
// 'Close a task when there is no activity' => '',
// 'Duration in days' => '',
// 'Send email when there is no activity on a task' => '',
// 'List of external links' => '',
// 'Unable to fetch link information.' => '',
// 'Daily background job for tasks' => '',
// 'Auto' => '',
// 'Related' => '',
// 'Attachment' => '',
// 'Title not found' => '',
// 'Web Link' => '',
// 'External links' => '',
// 'Add external link' => '',
// 'Type' => '',
// 'Dependency' => '',
// 'View internal links' => '',
// 'View external links' => '',
// 'Add internal link' => '',
// 'Add a new external link' => '',
// 'Edit external link' => '',
// 'External link' => '',
// 'Copy and paste your link here...' => '',
// 'URL' => '',
// 'There is no external link for the moment.' => '',
// 'Internal links' => '',
// 'There is no internal link for the moment.' => '',
// 'Assign to me' => '',
// 'Me' => '',
// 'Do not duplicate anything' => '',
// 'Projects management' => '',
// 'Users management' => '',
// 'Groups management' => '',
// 'Create from another project' => '',
);

View File

@ -260,9 +260,6 @@ return array(
'External authentication failed' => 'Otentifikasi eksternal gagal',
'Your external account is linked to your profile successfully.' => 'Akun eksternal anda berhasil dihubungkan ke profil anda.',
'Email' => 'Email',
'Link my Google Account' => 'Hubungkan akun Google saya',
'Unlink my Google Account' => 'Putuskan akun Google saya',
'Login with my Google Account' => 'Masuk menggunakan akun Google saya',
'Project not found.' => 'Proyek tidak ditemukan.',
'Task removed successfully.' => 'Tugas berhasil dihapus.',
'Unable to remove this task.' => 'Tidak dapat menghapus tugas ini.',
@ -327,9 +324,6 @@ return array(
'Maximum size: ' => 'Ukuran maksimum: ',
'Unable to upload the file.' => 'Tidak dapat mengunggah berkas.',
'Display another project' => 'Lihat proyek lain',
'Login with my Github Account' => 'Masuk menggunakan akun Github saya',
'Link my Github Account' => 'Hubungkan akun Github saya ',
'Unlink my Github Account' => 'Putuskan akun Github saya',
'Created by %s' => 'Dibuat oleh %s',
'Last modified on %B %e, %Y at %k:%M %p' => 'Modifikasi terakhir pada tanggal %d/%m/%Y à %H:%M',
'Tasks Export' => 'Ekspor Tugas',
@ -395,8 +389,6 @@ return array(
'Change password' => 'Rubah kata sandri',
'Password modification' => 'Modifikasi kata sandi',
'External authentications' => 'Otentifikasi eksternal',
'Google Account' => 'Akun Google',
'Github Account' => 'Akun Github',
'Never connected.' => 'Tidak pernah terhubung.',
'No account linked.' => 'Tidak ada akun terhubung.',
'Account linked.' => 'Akun terhubung.',
@ -846,10 +838,6 @@ return array(
'This chart show the average lead and cycle time for the last %d tasks over the time.' => 'Grafik ini menunjukkan memimpin rata-rata dan waktu siklus untuk %d tugas terakhir dari waktu ke waktu.',
'Average time into each column' => 'Rata-rata waktu ke setiap kolom',
'Lead and cycle time' => 'Lead dan siklus waktu',
'Google Authentication' => 'Google Otentifikasi',
'Help on Google authentication' => 'Bantuan pada otentifikasi Google',
'Github Authentication' => 'Otentifikasi Github',
'Help on Github authentication' => 'Bantuan pada otentifikasi Github',
'Lead time: ' => 'Lead time : ',
'Cycle time: ' => 'Siklus waktu : ',
'Time spent into each column' => 'Waktu yang dihabiskan di setiap kolom',
@ -858,8 +846,6 @@ return array(
'If the task is not closed the current time is used instead of the completion date.' => 'Jika tugas tidak ditutup waktu saat ini yang digunakan sebagai pengganti tanggal penyelesaian.',
'Set automatically the start date' => 'Secara otomatis mengatur tanggal mulai',
'Edit Authentication' => 'Modifikasi Otentifikasi',
'Google Id' => 'Id Google',
'Github Id' => 'Id Github',
'Remote user' => 'Pengguna jauh',
'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => 'Pengguna jauh tidak menyimpan kata sandi mereka dalam basis data Kanboard, contoh: akun LDAP, Google dan Github.',
'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => 'Jika anda mencentang kotak "Larang formulir login", kredensial masuk ke formulis login akan diabaikan.',
@ -917,14 +903,7 @@ return array(
'Link type' => 'Tipe tautan',
'Change task color when using a specific task link' => 'Rubah warna tugas ketika menggunakan tautan tugas yang spesifik',
'Task link creation or modification' => 'Tautan pembuatan atau modifikasi tugas ',
'Login with my Gitlab Account' => 'Masuk menggunakan akun Gitlab saya',
'Milestone' => 'Milestone',
'Gitlab Authentication' => 'Authentification Gitlab',
'Help on Gitlab authentication' => 'Bantuan pada otentifikasi Gitlab',
'Gitlab Id' => 'Id Gitlab',
'Gitlab Account' => 'Akun Gitlab',
'Link my Gitlab Account' => 'Hubungkan akun Gitlab saya',
'Unlink my Gitlab Account' => 'Putuskan akun Gitlab saya',
'Documentation: %s' => 'Dokumentasi : %s',
'Switch to the Gantt chart view' => 'Beralih ke tampilan grafik Gantt',
'Reset the search/filter box' => 'Atur ulang pencarian/kotak filter',
@ -1118,4 +1097,37 @@ return array(
// 'Highest priority' => '',
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
// 'Priority: %d' => '',
// 'Close a task when there is no activity' => '',
// 'Duration in days' => '',
// 'Send email when there is no activity on a task' => '',
// 'List of external links' => '',
// 'Unable to fetch link information.' => '',
// 'Daily background job for tasks' => '',
// 'Auto' => '',
// 'Related' => '',
// 'Attachment' => '',
// 'Title not found' => '',
// 'Web Link' => '',
// 'External links' => '',
// 'Add external link' => '',
// 'Type' => '',
// 'Dependency' => '',
// 'View internal links' => '',
// 'View external links' => '',
// 'Add internal link' => '',
// 'Add a new external link' => '',
// 'Edit external link' => '',
// 'External link' => '',
// 'Copy and paste your link here...' => '',
// 'URL' => '',
// 'There is no external link for the moment.' => '',
// 'Internal links' => '',
// 'There is no internal link for the moment.' => '',
// 'Assign to me' => '',
// 'Me' => '',
// 'Do not duplicate anything' => '',
// 'Projects management' => '',
// 'Users management' => '',
// 'Groups management' => '',
// 'Create from another project' => '',
);

File diff suppressed because it is too large Load Diff

View File

@ -260,9 +260,6 @@ return array(
// 'External authentication failed' => '',
// 'Your external account is linked to your profile successfully.' => '',
'Email' => 'Email',
'Link my Google Account' => 'Google アカウントをリンクする',
'Unlink my Google Account' => 'Google アカウントのリンクを解除する',
'Login with my Google Account' => 'Google アカウントでログインする',
'Project not found.' => 'プロジェクトが見つかりません。',
'Task removed successfully.' => 'タスクを削除しました。',
'Unable to remove this task.' => 'タスクの削除に失敗しました。',
@ -327,9 +324,6 @@ return array(
'Maximum size: ' => '最大: ',
'Unable to upload the file.' => 'ファイルのアップロードに失敗しました。',
'Display another project' => '別のプロジェクトを表示',
'Login with my Github Account' => 'Github アカウントでログインする',
'Link my Github Account' => 'Github アカウントをリンクする',
'Unlink my Github Account' => 'Github アカウントとのリンクを解除する',
'Created by %s' => '%s が作成',
'Last modified on %B %e, %Y at %k:%M %p' => ' %Y/%m/%d %H:%M に変更',
'Tasks Export' => 'タスクの出力',
@ -395,8 +389,6 @@ return array(
'Change password' => 'パスワードの変更',
'Password modification' => 'パスワードの変更',
'External authentications' => '外部認証',
'Google Account' => 'Google アカウント',
'Github Account' => 'Github アカウント',
'Never connected.' => '未接続。',
'No account linked.' => 'アカウントがリンクしていません。',
'Account linked.' => 'アカウントがリンクしました。',
@ -846,10 +838,6 @@ return array(
// 'This chart show the average lead and cycle time for the last %d tasks over the time.' => '',
// 'Average time into each column' => '',
// 'Lead and cycle time' => '',
// 'Google Authentication' => '',
// 'Help on Google authentication' => '',
// 'Github Authentication' => '',
// 'Help on Github authentication' => '',
// 'Lead time: ' => '',
// 'Cycle time: ' => '',
// 'Time spent into each column' => '',
@ -858,8 +846,6 @@ return array(
// 'If the task is not closed the current time is used instead of the completion date.' => '',
// 'Set automatically the start date' => '',
// 'Edit Authentication' => '',
// 'Google Id' => '',
// 'Github Id' => '',
// 'Remote user' => '',
// 'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => '',
// 'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => '',
@ -917,14 +903,7 @@ return array(
// 'Link type' => '',
// 'Change task color when using a specific task link' => '',
// 'Task link creation or modification' => '',
// 'Login with my Gitlab Account' => '',
// 'Milestone' => '',
// 'Gitlab Authentication' => '',
// 'Help on Gitlab authentication' => '',
// 'Gitlab Id' => '',
// 'Gitlab Account' => '',
// 'Link my Gitlab Account' => '',
// 'Unlink my Gitlab Account' => '',
// 'Documentation: %s' => '',
// 'Switch to the Gantt chart view' => '',
// 'Reset the search/filter box' => '',
@ -1118,4 +1097,37 @@ return array(
// 'Highest priority' => '',
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
// 'Priority: %d' => '',
// 'Close a task when there is no activity' => '',
// 'Duration in days' => '',
// 'Send email when there is no activity on a task' => '',
// 'List of external links' => '',
// 'Unable to fetch link information.' => '',
// 'Daily background job for tasks' => '',
// 'Auto' => '',
// 'Related' => '',
// 'Attachment' => '',
// 'Title not found' => '',
// 'Web Link' => '',
// 'External links' => '',
// 'Add external link' => '',
// 'Type' => '',
// 'Dependency' => '',
// 'View internal links' => '',
// 'View external links' => '',
// 'Add internal link' => '',
// 'Add a new external link' => '',
// 'Edit external link' => '',
// 'External link' => '',
// 'Copy and paste your link here...' => '',
// 'URL' => '',
// 'There is no external link for the moment.' => '',
// 'Internal links' => '',
// 'There is no internal link for the moment.' => '',
// 'Assign to me' => '',
// 'Me' => '',
// 'Do not duplicate anything' => '',
// 'Projects management' => '',
// 'Users management' => '',
// 'Groups management' => '',
// 'Create from another project' => '',
);

View File

@ -260,9 +260,6 @@ return array(
'External authentication failed' => 'Otentifikasi eksternal gagal',
'Your external account is linked to your profile successfully.' => 'Akaun eksternal anda berhasil dihubungkan ke profil anda.',
'Email' => 'Email',
'Link my Google Account' => 'Hubungkan Akaun Google saya',
'Unlink my Google Account' => 'Putuskan Akaun Google saya',
'Login with my Google Account' => 'Masuk menggunakan Akaun Google saya',
'Project not found.' => 'projek tidak ditemukan.',
'Task removed successfully.' => 'Tugas berhasil dihapus.',
'Unable to remove this task.' => 'Tidak dapat menghapus tugas ini.',
@ -327,9 +324,6 @@ return array(
'Maximum size: ' => 'Ukuran maksimum: ',
'Unable to upload the file.' => 'Tidak dapat mengunggah berkas.',
'Display another project' => 'Lihat projek lain',
'Login with my Github Account' => 'Masuk menggunakan Akaun Github saya',
'Link my Github Account' => 'Hubungkan Akaun Github saya ',
'Unlink my Github Account' => 'Putuskan Akaun Github saya',
'Created by %s' => 'Dibuat oleh %s',
'Last modified on %B %e, %Y at %k:%M %p' => 'Modifikasi terakhir pada tanggal %d/%m/%Y à %H:%M',
'Tasks Export' => 'Ekspor Tugas',
@ -395,8 +389,6 @@ return array(
'Change password' => 'Rubah kata sandri',
'Password modification' => 'Modifikasi kata laluan',
'External authentications' => 'Otentifikasi eksternal',
'Google Account' => 'Akaun Google',
'Github Account' => 'Akaun Github',
'Never connected.' => 'Tidak pernah terhubung.',
'No account linked.' => 'Tidak ada Akaun terhubung.',
'Account linked.' => 'Akaun terhubung.',
@ -846,10 +838,6 @@ return array(
'This chart show the average lead and cycle time for the last %d tasks over the time.' => 'Grafik ini menunjukkan memimpin rata-rata dan waktu siklus untuk %d tugas terakhir dari waktu ke waktu.',
'Average time into each column' => 'Rata-rata waktu ke setiap kolom',
'Lead and cycle time' => 'Lead dan siklus waktu',
'Google Authentication' => 'Google Otentifikasi',
'Help on Google authentication' => 'Bantuan pada otentifikasi Google',
'Github Authentication' => 'Otentifikasi Github',
'Help on Github authentication' => 'Bantuan pada otentifikasi Github',
'Lead time: ' => 'Lead time : ',
'Cycle time: ' => 'Siklus waktu : ',
'Time spent into each column' => 'Waktu yang dihabiskan di setiap kolom',
@ -858,8 +846,6 @@ return array(
'If the task is not closed the current time is used instead of the completion date.' => 'Jika tugas tidak ditutup waktu saat ini yang digunakan sebagai pengganti tanggal penyelesaian.',
'Set automatically the start date' => 'Secara otomatis mengatur tanggal mulai',
'Edit Authentication' => 'Modifikasi Otentifikasi',
'Google Id' => 'Id Google',
'Github Id' => 'Id Github',
'Remote user' => 'Pengguna jauh',
'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => 'Pengguna jauh tidak menyimpan kata laluan mereka dalam basis data Kanboard, contoh: Akaun LDAP, Google dan Github.',
'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => 'Jika anda mencentang kotak "Larang formulir login", kredensial masuk ke formulis login akan diabaikan.',
@ -917,14 +903,7 @@ return array(
'Link type' => 'Jenis pautan',
'Change task color when using a specific task link' => 'Rubah warna tugas ketika menggunakan Pautan tugas yang spesifik',
'Task link creation or modification' => 'Pautan tugas pada penciptaan atau penyuntingan',
'Login with my Gitlab Account' => 'Masuk menggunakan Akaun Gitlab saya',
'Milestone' => 'Batu Tanda',
'Gitlab Authentication' => 'Otentifikasi Gitlab',
'Help on Gitlab authentication' => 'Bantuan pada otentifikasi Gitlab',
'Gitlab Id' => 'Id Gitlab',
'Gitlab Account' => 'Akaun Gitlab',
'Link my Gitlab Account' => 'Hubungkan akaun Gitlab saya',
'Unlink my Gitlab Account' => 'Putuskan akaun Gitlab saya',
'Documentation: %s' => 'Dokumentasi : %s',
'Switch to the Gantt chart view' => 'Beralih ke tampilan Carta Gantt',
'Reset the search/filter box' => 'Tetap semula pencarian/saringan',
@ -1118,4 +1097,37 @@ return array(
// 'Highest priority' => '',
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
// 'Priority: %d' => '',
// 'Close a task when there is no activity' => '',
// 'Duration in days' => '',
// 'Send email when there is no activity on a task' => '',
// 'List of external links' => '',
// 'Unable to fetch link information.' => '',
// 'Daily background job for tasks' => '',
// 'Auto' => '',
// 'Related' => '',
// 'Attachment' => '',
// 'Title not found' => '',
// 'Web Link' => '',
// 'External links' => '',
// 'Add external link' => '',
// 'Type' => '',
// 'Dependency' => '',
// 'View internal links' => '',
// 'View external links' => '',
// 'Add internal link' => '',
// 'Add a new external link' => '',
// 'Edit external link' => '',
// 'External link' => '',
// 'Copy and paste your link here...' => '',
// 'URL' => '',
// 'There is no external link for the moment.' => '',
// 'Internal links' => '',
// 'There is no internal link for the moment.' => '',
// 'Assign to me' => '',
// 'Me' => '',
// 'Do not duplicate anything' => '',
// 'Projects management' => '',
// 'Users management' => '',
// 'Groups management' => '',
// 'Create from another project' => '',
);

View File

@ -260,9 +260,6 @@ return array(
// 'External authentication failed' => '',
// 'Your external account is linked to your profile successfully.' => '',
'Email' => 'Epost',
'Link my Google Account' => 'Knytt til min Google-konto',
'Unlink my Google Account' => 'Fjern knytningen til min Google-konto',
'Login with my Google Account' => 'Login med min Google-konto',
'Project not found.' => 'Prosjekt ikke funnet.',
'Task removed successfully.' => 'Oppgaven er fjernet.',
'Unable to remove this task.' => 'Oppgaven kunne ikke fjernes.',
@ -327,9 +324,6 @@ return array(
'Maximum size: ' => 'Maksimum størrelse: ',
'Unable to upload the file.' => 'Filen kunne ikke lastes opp.',
'Display another project' => 'Vis annet prosjekt...',
// 'Login with my Github Account' => '',
// 'Link my Github Account' => '',
// 'Unlink my Github Account' => '',
'Created by %s' => 'Opprettet av %s',
'Last modified on %B %e, %Y at %k:%M %p' => 'Sist endret %d.%m.%Y - %H:%M',
'Tasks Export' => 'Oppgave eksport',
@ -395,8 +389,6 @@ return array(
'Change password' => 'Endre passord',
'Password modification' => 'Passordendring',
'External authentications' => 'Ekstern godkjenning',
'Google Account' => 'Google-konto',
'Github Account' => 'GitHub-konto',
'Never connected.' => 'Aldri innlogget.',
'No account linked.' => 'Ingen kontoer knyttet.',
'Account linked.' => 'Konto knyttet.',
@ -846,10 +838,6 @@ return array(
// 'This chart show the average lead and cycle time for the last %d tasks over the time.' => '',
// 'Average time into each column' => '',
// 'Lead and cycle time' => '',
// 'Google Authentication' => '',
// 'Help on Google authentication' => '',
// 'Github Authentication' => '',
// 'Help on Github authentication' => '',
// 'Lead time: ' => '',
// 'Cycle time: ' => '',
// 'Time spent into each column' => '',
@ -858,8 +846,6 @@ return array(
// 'If the task is not closed the current time is used instead of the completion date.' => '',
// 'Set automatically the start date' => '',
// 'Edit Authentication' => '',
// 'Google Id' => '',
// 'Github Id' => '',
// 'Remote user' => '',
// 'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => '',
// 'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => '',
@ -917,14 +903,7 @@ return array(
'Link type' => 'Relasjonstype',
// 'Change task color when using a specific task link' => '',
// 'Task link creation or modification' => '',
// 'Login with my Gitlab Account' => '',
'Milestone' => 'Milepæl',
// 'Gitlab Authentication' => '',
// 'Help on Gitlab authentication' => '',
// 'Gitlab Id' => '',
// 'Gitlab Account' => '',
// 'Link my Gitlab Account' => '',
// 'Unlink my Gitlab Account' => '',
'Documentation: %s' => 'Dokumentasjon: %s',
'Switch to the Gantt chart view' => 'Gantt skjema visning',
'Reset the search/filter box' => 'Nullstill søk/filter',
@ -1118,4 +1097,37 @@ return array(
// 'Highest priority' => '',
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
// 'Priority: %d' => '',
// 'Close a task when there is no activity' => '',
// 'Duration in days' => '',
// 'Send email when there is no activity on a task' => '',
// 'List of external links' => '',
// 'Unable to fetch link information.' => '',
// 'Daily background job for tasks' => '',
// 'Auto' => '',
// 'Related' => '',
// 'Attachment' => '',
// 'Title not found' => '',
// 'Web Link' => '',
// 'External links' => '',
// 'Add external link' => '',
// 'Type' => '',
// 'Dependency' => '',
// 'View internal links' => '',
// 'View external links' => '',
// 'Add internal link' => '',
// 'Add a new external link' => '',
// 'Edit external link' => '',
// 'External link' => '',
// 'Copy and paste your link here...' => '',
// 'URL' => '',
// 'There is no external link for the moment.' => '',
// 'Internal links' => '',
// 'There is no internal link for the moment.' => '',
// 'Assign to me' => '',
// 'Me' => '',
// 'Do not duplicate anything' => '',
// 'Projects management' => '',
// 'Users management' => '',
// 'Groups management' => '',
// 'Create from another project' => '',
);

View File

@ -260,9 +260,6 @@ return array(
// 'External authentication failed' => '',
// 'Your external account is linked to your profile successfully.' => '',
'Email' => 'Email',
'Link my Google Account' => 'Link mijn Google Account',
'Unlink my Google Account' => 'Link met Google Account verwijderen',
'Login with my Google Account' => 'Inloggen met mijn Google Account',
'Project not found.' => 'Project niet gevonden.',
'Task removed successfully.' => 'Taak succesvol verwijderd.',
'Unable to remove this task.' => 'Taak verwijderen niet gelukt.',
@ -327,9 +324,6 @@ return array(
'Maximum size: ' => 'Maximale grootte : ',
'Unable to upload the file.' => 'Uploaden van bestand niet gelukt.',
'Display another project' => 'Een ander project weergeven',
'Login with my Github Account' => 'Login met mijn Github Account',
'Link my Github Account' => 'Link met mijn Github',
'Unlink my Github Account' => 'Link met mijn Github verwijderen',
'Created by %s' => 'Aangemaakt door %s',
'Last modified on %B %e, %Y at %k:%M %p' => 'Laatst gewijzigd op %d/%m/%Y à %H:%M',
'Tasks Export' => 'Taken exporteren',
@ -395,8 +389,6 @@ return array(
'Change password' => 'Wachtwoord aanpassen',
'Password modification' => 'Wachtwoord aanpassen',
'External authentications' => 'Externe authenticatie',
'Google Account' => 'Google Account',
'Github Account' => 'Github Account',
'Never connected.' => 'Nooit verbonden.',
'No account linked.' => 'Geen account gelinkt.',
'Account linked.' => 'Account gelinkt.',
@ -846,10 +838,6 @@ return array(
// 'This chart show the average lead and cycle time for the last %d tasks over the time.' => '',
// 'Average time into each column' => '',
// 'Lead and cycle time' => '',
// 'Google Authentication' => '',
// 'Help on Google authentication' => '',
// 'Github Authentication' => '',
// 'Help on Github authentication' => '',
// 'Lead time: ' => '',
// 'Cycle time: ' => '',
// 'Time spent into each column' => '',
@ -858,8 +846,6 @@ return array(
// 'If the task is not closed the current time is used instead of the completion date.' => '',
// 'Set automatically the start date' => '',
// 'Edit Authentication' => '',
// 'Google Id' => '',
// 'Github Id' => '',
// 'Remote user' => '',
// 'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => '',
// 'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => '',
@ -917,14 +903,7 @@ return array(
// 'Link type' => '',
// 'Change task color when using a specific task link' => '',
// 'Task link creation or modification' => '',
// 'Login with my Gitlab Account' => '',
// 'Milestone' => '',
// 'Gitlab Authentication' => '',
// 'Help on Gitlab authentication' => '',
// 'Gitlab Id' => '',
// 'Gitlab Account' => '',
// 'Link my Gitlab Account' => '',
// 'Unlink my Gitlab Account' => '',
// 'Documentation: %s' => '',
// 'Switch to the Gantt chart view' => '',
// 'Reset the search/filter box' => '',
@ -1118,4 +1097,37 @@ return array(
// 'Highest priority' => '',
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
// 'Priority: %d' => '',
// 'Close a task when there is no activity' => '',
// 'Duration in days' => '',
// 'Send email when there is no activity on a task' => '',
// 'List of external links' => '',
// 'Unable to fetch link information.' => '',
// 'Daily background job for tasks' => '',
// 'Auto' => '',
// 'Related' => '',
// 'Attachment' => '',
// 'Title not found' => '',
// 'Web Link' => '',
// 'External links' => '',
// 'Add external link' => '',
// 'Type' => '',
// 'Dependency' => '',
// 'View internal links' => '',
// 'View external links' => '',
// 'Add internal link' => '',
// 'Add a new external link' => '',
// 'Edit external link' => '',
// 'External link' => '',
// 'Copy and paste your link here...' => '',
// 'URL' => '',
// 'There is no external link for the moment.' => '',
// 'Internal links' => '',
// 'There is no internal link for the moment.' => '',
// 'Assign to me' => '',
// 'Me' => '',
// 'Do not duplicate anything' => '',
// 'Projects management' => '',
// 'Users management' => '',
// 'Groups management' => '',
// 'Create from another project' => '',
);

View File

@ -260,9 +260,6 @@ return array(
// 'External authentication failed' => '',
// 'Your external account is linked to your profile successfully.' => '',
'Email' => 'Email',
'Link my Google Account' => 'Połącz z kontem Google',
'Unlink my Google Account' => 'Rozłącz z kontem Google',
'Login with my Google Account' => 'Zaloguj przy pomocy konta Google',
'Project not found.' => 'Projek nieznaleziony.',
'Task removed successfully.' => 'Zadanie usunięto pomyślnie.',
'Unable to remove this task.' => 'Nie można usunąć tego zadania.',
@ -327,9 +324,6 @@ return array(
'Maximum size: ' => 'Maksymalny rozmiar: ',
'Unable to upload the file.' => 'Nie można wczytać pliku.',
'Display another project' => 'Wyświetl inny projekt',
'Login with my Github Account' => 'Zaloguj przy użyciu konta Github',
'Link my Github Account' => 'Podłącz konto Github',
'Unlink my Github Account' => 'Odłącz konto Github',
'Created by %s' => 'Utworzone przez %s',
'Last modified on %B %e, %Y at %k:%M %p' => 'Ostatnio zmienione %e %B %Y o %k:%M',
'Tasks Export' => 'Eksport zadań',
@ -395,8 +389,6 @@ return array(
'Change password' => 'Zmień hasło',
'Password modification' => 'Zmiana hasła',
'External authentications' => 'Autentykacja zewnętrzna',
'Google Account' => 'Konto Google',
'Github Account' => 'Konto Github',
'Never connected.' => 'Nigdy nie połączone.',
'No account linked.' => 'Brak połączonych kont.',
'Account linked.' => 'Konto połączone.',
@ -846,10 +838,6 @@ return array(
// 'This chart show the average lead and cycle time for the last %d tasks over the time.' => '',
// 'Average time into each column' => '',
// 'Lead and cycle time' => '',
// 'Google Authentication' => '',
// 'Help on Google authentication' => '',
// 'Github Authentication' => '',
// 'Help on Github authentication' => '',
// 'Lead time: ' => '',
// 'Cycle time: ' => '',
// 'Time spent into each column' => '',
@ -858,8 +846,6 @@ return array(
// 'If the task is not closed the current time is used instead of the completion date.' => '',
// 'Set automatically the start date' => '',
'Edit Authentication' => 'Edycja autoryzacji',
// 'Google Id' => '',
// 'Github Id' => '',
// 'Remote user' => '',
// 'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => '',
// 'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => '',
@ -917,14 +903,7 @@ return array(
'Link type' => 'Typ adresu URL',
'Change task color when using a specific task link' => 'Zmień kolor zadania używając specjalnego adresu URL',
'Task link creation or modification' => 'Adres URL do utworzenia zadania lub modyfikacji',
// 'Login with my Gitlab Account' => '',
'Milestone' => 'Kamień milowy',
// 'Gitlab Authentication' => '',
// 'Help on Gitlab authentication' => '',
// 'Gitlab Id' => '',
// 'Gitlab Account' => '',
// 'Link my Gitlab Account' => '',
// 'Unlink my Gitlab Account' => '',
// 'Documentation: %s' => '',
// 'Switch to the Gantt chart view' => '',
// 'Reset the search/filter box' => '',
@ -1118,4 +1097,37 @@ return array(
// 'Highest priority' => '',
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
// 'Priority: %d' => '',
// 'Close a task when there is no activity' => '',
// 'Duration in days' => '',
// 'Send email when there is no activity on a task' => '',
// 'List of external links' => '',
// 'Unable to fetch link information.' => '',
// 'Daily background job for tasks' => '',
// 'Auto' => '',
// 'Related' => '',
// 'Attachment' => '',
// 'Title not found' => '',
// 'Web Link' => '',
// 'External links' => '',
// 'Add external link' => '',
// 'Type' => '',
// 'Dependency' => '',
// 'View internal links' => '',
// 'View external links' => '',
// 'Add internal link' => '',
// 'Add a new external link' => '',
// 'Edit external link' => '',
// 'External link' => '',
// 'Copy and paste your link here...' => '',
// 'URL' => '',
// 'There is no external link for the moment.' => '',
// 'Internal links' => '',
// 'There is no internal link for the moment.' => '',
// 'Assign to me' => '',
// 'Me' => '',
// 'Do not duplicate anything' => '',
// 'Projects management' => '',
// 'Users management' => '',
// 'Groups management' => '',
// 'Create from another project' => '',
);

View File

@ -260,9 +260,6 @@ return array(
'External authentication failed' => 'Autenticação externa falhou',
'Your external account is linked to your profile successfully.' => 'Sua conta externa está agora ligada ao seu perfil.',
'Email' => 'E-mail',
'Link my Google Account' => 'Vincular minha Conta do Google',
'Unlink my Google Account' => 'Desvincular minha Conta do Google',
'Login with my Google Account' => 'Entrar com minha Conta do Google',
'Project not found.' => 'Projeto não encontrado.',
'Task removed successfully.' => 'Tarefa removida com sucesso.',
'Unable to remove this task.' => 'Não foi possível remover esta tarefa.',
@ -327,9 +324,6 @@ return array(
'Maximum size: ' => 'Tamanho máximo: ',
'Unable to upload the file.' => 'Não foi possível carregar o arquivo.',
'Display another project' => 'Exibir outro projeto',
'Login with my Github Account' => 'Entrar com minha Conta do Github',
'Link my Github Account' => 'Associar à minha Conta do Github',
'Unlink my Github Account' => 'Desassociar a minha Conta do Github',
'Created by %s' => 'Criado por %s',
'Last modified on %B %e, %Y at %k:%M %p' => 'Última modificação em %B %e, %Y às %k: %M %p',
'Tasks Export' => 'Exportar Tarefas',
@ -395,8 +389,6 @@ return array(
'Change password' => 'Alterar senha',
'Password modification' => 'Alteração de senha',
'External authentications' => 'Autenticação externa',
'Google Account' => 'Conta do Google',
'Github Account' => 'Conta do Github',
'Never connected.' => 'Nunca conectado.',
'No account linked.' => 'Nenhuma conta associada.',
'Account linked.' => 'Conta associada.',
@ -846,10 +838,6 @@ return array(
'This chart show the average lead and cycle time for the last %d tasks over the time.' => 'Este gráfico mostra o tempo médio do Lead and cycle time das últimas %d tarefas.',
'Average time into each column' => 'Tempo médio de cada coluna',
'Lead and cycle time' => 'Lead and cycle time',
'Google Authentication' => 'Autenticação Google',
'Help on Google authentication' => 'Ajuda com a autenticação Google',
'Github Authentication' => 'Autenticação Github',
'Help on Github authentication' => 'Ajuda com a autenticação Github',
'Lead time: ' => 'Lead time: ',
'Cycle time: ' => 'Cycle time: ',
'Time spent into each column' => 'Tempo gasto em cada coluna',
@ -858,8 +846,6 @@ return array(
'If the task is not closed the current time is used instead of the completion date.' => 'Se a tarefa não está fechada, a hora atual é usada no lugar da data de conclusão.',
'Set automatically the start date' => 'Definir automaticamente a data de início',
'Edit Authentication' => 'Modificar a autenticação',
'Google Id' => 'Google ID',
'Github Id' => 'Github Id',
'Remote user' => 'Usuário remoto',
'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => 'Os usuários remotos não conservam as suas senhas no banco de dados Kanboard, exemplos: contas LDAP, Github ou Google.',
'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => 'Se você marcar "Interdir o formulário de autenticação", os identificadores entrados no formulário de login serão ignorado.',
@ -917,14 +903,7 @@ return array(
'Link type' => 'Tipo de link',
'Change task color when using a specific task link' => 'Mudar a cor da tarefa quando um link específico é utilizado',
'Task link creation or modification' => 'Criação ou modificação de um link em uma tarefa',
'Login with my Gitlab Account' => 'Login com a minha conta Gitlab',
'Milestone' => 'Milestone',
'Gitlab Authentication' => 'Autenticação Gitlab',
'Help on Gitlab authentication' => 'Ajuda com a autenticação Gitlab',
'Gitlab Id' => 'Gitlab Id',
'Gitlab Account' => 'Conta Gitlab',
'Link my Gitlab Account' => 'Vincular minha conta Gitlab',
'Unlink my Gitlab Account' => 'Desvincular minha conta Gitlab',
'Documentation: %s' => 'Documentação: %s',
'Switch to the Gantt chart view' => 'Mudar para a vista gráfico de Gantt',
'Reset the search/filter box' => 'Reiniciar o campo de pesquisa',
@ -1118,4 +1097,37 @@ return array(
// 'Highest priority' => '',
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
// 'Priority: %d' => '',
// 'Close a task when there is no activity' => '',
// 'Duration in days' => '',
// 'Send email when there is no activity on a task' => '',
// 'List of external links' => '',
// 'Unable to fetch link information.' => '',
// 'Daily background job for tasks' => '',
// 'Auto' => '',
// 'Related' => '',
// 'Attachment' => '',
// 'Title not found' => '',
// 'Web Link' => '',
// 'External links' => '',
// 'Add external link' => '',
// 'Type' => '',
// 'Dependency' => '',
// 'View internal links' => '',
// 'View external links' => '',
// 'Add internal link' => '',
// 'Add a new external link' => '',
// 'Edit external link' => '',
// 'External link' => '',
// 'Copy and paste your link here...' => '',
// 'URL' => '',
// 'There is no external link for the moment.' => '',
// 'Internal links' => '',
// 'There is no internal link for the moment.' => '',
// 'Assign to me' => '',
// 'Me' => '',
// 'Do not duplicate anything' => '',
// 'Projects management' => '',
// 'Users management' => '',
// 'Groups management' => '',
// 'Create from another project' => '',
);

View File

@ -260,9 +260,6 @@ return array(
'External authentication failed' => 'Autenticação externa falhou',
'Your external account is linked to your profile successfully.' => 'A sua conta externa foi vinculada com sucesso ao seu perfil',
'Email' => 'E-mail',
'Link my Google Account' => 'Vincular a minha Conta do Google',
'Unlink my Google Account' => 'Desvincular a minha Conta do Google',
'Login with my Google Account' => 'Entrar com a minha Conta do Google',
'Project not found.' => 'Projecto não encontrado.',
'Task removed successfully.' => 'Tarefa removida com sucesso.',
'Unable to remove this task.' => 'Não foi possível remover esta tarefa.',
@ -327,9 +324,6 @@ return array(
'Maximum size: ' => 'Tamanho máximo: ',
'Unable to upload the file.' => 'Não foi possível carregar o arquivo.',
'Display another project' => 'Mostrar outro projecto',
'Login with my Github Account' => 'Entrar com a minha Conta do Github',
'Link my Github Account' => 'Associar à minha Conta do Github',
'Unlink my Github Account' => 'Desassociar a minha Conta do Github',
'Created by %s' => 'Criado por %s',
'Last modified on %B %e, %Y at %k:%M %p' => 'Última modificação em %B %e, %Y às %k: %M %p',
'Tasks Export' => 'Exportar Tarefas',
@ -395,8 +389,6 @@ return array(
'Change password' => 'Alterar senha',
'Password modification' => 'Alteração de senha',
'External authentications' => 'Autenticação externa',
'Google Account' => 'Conta do Google',
'Github Account' => 'Conta do Github',
'Never connected.' => 'Nunca conectado.',
'No account linked.' => 'Nenhuma conta associada.',
'Account linked.' => 'Conta associada.',
@ -846,10 +838,6 @@ return array(
'This chart show the average lead and cycle time for the last %d tasks over the time.' => 'Este gráfico mostra o tempo médio de espera e ciclo para as últimas %d tarefas realizadas.',
'Average time into each column' => 'Tempo médio em cada coluna',
'Lead and cycle time' => 'Tempo de Espera e Ciclo',
'Google Authentication' => 'Autenticação Google',
'Help on Google authentication' => 'Ajuda com autenticação Google',
'Github Authentication' => 'Autenticação Github',
'Help on Github authentication' => 'Ajuda com autenticação Github',
'Lead time: ' => 'Tempo de Espera: ',
'Cycle time: ' => 'Tempo de Ciclo: ',
'Time spent into each column' => 'Tempo gasto em cada coluna',
@ -858,8 +846,6 @@ return array(
'If the task is not closed the current time is used instead of the completion date.' => 'Se a tarefa não estiver fechada o hora actual será usada em vez da hora de conclusão',
'Set automatically the start date' => 'Definir data de inicio automáticamente',
'Edit Authentication' => 'Editar Autenticação',
'Google Id' => 'Id Google',
'Github Id' => 'Id Github',
'Remote user' => 'Utilizador remoto',
'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => 'Utilizadores remotos não guardam a password na base de dados do Kanboard, por exemplo: LDAP, contas do Google e Github.',
'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => 'Se activar a opção "Desactivar login", as credenciais digitadas no login serão ignoradas.',
@ -917,14 +903,7 @@ return array(
'Link type' => 'Tipo de ligação',
'Change task color when using a specific task link' => 'Alterar cor da tarefa quando se usar um tipo especifico de ligação de tarefa',
'Task link creation or modification' => 'Criação ou modificação de ligação de tarefa',
'Login with my Gitlab Account' => 'Login com a minha Conta Gitlab',
'Milestone' => 'Objectivo',
'Gitlab Authentication' => 'Autenticação Gitlab',
'Help on Gitlab authentication' => 'Ajuda com autenticação Gitlab',
'Gitlab Id' => 'Id Gitlab',
'Gitlab Account' => 'Conta Gitlab',
'Link my Gitlab Account' => 'Connectar a minha Conta Gitlab',
'Unlink my Gitlab Account' => 'Desconectar a minha Conta Gitlab',
'Documentation: %s' => 'Documentação: %s',
'Switch to the Gantt chart view' => 'Mudar para vista de gráfico de Gantt',
'Reset the search/filter box' => 'Repor caixa de procura/filtro',
@ -1100,22 +1079,50 @@ return array(
'Do you really want to close all tasks of this column?' => 'Tem a certeza que quer fechar todas as tarefas nesta coluna?',
'%d task(s) in the column "%s" and the swimlane "%s" will be closed.' => '%d tarefa(s) na coluna "%s" e na swimlane "%s" serão fechadas.',
'Close all tasks of this column' => 'Fechar todas as tarefas nesta coluna',
// 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => '',
// 'My dashboard' => '',
// 'My profile' => '',
// 'Project owner: ' => '',
// 'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => '',
// 'Project owner' => '',
// 'Those dates are useful for the project Gantt chart.' => '',
// 'Private projects do not have users and groups management.' => '',
// 'There is no project member.' => '',
// 'Priority' => '',
// 'Task priority' => '',
// 'General' => '',
// 'Dates' => '',
// 'Default priority' => '',
// 'Lowest priority' => '',
// 'Highest priority' => '',
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
// 'Priority: %d' => '',
'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => 'Nenhum plugin tem registado um método de notificação do projecto. Pode continuar a configurar notificações individuais no seu perfil de utilizador.',
'My dashboard' => 'Meu painel',
'My profile' => 'Meu perfil',
'Project owner: ' => 'Dono do projecto: ',
'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => 'O identificador do projecto é opcional e tem de ser alfa-numerico, exemplo: MEUPROJECTO.',
'Project owner' => 'Dono do projecto',
'Those dates are useful for the project Gantt chart.' => 'Estas datas são uteis para o gráfico de Grantt do projecto.',
'Private projects do not have users and groups management.' => 'Projectos privados não têm gestão de utilizadores nem de grupos.',
'There is no project member.' => 'Não existe membro do projecto.',
'Priority' => 'Prioridade',
'Task priority' => 'Prioridade da Tarefa',
'General' => 'Geral',
'Dates' => 'Datas',
'Default priority' => 'Prioridade por defeito',
'Lowest priority' => 'Prioridade mais baixa',
'Highest priority' => 'Prioridade mais alta',
'If you put zero to the low and high priority, this feature will be disabled.' => 'Se colocar zero na prioridade baixa ou alta, essa funcionalidade será desactivada.',
'Priority: %d' => 'Prioridade: %d',
'Close a task when there is no activity' => 'Fechar tarefa quando não há actividade',
'Duration in days' => 'Duração em dias',
'Send email when there is no activity on a task' => 'Enviar email quando não há actividade numa tarefa',
'List of external links' => 'Lista de ligações externas',
'Unable to fetch link information.' => 'Impossivel obter informação da ligação.',
'Daily background job for tasks' => 'Trabalho diário em segundo plano para tarefas',
'Auto' => 'Auto',
'Related' => 'Relacionado',
'Attachment' => 'Anexo',
'Title not found' => 'Titulo não encontrado',
'Web Link' => 'Ligação Web',
'External links' => 'Ligações externas',
'Add external link' => 'Adicionar ligação externa',
'Type' => 'Tipo',
'Dependency' => 'Dependencia',
'View internal links' => 'Ver ligações internas',
'View external links' => 'Ver ligações externas',
'Add internal link' => 'Adicionar ligação interna',
'Add a new external link' => 'Adicionar nova ligação externa',
'Edit external link' => 'Editar ligação externa',
'External link' => 'Ligação externa',
'Copy and paste your link here...' => 'Copie e cole a sua ligação aqui...',
'URL' => 'URL',
'There is no external link for the moment.' => 'De momento não existe nenhuma ligação externa.',
'Internal links' => 'Ligações internas',
'There is no internal link for the moment.' => 'De momento não existe nenhuma ligação interna.',
'Assign to me' => 'Assignar a mim',
'Me' => 'Eu',
);

View File

@ -120,7 +120,7 @@ return array(
'The user id is required' => 'Необходим ID пользователя',
'Passwords don\'t match' => 'Пароли не совпадают',
'The confirmation is required' => 'Необходимо подтверждение',
'The project is required' => 'Необъодимо указать проект',
'The project is required' => 'Необходимо указать проект',
'The id is required' => 'Необходим ID',
'The project id is required' => 'Необходим ID проекта',
'The project name is required' => 'Необходимо имя проекта',
@ -177,7 +177,7 @@ return array(
'User' => 'Пользователь',
'Comments' => 'Комментарии',
'Write your text in Markdown' => 'Справка по синтаксису Markdown',
'Leave a comment' => 'Оставить комментарий 2',
'Leave a comment' => 'Оставить комментарий',
'Comment is required' => 'Нужен комментарий',
'Leave a description' => 'Напишите описание',
'Comment added successfully.' => 'Комментарий успешно добавлен.',
@ -189,7 +189,7 @@ return array(
'%B %e, %Y' => '%B, %e, %Y',
'%b %e, %Y' => '%b %e, %Y',
'Automatic actions' => 'Автоматические действия',
'Your automatic action have been created successfully.' => 'Автоматика успешно настроена.',
'Your automatic action have been created successfully.' => 'Автоматизированное действие успешно настроено.',
'Unable to create your automatic action.' => 'Не удалось создать автоматизированное действие.',
'Remove an action' => 'Удалить действие',
'Unable to remove this action.' => 'Не удалось удалить действие',
@ -260,9 +260,6 @@ return array(
'External authentication failed' => 'Внешняя авторизация не удалась',
'Your external account is linked to your profile successfully.' => 'Ваш внешний аккаунт успешно подключен к профилю.',
'Email' => 'E-mail',
'Link my Google Account' => 'Привязать мой профиль к Google',
'Unlink my Google Account' => 'Отвязать мой профиль от Google',
'Login with my Google Account' => 'Аутентификация через Google',
'Project not found.' => 'Проект не найден.',
'Task removed successfully.' => 'Задача удалена.',
'Unable to remove this task.' => 'Не удалось удалить эту задачу.',
@ -327,9 +324,6 @@ return array(
'Maximum size: ' => 'Максимальный размер: ',
'Unable to upload the file.' => 'Не удалось загрузить файл.',
'Display another project' => 'Показать другой проект',
'Login with my Github Account' => 'Аутентификация через Github',
'Link my Github Account' => 'Привязать мой профиль к Github',
'Unlink my Github Account' => 'Отвязать мой профиль от Github',
'Created by %s' => 'Создано %s',
'Last modified on %B %e, %Y at %k:%M %p' => 'Последнее изменение %d/%m/%Y в %H:%M',
'Tasks Export' => 'Экспорт задач',
@ -395,8 +389,6 @@ return array(
'Change password' => 'Сменить пароль',
'Password modification' => 'Изменение пароля',
'External authentications' => 'Внешняя аутентификация',
'Google Account' => 'Профиль Google',
'Github Account' => 'Профиль Github',
'Never connected.' => 'Ранее не соединялось.',
'No account linked.' => 'Нет связанных профилей.',
'Account linked.' => 'Профиль связан.',
@ -839,17 +831,13 @@ return array(
'Average time spent' => 'Затрачено времени в среднем',
'This chart show the average time spent into each column for the last %d tasks.' => 'Эта диаграмма показывает среднее время, проведенное задачами в каждой колонке за последний %d.',
'Average Lead and Cycle time' => 'Среднее время выполнения и цикла',
'Average lead time: ' => 'Среднее время выполнения',
'Average cycle time: ' => 'Среднее время цикла',
'Average lead time: ' => 'Среднее время выполнения: ',
'Average cycle time: ' => 'Среднее время цикла: ',
'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' => 'Среднее время в каждом столбце',
'Lead and cycle time' => 'Время выполнения и цикла',
'Google Authentication' => 'Авторизация Google',
'Help on Google authentication' => 'Помощь в авторизации Google',
'Github Authentication' => 'Авторизация Github',
'Help on Github authentication' => 'Помощь в авторизации Github',
'Lead time: ' => 'Время выполнения:',
'Cycle time: ' => 'Время цикла:',
'Time spent into each column' => 'Время, проведенное в каждой колонке',
@ -858,16 +846,14 @@ return array(
'If the task is not closed the current time is used instead of the completion date.' => 'Если задача не закрыта, то текущая дата будет указана в дате завершения задачи.',
'Set automatically the start date' => 'Установить автоматическую дату начала',
'Edit Authentication' => 'Редактировать авторизацию',
'Google Id' => 'Google Id',
'Github Id' => 'Github Id',
'Remote user' => 'Удаленный пользователь',
'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => 'Учетные данные для входа через LDAP, Google и Github не будут сохранены в Kanboard.',
'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => 'Если вы установите флажок "Запретить форму входа", учетные данные, введенные в форму входа будет игнорироваться.',
'New remote user' => 'Новый удаленный пользователь',
'New local user' => 'Новый локальный пользователь',
'Default task color' => 'Стандартные цвета задач',
'Hide sidebar' => 'Свернуть сайдбар',
'Expand sidebar' => 'Показать сайдбар',
'Hide sidebar' => 'Свернуть боковое меню',
'Expand sidebar' => 'Показать боковое меню',
'This feature does not work with all browsers.' => 'Эта функция доступна не во всех браузерах.',
'There is no destination project available.' => 'Нет доступного для назначения проекта.',
'Trigger automatically subtask time tracking' => 'Триггер автоматического отслеживания времени подзадач',
@ -876,14 +862,14 @@ return array(
'Current column: %s' => 'Текущая колонка: %s',
'Current category: %s' => 'Текущая категория: %s',
'no category' => 'без категории',
'Current assignee: %s' => 'Current assignee: %s',
'Current assignee: %s' => 'Текущее назначенное лицо: %s',
'not assigned' => 'не назначен',
'Author:' => 'Автор:',
'contributors' => 'соавторы',
'License:' => 'Лицензия:',
'License' => 'Лицензия',
'Enter the text below' => 'Введите текст ниже',
'Gantt chart for %s' => 'Диаграмма Гантта для %s',
'Gantt chart for %s' => 'Диаграмма Ганта для %s',
'Sort by position' => 'Сортировать по позиции',
'Sort by date' => 'Сортировать по дате',
'Add task' => 'Добавить задачу',
@ -892,7 +878,7 @@ return array(
'There is no start date or due date for this task.' => 'Для этой задачи нет даты начала или завершения.',
'Moving or resizing a task will change the start and due date of the task.' => 'Изменение или перемещение задачи повлечет изменение даты начала завершения задачи.',
'There is no task in your project.' => 'В Вашем проекте задач нет.',
'Gantt chart' => 'Диаграмма Гантта',
'Gantt chart' => 'Диаграмма Ганта',
'People who are project managers' => 'Люди, которые менеджеры проекта',
'People who are project members' => 'Люди, которые участники проекта',
'NOK - Norwegian Krone' => 'НК - Норвежская крона',
@ -905,32 +891,25 @@ return array(
'Members' => 'Участники',
'Shared project' => 'Общие/публичные проекты',
'Project managers' => 'Менеджер проекта',
'Gantt chart for all projects' => 'Диаграмма Гантта для всех проектов',
'Gantt chart for all projects' => 'Диаграмма Ганта для всех проектов',
'Projects list' => 'Список проектов',
'Gantt chart for this project' => 'Диаграмма Гантта для этого проекта',
'Gantt chart for this project' => 'Диаграмма Ганта для этого проекта',
'Project board' => 'Доска проекта',
'End date:' => 'Дата завершения:',
'There is no start date or end date for this project.' => 'В проекте не указаны дата начала или завершения.',
'Projects Gantt chart' => 'Диаграмма Гантта проектов',
'Projects Gantt chart' => 'Диаграмма Ганта проектов',
'Start date: %s' => 'Дата начала: %s',
'End date: %s' => 'Дата завершения: %s',
'Link type' => 'Тип ссылки',
'Change task color when using a specific task link' => 'Изменение цвета задач при использовании ссылки на определенные задачи',
'Task link creation or modification' => 'Ссылка на создание или модификацию задачи',
'Login with my Gitlab Account' => 'Авторизоваться через аккаунт Gitlab',
'Milestone' => 'Веха',
'Gitlab Authentication' => 'Авторизация через Gitlab',
'Help on Gitlab authentication' => 'Помощь а авторизации через Gitlab',
'Gitlab Id' => 'Gitlab Id',
'Gitlab Account' => 'Аккаунт Gitlab',
'Link my Gitlab Account' => 'Привязать аккаунт Gitlab',
'Unlink my Gitlab Account' => 'Отвязать аккаунт Gitlab',
'Documentation: %s' => 'Документация: %s',
'Switch to the Gantt chart view' => 'Переключиться в режим диаграммы Гантта',
'Switch to the Gantt chart view' => 'Переключиться в режим диаграммы Ганта',
'Reset the search/filter box' => 'Сбросить поиск/фильтр',
'Documentation' => 'Документация',
'Table of contents' => 'Содержание',
'Gantt' => 'Гантт',
'Gantt' => 'Гант',
'Author' => 'Автор',
'Version' => 'Версия',
'Plugins' => 'Плагины',
@ -1040,8 +1019,8 @@ return array(
'Your account is locked for %d minutes' => 'Ваш аккаунт заблокирован на %d минут',
'Invalid captcha' => 'Неверный код подтверждения',
'The name must be unique' => 'Имя должно быть уникальным',
'View all groups' => 'Просмотр всех группы',
'View group members' => 'Просмотр всех группы участников группы',
'View all groups' => 'Просмотр всех групп',
'View group members' => 'Просмотр участников группы',
'There is no user available.' => 'Нет доступных пользователей.',
'Do you really want to remove the user "%s" from the group "%s"?' => 'Вы действительно хотите удалить пользователя "%s" из группы "%s"?',
'There is no group.' => 'Нет созданных групп.',
@ -1076,46 +1055,81 @@ return array(
'Estimated Time' => 'Запланировано времени',
'Actual Time' => 'Затрачено времени',
'Estimated vs actual time' => 'Запланировано и реально затрачено времени',
// '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' => '',
// 'Time-based One-time Password Algorithm' => '',
// 'Two-Factor Provider: ' => '',
// 'Disable two-factor authentication' => '',
// 'Enable two-factor authentication' => '',
// 'There is no integration registered at the moment.' => '',
// 'Password Reset for Kanboard' => '',
// 'Forgot password?' => '',
// 'Enable "Forget Password"' => '',
// 'Password Reset' => '',
// 'New password' => '',
// 'Change Password' => '',
// 'To reset your password click on this link:' => '',
// 'Last Password Reset' => '',
// 'The password has never been reinitialized.' => '',
// 'Creation' => '',
// 'Expiration' => '',
// 'Password reset history' => '',
// 'All tasks of the column "%s" and the swimlane "%s" have been closed successfully.' => '',
// '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.' => '',
// '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' => '',
// 'Project owner: ' => '',
// 'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => '',
// 'Project owner' => '',
// 'Those dates are useful for the project Gantt chart.' => '',
// 'Private projects do not have users and groups management.' => '',
// 'There is no project member.' => '',
// 'Priority' => '',
// 'Task priority' => '',
// 'General' => '',
// 'Dates' => '',
// 'Default priority' => '',
// 'Lowest priority' => '',
// 'Highest priority' => '',
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
// 'Priority: %d' => '',
'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' => 'Закрыть задачу в выбранной колонке',
'Time-based One-time Password Algorithm' => 'Зависимый от времени, одноразовый алгоритм пароля',
'Two-Factor Provider: ' => 'Провайдер двух-факторной авторизации: ',
'Disable two-factor authentication' => 'Отключить двух-факторную авторизацию',
'Enable two-factor authentication' => 'Включить двух-факторную авторизацию',
'There is no integration registered at the moment.' => 'Интеграции в данный момент не зарегистрированы.',
'Password Reset for Kanboard' => 'Сброс пароля для Kanboard',
'Forgot password?' => 'Забыли пароль?',
'Enable "Forget Password"' => 'Включить возможность восстановления пароля',
'Password Reset' => 'Сброс пароля',
'New password' => 'Новый пароль',
'Change Password' => 'Изменить пароль',
'To reset your password click on this link:' => 'Чтобы изменить пароль нажмите на эту ссылку:',
'Last Password Reset' => 'Последний сброс пароля',
'The password has never been reinitialized.' => 'Пароль никогда не был сброшен.',
'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.' => '%d задач в колонке "%s" и дорожке "%s" будут закрыты.',
'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' => 'Мой профиль',
'Project owner: ' => 'Владелец проекта:',
'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => 'Идентификатор проекта не обязателен и должен содержать буквенно-цифровые символы, пример: MYPROJECT',
'Project owner' => 'Владелец проекта',
'Those dates are useful for the project Gantt chart.' => 'Эти даты используются для диаграммы Ганта проекта.',
'Private projects do not have users and groups management.' => 'Приватные проекты не имеют управления пользователями и группами.',
'There is no project member.' => 'Нет участников проекта.',
'Priority' => 'Приоритет',
'Task priority' => 'Приоритет задачи',
'General' => 'Общее',
'Dates' => 'Даты',
'Default priority' => 'Приоритет по-умолчанию',
'Lowest priority' => 'Наименьший приоритет',
'Highest priority' => 'Наивысший приоритет',
'If you put zero to the low and high priority, this feature will be disabled.' => 'Если Вы введете 0 для наименьшего и наивысшего приоритета, этот функционал будет отключен.',
'Priority: %d' => 'Приоритет: %d',
'Close a task when there is no activity' => 'Закрывать задачу, когда нет активности',
'Duration in days' => 'Длительность в днях',
'Send email when there is no activity on a task' => 'Отправлять email, когда активность по задаче отсутствует',
'List of external links' => 'Список внешних ссылок',
'Unable to fetch link information.' => 'Не удалось получить информацию о ссылке',
'Daily background job for tasks' => 'Ежедневные фоновые работы для задач',
'Auto' => 'Авто',
'Related' => 'Связано',
'Attachment' => 'Вложение',
'Title not found' => 'Заголовок не найден',
'Web Link' => 'Web-ссылка',
'External links' => 'Внешние ссылки',
'Add external link' => 'Добавить внешнюю ссылку',
'Type' => 'Тип',
'Dependency' => 'Зависимость',
'View internal links' => 'Просмотр внутренних ссылок',
'View external links' => 'Просмотр внешних ссылок',
'Add internal link' => 'Добавить внутреннюю ссылку',
'Add a new external link' => 'Добавить новую внешнюю ссылку',
'Edit external link' => 'Изменить внешнюю ссылку',
'External link' => 'Внешняя ссылка',
'Copy and paste your link here...' => 'Скопируйте и вставьте вашу ссылку здесь',
'URL' => 'URL',
'There is no external link for the moment.' => 'На данный момент внешние ссылки отсутствуют',
'Internal links' => 'Внутренние ссылки',
'There is no internal link for the moment.' => 'На данные момент внутреннии ссылки отсутствуют',
'Assign to me' => 'Связать со мной',
'Me' => 'Мне',
'Do not duplicate anything' => 'Не дублировать ничего',
'Projects management' => 'Управление проектами',
'Users management' => 'Управление пользователями',
'Groups management' => 'Управление группами',
'Create from another project' => 'Создать из другого проекта',
'View all sub-tasks' => 'Просмотр всех подзадач'
);

View File

@ -260,9 +260,6 @@ return array(
// 'External authentication failed' => '',
// 'Your external account is linked to your profile successfully.' => '',
'Email' => 'E-mail',
'Link my Google Account' => 'Poveži sa Google nalogom',
'Unlink my Google Account' => 'Ukini vezu sa Google nalogom',
'Login with my Google Account' => 'Prijavi se preko Google naloga',
'Project not found.' => 'Projekat nije pronađen.',
'Task removed successfully.' => 'Zadatak uspešno uklonjen.',
'Unable to remove this task.' => 'Nemoguće uklanjanje zadatka.',
@ -327,9 +324,6 @@ return array(
'Maximum size: ' => 'Maksimalna veličina: ',
'Unable to upload the file.' => 'Nije moguće snimiti fajl.',
'Display another project' => 'Prikaži drugi projekat',
'Login with my Github Account' => 'Zaloguj przy użyciu konta Github',
'Link my Github Account' => 'Podłącz konto Github',
'Unlink my Github Account' => 'Odłącz konto Github',
'Created by %s' => 'Kreirao %s',
'Last modified on %B %e, %Y at %k:%M %p' => 'Poslednja izmena %e %B %Y o %k:%M',
'Tasks Export' => 'Izvoz zadataka',
@ -395,8 +389,6 @@ return array(
'Change password' => 'Izmeni lozinku',
'Password modification' => 'Izmena lozinke',
'External authentications' => 'Spoljne akcije',
'Google Account' => 'Google nalog',
'Github Account' => 'Github nalog',
'Never connected.' => 'Bez konekcija.',
'No account linked.' => 'Bez povezanih naloga.',
'Account linked.' => 'Nalog povezan.',
@ -846,10 +838,6 @@ return array(
// 'This chart show the average lead and cycle time for the last %d tasks over the time.' => '',
// 'Average time into each column' => '',
// 'Lead and cycle time' => '',
// 'Google Authentication' => '',
// 'Help on Google authentication' => '',
// 'Github Authentication' => '',
// 'Help on Github authentication' => '',
// 'Lead time: ' => '',
// 'Cycle time: ' => '',
// 'Time spent into each column' => '',
@ -858,8 +846,6 @@ return array(
// 'If the task is not closed the current time is used instead of the completion date.' => '',
// 'Set automatically the start date' => '',
// 'Edit Authentication' => '',
// 'Google Id' => '',
// 'Github Id' => '',
// 'Remote user' => '',
// 'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => '',
// 'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => '',
@ -917,14 +903,7 @@ return array(
// 'Link type' => '',
// 'Change task color when using a specific task link' => '',
// 'Task link creation or modification' => '',
// 'Login with my Gitlab Account' => '',
// 'Milestone' => '',
// 'Gitlab Authentication' => '',
// 'Help on Gitlab authentication' => '',
// 'Gitlab Id' => '',
// 'Gitlab Account' => '',
// 'Link my Gitlab Account' => '',
// 'Unlink my Gitlab Account' => '',
// 'Documentation: %s' => '',
// 'Switch to the Gantt chart view' => '',
// 'Reset the search/filter box' => '',
@ -1118,4 +1097,37 @@ return array(
// 'Highest priority' => '',
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
// 'Priority: %d' => '',
// 'Close a task when there is no activity' => '',
// 'Duration in days' => '',
// 'Send email when there is no activity on a task' => '',
// 'List of external links' => '',
// 'Unable to fetch link information.' => '',
// 'Daily background job for tasks' => '',
// 'Auto' => '',
// 'Related' => '',
// 'Attachment' => '',
// 'Title not found' => '',
// 'Web Link' => '',
// 'External links' => '',
// 'Add external link' => '',
// 'Type' => '',
// 'Dependency' => '',
// 'View internal links' => '',
// 'View external links' => '',
// 'Add internal link' => '',
// 'Add a new external link' => '',
// 'Edit external link' => '',
// 'External link' => '',
// 'Copy and paste your link here...' => '',
// 'URL' => '',
// 'There is no external link for the moment.' => '',
// 'Internal links' => '',
// 'There is no internal link for the moment.' => '',
// 'Assign to me' => '',
// 'Me' => '',
// 'Do not duplicate anything' => '',
// 'Projects management' => '',
// 'Users management' => '',
// 'Groups management' => '',
// 'Create from another project' => '',
);

View File

@ -260,9 +260,6 @@ return array(
'External authentication failed' => 'Extern autentisering misslyckades',
'Your external account is linked to your profile successfully.' => 'Ditt externa konto länkades till din profil.',
'Email' => 'Epost',
'Link my Google Account' => 'Länka till mitt Google-konto',
'Unlink my Google Account' => 'Ta bort länken till mitt Google-konto',
'Login with my Google Account' => 'Logga in med mitt Google-konto',
'Project not found.' => 'Projektet kunde inte hittas',
'Task removed successfully.' => 'Uppgiften har tagits bort',
'Unable to remove this task.' => 'Kunde inte ta bort denna uppgift',
@ -327,9 +324,6 @@ return array(
'Maximum size: ' => 'Maxstorlek: ',
'Unable to upload the file.' => 'Kunde inte ladda upp filen.',
'Display another project' => 'Visa ett annat projekt',
'Login with my Github Account' => 'Logga in med mitt Github-konto',
'Link my Github Account' => 'Anslut mitt Github-konto',
'Unlink my Github Account' => 'Koppla ifrån mitt Github-konto',
'Created by %s' => 'Skapad av %s',
'Last modified on %B %e, %Y at %k:%M %p' => 'Senaste ändring %Y-%m-%d kl %H:%M',
'Tasks Export' => 'Exportera uppgifter',
@ -395,8 +389,6 @@ return array(
'Change password' => 'Byt lösenord',
'Password modification' => 'Ändra lösenord',
'External authentications' => 'Extern autentisering',
'Google Account' => 'Googlekonto',
'Github Account' => 'Githubkonto',
'Never connected.' => 'Inte ansluten.',
'No account linked.' => 'Inget konto länkat.',
'Account linked.' => 'Konto länkat.',
@ -846,10 +838,6 @@ return array(
'This chart show the average lead and cycle time for the last %d tasks over the time.' => 'Diagramet visar medel av led och cykeltid för de senaste %d uppgifterna över tiden.',
'Average time into each column' => 'Medeltidsåtgång i varje kolumn',
'Lead and cycle time' => 'Led och cykeltid',
'Google Authentication' => 'Google autentisering',
'Help on Google authentication' => 'Hjälp för Google autentisering',
'Github Authentication' => 'Github autentisering',
'Help on Github authentication' => 'Hjälp för Github autentisering',
'Lead time: ' => 'Ledtid',
'Cycle time: ' => 'Cykeltid',
'Time spent into each column' => 'Tidsåtgång per kolumn',
@ -858,8 +846,6 @@ return array(
'If the task is not closed the current time is used instead of the completion date.' => 'Om uppgiften inte är stängd används nuvarande tid istället för slutförandedatum.',
'Set automatically the start date' => 'Sätt startdatum automatiskt',
'Edit Authentication' => 'Ändra autentisering',
'Google Id' => 'Google Id',
'Github Id' => 'Github Id',
'Remote user' => 'Extern användare',
'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => 'Externa användares lösenord lagras inte i Kanboard-databasen, exempel: LDAP, Google och Github-konton.',
'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => 'Om du aktiverar boxen "Tillåt inte loginformulär" kommer inloggningsuppgifter i formuläret att ignoreras.',
@ -917,14 +903,7 @@ return array(
// 'Link type' => '',
// 'Change task color when using a specific task link' => '',
// 'Task link creation or modification' => '',
// 'Login with my Gitlab Account' => '',
// 'Milestone' => '',
// 'Gitlab Authentication' => '',
// 'Help on Gitlab authentication' => '',
// 'Gitlab Id' => '',
// 'Gitlab Account' => '',
// 'Link my Gitlab Account' => '',
// 'Unlink my Gitlab Account' => '',
// 'Documentation: %s' => '',
// 'Switch to the Gantt chart view' => '',
// 'Reset the search/filter box' => '',
@ -1118,4 +1097,37 @@ return array(
// 'Highest priority' => '',
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
// 'Priority: %d' => '',
// 'Close a task when there is no activity' => '',
// 'Duration in days' => '',
// 'Send email when there is no activity on a task' => '',
// 'List of external links' => '',
// 'Unable to fetch link information.' => '',
// 'Daily background job for tasks' => '',
// 'Auto' => '',
// 'Related' => '',
// 'Attachment' => '',
// 'Title not found' => '',
// 'Web Link' => '',
// 'External links' => '',
// 'Add external link' => '',
// 'Type' => '',
// 'Dependency' => '',
// 'View internal links' => '',
// 'View external links' => '',
// 'Add internal link' => '',
// 'Add a new external link' => '',
// 'Edit external link' => '',
// 'External link' => '',
// 'Copy and paste your link here...' => '',
// 'URL' => '',
// 'There is no external link for the moment.' => '',
// 'Internal links' => '',
// 'There is no internal link for the moment.' => '',
// 'Assign to me' => '',
// 'Me' => '',
// 'Do not duplicate anything' => '',
// 'Projects management' => '',
// 'Users management' => '',
// 'Groups management' => '',
// 'Create from another project' => '',
);

Some files were not shown because too many files have changed in this diff Show More