mirror of
https://github.com/YunoHost-Apps/kanboard_ynh.git
synced 2024-09-03 19:36:17 +02:00
Update to kanboard v1.0.27
This commit is contained in:
parent
00a82fdf05
commit
fff59a2e84
570 changed files with 9329 additions and 8452 deletions
|
@ -1,11 +1,56 @@
|
||||||
|
Version 1.0.27
|
||||||
|
--------------
|
||||||
|
|
||||||
|
New features:
|
||||||
|
|
||||||
|
* Added Markdown editor
|
||||||
|
* Added user avatars with pluggable system
|
||||||
|
- Default is a letter based avatar
|
||||||
|
- Gravatar
|
||||||
|
- Avatar Image upload
|
||||||
|
* Added Korean translation
|
||||||
|
|
||||||
|
Improvements:
|
||||||
|
|
||||||
|
* Added more logging for LDAP client
|
||||||
|
* Improve schema migration process
|
||||||
|
* Improve notification configuration form
|
||||||
|
* Handle state in OAuth2 client
|
||||||
|
* Allow to use the original template in overridden templates
|
||||||
|
* Unification of the project header
|
||||||
|
* Refactoring of Javascript code
|
||||||
|
* Improve comments design
|
||||||
|
* Improve task summary sections
|
||||||
|
* Put back the action sidebar in task view
|
||||||
|
* Added support for multiple placeholders for LDAP_USER_FILTER
|
||||||
|
* Added local file link provider
|
||||||
|
* Show configuration in settings page
|
||||||
|
* Added "?" to display list of keyboard shortcuts
|
||||||
|
* Added new keyboard shortcuts for task view
|
||||||
|
* Always display project name and task title in task views
|
||||||
|
* Improve automatic action creation
|
||||||
|
* Move notifications to the bottom of the screen
|
||||||
|
* Added the possibility to import automatic actions from another project
|
||||||
|
* Added Ajax loading icon for submit buttons
|
||||||
|
* Added support for HTTP header "X-Forwarded-Proto: https"
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
|
||||||
|
* Fix bad unique constraints in Mysql table user_has_notifications
|
||||||
|
* Force integer type for aggregated metrics (Burndown chart concat values instead of summing)
|
||||||
|
* Fixes cycle time calculation when the start date is defined in the future
|
||||||
|
* Access allowed to any tasks from the shared public board by changing the URL parameters
|
||||||
|
* Fix invalid user filter for API procedure createLdapUser()
|
||||||
|
* Ambiguous column name with very old version of Sqlite
|
||||||
|
|
||||||
Version 1.0.26
|
Version 1.0.26
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
Breaking changes:
|
Breaking changes:
|
||||||
|
|
||||||
* API procedures:
|
* API procedures:
|
||||||
- "moveColumnUp" and "moveColumnDown" are replace by "changeColumnPosition"
|
- "moveColumnUp" and "moveColumnDown" are replaced by "changeColumnPosition"
|
||||||
- "moveSwimlaneUp" and "moveSwimlaneDown" are replace by "changeSwimlanePosition"
|
- "moveSwimlaneUp" and "moveSwimlaneDown" are replaced by "changeSwimlanePosition"
|
||||||
|
|
||||||
New features:
|
New features:
|
||||||
|
|
||||||
|
|
|
@ -132,6 +132,7 @@ abstract class Base extends \Kanboard\Core\Base
|
||||||
* Set project id
|
* Set project id
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
|
* @param integer $project_id
|
||||||
* @return Base
|
* @return Base
|
||||||
*/
|
*/
|
||||||
public function setProjectId($project_id)
|
public function setProjectId($project_id)
|
||||||
|
@ -157,7 +158,7 @@ abstract class Base extends \Kanboard\Core\Base
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $name Parameter name
|
* @param string $name Parameter name
|
||||||
* @param mixed $value Value
|
* @param mixed $value Value
|
||||||
* @param Base
|
* @return Base
|
||||||
*/
|
*/
|
||||||
public function setParam($name, $value)
|
public function setParam($name, $value)
|
||||||
{
|
{
|
||||||
|
@ -271,6 +272,7 @@ abstract class Base extends \Kanboard\Core\Base
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $event
|
* @param string $event
|
||||||
* @param string $description
|
* @param string $description
|
||||||
|
* @return Base
|
||||||
*/
|
*/
|
||||||
public function addEvent($event, $description = '')
|
public function addEvent($event, $description = '')
|
||||||
{
|
{
|
||||||
|
|
|
@ -85,20 +85,22 @@ class AverageLeadCycleTimeAnalytic extends Base
|
||||||
*/
|
*/
|
||||||
private function calculateCycleTime(array &$task)
|
private function calculateCycleTime(array &$task)
|
||||||
{
|
{
|
||||||
if (empty($task['date_started'])) {
|
$end = (int) $task['date_completed'] ?: time();
|
||||||
return 0;
|
$start = (int) $task['date_started'];
|
||||||
|
|
||||||
|
// Start date can be in the future when defined with the Gantt chart
|
||||||
|
if ($start > 0 && $end > $start) {
|
||||||
|
return $end - $start;
|
||||||
}
|
}
|
||||||
|
|
||||||
$end = $task['date_completed'] ?: time();
|
return 0;
|
||||||
$start = $task['date_started'];
|
|
||||||
|
|
||||||
return $end - $start;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the 1000 last created tasks
|
* Get the 1000 last created tasks
|
||||||
*
|
*
|
||||||
* @access private
|
* @access private
|
||||||
|
* @param integer $project_id
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
private function getTasks($project_id)
|
private function getTasks($project_id)
|
||||||
|
|
|
@ -126,6 +126,7 @@ class AverageTimeSpentColumnAnalytic extends Base
|
||||||
*
|
*
|
||||||
* @access private
|
* @access private
|
||||||
* @param array $task
|
* @param array $task
|
||||||
|
* @return integer
|
||||||
*/
|
*/
|
||||||
private function getTaskTimeSpentInCurrentColumn(array &$task)
|
private function getTaskTimeSpentInCurrentColumn(array &$task)
|
||||||
{
|
{
|
||||||
|
|
|
@ -31,6 +31,7 @@ class Auth extends Base
|
||||||
} elseif ($this->isAppAuthenticated($username, $password)) {
|
} elseif ($this->isAppAuthenticated($username, $password)) {
|
||||||
$this->checkProcedurePermission(false, $method);
|
$this->checkProcedurePermission(false, $method);
|
||||||
} else {
|
} else {
|
||||||
|
$this->logger->error('API authentication failure for '.$username);
|
||||||
throw new AuthenticationFailure('Wrong credentials');
|
throw new AuthenticationFailure('Wrong credentials');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,12 +66,29 @@ class User extends \Kanboard\Core\Base
|
||||||
return $valid ? $this->user->create($values) : false;
|
return $valid ? $this->user->create($values) : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create LDAP user in the database
|
||||||
|
*
|
||||||
|
* Only "anonymous" and "proxy" LDAP authentication are supported by this method
|
||||||
|
*
|
||||||
|
* User information will be fetched from the LDAP server
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $username
|
||||||
|
* @return bool|int
|
||||||
|
*/
|
||||||
public function createLdapUser($username)
|
public function createLdapUser($username)
|
||||||
{
|
{
|
||||||
|
if (LDAP_BIND_TYPE === 'user') {
|
||||||
|
$this->logger->error('LDAP authentication "user" is not supported by this API call');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
$ldap = LdapClient::connect();
|
$ldap = LdapClient::connect();
|
||||||
$user = LdapUser::getUser($ldap, sprintf(LDAP_USER_FILTER, $username));
|
$ldap->setLogger($this->logger);
|
||||||
|
$user = LdapUser::getUser($ldap, $username);
|
||||||
|
|
||||||
if ($user === null) {
|
if ($user === null) {
|
||||||
$this->logger->info('User not found in LDAP server');
|
$this->logger->info('User not found in LDAP server');
|
||||||
|
|
|
@ -63,10 +63,12 @@ class LdapAuth extends Base implements PasswordAuthenticationProviderInterface
|
||||||
try {
|
try {
|
||||||
|
|
||||||
$client = LdapClient::connect($this->getLdapUsername(), $this->getLdapPassword());
|
$client = LdapClient::connect($this->getLdapUsername(), $this->getLdapPassword());
|
||||||
|
$client->setLogger($this->logger);
|
||||||
|
|
||||||
$user = LdapUser::getUser($client, $this->username);
|
$user = LdapUser::getUser($client, $this->username);
|
||||||
|
|
||||||
if ($user === null) {
|
if ($user === null) {
|
||||||
$this->logger->info('User not found in LDAP server');
|
$this->logger->info('User ('.$this->username.') not found in LDAP server');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,6 +76,8 @@ class LdapAuth extends Base implements PasswordAuthenticationProviderInterface
|
||||||
throw new LogicException('Username not found in LDAP profile, check the parameter LDAP_USER_ATTRIBUTE_USERNAME');
|
throw new LogicException('Username not found in LDAP profile, check the parameter LDAP_USER_ATTRIBUTE_USERNAME');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->logger->info('Authenticate user: '.$user->getDn());
|
||||||
|
|
||||||
if ($client->authenticate($user->getDn(), $this->password)) {
|
if ($client->authenticate($user->getDn(), $this->password)) {
|
||||||
$this->userInfo = $user;
|
$this->userInfo = $user;
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -11,18 +11,18 @@ use Symfony\Component\Console\Command\Command;
|
||||||
* @package console
|
* @package console
|
||||||
* @author Frederic Guillot
|
* @author Frederic Guillot
|
||||||
*
|
*
|
||||||
|
* @property \Kanboard\Export\SubtaskExport $subtaskExport
|
||||||
|
* @property \Kanboard\Export\TaskExport $taskExport
|
||||||
|
* @property \Kanboard\Export\TransitionExport $transitionExport
|
||||||
* @property \Kanboard\Model\Notification $notification
|
* @property \Kanboard\Model\Notification $notification
|
||||||
* @property \Kanboard\Model\Project $project
|
* @property \Kanboard\Model\Project $project
|
||||||
* @property \Kanboard\Model\ProjectPermission $projectPermission
|
* @property \Kanboard\Model\ProjectPermission $projectPermission
|
||||||
* @property \Kanboard\Model\ProjectAnalytic $projectAnalytic
|
|
||||||
* @property \Kanboard\Model\ProjectDailyColumnStats $projectDailyColumnStats
|
* @property \Kanboard\Model\ProjectDailyColumnStats $projectDailyColumnStats
|
||||||
* @property \Kanboard\Model\ProjectDailyStats $projectDailyStats
|
* @property \Kanboard\Model\ProjectDailyStats $projectDailyStats
|
||||||
* @property \Kanboard\Model\SubtaskExport $subtaskExport
|
|
||||||
* @property \Kanboard\Model\OverdueNotification $overdueNotification
|
|
||||||
* @property \Kanboard\Model\Task $task
|
* @property \Kanboard\Model\Task $task
|
||||||
* @property \Kanboard\Model\TaskExport $taskExport
|
|
||||||
* @property \Kanboard\Model\TaskFinder $taskFinder
|
* @property \Kanboard\Model\TaskFinder $taskFinder
|
||||||
* @property \Kanboard\Model\Transition $transition
|
* @property \Kanboard\Model\UserNotification $userNotification
|
||||||
|
* @property \Kanboard\Model\UserNotificationFilter $userNotificationFilter
|
||||||
* @property \Symfony\Component\EventDispatcher\EventDispatcher $dispatcher
|
* @property \Symfony\Component\EventDispatcher\EventDispatcher $dispatcher
|
||||||
*/
|
*/
|
||||||
abstract class Base extends Command
|
abstract class Base extends Command
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
namespace Kanboard\Console;
|
namespace Kanboard\Console;
|
||||||
|
|
||||||
|
use Kanboard\Model\Task;
|
||||||
use Symfony\Component\Console\Helper\Table;
|
use Symfony\Component\Console\Helper\Table;
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
use Symfony\Component\Console\Input\InputOption;
|
use Symfony\Component\Console\Input\InputOption;
|
||||||
|
@ -19,7 +20,7 @@ class TaskOverdueNotification extends Base
|
||||||
|
|
||||||
protected function execute(InputInterface $input, OutputInterface $output)
|
protected function execute(InputInterface $input, OutputInterface $output)
|
||||||
{
|
{
|
||||||
$tasks = $this->overdueNotification->sendOverdueTaskNotifications();
|
$tasks = $this->sendOverdueTaskNotifications();
|
||||||
|
|
||||||
if ($input->getOption('show')) {
|
if ($input->getOption('show')) {
|
||||||
$this->showTable($output, $tasks);
|
$this->showTable($output, $tasks);
|
||||||
|
@ -47,4 +48,69 @@ class TaskOverdueNotification extends Base
|
||||||
->setRows($rows)
|
->setRows($rows)
|
||||||
->render();
|
->render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send overdue tasks
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
public function sendOverdueTaskNotifications()
|
||||||
|
{
|
||||||
|
$tasks = $this->taskFinder->getOverdueTasks();
|
||||||
|
|
||||||
|
foreach ($this->groupByColumn($tasks, 'project_id') as $project_id => $project_tasks) {
|
||||||
|
$users = $this->userNotification->getUsersWithNotificationEnabled($project_id);
|
||||||
|
|
||||||
|
foreach ($users as $user) {
|
||||||
|
$this->sendUserOverdueTaskNotifications($user, $project_tasks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $tasks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send overdue tasks for a given user
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param array $user
|
||||||
|
* @param array $tasks
|
||||||
|
*/
|
||||||
|
public function sendUserOverdueTaskNotifications(array $user, array $tasks)
|
||||||
|
{
|
||||||
|
$user_tasks = array();
|
||||||
|
|
||||||
|
foreach ($tasks as $task) {
|
||||||
|
if ($this->userNotificationFilter->shouldReceiveNotification($user, array('task' => $task))) {
|
||||||
|
$user_tasks[] = $task;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! empty($user_tasks)) {
|
||||||
|
$this->userNotification->sendUserNotification(
|
||||||
|
$user,
|
||||||
|
Task::EVENT_OVERDUE,
|
||||||
|
array('tasks' => $user_tasks, 'project_name' => $tasks[0]['project_name'])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Group a collection of records by a column
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param array $collection
|
||||||
|
* @param string $column
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function groupByColumn(array $collection, $column)
|
||||||
|
{
|
||||||
|
$result = array();
|
||||||
|
|
||||||
|
foreach ($collection as $item) {
|
||||||
|
$result[$item[$column]][] = $item;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ class TransitionExport extends Base
|
||||||
|
|
||||||
protected function execute(InputInterface $input, OutputInterface $output)
|
protected function execute(InputInterface $input, OutputInterface $output)
|
||||||
{
|
{
|
||||||
$data = $this->transition->export(
|
$data = $this->transitionExport->export(
|
||||||
$input->getArgument('project_id'),
|
$input->getArgument('project_id'),
|
||||||
$input->getArgument('start_date'),
|
$input->getArgument('start_date'),
|
||||||
$input->getArgument('end_date')
|
$input->getArgument('end_date')
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
namespace Kanboard\Controller;
|
namespace Kanboard\Controller;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Automatic actions management
|
* Automatic Actions
|
||||||
*
|
*
|
||||||
* @package controller
|
* @package controller
|
||||||
* @author Frederic Guillot
|
* @author Frederic Guillot
|
||||||
|
@ -37,98 +37,6 @@ class Action extends Base
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Choose the event according to the action (step 2)
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
public function event()
|
|
||||||
{
|
|
||||||
$project = $this->getProject();
|
|
||||||
$values = $this->request->getValues();
|
|
||||||
|
|
||||||
if (empty($values['action_name']) || empty($values['project_id'])) {
|
|
||||||
$this->response->redirect($this->helper->url->to('action', 'index', array('project_id' => $project['id'])));
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->response->html($this->helper->layout->project('action/event', array(
|
|
||||||
'values' => $values,
|
|
||||||
'project' => $project,
|
|
||||||
'events' => $this->actionManager->getCompatibleEvents($values['action_name']),
|
|
||||||
'title' => t('Automatic actions')
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define action parameters (step 3)
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
public function params()
|
|
||||||
{
|
|
||||||
$project = $this->getProject();
|
|
||||||
$values = $this->request->getValues();
|
|
||||||
|
|
||||||
if (empty($values['action_name']) || empty($values['project_id']) || empty($values['event_name'])) {
|
|
||||||
$this->response->redirect($this->helper->url->to('action', 'index', array('project_id' => $project['id'])));
|
|
||||||
}
|
|
||||||
|
|
||||||
$action = $this->actionManager->getAction($values['action_name']);
|
|
||||||
$action_params = $action->getActionRequiredParameters();
|
|
||||||
|
|
||||||
if (empty($action_params)) {
|
|
||||||
$this->doCreation($project, $values + array('params' => array()));
|
|
||||||
}
|
|
||||||
|
|
||||||
$projects_list = $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId());
|
|
||||||
unset($projects_list[$project['id']]);
|
|
||||||
|
|
||||||
$this->response->html($this->helper->layout->project('action/params', array(
|
|
||||||
'values' => $values,
|
|
||||||
'action_params' => $action_params,
|
|
||||||
'columns_list' => $this->column->getList($project['id']),
|
|
||||||
'users_list' => $this->projectUserRole->getAssignableUsersList($project['id']),
|
|
||||||
'projects_list' => $projects_list,
|
|
||||||
'colors_list' => $this->color->getList(),
|
|
||||||
'categories_list' => $this->category->getList($project['id']),
|
|
||||||
'links_list' => $this->link->getList(0, false),
|
|
||||||
'project' => $project,
|
|
||||||
'title' => t('Automatic actions')
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new action (last step)
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
public function create()
|
|
||||||
{
|
|
||||||
$this->doCreation($this->getProject(), $this->request->getValues());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Save the action
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
* @param array $project Project properties
|
|
||||||
* @param array $values Form values
|
|
||||||
*/
|
|
||||||
private function doCreation(array $project, array $values)
|
|
||||||
{
|
|
||||||
list($valid, ) = $this->actionValidator->validateCreation($values);
|
|
||||||
|
|
||||||
if ($valid) {
|
|
||||||
if ($this->action->create($values) !== false) {
|
|
||||||
$this->flash->success(t('Your automatic action have been created successfully.'));
|
|
||||||
} else {
|
|
||||||
$this->flash->failure(t('Unable to create your automatic action.'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->response->redirect($this->helper->url->to('action', 'index', array('project_id' => $project['id'])));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Confirmation dialog before removing an action
|
* Confirmation dialog before removing an action
|
||||||
*
|
*
|
||||||
|
|
121
sources/app/Controller/ActionCreation.php
Normal file
121
sources/app/Controller/ActionCreation.php
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Kanboard\Controller;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action Creation
|
||||||
|
*
|
||||||
|
* @package controller
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class ActionCreation extends Base
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Show the form (step 1)
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
public function create()
|
||||||
|
{
|
||||||
|
$project = $this->getProject();
|
||||||
|
|
||||||
|
$this->response->html($this->template->render('action_creation/create', array(
|
||||||
|
'project' => $project,
|
||||||
|
'values' => array('project_id' => $project['id']),
|
||||||
|
'available_actions' => $this->actionManager->getAvailableActions(),
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Choose the event according to the action (step 2)
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
public function event()
|
||||||
|
{
|
||||||
|
$project = $this->getProject();
|
||||||
|
$values = $this->request->getValues();
|
||||||
|
|
||||||
|
if (empty($values['action_name']) || empty($values['project_id'])) {
|
||||||
|
return $this->create();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->response->html($this->template->render('action_creation/event', array(
|
||||||
|
'values' => $values,
|
||||||
|
'project' => $project,
|
||||||
|
'available_actions' => $this->actionManager->getAvailableActions(),
|
||||||
|
'events' => $this->actionManager->getCompatibleEvents($values['action_name']),
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define action parameters (step 3)
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
public function params()
|
||||||
|
{
|
||||||
|
$project = $this->getProject();
|
||||||
|
$values = $this->request->getValues();
|
||||||
|
|
||||||
|
if (empty($values['action_name']) || empty($values['project_id']) || empty($values['event_name'])) {
|
||||||
|
return $this->create();
|
||||||
|
}
|
||||||
|
|
||||||
|
$action = $this->actionManager->getAction($values['action_name']);
|
||||||
|
$action_params = $action->getActionRequiredParameters();
|
||||||
|
|
||||||
|
if (empty($action_params)) {
|
||||||
|
$this->doCreation($project, $values + array('params' => array()));
|
||||||
|
}
|
||||||
|
|
||||||
|
$projects_list = $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId());
|
||||||
|
unset($projects_list[$project['id']]);
|
||||||
|
|
||||||
|
$this->response->html($this->template->render('action_creation/params', array(
|
||||||
|
'values' => $values,
|
||||||
|
'action_params' => $action_params,
|
||||||
|
'columns_list' => $this->column->getList($project['id']),
|
||||||
|
'users_list' => $this->projectUserRole->getAssignableUsersList($project['id']),
|
||||||
|
'projects_list' => $projects_list,
|
||||||
|
'colors_list' => $this->color->getList(),
|
||||||
|
'categories_list' => $this->category->getList($project['id']),
|
||||||
|
'links_list' => $this->link->getList(0, false),
|
||||||
|
'project' => $project,
|
||||||
|
'available_actions' => $this->actionManager->getAvailableActions(),
|
||||||
|
'events' => $this->actionManager->getCompatibleEvents($values['action_name']),
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save the action (last step)
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
public function save()
|
||||||
|
{
|
||||||
|
$this->doCreation($this->getProject(), $this->request->getValues());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common method to save the action
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @param array $project Project properties
|
||||||
|
* @param array $values Form values
|
||||||
|
*/
|
||||||
|
private function doCreation(array $project, array $values)
|
||||||
|
{
|
||||||
|
list($valid, ) = $this->actionValidator->validateCreation($values);
|
||||||
|
|
||||||
|
if ($valid) {
|
||||||
|
if ($this->action->create($values) !== false) {
|
||||||
|
$this->flash->success(t('Your automatic action have been created successfully.'));
|
||||||
|
} else {
|
||||||
|
$this->flash->failure(t('Unable to create your automatic action.'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->response->redirect($this->helper->url->to('action', 'index', array('project_id' => $project['id'])));
|
||||||
|
}
|
||||||
|
}
|
38
sources/app/Controller/ActionProject.php
Normal file
38
sources/app/Controller/ActionProject.php
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Kanboard\Controller;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Duplicate automatic action from another project
|
||||||
|
*
|
||||||
|
* @package controller
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class ActionProject extends Base
|
||||||
|
{
|
||||||
|
public function project()
|
||||||
|
{
|
||||||
|
$project = $this->getProject();
|
||||||
|
$projects = $this->projectUserRole->getProjectsByUser($this->userSession->getId());
|
||||||
|
unset($projects[$project['id']]);
|
||||||
|
|
||||||
|
$this->response->html($this->template->render('action_project/project', array(
|
||||||
|
'project' => $project,
|
||||||
|
'projects_list' => $projects,
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function save()
|
||||||
|
{
|
||||||
|
$project = $this->getProject();
|
||||||
|
$src_project_id = $this->request->getValue('src_project_id');
|
||||||
|
|
||||||
|
if ($this->action->duplicate($src_project_id, $project['id'])) {
|
||||||
|
$this->flash->success(t('Actions duplicated successfully.'));
|
||||||
|
} else {
|
||||||
|
$this->flash->failure(t('Unable to duplicate actions.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->response->redirect($this->helper->url->to('action', 'index', array('project_id' => $project['id'])));
|
||||||
|
}
|
||||||
|
}
|
|
@ -38,6 +38,7 @@ class Activity extends Base
|
||||||
$this->response->html($this->helper->layout->task('activity/task', array(
|
$this->response->html($this->helper->layout->task('activity/task', array(
|
||||||
'title' => $task['title'],
|
'title' => $task['title'],
|
||||||
'task' => $task,
|
'task' => $task,
|
||||||
|
'project' => $this->project->getById($task['project_id']),
|
||||||
'events' => $this->projectActivity->getTask($task['id']),
|
'events' => $this->projectActivity->getTask($task['id']),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,8 +44,7 @@ class Analytic extends Base
|
||||||
public function compareHours()
|
public function compareHours()
|
||||||
{
|
{
|
||||||
$project = $this->getProject();
|
$project = $this->getProject();
|
||||||
$params = $this->getProjectFilters('analytic', 'compareHours');
|
$query = $this->taskFilter->create()->filterByProject($project['id'])->getQuery();
|
||||||
$query = $this->taskFilter->create()->filterByProject($params['project']['id'])->getQuery();
|
|
||||||
|
|
||||||
$paginator = $this->paginator
|
$paginator = $this->paginator
|
||||||
->setUrl('analytic', 'compareHours', array('project_id' => $project['id']))
|
->setUrl('analytic', 'compareHours', array('project_id' => $project['id']))
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
namespace Kanboard\Controller;
|
namespace Kanboard\Controller;
|
||||||
|
|
||||||
|
use Kanboard\Model\Project as ProjectModel;
|
||||||
use Kanboard\Model\Subtask as SubtaskModel;
|
use Kanboard\Model\Subtask as SubtaskModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -19,13 +20,14 @@ class App extends Base
|
||||||
* @param integer $user_id
|
* @param integer $user_id
|
||||||
* @param string $action
|
* @param string $action
|
||||||
* @param integer $max
|
* @param integer $max
|
||||||
|
* @return \Kanboard\Core\Paginator
|
||||||
*/
|
*/
|
||||||
private function getProjectPaginator($user_id, $action, $max)
|
private function getProjectPaginator($user_id, $action, $max)
|
||||||
{
|
{
|
||||||
return $this->paginator
|
return $this->paginator
|
||||||
->setUrl('app', $action, array('pagination' => 'projects', 'user_id' => $user_id))
|
->setUrl('app', $action, array('pagination' => 'projects', 'user_id' => $user_id))
|
||||||
->setMax($max)
|
->setMax($max)
|
||||||
->setOrder('name')
|
->setOrder(ProjectModel::TABLE.'.name')
|
||||||
->setQuery($this->project->getQueryColumnStats($this->projectPermission->getActiveProjectIds($user_id)))
|
->setQuery($this->project->getQueryColumnStats($this->projectPermission->getActiveProjectIds($user_id)))
|
||||||
->calculateOnlyIf($this->request->getStringParam('pagination') === 'projects');
|
->calculateOnlyIf($this->request->getStringParam('pagination') === 'projects');
|
||||||
}
|
}
|
||||||
|
@ -37,6 +39,7 @@ class App extends Base
|
||||||
* @param integer $user_id
|
* @param integer $user_id
|
||||||
* @param string $action
|
* @param string $action
|
||||||
* @param integer $max
|
* @param integer $max
|
||||||
|
* @return \Kanboard\Core\Paginator
|
||||||
*/
|
*/
|
||||||
private function getTaskPaginator($user_id, $action, $max)
|
private function getTaskPaginator($user_id, $action, $max)
|
||||||
{
|
{
|
||||||
|
@ -55,6 +58,7 @@ class App extends Base
|
||||||
* @param integer $user_id
|
* @param integer $user_id
|
||||||
* @param string $action
|
* @param string $action
|
||||||
* @param integer $max
|
* @param integer $max
|
||||||
|
* @return \Kanboard\Core\Paginator
|
||||||
*/
|
*/
|
||||||
private function getSubtaskPaginator($user_id, $action, $max)
|
private function getSubtaskPaginator($user_id, $action, $max)
|
||||||
{
|
{
|
||||||
|
|
|
@ -14,6 +14,8 @@ class Auth extends Base
|
||||||
* Display the form login
|
* Display the form login
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
|
* @param array $values
|
||||||
|
* @param array $errors
|
||||||
*/
|
*/
|
||||||
public function login(array $values = array(), array $errors = array())
|
public function login(array $values = array(), array $errors = array())
|
||||||
{
|
{
|
||||||
|
|
92
sources/app/Controller/AvatarFile.php
Normal file
92
sources/app/Controller/AvatarFile.php
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Kanboard\Controller;
|
||||||
|
|
||||||
|
use Kanboard\Core\ObjectStorage\ObjectStorageException;
|
||||||
|
use Kanboard\Core\Thumbnail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Avatar File Controller
|
||||||
|
*
|
||||||
|
* @package controller
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class AvatarFile extends Base
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display avatar page
|
||||||
|
*/
|
||||||
|
public function show()
|
||||||
|
{
|
||||||
|
$user = $this->getUser();
|
||||||
|
|
||||||
|
$this->response->html($this->helper->layout->user('avatar_file/show', array(
|
||||||
|
'user' => $user,
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upload Avatar
|
||||||
|
*/
|
||||||
|
public function upload()
|
||||||
|
{
|
||||||
|
$user = $this->getUser();
|
||||||
|
|
||||||
|
if (! $this->avatarFile->uploadFile($user['id'], $this->request->getFileInfo('avatar'))) {
|
||||||
|
$this->flash->failure(t('Unable to upload the file.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->response->redirect($this->helper->url->to('AvatarFile', 'show', array('user_id' => $user['id'])));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove Avatar image
|
||||||
|
*/
|
||||||
|
public function remove()
|
||||||
|
{
|
||||||
|
$this->checkCSRFParam();
|
||||||
|
$user = $this->getUser();
|
||||||
|
$this->avatarFile->remove($user['id']);
|
||||||
|
$this->response->redirect($this->helper->url->to('AvatarFile', 'show', array('user_id' => $user['id'])));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show Avatar image (public)
|
||||||
|
*/
|
||||||
|
public function image()
|
||||||
|
{
|
||||||
|
$user_id = $this->request->getIntegerParam('user_id');
|
||||||
|
$size = $this->request->getStringParam('size', 48);
|
||||||
|
$filename = $this->avatarFile->getFilename($user_id);
|
||||||
|
$etag = md5($filename.$size);
|
||||||
|
|
||||||
|
$this->response->cache(365 * 86400, $etag);
|
||||||
|
$this->response->contentType('image/jpeg');
|
||||||
|
|
||||||
|
if ($this->request->getHeader('If-None-Match') !== '"'.$etag.'"') {
|
||||||
|
$this->render($filename, $size);
|
||||||
|
} else {
|
||||||
|
$this->response->status(304);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render thumbnail from object storage
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @param string $filename
|
||||||
|
* @param integer $size
|
||||||
|
*/
|
||||||
|
private function render($filename, $size)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$blob = $this->objectStorage->get($filename);
|
||||||
|
|
||||||
|
Thumbnail::createFromString($blob)
|
||||||
|
->resize($size, $size)
|
||||||
|
->toOutput();
|
||||||
|
} catch (ObjectStorageException $e) {
|
||||||
|
$this->logger->error($e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -287,60 +287,4 @@ abstract class Base extends \Kanboard\Core\Base
|
||||||
|
|
||||||
return $subtask;
|
return $subtask;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Common method to get project filters
|
|
||||||
*
|
|
||||||
* @access protected
|
|
||||||
* @param string $controller
|
|
||||||
* @param string $action
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
protected function getProjectFilters($controller, $action)
|
|
||||||
{
|
|
||||||
$project = $this->getProject();
|
|
||||||
$search = $this->request->getStringParam('search', $this->userSession->getFilters($project['id']));
|
|
||||||
$board_selector = $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId());
|
|
||||||
unset($board_selector[$project['id']]);
|
|
||||||
|
|
||||||
$filters = array(
|
|
||||||
'controller' => $controller,
|
|
||||||
'action' => $action,
|
|
||||||
'project_id' => $project['id'],
|
|
||||||
'search' => urldecode($search),
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->userSession->setFilters($project['id'], $filters['search']);
|
|
||||||
|
|
||||||
return array(
|
|
||||||
'project' => $project,
|
|
||||||
'board_selector' => $board_selector,
|
|
||||||
'filters' => $filters,
|
|
||||||
'title' => $project['name'],
|
|
||||||
'description' => $this->getProjectDescription($project),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get project description
|
|
||||||
*
|
|
||||||
* @access protected
|
|
||||||
* @param array &$project
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
|
|
||||||
if (! empty($project['description'])) {
|
|
||||||
$description .= '***'.PHP_EOL.PHP_EOL;
|
|
||||||
$description .= $project['description'];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$description = $project['description'];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $description;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,16 +47,17 @@ class Board extends Base
|
||||||
*/
|
*/
|
||||||
public function show()
|
public function show()
|
||||||
{
|
{
|
||||||
$params = $this->getProjectFilters('board', 'show');
|
$project = $this->getProject();
|
||||||
|
$search = $this->helper->projectHeader->getSearchQuery($project);
|
||||||
|
|
||||||
$this->response->html($this->helper->layout->app('board/view_private', array(
|
$this->response->html($this->helper->layout->app('board/view_private', array(
|
||||||
'categories_list' => $this->category->getList($params['project']['id'], false),
|
'swimlanes' => $this->taskFilter->search($search)->getBoard($project['id']),
|
||||||
'users_list' => $this->projectUserRole->getAssignableUsersList($params['project']['id'], false),
|
'project' => $project,
|
||||||
'custom_filters_list' => $this->customFilter->getAll($params['project']['id'], $this->userSession->getId()),
|
'title' => $project['name'],
|
||||||
'swimlanes' => $this->taskFilter->search($params['filters']['search'])->getBoard($params['project']['id']),
|
'description' => $this->helper->projectHeader->getDescription($project),
|
||||||
'board_private_refresh_interval' => $this->config->get('board_private_refresh_interval'),
|
'board_private_refresh_interval' => $this->config->get('board_private_refresh_interval'),
|
||||||
'board_highlight_period' => $this->config->get('board_highlight_period'),
|
'board_highlight_period' => $this->config->get('board_highlight_period'),
|
||||||
) + $params));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -77,6 +77,7 @@ class BoardTooltip extends Base
|
||||||
$task = $this->getTask();
|
$task = $this->getTask();
|
||||||
|
|
||||||
$this->response->html($this->template->render('board/tooltip_comments', array(
|
$this->response->html($this->template->render('board/tooltip_comments', array(
|
||||||
|
'task' => $task,
|
||||||
'comments' => $this->comment->getAll($task['id'], $this->userSession->getCommentSorting())
|
'comments' => $this->comment->getAll($task['id'], $this->userSession->getCommentSorting())
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,9 +20,14 @@ class Calendar extends Base
|
||||||
*/
|
*/
|
||||||
public function show()
|
public function show()
|
||||||
{
|
{
|
||||||
|
$project = $this->getProject();
|
||||||
|
|
||||||
$this->response->html($this->helper->layout->app('calendar/show', array(
|
$this->response->html($this->helper->layout->app('calendar/show', array(
|
||||||
|
'project' => $project,
|
||||||
|
'title' => $project['name'],
|
||||||
|
'description' => $this->helper->projectHeader->getDescription($project),
|
||||||
'check_interval' => $this->config->get('board_private_refresh_interval'),
|
'check_interval' => $this->config->get('board_private_refresh_interval'),
|
||||||
) + $this->getProjectFilters('calendar', 'show')));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -76,6 +76,8 @@ class Column extends Base
|
||||||
* Display a form to edit a column
|
* Display a form to edit a column
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
|
* @param array $values
|
||||||
|
* @param array $errors
|
||||||
*/
|
*/
|
||||||
public function edit(array $values = array(), array $errors = array())
|
public function edit(array $values = array(), array $errors = array())
|
||||||
{
|
{
|
||||||
|
|
|
@ -47,11 +47,10 @@ class Comment extends Base
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->response->html($this->helper->layout->task('comment/create', array(
|
$this->response->html($this->template->render('comment/create', array(
|
||||||
'values' => $values,
|
'values' => $values,
|
||||||
'errors' => $errors,
|
'errors' => $errors,
|
||||||
'task' => $task,
|
'task' => $task,
|
||||||
'title' => t('Add a comment'),
|
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +89,7 @@ class Comment extends Base
|
||||||
$task = $this->getTask();
|
$task = $this->getTask();
|
||||||
$comment = $this->getComment();
|
$comment = $this->getComment();
|
||||||
|
|
||||||
$this->response->html($this->helper->layout->task('comment/edit', array(
|
$this->response->html($this->template->render('comment/edit', array(
|
||||||
'values' => empty($values) ? $comment : $values,
|
'values' => empty($values) ? $comment : $values,
|
||||||
'errors' => $errors,
|
'errors' => $errors,
|
||||||
'comment' => $comment,
|
'comment' => $comment,
|
||||||
|
@ -135,7 +134,7 @@ class Comment extends Base
|
||||||
$task = $this->getTask();
|
$task = $this->getTask();
|
||||||
$comment = $this->getComment();
|
$comment = $this->getComment();
|
||||||
|
|
||||||
$this->response->html($this->helper->layout->task('comment/remove', array(
|
$this->response->html($this->template->render('comment/remove', array(
|
||||||
'comment' => $comment,
|
'comment' => $comment,
|
||||||
'task' => $task,
|
'task' => $task,
|
||||||
'title' => t('Remove a comment')
|
'title' => t('Remove a comment')
|
||||||
|
|
|
@ -61,6 +61,8 @@ class Config extends Base
|
||||||
{
|
{
|
||||||
$this->response->html($this->helper->layout->config('config/about', array(
|
$this->response->html($this->helper->layout->config('config/about', array(
|
||||||
'db_size' => $this->config->getDatabaseSize(),
|
'db_size' => $this->config->getDatabaseSize(),
|
||||||
|
'db_version' => $this->db->getDriver()->getDatabaseVersion(),
|
||||||
|
'user_agent' => $this->request->getServerVariable('HTTP_USER_AGENT'),
|
||||||
'title' => t('Settings').' > '.t('About'),
|
'title' => t('Settings').' > '.t('About'),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,31 +5,13 @@ namespace Kanboard\Controller;
|
||||||
use Parsedown;
|
use Parsedown;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Documentation controller
|
* Documentation Viewer
|
||||||
*
|
*
|
||||||
* @package controller
|
* @package controller
|
||||||
* @author Frederic Guillot
|
* @author Frederic Guillot
|
||||||
*/
|
*/
|
||||||
class Doc extends Base
|
class Doc extends Base
|
||||||
{
|
{
|
||||||
private function readFile($filename)
|
|
||||||
{
|
|
||||||
$url = $this->helper->url;
|
|
||||||
$data = file_get_contents($filename);
|
|
||||||
list($title, ) = explode("\n", $data, 2);
|
|
||||||
|
|
||||||
$replaceUrl = function (array $matches) use ($url) {
|
|
||||||
return '('.$url->to('doc', 'show', array('file' => str_replace('.markdown', '', $matches[1]))).')';
|
|
||||||
};
|
|
||||||
|
|
||||||
$content = preg_replace_callback('/\((.*.markdown)\)/', $replaceUrl, $data);
|
|
||||||
|
|
||||||
return array(
|
|
||||||
'content' => Parsedown::instance()->text($content),
|
|
||||||
'title' => $title !== 'Documentation' ? t('Documentation: %s', $title) : $title,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function show()
|
public function show()
|
||||||
{
|
{
|
||||||
$page = $this->request->getStringParam('file', 'index');
|
$page = $this->request->getStringParam('file', 'index');
|
||||||
|
@ -38,20 +20,73 @@ class Doc extends Base
|
||||||
$page = 'index';
|
$page = 'index';
|
||||||
}
|
}
|
||||||
|
|
||||||
$filenames = array(__DIR__.'/../../doc/'.$page.'.markdown');
|
|
||||||
$filename = __DIR__.'/../../doc/index.markdown';
|
|
||||||
|
|
||||||
if ($this->config->getCurrentLanguage() === 'fr_FR') {
|
if ($this->config->getCurrentLanguage() === 'fr_FR') {
|
||||||
array_unshift($filenames, __DIR__.'/../../doc/fr/'.$page.'.markdown');
|
$filename = __DIR__.'/../../doc/fr/' . $page . '.markdown';
|
||||||
|
} else {
|
||||||
|
$filename = __DIR__ . '/../../doc/' . $page . '.markdown';
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($filenames as $file) {
|
if (!file_exists($filename)) {
|
||||||
if (file_exists($file)) {
|
$filename = __DIR__.'/../../doc/index.markdown';
|
||||||
$filename = $file;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->response->html($this->helper->layout->app('doc/show', $this->readFile($filename)));
|
$this->response->html($this->helper->layout->app('doc/show', $this->render($filename)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display keyboard shortcut
|
||||||
|
*/
|
||||||
|
public function shortcuts()
|
||||||
|
{
|
||||||
|
$this->response->html($this->template->render('config/keyboard_shortcuts'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare Markdown file
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @param string $filename
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function render($filename)
|
||||||
|
{
|
||||||
|
$data = file_get_contents($filename);
|
||||||
|
$content = preg_replace_callback('/\((.*.markdown)\)/', array($this, 'replaceMarkdownUrl'), $data);
|
||||||
|
$content = preg_replace_callback('/\((screenshots.*\.png)\)/', array($this, 'replaceImageUrl'), $content);
|
||||||
|
|
||||||
|
list($title, ) = explode("\n", $data, 2);
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'content' => Parsedown::instance()->text($content),
|
||||||
|
'title' => $title !== 'Documentation' ? t('Documentation: %s', $title) : $title,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Regex callback to replace Markdown links
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param array $matches
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function replaceMarkdownUrl(array $matches)
|
||||||
|
{
|
||||||
|
return '('.$this->helper->url->to('doc', 'show', array('file' => str_replace('.markdown', '', $matches[1]))).')';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Regex callback to replace image links
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param array $matches
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function replaceImageUrl(array $matches)
|
||||||
|
{
|
||||||
|
if ($this->config->getCurrentLanguage() === 'fr_FR') {
|
||||||
|
return '('.$this->helper->url->base().'doc/fr/'.$matches[1].')';
|
||||||
|
}
|
||||||
|
|
||||||
|
return '('.$this->helper->url->base().'doc/'.$matches[1].')';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,6 +80,6 @@ class Export extends Base
|
||||||
*/
|
*/
|
||||||
public function transitions()
|
public function transitions()
|
||||||
{
|
{
|
||||||
$this->common('transition', 'export', t('Transitions'), 'transitions', t('Task transitions export'));
|
$this->common('transitionExport', 'export', t('Transitions'), 'transitions', t('Task transitions export'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,9 +66,16 @@ class FileViewer extends Base
|
||||||
*/
|
*/
|
||||||
public function image()
|
public function image()
|
||||||
{
|
{
|
||||||
try {
|
|
||||||
$file = $this->getFile();
|
$file = $this->getFile();
|
||||||
|
$etag = md5($file['path']);
|
||||||
$this->response->contentType($this->helper->file->getImageMimeType($file['name']));
|
$this->response->contentType($this->helper->file->getImageMimeType($file['name']));
|
||||||
|
$this->response->cache(5 * 86400, $etag);
|
||||||
|
|
||||||
|
if ($this->request->getHeader('If-None-Match') === '"'.$etag.'"') {
|
||||||
|
return $this->response->status(304);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
$this->objectStorage->output($file['path']);
|
$this->objectStorage->output($file['path']);
|
||||||
} catch (ObjectStorageException $e) {
|
} catch (ObjectStorageException $e) {
|
||||||
$this->logger->error($e->getMessage());
|
$this->logger->error($e->getMessage());
|
||||||
|
@ -82,12 +89,21 @@ class FileViewer extends Base
|
||||||
*/
|
*/
|
||||||
public function thumbnail()
|
public function thumbnail()
|
||||||
{
|
{
|
||||||
$this->response->contentType('image/jpeg');
|
|
||||||
|
|
||||||
try {
|
|
||||||
$file = $this->getFile();
|
$file = $this->getFile();
|
||||||
$model = $file['model'];
|
$model = $file['model'];
|
||||||
$this->objectStorage->output($this->$model->getThumbnailPath($file['path']));
|
$filename = $this->$model->getThumbnailPath($file['path']);
|
||||||
|
$etag = md5($filename);
|
||||||
|
|
||||||
|
$this->response->cache(5 * 86400, $etag);
|
||||||
|
$this->response->contentType('image/jpeg');
|
||||||
|
|
||||||
|
if ($this->request->getHeader('If-None-Match') === '"'.$etag.'"') {
|
||||||
|
return $this->response->status(304);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
$this->objectStorage->output($filename);
|
||||||
} catch (ObjectStorageException $e) {
|
} catch (ObjectStorageException $e) {
|
||||||
$this->logger->error($e->getMessage());
|
$this->logger->error($e->getMessage());
|
||||||
|
|
||||||
|
|
|
@ -54,8 +54,9 @@ class Gantt extends Base
|
||||||
*/
|
*/
|
||||||
public function project()
|
public function project()
|
||||||
{
|
{
|
||||||
$params = $this->getProjectFilters('gantt', 'project');
|
$project = $this->getProject();
|
||||||
$filter = $this->taskFilterGanttFormatter->search($params['filters']['search'])->filterByProject($params['project']['id']);
|
$search = $this->helper->projectHeader->getSearchQuery($project);
|
||||||
|
$filter = $this->taskFilterGanttFormatter->search($search)->filterByProject($project['id']);
|
||||||
$sorting = $this->request->getStringParam('sorting', 'board');
|
$sorting = $this->request->getStringParam('sorting', 'board');
|
||||||
|
|
||||||
if ($sorting === 'date') {
|
if ($sorting === 'date') {
|
||||||
|
@ -64,8 +65,10 @@ class Gantt extends Base
|
||||||
$filter->getQuery()->asc('column_position')->asc(TaskModel::TABLE.'.position');
|
$filter->getQuery()->asc('column_position')->asc(TaskModel::TABLE.'.position');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->response->html($this->helper->layout->app('gantt/project', $params + array(
|
$this->response->html($this->helper->layout->app('gantt/project', array(
|
||||||
'users_list' => $this->projectUserRole->getAssignableUsersList($params['project']['id'], false),
|
'project' => $project,
|
||||||
|
'title' => $project['name'],
|
||||||
|
'description' => $this->helper->projectHeader->getDescription($project),
|
||||||
'sorting' => $sorting,
|
'sorting' => $sorting,
|
||||||
'tasks' => $filter->format(),
|
'tasks' => $filter->format(),
|
||||||
)));
|
)));
|
||||||
|
|
|
@ -19,22 +19,23 @@ class Listing extends Base
|
||||||
*/
|
*/
|
||||||
public function show()
|
public function show()
|
||||||
{
|
{
|
||||||
$params = $this->getProjectFilters('listing', 'show');
|
$project = $this->getProject();
|
||||||
$query = $this->taskFilter->search($params['filters']['search'])->filterByProject($params['project']['id'])->getQuery();
|
$search = $this->helper->projectHeader->getSearchQuery($project);
|
||||||
|
$query = $this->taskFilter->search($search)->filterByProject($project['id'])->getQuery();
|
||||||
|
|
||||||
$paginator = $this->paginator
|
$paginator = $this->paginator
|
||||||
->setUrl('listing', 'show', array('project_id' => $params['project']['id']))
|
->setUrl('listing', 'show', array('project_id' => $project['id']))
|
||||||
->setMax(30)
|
->setMax(30)
|
||||||
->setOrder(TaskModel::TABLE.'.id')
|
->setOrder(TaskModel::TABLE.'.id')
|
||||||
->setDirection('DESC')
|
->setDirection('DESC')
|
||||||
->setQuery($query)
|
->setQuery($query)
|
||||||
->calculate();
|
->calculate();
|
||||||
|
|
||||||
$this->response->html($this->helper->layout->app('listing/show', $params + array(
|
$this->response->html($this->helper->layout->app('listing/show', array(
|
||||||
|
'project' => $project,
|
||||||
|
'title' => $project['name'],
|
||||||
|
'description' => $this->helper->projectHeader->getDescription($project),
|
||||||
'paginator' => $paginator,
|
'paginator' => $paginator,
|
||||||
'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()),
|
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
namespace Kanboard\Controller;
|
namespace Kanboard\Controller;
|
||||||
|
|
||||||
|
use Kanboard\Core\Security\OAuthAuthenticationProviderInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* OAuth controller
|
* OAuth controller
|
||||||
*
|
*
|
||||||
|
@ -10,6 +12,72 @@ namespace Kanboard\Controller;
|
||||||
*/
|
*/
|
||||||
class Oauth extends Base
|
class Oauth extends Base
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Redirect to the provider if no code received
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @param string $provider
|
||||||
|
*/
|
||||||
|
protected function step1($provider)
|
||||||
|
{
|
||||||
|
$code = $this->request->getStringParam('code');
|
||||||
|
$state = $this->request->getStringParam('state');
|
||||||
|
|
||||||
|
if (! empty($code)) {
|
||||||
|
$this->step2($provider, $code, $state);
|
||||||
|
} else {
|
||||||
|
$this->response->redirect($this->authenticationManager->getProvider($provider)->getService()->getAuthorizationUrl());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Link or authenticate the user
|
||||||
|
*
|
||||||
|
* @access protected
|
||||||
|
* @param string $providerName
|
||||||
|
* @param string $code
|
||||||
|
* @param string $state
|
||||||
|
*/
|
||||||
|
protected function step2($providerName, $code, $state)
|
||||||
|
{
|
||||||
|
$provider = $this->authenticationManager->getProvider($providerName);
|
||||||
|
$provider->setCode($code);
|
||||||
|
$hasValidState = $provider->getService()->isValidateState($state);
|
||||||
|
|
||||||
|
if ($this->userSession->isLogged()) {
|
||||||
|
if ($hasValidState) {
|
||||||
|
$this->link($provider);
|
||||||
|
} else {
|
||||||
|
$this->flash->failure(t('The OAuth2 state parameter is invalid'));
|
||||||
|
$this->response->redirect($this->helper->url->to('user', 'external', array('user_id' => $this->userSession->getId())));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ($hasValidState) {
|
||||||
|
$this->authenticate($providerName);
|
||||||
|
} else {
|
||||||
|
$this->authenticationFailure(t('The OAuth2 state parameter is invalid'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Link the account
|
||||||
|
*
|
||||||
|
* @access protected
|
||||||
|
* @param OAuthAuthenticationProviderInterface $provider
|
||||||
|
*/
|
||||||
|
protected function link(OAuthAuthenticationProviderInterface $provider)
|
||||||
|
{
|
||||||
|
if (! $provider->authenticate()) {
|
||||||
|
$this->flash->failure(t('External authentication failed'));
|
||||||
|
} else {
|
||||||
|
$this->userProfile->assign($this->userSession->getId(), $provider->getUser());
|
||||||
|
$this->flash->success(t('Your external account is linked to your profile successfully.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->response->redirect($this->helper->url->to('user', 'external', array('user_id' => $this->userSession->getId())));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unlink external account
|
* Unlink external account
|
||||||
*
|
*
|
||||||
|
@ -29,78 +97,34 @@ class Oauth extends Base
|
||||||
$this->response->redirect($this->helper->url->to('user', 'external', array('user_id' => $this->userSession->getId())));
|
$this->response->redirect($this->helper->url->to('user', 'external', array('user_id' => $this->userSession->getId())));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Redirect to the provider if no code received
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
* @param string $provider
|
|
||||||
*/
|
|
||||||
protected function step1($provider)
|
|
||||||
{
|
|
||||||
$code = $this->request->getStringParam('code');
|
|
||||||
|
|
||||||
if (! empty($code)) {
|
|
||||||
$this->step2($provider, $code);
|
|
||||||
} else {
|
|
||||||
$this->response->redirect($this->authenticationManager->getProvider($provider)->getService()->getAuthorizationUrl());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Link or authenticate the user
|
|
||||||
*
|
|
||||||
* @access protected
|
|
||||||
* @param string $provider
|
|
||||||
* @param string $code
|
|
||||||
*/
|
|
||||||
protected function step2($provider, $code)
|
|
||||||
{
|
|
||||||
$this->authenticationManager->getProvider($provider)->setCode($code);
|
|
||||||
|
|
||||||
if ($this->userSession->isLogged()) {
|
|
||||||
$this->link($provider);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->authenticate($provider);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Link the account
|
|
||||||
*
|
|
||||||
* @access protected
|
|
||||||
* @param string $provider
|
|
||||||
*/
|
|
||||||
protected function link($provider)
|
|
||||||
{
|
|
||||||
$authProvider = $this->authenticationManager->getProvider($provider);
|
|
||||||
|
|
||||||
if (! $authProvider->authenticate()) {
|
|
||||||
$this->flash->failure(t('External authentication failed'));
|
|
||||||
} else {
|
|
||||||
$this->userProfile->assign($this->userSession->getId(), $authProvider->getUser());
|
|
||||||
$this->flash->success(t('Your external account is linked to your profile successfully.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->response->redirect($this->helper->url->to('user', 'external', array('user_id' => $this->userSession->getId())));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Authenticate the account
|
* Authenticate the account
|
||||||
*
|
*
|
||||||
* @access protected
|
* @access protected
|
||||||
* @param string $provider
|
* @param string $providerName
|
||||||
*/
|
*/
|
||||||
protected function authenticate($provider)
|
protected function authenticate($providerName)
|
||||||
{
|
{
|
||||||
if ($this->authenticationManager->oauthAuthentication($provider)) {
|
if ($this->authenticationManager->oauthAuthentication($providerName)) {
|
||||||
$this->response->redirect($this->helper->url->to('app', 'index'));
|
$this->response->redirect($this->helper->url->to('app', 'index'));
|
||||||
} else {
|
} else {
|
||||||
|
$this->authenticationFailure(t('External authentication failed'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show login failure page
|
||||||
|
*
|
||||||
|
* @access protected
|
||||||
|
* @param string $message
|
||||||
|
*/
|
||||||
|
protected function authenticationFailure($message)
|
||||||
|
{
|
||||||
$this->response->html($this->helper->layout->app('auth/index', array(
|
$this->response->html($this->helper->layout->app('auth/index', array(
|
||||||
'errors' => array('login' => t('External authentication failed')),
|
'errors' => array('login' => $message),
|
||||||
'values' => array(),
|
'values' => array(),
|
||||||
'no_layout' => true,
|
'no_layout' => true,
|
||||||
'title' => t('Login')
|
'title' => t('Login')
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -67,7 +67,7 @@ class ProjectEdit extends Base
|
||||||
if ($valid) {
|
if ($valid) {
|
||||||
if ($this->project->update($values)) {
|
if ($this->project->update($values)) {
|
||||||
$this->flash->success(t('Project updated successfully.'));
|
$this->flash->success(t('Project updated successfully.'));
|
||||||
$this->response->redirect($this->helper->url->to('ProjectEdit', $redirect, array('project_id' => $project['id'])));
|
$this->response->redirect($this->helper->url->to('ProjectEdit', $redirect, array('project_id' => $project['id'])), true);
|
||||||
} else {
|
} else {
|
||||||
$this->flash->failure(t('Unable to update this project.'));
|
$this->flash->failure(t('Unable to update this project.'));
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,15 +15,18 @@ class ProjectOverview extends Base
|
||||||
*/
|
*/
|
||||||
public function show()
|
public function show()
|
||||||
{
|
{
|
||||||
$params = $this->getProjectFilters('ProjectOverview', 'show');
|
$project = $this->getProject();
|
||||||
$params['users'] = $this->projectUserRole->getAllUsersGroupedByRole($params['project']['id']);
|
$this->project->getColumnStats($project);
|
||||||
$params['roles'] = $this->role->getProjectRoles();
|
|
||||||
$params['events'] = $this->projectActivity->getProject($params['project']['id'], 10);
|
|
||||||
$params['images'] = $this->projectFile->getAllImages($params['project']['id']);
|
|
||||||
$params['files'] = $this->projectFile->getAllDocuments($params['project']['id']);
|
|
||||||
|
|
||||||
$this->project->getColumnStats($params['project']);
|
$this->response->html($this->helper->layout->app('project_overview/show', array(
|
||||||
|
'project' => $project,
|
||||||
$this->response->html($this->helper->layout->app('project_overview/show', $params));
|
'title' => $project['name'],
|
||||||
|
'description' => $this->helper->projectHeader->getDescription($project),
|
||||||
|
'users' => $this->projectUserRole->getAllUsersGroupedByRole($project['id']),
|
||||||
|
'roles' => $this->role->getProjectRoles(),
|
||||||
|
'events' => $this->projectActivity->getProject($project['id'], 10),
|
||||||
|
'images' => $this->projectFile->getAllImages($project['id']),
|
||||||
|
'files' => $this->projectFile->getAllDocuments($project['id']),
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,22 +10,6 @@ namespace Kanboard\Controller;
|
||||||
*/
|
*/
|
||||||
class Subtask extends Base
|
class Subtask extends Base
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Show list of subtasks
|
|
||||||
*/
|
|
||||||
public function show()
|
|
||||||
{
|
|
||||||
$task = $this->getTask();
|
|
||||||
|
|
||||||
$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,
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creation form
|
* Creation form
|
||||||
*
|
*
|
||||||
|
@ -42,7 +26,7 @@ class Subtask extends Base
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->response->html($this->helper->layout->task('subtask/create', array(
|
$this->response->html($this->template->render('subtask/create', array(
|
||||||
'values' => $values,
|
'values' => $values,
|
||||||
'errors' => $errors,
|
'errors' => $errors,
|
||||||
'users_list' => $this->projectUserRole->getAssignableUsersList($task['project_id']),
|
'users_list' => $this->projectUserRole->getAssignableUsersList($task['project_id']),
|
||||||
|
@ -89,7 +73,7 @@ class Subtask extends Base
|
||||||
$task = $this->getTask();
|
$task = $this->getTask();
|
||||||
$subtask = $this->getSubTask();
|
$subtask = $this->getSubTask();
|
||||||
|
|
||||||
$this->response->html($this->helper->layout->task('subtask/edit', array(
|
$this->response->html($this->template->render('subtask/edit', array(
|
||||||
'values' => empty($values) ? $subtask : $values,
|
'values' => empty($values) ? $subtask : $values,
|
||||||
'errors' => $errors,
|
'errors' => $errors,
|
||||||
'users_list' => $this->projectUserRole->getAssignableUsersList($task['project_id']),
|
'users_list' => $this->projectUserRole->getAssignableUsersList($task['project_id']),
|
||||||
|
@ -135,7 +119,7 @@ class Subtask extends Base
|
||||||
$task = $this->getTask();
|
$task = $this->getTask();
|
||||||
$subtask = $this->getSubtask();
|
$subtask = $this->getSubtask();
|
||||||
|
|
||||||
$this->response->html($this->helper->layout->task('subtask/remove', array(
|
$this->response->html($this->template->render('subtask/remove', array(
|
||||||
'subtask' => $subtask,
|
'subtask' => $subtask,
|
||||||
'task' => $task,
|
'task' => $task,
|
||||||
)));
|
)));
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
namespace Kanboard\Controller;
|
namespace Kanboard\Controller;
|
||||||
|
|
||||||
|
use Kanboard\Core\DateParser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Task controller
|
* Task controller
|
||||||
*
|
*
|
||||||
|
@ -21,13 +23,17 @@ class Task extends Base
|
||||||
|
|
||||||
// Token verification
|
// Token verification
|
||||||
if (empty($project)) {
|
if (empty($project)) {
|
||||||
$this->forbidden(true);
|
return $this->forbidden(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
$task = $this->taskFinder->getDetails($this->request->getIntegerParam('task_id'));
|
$task = $this->taskFinder->getDetails($this->request->getIntegerParam('task_id'));
|
||||||
|
|
||||||
if (empty($task)) {
|
if (empty($task)) {
|
||||||
$this->notfound(true);
|
return $this->notfound(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($task['project_id'] != $project['id']) {
|
||||||
|
return $this->forbidden(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->response->html($this->helper->layout->app('task/public', array(
|
$this->response->html($this->helper->layout->app('task/public', array(
|
||||||
|
@ -62,25 +68,19 @@ class Task extends Base
|
||||||
'time_spent' => $task['time_spent'] ?: '',
|
'time_spent' => $task['time_spent'] ?: '',
|
||||||
);
|
);
|
||||||
|
|
||||||
$values = $this->dateParser->format($values, array('date_started'), $this->config->get('application_datetime_format', 'm/d/Y H:i'));
|
$values = $this->dateParser->format($values, array('date_started'), $this->config->get('application_datetime_format', DateParser::DATE_TIME_FORMAT));
|
||||||
|
|
||||||
$this->response->html($this->helper->layout->task('task/show', array(
|
$this->response->html($this->helper->layout->task('task/show', array(
|
||||||
|
'task' => $task,
|
||||||
'project' => $this->project->getById($task['project_id']),
|
'project' => $this->project->getById($task['project_id']),
|
||||||
|
'values' => $values,
|
||||||
'files' => $this->taskFile->getAllDocuments($task['id']),
|
'files' => $this->taskFile->getAllDocuments($task['id']),
|
||||||
'images' => $this->taskFile->getAllImages($task['id']),
|
'images' => $this->taskFile->getAllImages($task['id']),
|
||||||
'comments' => $this->comment->getAll($task['id'], $this->userSession->getCommentSorting()),
|
'comments' => $this->comment->getAll($task['id'], $this->userSession->getCommentSorting()),
|
||||||
'subtasks' => $subtasks,
|
'subtasks' => $subtasks,
|
||||||
'links' => $this->taskLink->getAllGroupedByLabel($task['id']),
|
'internal_links' => $this->taskLink->getAllGroupedByLabel($task['id']),
|
||||||
'task' => $task,
|
'external_links' => $this->taskExternalLink->getAll($task['id']),
|
||||||
'values' => $values,
|
|
||||||
'link_label_list' => $this->link->getList(0, false),
|
'link_label_list' => $this->link->getList(0, false),
|
||||||
'columns_list' => $this->column->getList($task['project_id']),
|
|
||||||
'colors_list' => $this->color->getList(),
|
|
||||||
'users_list' => $this->projectUserRole->getAssignableUsersList($task['project_id'], true, false, false),
|
|
||||||
'title' => $task['project_name'].' > '.$task['title'],
|
|
||||||
'recurrence_trigger_list' => $this->task->getRecurrenceTriggerList(),
|
|
||||||
'recurrence_timeframe_list' => $this->task->getRecurrenceTimeframeList(),
|
|
||||||
'recurrence_basedate_list' => $this->task->getRecurrenceBasedateList(),
|
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,8 +94,8 @@ class Task extends Base
|
||||||
$task = $this->getTask();
|
$task = $this->getTask();
|
||||||
|
|
||||||
$this->response->html($this->helper->layout->task('task/analytics', array(
|
$this->response->html($this->helper->layout->task('task/analytics', array(
|
||||||
'title' => $task['title'],
|
|
||||||
'task' => $task,
|
'task' => $task,
|
||||||
|
'project' => $this->project->getById($task['project_id']),
|
||||||
'lead_time' => $this->taskAnalytic->getLeadTime($task),
|
'lead_time' => $this->taskAnalytic->getLeadTime($task),
|
||||||
'cycle_time' => $this->taskAnalytic->getCycleTime($task),
|
'cycle_time' => $this->taskAnalytic->getCycleTime($task),
|
||||||
'time_spent_columns' => $this->taskAnalytic->getTimeSpentByColumn($task),
|
'time_spent_columns' => $this->taskAnalytic->getTimeSpentByColumn($task),
|
||||||
|
@ -121,6 +121,7 @@ class Task extends Base
|
||||||
|
|
||||||
$this->response->html($this->helper->layout->task('task/time_tracking_details', array(
|
$this->response->html($this->helper->layout->task('task/time_tracking_details', array(
|
||||||
'task' => $task,
|
'task' => $task,
|
||||||
|
'project' => $this->project->getById($task['project_id']),
|
||||||
'subtask_paginator' => $subtask_paginator,
|
'subtask_paginator' => $subtask_paginator,
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
@ -136,6 +137,7 @@ class Task extends Base
|
||||||
|
|
||||||
$this->response->html($this->helper->layout->task('task/transitions', array(
|
$this->response->html($this->helper->layout->task('task/transitions', array(
|
||||||
'task' => $task,
|
'task' => $task,
|
||||||
|
'project' => $this->project->getById($task['project_id']),
|
||||||
'transitions' => $this->transition->getAllByTask($task['id']),
|
'transitions' => $this->transition->getAllByTask($task['id']),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
@ -165,7 +167,7 @@ class Task extends Base
|
||||||
$this->response->redirect($this->helper->url->to('board', 'show', array('project_id' => $task['project_id'])));
|
$this->response->redirect($this->helper->url->to('board', 'show', array('project_id' => $task['project_id'])));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->response->html($this->helper->layout->task('task/remove', array(
|
$this->response->html($this->template->render('task/remove', array(
|
||||||
'task' => $task,
|
'task' => $task,
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,22 +12,6 @@ use Kanboard\Core\ExternalLink\ExternalLinkProviderNotFound;
|
||||||
*/
|
*/
|
||||||
class TaskExternalLink extends Base
|
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
|
* First creation form
|
||||||
*
|
*
|
||||||
|
@ -37,7 +21,7 @@ class TaskExternalLink extends Base
|
||||||
{
|
{
|
||||||
$task = $this->getTask();
|
$task = $this->getTask();
|
||||||
|
|
||||||
$this->response->html($this->helper->layout->task('task_external_link/find', array(
|
$this->response->html($this->template->render('task_external_link/find', array(
|
||||||
'values' => $values,
|
'values' => $values,
|
||||||
'errors' => $errors,
|
'errors' => $errors,
|
||||||
'task' => $task,
|
'task' => $task,
|
||||||
|
@ -60,7 +44,7 @@ class TaskExternalLink extends Base
|
||||||
$provider = $this->externalLinkManager->setUserInput($values)->find();
|
$provider = $this->externalLinkManager->setUserInput($values)->find();
|
||||||
$link = $provider->getLink();
|
$link = $provider->getLink();
|
||||||
|
|
||||||
$this->response->html($this->helper->layout->task('task_external_link/create', array(
|
$this->response->html($this->template->render('task_external_link/create', array(
|
||||||
'values' => array(
|
'values' => array(
|
||||||
'title' => $link->getTitle(),
|
'title' => $link->getTitle(),
|
||||||
'url' => $link->getUrl(),
|
'url' => $link->getUrl(),
|
||||||
|
@ -90,7 +74,7 @@ class TaskExternalLink extends Base
|
||||||
|
|
||||||
if ($valid && $this->taskExternalLink->create($values)) {
|
if ($valid && $this->taskExternalLink->create($values)) {
|
||||||
$this->flash->success(t('Link added successfully.'));
|
$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);
|
return $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->edit($values, $errors);
|
$this->edit($values, $errors);
|
||||||
|
@ -116,7 +100,7 @@ class TaskExternalLink extends Base
|
||||||
|
|
||||||
$provider = $this->externalLinkManager->getProvider($values['link_type']);
|
$provider = $this->externalLinkManager->getProvider($values['link_type']);
|
||||||
|
|
||||||
$this->response->html($this->helper->layout->task('task_external_link/edit', array(
|
$this->response->html($this->template->render('task_external_link/edit', array(
|
||||||
'values' => $values,
|
'values' => $values,
|
||||||
'errors' => $errors,
|
'errors' => $errors,
|
||||||
'task' => $task,
|
'task' => $task,
|
||||||
|
@ -137,7 +121,7 @@ class TaskExternalLink extends Base
|
||||||
|
|
||||||
if ($valid && $this->taskExternalLink->update($values)) {
|
if ($valid && $this->taskExternalLink->update($values)) {
|
||||||
$this->flash->success(t('Link updated successfully.'));
|
$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);
|
return $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->edit($values, $errors);
|
$this->edit($values, $errors);
|
||||||
|
@ -158,7 +142,7 @@ class TaskExternalLink extends Base
|
||||||
return $this->notfound();
|
return $this->notfound();
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->response->html($this->helper->layout->task('task_external_link/remove', array(
|
$this->response->html($this->template->render('task_external_link/remove', array(
|
||||||
'link' => $link,
|
'link' => $link,
|
||||||
'task' => $task,
|
'task' => $task,
|
||||||
)));
|
)));
|
||||||
|
@ -180,6 +164,6 @@ class TaskExternalLink extends Base
|
||||||
$this->flash->failure(t('Unable to remove this link.'));
|
$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'])));
|
$this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,22 +10,6 @@ namespace Kanboard\Controller;
|
||||||
*/
|
*/
|
||||||
class TaskHelper extends Base
|
class TaskHelper extends Base
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Render Markdown text and reply with the HTML Code
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
public function preview()
|
|
||||||
{
|
|
||||||
$payload = $this->request->getJson();
|
|
||||||
|
|
||||||
if (empty($payload['text'])) {
|
|
||||||
$this->response->html('<p>'.t('Nothing to preview...').'</p>');
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->response->html($this->helper->text->markdown($payload['text']));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Task autocompletion (Ajax)
|
* Task autocompletion (Ajax)
|
||||||
*
|
*
|
||||||
|
|
|
@ -3,13 +3,13 @@
|
||||||
namespace Kanboard\Controller;
|
namespace Kanboard\Controller;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TaskLink controller
|
* TaskInternalLink Controller
|
||||||
*
|
*
|
||||||
* @package controller
|
* @package controller
|
||||||
* @author Olivier Maridat
|
* @author Olivier Maridat
|
||||||
* @author Frederic Guillot
|
* @author Frederic Guillot
|
||||||
*/
|
*/
|
||||||
class Tasklink extends Base
|
class TaskInternalLink extends Base
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Get the current link
|
* Get the current link
|
||||||
|
@ -28,25 +28,6 @@ class Tasklink extends Base
|
||||||
return $link;
|
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
|
* Creation form
|
||||||
*
|
*
|
||||||
|
@ -56,12 +37,11 @@ class Tasklink extends Base
|
||||||
{
|
{
|
||||||
$task = $this->getTask();
|
$task = $this->getTask();
|
||||||
|
|
||||||
$this->response->html($this->helper->layout->task('tasklink/create', array(
|
$this->response->html($this->template->render('task_internal_link/create', array(
|
||||||
'values' => $values,
|
'values' => $values,
|
||||||
'errors' => $errors,
|
'errors' => $errors,
|
||||||
'task' => $task,
|
'task' => $task,
|
||||||
'labels' => $this->link->getList(0, false),
|
'labels' => $this->link->getList(0, false),
|
||||||
'title' => t('Add a new link')
|
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,7 +60,7 @@ class Tasklink extends Base
|
||||||
if ($valid) {
|
if ($valid) {
|
||||||
if ($this->taskLink->create($values['task_id'], $values['opposite_task_id'], $values['link_id'])) {
|
if ($this->taskLink->create($values['task_id'], $values['opposite_task_id'], $values['link_id'])) {
|
||||||
$this->flash->success(t('Link added successfully.'));
|
$this->flash->success(t('Link added successfully.'));
|
||||||
return $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])).'#links', true);
|
return $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
$errors = array('title' => array(t('The exact same link already exists')));
|
$errors = array('title' => array(t('The exact same link already exists')));
|
||||||
|
@ -106,13 +86,12 @@ class Tasklink extends Base
|
||||||
$values['title'] = '#'.$opposite_task['id'].' - '.$opposite_task['title'];
|
$values['title'] = '#'.$opposite_task['id'].' - '.$opposite_task['title'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->response->html($this->helper->layout->task('tasklink/edit', array(
|
$this->response->html($this->template->render('task_internal_link/edit', array(
|
||||||
'values' => $values,
|
'values' => $values,
|
||||||
'errors' => $errors,
|
'errors' => $errors,
|
||||||
'task_link' => $task_link,
|
'task_link' => $task_link,
|
||||||
'task' => $task,
|
'task' => $task,
|
||||||
'labels' => $this->link->getList(0, false),
|
'labels' => $this->link->getList(0, false)
|
||||||
'title' => t('Edit link')
|
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,7 +129,7 @@ class Tasklink extends Base
|
||||||
$task = $this->getTask();
|
$task = $this->getTask();
|
||||||
$link = $this->getTaskLink();
|
$link = $this->getTaskLink();
|
||||||
|
|
||||||
$this->response->html($this->helper->layout->task('tasklink/remove', array(
|
$this->response->html($this->template->render('task_internal_link/remove', array(
|
||||||
'link' => $link,
|
'link' => $link,
|
||||||
'task' => $task,
|
'task' => $task,
|
||||||
)));
|
)));
|
||||||
|
@ -172,6 +151,6 @@ class Tasklink extends Base
|
||||||
$this->flash->failure(t('Unable to remove this link.'));
|
$this->flash->failure(t('Unable to remove this link.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])).'#links');
|
$this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -23,7 +23,7 @@ class TaskRecurrence extends Base
|
||||||
$values = $task;
|
$values = $task;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->response->html($this->helper->layout->task('task_recurrence/edit', array(
|
$this->response->html($this->template->render('task_recurrence/edit', array(
|
||||||
'values' => $values,
|
'values' => $values,
|
||||||
'errors' => $errors,
|
'errors' => $errors,
|
||||||
'task' => $task,
|
'task' => $task,
|
||||||
|
|
|
@ -32,7 +32,7 @@ class Taskduplication extends Base
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->response->html($this->helper->layout->task('task_duplication/duplicate', array(
|
$this->response->html($this->template->render('task_duplication/duplicate', array(
|
||||||
'task' => $task,
|
'task' => $task,
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
@ -128,7 +128,7 @@ class Taskduplication extends Base
|
||||||
$users_list = array();
|
$users_list = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->response->html($this->helper->layout->task($template, array(
|
$this->response->html($this->template->render($template, array(
|
||||||
'values' => $values,
|
'values' => $values,
|
||||||
'task' => $task,
|
'task' => $task,
|
||||||
'projects_list' => $projects_list,
|
'projects_list' => $projects_list,
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
namespace Kanboard\Controller;
|
namespace Kanboard\Controller;
|
||||||
|
|
||||||
|
use Kanboard\Core\DateParser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Task Modification controller
|
* Task Modification controller
|
||||||
*
|
*
|
||||||
|
@ -35,7 +37,7 @@ class Taskmodification extends Base
|
||||||
$values = array('id' => $task['id'], 'description' => $task['description']);
|
$values = array('id' => $task['id'], 'description' => $task['description']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->response->html($this->helper->layout->task('task_modification/edit_description', array(
|
$this->response->html($this->template->render('task_modification/edit_description', array(
|
||||||
'values' => $values,
|
'values' => $values,
|
||||||
'errors' => $errors,
|
'errors' => $errors,
|
||||||
'task' => $task,
|
'task' => $task,
|
||||||
|
@ -83,10 +85,10 @@ class Taskmodification extends Base
|
||||||
$values = $this->hook->merge('controller:task-modification:form:default', $values, array('default_values' => $values));
|
$values = $this->hook->merge('controller:task-modification:form:default', $values, array('default_values' => $values));
|
||||||
}
|
}
|
||||||
|
|
||||||
$values = $this->dateParser->format($values, array('date_due'), $this->config->get('application_date_format', 'm/d/Y'));
|
$values = $this->dateParser->format($values, array('date_due'), $this->config->get('application_date_format', DateParser::DATE_FORMAT));
|
||||||
$values = $this->dateParser->format($values, array('date_started'), $this->config->get('application_datetime_format', 'm/d/Y H:i'));
|
$values = $this->dateParser->format($values, array('date_started'), $this->config->get('application_datetime_format', DateParser::DATE_TIME_FORMAT));
|
||||||
|
|
||||||
$this->response->html($this->helper->layout->task('task_modification/edit_task', array(
|
$this->response->html($this->template->render('task_modification/edit_task', array(
|
||||||
'project' => $project,
|
'project' => $project,
|
||||||
'values' => $values,
|
'values' => $values,
|
||||||
'errors' => $errors,
|
'errors' => $errors,
|
||||||
|
|
|
@ -55,7 +55,7 @@ class Taskstatus extends Base
|
||||||
return $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), true);
|
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->helper->layout->task($template, array(
|
$this->response->html($this->template->render($template, array(
|
||||||
'task' => $task,
|
'task' => $task,
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,6 @@ use Pimple\Container;
|
||||||
* @property \Kanboard\Core\ObjectStorage\ObjectStorageInterface $objectStorage
|
* @property \Kanboard\Core\ObjectStorage\ObjectStorageInterface $objectStorage
|
||||||
* @property \Kanboard\Core\Plugin\Hook $hook
|
* @property \Kanboard\Core\Plugin\Hook $hook
|
||||||
* @property \Kanboard\Core\Plugin\Loader $pluginLoader
|
* @property \Kanboard\Core\Plugin\Loader $pluginLoader
|
||||||
* @property \Kanboard\Core\Security\AccessMap $projectAccessMap
|
|
||||||
* @property \Kanboard\Core\Security\AuthenticationManager $authenticationManager
|
* @property \Kanboard\Core\Security\AuthenticationManager $authenticationManager
|
||||||
* @property \Kanboard\Core\Security\AccessMap $applicationAccessMap
|
* @property \Kanboard\Core\Security\AccessMap $applicationAccessMap
|
||||||
* @property \Kanboard\Core\Security\AccessMap $projectAccessMap
|
* @property \Kanboard\Core\Security\AccessMap $projectAccessMap
|
||||||
|
@ -42,6 +41,7 @@ use Pimple\Container;
|
||||||
* @property \Kanboard\Core\Session\FlashMessage $flash
|
* @property \Kanboard\Core\Session\FlashMessage $flash
|
||||||
* @property \Kanboard\Core\Session\SessionManager $sessionManager
|
* @property \Kanboard\Core\Session\SessionManager $sessionManager
|
||||||
* @property \Kanboard\Core\Session\SessionStorage $sessionStorage
|
* @property \Kanboard\Core\Session\SessionStorage $sessionStorage
|
||||||
|
* @property \Kanboard\Core\User\Avatar\AvatarManager $avatarManager
|
||||||
* @property \Kanboard\Core\User\GroupSync $groupSync
|
* @property \Kanboard\Core\User\GroupSync $groupSync
|
||||||
* @property \Kanboard\Core\User\UserProfile $userProfile
|
* @property \Kanboard\Core\User\UserProfile $userProfile
|
||||||
* @property \Kanboard\Core\User\UserSync $userSync
|
* @property \Kanboard\Core\User\UserSync $userSync
|
||||||
|
@ -60,6 +60,7 @@ use Pimple\Container;
|
||||||
* @property \Kanboard\Formatter\GroupAutoCompleteFormatter $groupAutoCompleteFormatter
|
* @property \Kanboard\Formatter\GroupAutoCompleteFormatter $groupAutoCompleteFormatter
|
||||||
* @property \Kanboard\Model\Action $action
|
* @property \Kanboard\Model\Action $action
|
||||||
* @property \Kanboard\Model\ActionParameter $actionParameter
|
* @property \Kanboard\Model\ActionParameter $actionParameter
|
||||||
|
* @property \Kanboard\Model\AvatarFile $avatarFile
|
||||||
* @property \Kanboard\Model\Board $board
|
* @property \Kanboard\Model\Board $board
|
||||||
* @property \Kanboard\Model\Category $category
|
* @property \Kanboard\Model\Category $category
|
||||||
* @property \Kanboard\Model\Color $color
|
* @property \Kanboard\Model\Color $color
|
||||||
|
@ -75,11 +76,9 @@ use Pimple\Container;
|
||||||
* @property \Kanboard\Model\LastLogin $lastLogin
|
* @property \Kanboard\Model\LastLogin $lastLogin
|
||||||
* @property \Kanboard\Model\Link $link
|
* @property \Kanboard\Model\Link $link
|
||||||
* @property \Kanboard\Model\Notification $notification
|
* @property \Kanboard\Model\Notification $notification
|
||||||
* @property \Kanboard\Model\OverdueNotification $overdueNotification
|
|
||||||
* @property \Kanboard\Model\PasswordReset $passwordReset
|
* @property \Kanboard\Model\PasswordReset $passwordReset
|
||||||
* @property \Kanboard\Model\Project $project
|
* @property \Kanboard\Model\Project $project
|
||||||
* @property \Kanboard\Model\ProjectActivity $projectActivity
|
* @property \Kanboard\Model\ProjectActivity $projectActivity
|
||||||
* @property \Kanboard\Model\ProjectAnalytic $projectAnalytic
|
|
||||||
* @property \Kanboard\Model\ProjectDuplication $projectDuplication
|
* @property \Kanboard\Model\ProjectDuplication $projectDuplication
|
||||||
* @property \Kanboard\Model\ProjectDailyColumnStats $projectDailyColumnStats
|
* @property \Kanboard\Model\ProjectDailyColumnStats $projectDailyColumnStats
|
||||||
* @property \Kanboard\Model\ProjectDailyStats $projectDailyStats
|
* @property \Kanboard\Model\ProjectDailyStats $projectDailyStats
|
||||||
|
@ -92,16 +91,13 @@ use Pimple\Container;
|
||||||
* @property \Kanboard\Model\ProjectNotificationType $projectNotificationType
|
* @property \Kanboard\Model\ProjectNotificationType $projectNotificationType
|
||||||
* @property \Kanboard\Model\RememberMeSession $rememberMeSession
|
* @property \Kanboard\Model\RememberMeSession $rememberMeSession
|
||||||
* @property \Kanboard\Model\Subtask $subtask
|
* @property \Kanboard\Model\Subtask $subtask
|
||||||
* @property \Kanboard\Model\SubtaskExport $subtaskExport
|
|
||||||
* @property \Kanboard\Model\SubtaskTimeTracking $subtaskTimeTracking
|
* @property \Kanboard\Model\SubtaskTimeTracking $subtaskTimeTracking
|
||||||
* @property \Kanboard\Model\Swimlane $swimlane
|
* @property \Kanboard\Model\Swimlane $swimlane
|
||||||
* @property \Kanboard\Model\Task $task
|
* @property \Kanboard\Model\Task $task
|
||||||
* @property \Kanboard\Model\TaskAnalytic $taskAnalytic
|
* @property \Kanboard\Model\TaskAnalytic $taskAnalytic
|
||||||
* @property \Kanboard\Model\TaskCreation $taskCreation
|
* @property \Kanboard\Model\TaskCreation $taskCreation
|
||||||
* @property \Kanboard\Model\TaskDuplication $taskDuplication
|
* @property \Kanboard\Model\TaskDuplication $taskDuplication
|
||||||
* @property \Kanboard\Model\TaskExport $taskExport
|
|
||||||
* @property \Kanboard\Model\TaskExternalLink $taskExternalLink
|
* @property \Kanboard\Model\TaskExternalLink $taskExternalLink
|
||||||
* @property \Kanboard\Model\TaskImport $taskImport
|
|
||||||
* @property \Kanboard\Model\TaskFinder $taskFinder
|
* @property \Kanboard\Model\TaskFinder $taskFinder
|
||||||
* @property \Kanboard\Model\TaskFilter $taskFilter
|
* @property \Kanboard\Model\TaskFilter $taskFilter
|
||||||
* @property \Kanboard\Model\TaskLink $taskLink
|
* @property \Kanboard\Model\TaskLink $taskLink
|
||||||
|
@ -112,7 +108,6 @@ use Pimple\Container;
|
||||||
* @property \Kanboard\Model\TaskMetadata $taskMetadata
|
* @property \Kanboard\Model\TaskMetadata $taskMetadata
|
||||||
* @property \Kanboard\Model\Transition $transition
|
* @property \Kanboard\Model\Transition $transition
|
||||||
* @property \Kanboard\Model\User $user
|
* @property \Kanboard\Model\User $user
|
||||||
* @property \Kanboard\Model\UserImport $userImport
|
|
||||||
* @property \Kanboard\Model\UserLocking $userLocking
|
* @property \Kanboard\Model\UserLocking $userLocking
|
||||||
* @property \Kanboard\Model\UserMention $userMention
|
* @property \Kanboard\Model\UserMention $userMention
|
||||||
* @property \Kanboard\Model\UserNotification $userNotification
|
* @property \Kanboard\Model\UserNotification $userNotification
|
||||||
|
@ -120,12 +115,10 @@ use Pimple\Container;
|
||||||
* @property \Kanboard\Model\UserNotificationFilter $userNotificationFilter
|
* @property \Kanboard\Model\UserNotificationFilter $userNotificationFilter
|
||||||
* @property \Kanboard\Model\UserUnreadNotification $userUnreadNotification
|
* @property \Kanboard\Model\UserUnreadNotification $userUnreadNotification
|
||||||
* @property \Kanboard\Model\UserMetadata $userMetadata
|
* @property \Kanboard\Model\UserMetadata $userMetadata
|
||||||
* @property \Kanboard\Model\Webhook $webhook
|
|
||||||
* @property \Kanboard\Validator\ActionValidator $actionValidator
|
* @property \Kanboard\Validator\ActionValidator $actionValidator
|
||||||
* @property \Kanboard\Validator\AuthValidator $authValidator
|
* @property \Kanboard\Validator\AuthValidator $authValidator
|
||||||
* @property \Kanboard\Validator\ColumnValidator $columnValidator
|
* @property \Kanboard\Validator\ColumnValidator $columnValidator
|
||||||
* @property \Kanboard\Validator\CategoryValidator $categoryValidator
|
* @property \Kanboard\Validator\CategoryValidator $categoryValidator
|
||||||
* @property \Kanboard\Validator\ColumnValidator $columnValidator
|
|
||||||
* @property \Kanboard\Validator\CommentValidator $commentValidator
|
* @property \Kanboard\Validator\CommentValidator $commentValidator
|
||||||
* @property \Kanboard\Validator\CurrencyValidator $currencyValidator
|
* @property \Kanboard\Validator\CurrencyValidator $currencyValidator
|
||||||
* @property \Kanboard\Validator\CustomFilterValidator $customFilterValidator
|
* @property \Kanboard\Validator\CustomFilterValidator $customFilterValidator
|
||||||
|
@ -136,9 +129,14 @@ use Pimple\Container;
|
||||||
* @property \Kanboard\Validator\SubtaskValidator $subtaskValidator
|
* @property \Kanboard\Validator\SubtaskValidator $subtaskValidator
|
||||||
* @property \Kanboard\Validator\SwimlaneValidator $swimlaneValidator
|
* @property \Kanboard\Validator\SwimlaneValidator $swimlaneValidator
|
||||||
* @property \Kanboard\Validator\TaskLinkValidator $taskLinkValidator
|
* @property \Kanboard\Validator\TaskLinkValidator $taskLinkValidator
|
||||||
* @property \Kanboard\Validator\TaskExternalLinkValidator $taskExternalLinkValidator
|
* @property \Kanboard\Validator\ExternalLinkValidator $externalLinkValidator
|
||||||
* @property \Kanboard\Validator\TaskValidator $taskValidator
|
* @property \Kanboard\Validator\TaskValidator $taskValidator
|
||||||
* @property \Kanboard\Validator\UserValidator $userValidator
|
* @property \Kanboard\Validator\UserValidator $userValidator
|
||||||
|
* @property \Kanboard\Import\TaskImport $taskImport
|
||||||
|
* @property \Kanboard\Import\UserImport $userImport
|
||||||
|
* @property \Kanboard\Export\SubtaskExport $subtaskExport
|
||||||
|
* @property \Kanboard\Export\TaskExport $taskExport
|
||||||
|
* @property \Kanboard\Export\TransitionExport $transitionExport
|
||||||
* @property \Psr\Log\LoggerInterface $logger
|
* @property \Psr\Log\LoggerInterface $logger
|
||||||
* @property \PicoDb\Database $db
|
* @property \PicoDb\Database $db
|
||||||
* @property \Symfony\Component\EventDispatcher\EventDispatcher $dispatcher
|
* @property \Symfony\Component\EventDispatcher\EventDispatcher $dispatcher
|
||||||
|
|
|
@ -87,7 +87,8 @@ class Csv
|
||||||
*
|
*
|
||||||
* @static
|
* @static
|
||||||
* @access public
|
* @access public
|
||||||
* @return integer
|
* @param mixed $value
|
||||||
|
* @return int
|
||||||
*/
|
*/
|
||||||
public static function getBooleanValue($value)
|
public static function getBooleanValue($value)
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,6 +12,9 @@ use DateTime;
|
||||||
*/
|
*/
|
||||||
class DateParser extends Base
|
class DateParser extends Base
|
||||||
{
|
{
|
||||||
|
const DATE_FORMAT = 'm/d/Y';
|
||||||
|
const DATE_TIME_FORMAT = 'm/d/Y H:i';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of time formats
|
* List of time formats
|
||||||
*
|
*
|
||||||
|
@ -201,7 +204,7 @@ class DateParser extends Base
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a timetstamp from an ISO date format
|
* Get a timestamp from an ISO date format
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $value
|
* @param string $value
|
||||||
|
|
|
@ -10,17 +10,20 @@ use Pimple\Container;
|
||||||
* @package core
|
* @package core
|
||||||
* @author Frederic Guillot
|
* @author Frederic Guillot
|
||||||
*
|
*
|
||||||
* @property \Helper\App $app
|
* @property \Kanboard\Helper\AppHelper $app
|
||||||
* @property \Helper\Asset $asset
|
* @property \Kanboard\Helper\AssetHelper $asset
|
||||||
* @property \Helper\Dt $dt
|
* @property \Kanboard\Helper\DateHelper $dt
|
||||||
* @property \Helper\File $file
|
* @property \Kanboard\Helper\FileHelper $file
|
||||||
* @property \Helper\Form $form
|
* @property \Kanboard\Helper\FormHelper $form
|
||||||
* @property \Helper\Subtask $subtask
|
* @property \Kanboard\Helper\HookHelper $hook
|
||||||
* @property \Helper\Task $task
|
* @property \Kanboard\Helper\ModelHelper $model
|
||||||
* @property \Helper\Text $text
|
* @property \Kanboard\Helper\SubtaskHelper $subtask
|
||||||
* @property \Helper\Url $url
|
* @property \Kanboard\Helper\TaskHelper $task
|
||||||
* @property \Helper\User $user
|
* @property \Kanboard\Helper\TextHelper $text
|
||||||
* @property \Helper\Layout $layout
|
* @property \Kanboard\Helper\UrlHelper $url
|
||||||
|
* @property \Kanboard\Helper\UserHelper $user
|
||||||
|
* @property \Kanboard\Helper\LayoutHelper $layout
|
||||||
|
* @property \Kanboard\Helper\ProjectHeaderHelper $projectHeader
|
||||||
*/
|
*/
|
||||||
class Helper
|
class Helper
|
||||||
{
|
{
|
||||||
|
@ -28,17 +31,17 @@ class Helper
|
||||||
* Helper instances
|
* Helper instances
|
||||||
*
|
*
|
||||||
* @access private
|
* @access private
|
||||||
* @var array
|
* @var \Pimple\Container
|
||||||
*/
|
*/
|
||||||
private $helpers = array();
|
private $helpers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Container instance
|
* Container instance
|
||||||
*
|
*
|
||||||
* @access protected
|
* @access private
|
||||||
* @var \Pimple\Container
|
* @var \Pimple\Container
|
||||||
*/
|
*/
|
||||||
protected $container;
|
private $container;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
|
@ -49,33 +52,49 @@ class Helper
|
||||||
public function __construct(Container $container)
|
public function __construct(Container $container)
|
||||||
{
|
{
|
||||||
$this->container = $container;
|
$this->container = $container;
|
||||||
|
$this->helpers = new Container;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load automatically helpers
|
* Expose helpers with magic getter
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $name Helper name
|
* @param string $helper
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function __get($name)
|
public function __get($helper)
|
||||||
{
|
{
|
||||||
if (! isset($this->helpers[$name])) {
|
return $this->getHelper($helper);
|
||||||
$class = '\Kanboard\Helper\\'.ucfirst($name);
|
|
||||||
$this->helpers[$name] = new $class($this->container);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->helpers[$name];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HTML escaping
|
* Expose helpers with method
|
||||||
*
|
*
|
||||||
* @param string $value Value to escape
|
* @access public
|
||||||
* @return string
|
* @param string $helper
|
||||||
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function e($value)
|
public function getHelper($helper)
|
||||||
{
|
{
|
||||||
return htmlspecialchars($value, ENT_QUOTES, 'UTF-8', false);
|
return $this->helpers[$helper];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a new Helper
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $property
|
||||||
|
* @param string $className
|
||||||
|
* @return Helper
|
||||||
|
*/
|
||||||
|
public function register($property, $className)
|
||||||
|
{
|
||||||
|
$container = $this->container;
|
||||||
|
|
||||||
|
$this->helpers[$property] = function() use($className, $container) {
|
||||||
|
return new $className($container);
|
||||||
|
};
|
||||||
|
|
||||||
|
return $this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,14 +12,14 @@ use Kanboard\Core\Base;
|
||||||
*/
|
*/
|
||||||
class OAuth2 extends Base
|
class OAuth2 extends Base
|
||||||
{
|
{
|
||||||
private $clientId;
|
protected $clientId;
|
||||||
private $secret;
|
protected $secret;
|
||||||
private $callbackUrl;
|
protected $callbackUrl;
|
||||||
private $authUrl;
|
protected $authUrl;
|
||||||
private $tokenUrl;
|
protected $tokenUrl;
|
||||||
private $scopes;
|
protected $scopes;
|
||||||
private $tokenType;
|
protected $tokenType;
|
||||||
private $accessToken;
|
protected $accessToken;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create OAuth2 service
|
* Create OAuth2 service
|
||||||
|
@ -45,6 +45,33 @@ class OAuth2 extends Base
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate OAuth2 state and return the token value
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getState()
|
||||||
|
{
|
||||||
|
if (! isset($this->sessionStorage->oauthState) || empty($this->sessionStorage->oauthState)) {
|
||||||
|
$this->sessionStorage->oauthState = $this->token->getToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->sessionStorage->oauthState;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check the validity of the state (CSRF token)
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $state
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isValidateState($state)
|
||||||
|
{
|
||||||
|
return $state === $this->getState();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get authorization url
|
* Get authorization url
|
||||||
*
|
*
|
||||||
|
@ -58,6 +85,7 @@ class OAuth2 extends Base
|
||||||
'client_id' => $this->clientId,
|
'client_id' => $this->clientId,
|
||||||
'redirect_uri' => $this->callbackUrl,
|
'redirect_uri' => $this->callbackUrl,
|
||||||
'scope' => implode(' ', $this->scopes),
|
'scope' => implode(' ', $this->scopes),
|
||||||
|
'state' => $this->getState(),
|
||||||
);
|
);
|
||||||
|
|
||||||
return $this->authUrl.'?'.http_build_query($params);
|
return $this->authUrl.'?'.http_build_query($params);
|
||||||
|
@ -94,6 +122,7 @@ class OAuth2 extends Base
|
||||||
'client_secret' => $this->secret,
|
'client_secret' => $this->secret,
|
||||||
'redirect_uri' => $this->callbackUrl,
|
'redirect_uri' => $this->callbackUrl,
|
||||||
'grant_type' => 'authorization_code',
|
'grant_type' => 'authorization_code',
|
||||||
|
'state' => $this->getState(),
|
||||||
);
|
);
|
||||||
|
|
||||||
$response = json_decode($this->httpClient->postForm($this->tokenUrl, $params, array('Accept: application/json')), true);
|
$response = json_decode($this->httpClient->postForm($this->tokenUrl, $params, array('Accept: application/json')), true);
|
||||||
|
|
|
@ -30,6 +30,11 @@ class Request extends Base
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @param \Pimple\Container $container
|
* @param \Pimple\Container $container
|
||||||
|
* @param array $server
|
||||||
|
* @param array $get
|
||||||
|
* @param array $post
|
||||||
|
* @param array $files
|
||||||
|
* @param array $cookies
|
||||||
*/
|
*/
|
||||||
public function __construct(Container $container, array $server = array(), array $get = array(), array $post = array(), array $files = array(), array $cookies = array())
|
public function __construct(Container $container, array $server = array(), array $get = array(), array $post = array(), array $files = array(), array $cookies = array())
|
||||||
{
|
{
|
||||||
|
@ -211,7 +216,11 @@ class Request extends Base
|
||||||
*/
|
*/
|
||||||
public function isHTTPS()
|
public function isHTTPS()
|
||||||
{
|
{
|
||||||
return isset($this->server['HTTPS']) && $this->server['HTTPS'] !== '' && $this->server['HTTPS'] !== 'off';
|
if ($this->getServerVariable('HTTP_X_FORWARDED_PROTO') === 'https') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->getServerVariable('HTTPS') !== '' && $this->server['HTTPS'] !== 'off';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -13,6 +13,24 @@ use Kanboard\Core\Csv;
|
||||||
*/
|
*/
|
||||||
class Response extends Base
|
class Response extends Base
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Send headers to cache a resource
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param integer $duration
|
||||||
|
* @param string $etag
|
||||||
|
*/
|
||||||
|
public function cache($duration, $etag = '')
|
||||||
|
{
|
||||||
|
header('Pragma: cache');
|
||||||
|
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $duration) . ' GMT');
|
||||||
|
header('Cache-Control: public, max-age=' . $duration);
|
||||||
|
|
||||||
|
if ($etag) {
|
||||||
|
header('ETag: "' . $etag . '"');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send no cache headers
|
* Send no cache headers
|
||||||
*
|
*
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
namespace Kanboard\Core\Ldap;
|
namespace Kanboard\Core\Ldap;
|
||||||
|
|
||||||
use LogicException;
|
use LogicException;
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* LDAP Client
|
* LDAP Client
|
||||||
|
@ -20,6 +21,14 @@ class Client
|
||||||
*/
|
*/
|
||||||
protected $ldap;
|
protected $ldap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logger instance
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var LoggerInterface
|
||||||
|
*/
|
||||||
|
private $logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Establish LDAP connection
|
* Establish LDAP connection
|
||||||
*
|
*
|
||||||
|
@ -31,7 +40,7 @@ class Client
|
||||||
*/
|
*/
|
||||||
public static function connect($username = null, $password = null)
|
public static function connect($username = null, $password = null)
|
||||||
{
|
{
|
||||||
$client = new self;
|
$client = new static;
|
||||||
$client->open($client->getLdapServer());
|
$client->open($client->getLdapServer());
|
||||||
$username = $username ?: $client->getLdapUsername();
|
$username = $username ?: $client->getLdapUsername();
|
||||||
$password = $password ?: $client->getLdapPassword();
|
$password = $password ?: $client->getLdapPassword();
|
||||||
|
@ -60,6 +69,7 @@ class Client
|
||||||
* Establish server connection
|
* Establish server connection
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
|
* @throws ClientException
|
||||||
* @param string $server LDAP server hostname or IP
|
* @param string $server LDAP server hostname or IP
|
||||||
* @param integer $port LDAP port
|
* @param integer $port LDAP port
|
||||||
* @param boolean $tls Start TLS
|
* @param boolean $tls Start TLS
|
||||||
|
@ -98,6 +108,7 @@ class Client
|
||||||
* Anonymous authentication
|
* Anonymous authentication
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
|
* @throws ClientException
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function useAnonymousAuthentication()
|
public function useAnonymousAuthentication()
|
||||||
|
@ -113,6 +124,7 @@ class Client
|
||||||
* Authentication with username/password
|
* Authentication with username/password
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
|
* @throws ClientException
|
||||||
* @param string $bind_rdn
|
* @param string $bind_rdn
|
||||||
* @param string $bind_password
|
* @param string $bind_password
|
||||||
* @return boolean
|
* @return boolean
|
||||||
|
@ -162,4 +174,39 @@ class Client
|
||||||
{
|
{
|
||||||
return LDAP_PASSWORD;
|
return LDAP_PASSWORD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set logger
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param LoggerInterface $logger
|
||||||
|
* @return Client
|
||||||
|
*/
|
||||||
|
public function setLogger(LoggerInterface $logger)
|
||||||
|
{
|
||||||
|
$this->logger = $logger;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get logger
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return LoggerInterface
|
||||||
|
*/
|
||||||
|
public function getLogger()
|
||||||
|
{
|
||||||
|
return $this->logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test if a logger is defined
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function hasLogger()
|
||||||
|
{
|
||||||
|
return $this->logger !== null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,12 @@ class Query
|
||||||
*/
|
*/
|
||||||
public function execute($baseDn, $filter, array $attributes)
|
public function execute($baseDn, $filter, array $attributes)
|
||||||
{
|
{
|
||||||
|
if (DEBUG && $this->client->hasLogger()) {
|
||||||
|
$this->client->getLogger()->debug('BaseDN='.$baseDn);
|
||||||
|
$this->client->getLogger()->debug('Filter='.$filter);
|
||||||
|
$this->client->getLogger()->debug('Attributes='.implode(', ', $attributes));
|
||||||
|
}
|
||||||
|
|
||||||
$sr = ldap_search($this->client->getConnection(), $baseDn, $filter, $attributes);
|
$sr = ldap_search($this->client->getConnection(), $baseDn, $filter, $attributes);
|
||||||
if ($sr === false) {
|
if ($sr === false) {
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -78,7 +84,7 @@ class Query
|
||||||
* Get LDAP Entries
|
* Get LDAP Entries
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @return Entities
|
* @return Entries
|
||||||
*/
|
*/
|
||||||
public function getEntries()
|
public function getEntries()
|
||||||
{
|
{
|
||||||
|
|
|
@ -44,8 +44,7 @@ class User
|
||||||
*/
|
*/
|
||||||
public static function getUser(Client $client, $username)
|
public static function getUser(Client $client, $username)
|
||||||
{
|
{
|
||||||
$className = get_called_class();
|
$self = new static(new Query($client));
|
||||||
$self = new $className(new Query($client));
|
|
||||||
return $self->find($self->getLdapUserPattern($username));
|
return $self->find($self->getLdapUserPattern($username));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,14 +210,15 @@ class User
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $username
|
* @param string $username
|
||||||
|
* @param string $filter
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getLdapUserPattern($username)
|
public function getLdapUserPattern($username, $filter = LDAP_USER_FILTER)
|
||||||
{
|
{
|
||||||
if (! LDAP_USER_FILTER) {
|
if (! $filter) {
|
||||||
throw new LogicException('LDAP user filter empty, check the parameter LDAP_USER_FILTER');
|
throw new LogicException('LDAP user filter empty, check the parameter LDAP_USER_FILTER');
|
||||||
}
|
}
|
||||||
|
|
||||||
return sprintf(LDAP_USER_FILTER, $username);
|
return str_replace('%s', $username, $filter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ class Client extends Base
|
||||||
* @param string $name
|
* @param string $name
|
||||||
* @param string $subject
|
* @param string $subject
|
||||||
* @param string $html
|
* @param string $html
|
||||||
* @return EmailClient
|
* @return Client
|
||||||
*/
|
*/
|
||||||
public function send($email, $name, $subject, $html)
|
public function send($email, $name, $subject, $html)
|
||||||
{
|
{
|
||||||
|
@ -70,7 +70,7 @@ class Client extends Base
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $transport
|
* @param string $transport
|
||||||
* @return EmailClientInterface
|
* @return ClientInterface
|
||||||
*/
|
*/
|
||||||
public function getTransport($transport)
|
public function getTransport($transport)
|
||||||
{
|
{
|
||||||
|
@ -83,7 +83,7 @@ class Client extends Base
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $transport
|
* @param string $transport
|
||||||
* @param string $class
|
* @param string $class
|
||||||
* @return EmailClient
|
* @return Client
|
||||||
*/
|
*/
|
||||||
public function setTransport($transport, $class)
|
public function setTransport($transport, $class)
|
||||||
{
|
{
|
||||||
|
|
|
@ -33,6 +33,7 @@ class FileStorage implements ObjectStorageInterface
|
||||||
* Fetch object contents
|
* Fetch object contents
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
|
* @throws ObjectStorageException
|
||||||
* @param string $key
|
* @param string $key
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
|
@ -51,6 +52,7 @@ class FileStorage implements ObjectStorageInterface
|
||||||
* Save object
|
* Save object
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
|
* @throws ObjectStorageException
|
||||||
* @param string $key
|
* @param string $key
|
||||||
* @param string $blob
|
* @param string $blob
|
||||||
*/
|
*/
|
||||||
|
@ -67,6 +69,7 @@ class FileStorage implements ObjectStorageInterface
|
||||||
* Output directly object content
|
* Output directly object content
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
|
* @throws ObjectStorageException
|
||||||
* @param string $key
|
* @param string $key
|
||||||
*/
|
*/
|
||||||
public function output($key)
|
public function output($key)
|
||||||
|
@ -84,6 +87,7 @@ class FileStorage implements ObjectStorageInterface
|
||||||
* Move local file to object storage
|
* Move local file to object storage
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
|
* @throws ObjectStorageException
|
||||||
* @param string $src_filename
|
* @param string $src_filename
|
||||||
* @param string $key
|
* @param string $key
|
||||||
* @return boolean
|
* @return boolean
|
||||||
|
@ -136,6 +140,7 @@ class FileStorage implements ObjectStorageInterface
|
||||||
* Create object folder
|
* Create object folder
|
||||||
*
|
*
|
||||||
* @access private
|
* @access private
|
||||||
|
* @throws ObjectStorageException
|
||||||
* @param string $key
|
* @param string $key
|
||||||
*/
|
*/
|
||||||
private function createFolder($key)
|
private function createFolder($key)
|
||||||
|
|
|
@ -40,6 +40,17 @@ abstract class Base extends \Kanboard\Core\Base
|
||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all helper classes that needs to be stored in the DI container
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getHelpers()
|
||||||
|
{
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Listen on internal events
|
* Listen on internal events
|
||||||
*
|
*
|
||||||
|
|
|
@ -55,6 +55,7 @@ class Loader extends \Kanboard\Core\Base
|
||||||
* Load plugin
|
* Load plugin
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
|
* @throws LogicException
|
||||||
* @param string $plugin
|
* @param string $plugin
|
||||||
*/
|
*/
|
||||||
public function load($plugin)
|
public function load($plugin)
|
||||||
|
@ -69,6 +70,8 @@ class Loader extends \Kanboard\Core\Base
|
||||||
|
|
||||||
Tool::buildDic($this->container, $instance->getClasses());
|
Tool::buildDic($this->container, $instance->getClasses());
|
||||||
|
|
||||||
|
Tool::buildDICHelpers($this->container, $instance->getHelpers());
|
||||||
|
|
||||||
$instance->initialize();
|
$instance->initialize();
|
||||||
$this->plugins[] = $instance;
|
$this->plugins[] = $instance;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ class AccessMap
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $role
|
* @param string $role
|
||||||
* @return Acl
|
* @return AccessMap
|
||||||
*/
|
*/
|
||||||
public function setDefaultRole($role)
|
public function setDefaultRole($role)
|
||||||
{
|
{
|
||||||
|
@ -53,7 +53,7 @@ class AccessMap
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $role
|
* @param string $role
|
||||||
* @param array $subroles
|
* @param array $subroles
|
||||||
* @return Acl
|
* @return AccessMap
|
||||||
*/
|
*/
|
||||||
public function setRoleHierarchy($role, array $subroles)
|
public function setRoleHierarchy($role, array $subroles)
|
||||||
{
|
{
|
||||||
|
@ -113,7 +113,7 @@ class AccessMap
|
||||||
* @param string $controller Controller class name
|
* @param string $controller Controller class name
|
||||||
* @param mixed $methods List of method name or just one method
|
* @param mixed $methods List of method name or just one method
|
||||||
* @param string $role Lowest role required
|
* @param string $role Lowest role required
|
||||||
* @return Acl
|
* @return AccessMap
|
||||||
*/
|
*/
|
||||||
public function add($controller, $methods, $role)
|
public function add($controller, $methods, $role)
|
||||||
{
|
{
|
||||||
|
@ -135,7 +135,7 @@ class AccessMap
|
||||||
* @param string $controller
|
* @param string $controller
|
||||||
* @param string $method
|
* @param string $method
|
||||||
* @param string $role
|
* @param string $role
|
||||||
* @return Acl
|
* @return AccessMap
|
||||||
*/
|
*/
|
||||||
private function addRule($controller, $method, $role)
|
private function addRule($controller, $method, $role)
|
||||||
{
|
{
|
||||||
|
@ -157,7 +157,7 @@ class AccessMap
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $controller
|
* @param string $controller
|
||||||
* @param string $method
|
* @param string $method
|
||||||
* @return boolean
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getRoles($controller, $method)
|
public function getRoles($controller, $method)
|
||||||
{
|
{
|
||||||
|
|
|
@ -14,7 +14,7 @@ interface OAuthAuthenticationProviderInterface extends AuthenticationProviderInt
|
||||||
* Get user object
|
* Get user object
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @return UserProviderInterface
|
* @return \Kanboard\Core\User\UserProviderInterface
|
||||||
*/
|
*/
|
||||||
public function getUser();
|
public function getUser();
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ interface OAuthAuthenticationProviderInterface extends AuthenticationProviderInt
|
||||||
* Get configured OAuth2 service
|
* Get configured OAuth2 service
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @return Kanboard\Core\Http\OAuth2
|
* @return \Kanboard\Core\Http\OAuth2
|
||||||
*/
|
*/
|
||||||
public function getService();
|
public function getService();
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ interface PasswordAuthenticationProviderInterface extends AuthenticationProvider
|
||||||
* Get user object
|
* Get user object
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @return UserProviderInterface
|
* @return \Kanboard\Core\User\UserProviderInterface
|
||||||
*/
|
*/
|
||||||
public function getUser();
|
public function getUser();
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ interface PreAuthenticationProviderInterface extends AuthenticationProviderInter
|
||||||
* Get user object
|
* Get user object
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @return UserProviderInterface
|
* @return \Kanboard\Core\User\UserProviderInterface
|
||||||
*/
|
*/
|
||||||
public function getUser();
|
public function getUser();
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ namespace Kanboard\Core\Session;
|
||||||
* @property bool $boardCollapsed
|
* @property bool $boardCollapsed
|
||||||
* @property bool $twoFactorBeforeCodeCalled
|
* @property bool $twoFactorBeforeCodeCalled
|
||||||
* @property string $twoFactorSecret
|
* @property string $twoFactorSecret
|
||||||
|
* @property string $oauthState
|
||||||
*/
|
*/
|
||||||
class SessionStorage
|
class SessionStorage
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,13 +3,36 @@
|
||||||
namespace Kanboard\Core;
|
namespace Kanboard\Core;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Template class
|
* Template
|
||||||
*
|
*
|
||||||
* @package core
|
* @package core
|
||||||
* @author Frederic Guillot
|
* @author Frederic Guillot
|
||||||
|
*
|
||||||
|
* @property \Kanboard\Helper\AppHelper $app
|
||||||
|
* @property \Kanboard\Helper\AssetHelper $asset
|
||||||
|
* @property \Kanboard\Helper\DateHelper $dt
|
||||||
|
* @property \Kanboard\Helper\FileHelper $file
|
||||||
|
* @property \Kanboard\Helper\FormHelper $form
|
||||||
|
* @property \Kanboard\Helper\HookHelper $hook
|
||||||
|
* @property \Kanboard\Helper\ModelHelper $model
|
||||||
|
* @property \Kanboard\Helper\SubtaskHelper $subtask
|
||||||
|
* @property \Kanboard\Helper\TaskHelper $task
|
||||||
|
* @property \Kanboard\Helper\TextHelper $text
|
||||||
|
* @property \Kanboard\Helper\UrlHelper $url
|
||||||
|
* @property \Kanboard\Helper\UserHelper $user
|
||||||
|
* @property \Kanboard\Helper\LayoutHelper $layout
|
||||||
|
* @property \Kanboard\Helper\ProjectHeaderHelper $projectHeader
|
||||||
*/
|
*/
|
||||||
class Template extends Helper
|
class Template
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Helper object
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var Helper
|
||||||
|
*/
|
||||||
|
private $helper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of template overrides
|
* List of template overrides
|
||||||
*
|
*
|
||||||
|
@ -19,47 +42,26 @@ class Template extends Helper
|
||||||
private $overrides = array();
|
private $overrides = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rendering start time
|
* Template constructor
|
||||||
*
|
*
|
||||||
* @access private
|
* @access public
|
||||||
* @var float
|
* @param Helper $helper
|
||||||
*/
|
*/
|
||||||
private $startTime = 0;
|
public function __construct(Helper $helper)
|
||||||
|
|
||||||
/**
|
|
||||||
* Total rendering time
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
* @var float
|
|
||||||
*/
|
|
||||||
private $renderingTime = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method executed before the rendering
|
|
||||||
*
|
|
||||||
* @access protected
|
|
||||||
* @param string $template
|
|
||||||
*/
|
|
||||||
protected function beforeRender($template)
|
|
||||||
{
|
{
|
||||||
if (DEBUG) {
|
$this->helper = $helper;
|
||||||
$this->startTime = microtime(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method executed after the rendering
|
* Expose helpers with magic getter
|
||||||
*
|
*
|
||||||
* @access protected
|
* @access public
|
||||||
* @param string $template
|
* @param string $helper
|
||||||
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
protected function afterRender($template)
|
public function __get($helper)
|
||||||
{
|
{
|
||||||
if (DEBUG) {
|
return $this->helper->getHelper($helper);
|
||||||
$duration = microtime(true) - $this->startTime;
|
|
||||||
$this->renderingTime += $duration;
|
|
||||||
$this->container['logger']->debug('Rendering '.$template.' in '.$duration.'s, total='.$this->renderingTime);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -76,33 +78,10 @@ class Template extends Helper
|
||||||
*/
|
*/
|
||||||
public function render($__template_name, array $__template_args = array())
|
public function render($__template_name, array $__template_args = array())
|
||||||
{
|
{
|
||||||
$this->beforeRender($__template_name);
|
|
||||||
|
|
||||||
extract($__template_args);
|
extract($__template_args);
|
||||||
ob_start();
|
ob_start();
|
||||||
include $this->getTemplateFile($__template_name);
|
include $this->getTemplateFile($__template_name);
|
||||||
$html = ob_get_clean();
|
return ob_get_clean();
|
||||||
|
|
||||||
$this->afterRender($__template_name);
|
|
||||||
|
|
||||||
return $html;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Render a page layout
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @param string $template_name Template name
|
|
||||||
* @param array $template_args Key/value map
|
|
||||||
* @param string $layout_name Layout name
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function layout($template_name, array $template_args = array(), $layout_name = 'layout')
|
|
||||||
{
|
|
||||||
return $this->render(
|
|
||||||
$layout_name,
|
|
||||||
$template_args + array('content_for_layout' => $this->render($template_name, $template_args))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -120,25 +99,26 @@ class Template extends Helper
|
||||||
/**
|
/**
|
||||||
* Find template filename
|
* Find template filename
|
||||||
*
|
*
|
||||||
* Core template name: 'task/show'
|
* Core template: 'task/show' or 'kanboard:task/show'
|
||||||
* Plugin template name: 'myplugin:task/show'
|
* Plugin template: 'myplugin:task/show'
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $template_name
|
* @param string $template
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getTemplateFile($template_name)
|
public function getTemplateFile($template)
|
||||||
{
|
{
|
||||||
$template_name = isset($this->overrides[$template_name]) ? $this->overrides[$template_name] : $template_name;
|
$plugin = '';
|
||||||
|
$template = isset($this->overrides[$template]) ? $this->overrides[$template] : $template;
|
||||||
|
|
||||||
if (strpos($template_name, ':') !== false) {
|
if (strpos($template, ':') !== false) {
|
||||||
list($plugin, $template) = explode(':', $template_name);
|
list($plugin, $template) = explode(':', $template);
|
||||||
$path = __DIR__.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'plugins';
|
|
||||||
$path .= DIRECTORY_SEPARATOR.ucfirst($plugin).DIRECTORY_SEPARATOR.'Template'.DIRECTORY_SEPARATOR.$template.'.php';
|
|
||||||
} else {
|
|
||||||
$path = __DIR__.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'Template'.DIRECTORY_SEPARATOR.$template_name.'.php';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $path;
|
if ($plugin !== 'kanboard' && $plugin !== '') {
|
||||||
|
return implode(DIRECTORY_SEPARATOR, array(__DIR__, '..', '..', 'plugins', ucfirst($plugin), 'Template', $template.'.php'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return implode(DIRECTORY_SEPARATOR, array(__DIR__, '..', 'Template', $template.'.php'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
172
sources/app/Core/Thumbnail.php
Normal file
172
sources/app/Core/Thumbnail.php
Normal file
|
@ -0,0 +1,172 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Kanboard\Core;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thumbnail Generator
|
||||||
|
*
|
||||||
|
* @package core
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class Thumbnail
|
||||||
|
{
|
||||||
|
protected $metadata = array();
|
||||||
|
protected $srcImage;
|
||||||
|
protected $dstImage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a thumbnail from a local file
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
* @access public
|
||||||
|
* @param string $filename
|
||||||
|
* @return Thumbnail
|
||||||
|
*/
|
||||||
|
public static function createFromFile($filename)
|
||||||
|
{
|
||||||
|
$self = new static();
|
||||||
|
$self->fromFile($filename);
|
||||||
|
return $self;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a thumbnail from a string
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
* @access public
|
||||||
|
* @param string $blob
|
||||||
|
* @return Thumbnail
|
||||||
|
*/
|
||||||
|
public static function createFromString($blob)
|
||||||
|
{
|
||||||
|
$self = new static();
|
||||||
|
$self->fromString($blob);
|
||||||
|
return $self;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the local image file in memory with GD
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $filename
|
||||||
|
* @return Thumbnail
|
||||||
|
*/
|
||||||
|
public function fromFile($filename)
|
||||||
|
{
|
||||||
|
$this->metadata = getimagesize($filename);
|
||||||
|
$this->srcImage = imagecreatefromstring(file_get_contents($filename));
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the image blob in memory with GD
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $blob
|
||||||
|
* @return Thumbnail
|
||||||
|
*/
|
||||||
|
public function fromString($blob)
|
||||||
|
{
|
||||||
|
if (!function_exists('getimagesizefromstring')) {
|
||||||
|
$uri = 'data://application/octet-stream;base64,' . base64_encode($blob);
|
||||||
|
$this->metadata = getimagesize($uri);
|
||||||
|
} else {
|
||||||
|
$this->metadata = getimagesizefromstring($blob);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->srcImage = imagecreatefromstring($blob);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resize the image
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param int $width
|
||||||
|
* @param int $height
|
||||||
|
* @return Thumbnail
|
||||||
|
*/
|
||||||
|
public function resize($width = 250, $height = 100)
|
||||||
|
{
|
||||||
|
$srcWidth = $this->metadata[0];
|
||||||
|
$srcHeight = $this->metadata[1];
|
||||||
|
$dstX = 0;
|
||||||
|
$dstY = 0;
|
||||||
|
|
||||||
|
if ($width == 0 && $height == 0) {
|
||||||
|
$width = 100;
|
||||||
|
$height = 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($width > 0 && $height == 0) {
|
||||||
|
$dstWidth = $width;
|
||||||
|
$dstHeight = floor($srcHeight * ($width / $srcWidth));
|
||||||
|
$this->dstImage = imagecreatetruecolor($dstWidth, $dstHeight);
|
||||||
|
} elseif ($width == 0 && $height > 0) {
|
||||||
|
$dstWidth = floor($srcWidth * ($height / $srcHeight));
|
||||||
|
$dstHeight = $height;
|
||||||
|
$this->dstImage = imagecreatetruecolor($dstWidth, $dstHeight);
|
||||||
|
} else {
|
||||||
|
$srcRatio = $srcWidth / $srcHeight;
|
||||||
|
$resizeRatio = $width / $height;
|
||||||
|
|
||||||
|
if ($srcRatio <= $resizeRatio) {
|
||||||
|
$dstWidth = $width;
|
||||||
|
$dstHeight = floor($srcHeight * ($width / $srcWidth));
|
||||||
|
$dstY = ($dstHeight - $height) / 2 * (-1);
|
||||||
|
} else {
|
||||||
|
$dstWidth = floor($srcWidth * ($height / $srcHeight));
|
||||||
|
$dstHeight = $height;
|
||||||
|
$dstX = ($dstWidth - $width) / 2 * (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->dstImage = imagecreatetruecolor($width, $height);
|
||||||
|
}
|
||||||
|
|
||||||
|
imagecopyresampled($this->dstImage, $this->srcImage, $dstX, $dstY, 0, 0, $dstWidth, $dstHeight, $srcWidth, $srcHeight);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save the thumbnail to a local file
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $filename
|
||||||
|
* @return Thumbnail
|
||||||
|
*/
|
||||||
|
public function toFile($filename)
|
||||||
|
{
|
||||||
|
imagejpeg($this->dstImage, $filename);
|
||||||
|
imagedestroy($this->dstImage);
|
||||||
|
imagedestroy($this->srcImage);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the thumbnail as a string
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function toString()
|
||||||
|
{
|
||||||
|
ob_start();
|
||||||
|
imagejpeg($this->dstImage, null);
|
||||||
|
imagedestroy($this->dstImage);
|
||||||
|
imagedestroy($this->srcImage);
|
||||||
|
return ob_get_clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Output the thumbnail directly to the browser or stdout
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
public function toOutput()
|
||||||
|
{
|
||||||
|
imagejpeg($this->dstImage, null);
|
||||||
|
imagedestroy($this->dstImage);
|
||||||
|
imagedestroy($this->srcImage);
|
||||||
|
}
|
||||||
|
}
|
|
@ -56,76 +56,23 @@ class Tool
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a jpeg thumbnail from an image
|
* Build dependency injection container for custom helpers from an array
|
||||||
*
|
*
|
||||||
* @static
|
* @static
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $src_file Source file image
|
* @param Container $container
|
||||||
* @param string $dst_file Destination file image
|
* @param array $namespaces
|
||||||
* @param integer $resize_width Desired image width
|
* @return Container
|
||||||
* @param integer $resize_height Desired image height
|
|
||||||
*/
|
*/
|
||||||
public static function generateThumbnail($src_file, $dst_file, $resize_width = 250, $resize_height = 100)
|
public static function buildDICHelpers(Container $container, array $namespaces)
|
||||||
{
|
{
|
||||||
$metadata = getimagesize($src_file);
|
foreach ($namespaces as $namespace => $classes) {
|
||||||
$src_width = $metadata[0];
|
foreach ($classes as $name) {
|
||||||
$src_height = $metadata[1];
|
$class = '\\Kanboard\\'.$namespace.'\\'.$name;
|
||||||
$dst_y = 0;
|
$container['helper']->register($name, $class);
|
||||||
$dst_x = 0;
|
}
|
||||||
|
}
|
||||||
if (empty($metadata['mime'])) {
|
|
||||||
return;
|
return $container;
|
||||||
}
|
|
||||||
|
|
||||||
if ($resize_width == 0 && $resize_height == 0) {
|
|
||||||
$resize_width = 100;
|
|
||||||
$resize_height = 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($resize_width > 0 && $resize_height == 0) {
|
|
||||||
$dst_width = $resize_width;
|
|
||||||
$dst_height = floor($src_height * ($resize_width / $src_width));
|
|
||||||
$dst_image = imagecreatetruecolor($dst_width, $dst_height);
|
|
||||||
} elseif ($resize_width == 0 && $resize_height > 0) {
|
|
||||||
$dst_width = floor($src_width * ($resize_height / $src_height));
|
|
||||||
$dst_height = $resize_height;
|
|
||||||
$dst_image = imagecreatetruecolor($dst_width, $dst_height);
|
|
||||||
} else {
|
|
||||||
$src_ratio = $src_width / $src_height;
|
|
||||||
$resize_ratio = $resize_width / $resize_height;
|
|
||||||
|
|
||||||
if ($src_ratio <= $resize_ratio) {
|
|
||||||
$dst_width = $resize_width;
|
|
||||||
$dst_height = floor($src_height * ($resize_width / $src_width));
|
|
||||||
|
|
||||||
$dst_y = ($dst_height - $resize_height) / 2 * (-1);
|
|
||||||
} else {
|
|
||||||
$dst_width = floor($src_width * ($resize_height / $src_height));
|
|
||||||
$dst_height = $resize_height;
|
|
||||||
|
|
||||||
$dst_x = ($dst_width - $resize_width) / 2 * (-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
$dst_image = imagecreatetruecolor($resize_width, $resize_height);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ($metadata['mime']) {
|
|
||||||
case 'image/jpeg':
|
|
||||||
case 'image/jpg':
|
|
||||||
$src_image = imagecreatefromjpeg($src_file);
|
|
||||||
break;
|
|
||||||
case 'image/png':
|
|
||||||
$src_image = imagecreatefrompng($src_file);
|
|
||||||
break;
|
|
||||||
case 'image/gif':
|
|
||||||
$src_image = imagecreatefromgif($src_file);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
imagecopyresampled($dst_image, $src_image, $dst_x, $dst_y, 0, 0, $dst_width, $dst_height, $src_width, $src_height);
|
|
||||||
imagejpeg($dst_image, $dst_file);
|
|
||||||
imagedestroy($dst_image);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
93
sources/app/Core/User/Avatar/AvatarManager.php
Normal file
93
sources/app/Core/User/Avatar/AvatarManager.php
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Kanboard\Core\User\Avatar;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Avatar Manager
|
||||||
|
*
|
||||||
|
* @package avatar
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class AvatarManager
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Providers
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var AvatarProviderInterface[]
|
||||||
|
*/
|
||||||
|
private $providers = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a new Avatar provider
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param AvatarProviderInterface $provider
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function register(AvatarProviderInterface $provider)
|
||||||
|
{
|
||||||
|
$this->providers[] = $provider;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render avatar HTML element
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $user_id
|
||||||
|
* @param string $username
|
||||||
|
* @param string $name
|
||||||
|
* @param string $email
|
||||||
|
* @param string $avatar_path
|
||||||
|
* @param int $size
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function render($user_id, $username, $name, $email, $avatar_path, $size)
|
||||||
|
{
|
||||||
|
$user = array(
|
||||||
|
'id' => $user_id,
|
||||||
|
'username' => $username,
|
||||||
|
'name' => $name,
|
||||||
|
'email' => $email,
|
||||||
|
'avatar_path' => $avatar_path,
|
||||||
|
);
|
||||||
|
|
||||||
|
krsort($this->providers);
|
||||||
|
|
||||||
|
foreach ($this->providers as $provider) {
|
||||||
|
if ($provider->isActive($user)) {
|
||||||
|
return $provider->render($user, $size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render default provider for unknown users (first provider registered)
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param integer $size
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function renderDefault($size)
|
||||||
|
{
|
||||||
|
if (count($this->providers) > 0) {
|
||||||
|
ksort($this->providers);
|
||||||
|
$provider = current($this->providers);
|
||||||
|
|
||||||
|
$user = array(
|
||||||
|
'id' => 0,
|
||||||
|
'username' => '',
|
||||||
|
'name' => '?',
|
||||||
|
'email' => '',
|
||||||
|
'avatar_path' => '',
|
||||||
|
);
|
||||||
|
|
||||||
|
return $provider->render($user, $size);
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
30
sources/app/Core/User/Avatar/AvatarProviderInterface.php
Normal file
30
sources/app/Core/User/Avatar/AvatarProviderInterface.php
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Kanboard\Core\User\Avatar;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Avatar Provider Interface
|
||||||
|
*
|
||||||
|
* @package user
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
interface AvatarProviderInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Render avatar html
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param array $user
|
||||||
|
* @param int $size
|
||||||
|
*/
|
||||||
|
public function render(array $user, $size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the provider is active
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param array $user
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function isActive(array $user);
|
||||||
|
}
|
|
@ -13,6 +13,19 @@ use Kanboard\Core\Security\Role;
|
||||||
*/
|
*/
|
||||||
class UserSession extends Base
|
class UserSession extends Base
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Refresh current session if necessary
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param integer $user_id
|
||||||
|
*/
|
||||||
|
public function refresh($user_id)
|
||||||
|
{
|
||||||
|
if ($this->getId() == $user_id) {
|
||||||
|
$this->initialize($this->user->getById($user_id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update user session
|
* Update user session
|
||||||
*
|
*
|
||||||
|
@ -35,6 +48,17 @@ class UserSession extends Base
|
||||||
$this->sessionStorage->postAuthenticationValidated = false;
|
$this->sessionStorage->postAuthenticationValidated = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get user properties
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getAll()
|
||||||
|
{
|
||||||
|
return $this->sessionStorage->user;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get user application role
|
* Get user application role
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,11 +1,16 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Kanboard\Model;
|
namespace Kanboard\Export;
|
||||||
|
|
||||||
|
use Kanboard\Core\Base;
|
||||||
|
use Kanboard\Model\Task;
|
||||||
|
use Kanboard\Model\Subtask;
|
||||||
|
use Kanboard\Model\User;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subtask Export
|
* Subtask Export
|
||||||
*
|
*
|
||||||
* @package model
|
* @package export
|
||||||
* @author Frederic Guillot
|
* @author Frederic Guillot
|
||||||
*/
|
*/
|
||||||
class SubtaskExport extends Base
|
class SubtaskExport extends Base
|
|
@ -1,13 +1,16 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Kanboard\Model;
|
namespace Kanboard\Export;
|
||||||
|
|
||||||
|
use Kanboard\Core\Base;
|
||||||
|
use Kanboard\Core\DateParser;
|
||||||
|
use Kanboard\Model\Task;
|
||||||
use PDO;
|
use PDO;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Task Export model
|
* Task Export
|
||||||
*
|
*
|
||||||
* @package model
|
* @package export
|
||||||
* @author Frederic Guillot
|
* @author Frederic Guillot
|
||||||
*/
|
*/
|
||||||
class TaskExport extends Base
|
class TaskExport extends Base
|
||||||
|
@ -106,7 +109,7 @@ class TaskExport extends Base
|
||||||
$task['score'] = $task['score'] ?: 0;
|
$task['score'] = $task['score'] ?: 0;
|
||||||
$task['swimlane_id'] = isset($swimlanes[$task['swimlane_id']]) ? $swimlanes[$task['swimlane_id']] : '?';
|
$task['swimlane_id'] = isset($swimlanes[$task['swimlane_id']]) ? $swimlanes[$task['swimlane_id']] : '?';
|
||||||
|
|
||||||
$task = $this->dateParser->format($task, array('date_due', 'date_modification', 'date_creation', 'date_started', 'date_completed'), 'Y-m-d');
|
$task = $this->dateParser->format($task, array('date_due', 'date_modification', 'date_creation', 'date_started', 'date_completed'), DateParser::DATE_FORMAT);
|
||||||
|
|
||||||
return $task;
|
return $task;
|
||||||
}
|
}
|
77
sources/app/Export/TransitionExport.php
Normal file
77
sources/app/Export/TransitionExport.php
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Kanboard\Export;
|
||||||
|
|
||||||
|
use Kanboard\Core\Base;
|
||||||
|
use Kanboard\Core\DateParser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transition Export
|
||||||
|
*
|
||||||
|
* @package export
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class TransitionExport extends Base
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get project export
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param integer $project_id Project id
|
||||||
|
* @param mixed $from Start date (timestamp or user formatted date)
|
||||||
|
* @param mixed $to End date (timestamp or user formatted date)
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function export($project_id, $from, $to)
|
||||||
|
{
|
||||||
|
$results = array($this->getColumns());
|
||||||
|
$transitions = $this->transition->getAllByProjectAndDate($project_id, $from, $to);
|
||||||
|
|
||||||
|
foreach ($transitions as $transition) {
|
||||||
|
$results[] = $this->format($transition);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $results;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get column titles
|
||||||
|
*
|
||||||
|
* @access protected
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
protected function getColumns()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
e('Id'),
|
||||||
|
e('Task Title'),
|
||||||
|
e('Source column'),
|
||||||
|
e('Destination column'),
|
||||||
|
e('Executer'),
|
||||||
|
e('Date'),
|
||||||
|
e('Time spent'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format the output of a transition array
|
||||||
|
*
|
||||||
|
* @access protected
|
||||||
|
* @param array $transition
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function format(array $transition)
|
||||||
|
{
|
||||||
|
$values = array(
|
||||||
|
(int) $transition['id'],
|
||||||
|
$transition['title'],
|
||||||
|
$transition['src_column'],
|
||||||
|
$transition['dst_column'],
|
||||||
|
$transition['name'] ?: $transition['username'],
|
||||||
|
date($this->config->get('application_datetime_format', DateParser::DATE_TIME_FORMAT), $transition['date']),
|
||||||
|
round($transition['time_spent'] / 3600, 2)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $values;
|
||||||
|
}
|
||||||
|
}
|
|
@ -85,7 +85,7 @@ class AttachmentLinkProvider extends BaseLinkProvider implements ExternalLinkPro
|
||||||
* Get the link found with the properties
|
* Get the link found with the properties
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @return ExternalLinkInterface
|
* @return \Kanboard\Core\ExternalLink\ExternalLinkInterface
|
||||||
*/
|
*/
|
||||||
public function getLink()
|
public function getLink()
|
||||||
{
|
{
|
||||||
|
|
26
sources/app/ExternalLink/FileLink.php
Normal file
26
sources/app/ExternalLink/FileLink.php
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Kanboard\ExternalLink;
|
||||||
|
|
||||||
|
use Kanboard\Core\ExternalLink\ExternalLinkInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* File Link
|
||||||
|
*
|
||||||
|
* @package externalLink
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class FileLink extends BaseLink implements ExternalLinkInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get link title
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getTitle()
|
||||||
|
{
|
||||||
|
$path = parse_url($this->url, PHP_URL_PATH);
|
||||||
|
return basename(str_replace('\\', '/', $path));
|
||||||
|
}
|
||||||
|
}
|
74
sources/app/ExternalLink/FileLinkProvider.php
Normal file
74
sources/app/ExternalLink/FileLinkProvider.php
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Kanboard\ExternalLink;
|
||||||
|
|
||||||
|
use Kanboard\Core\ExternalLink\ExternalLinkProviderInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* File Link Provider
|
||||||
|
*
|
||||||
|
* @package externalLink
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class FileLinkProvider extends BaseLinkProvider implements ExternalLinkProviderInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get provider name
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return t('Local File');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get link type
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getType()
|
||||||
|
{
|
||||||
|
return 'file';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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()
|
||||||
|
{
|
||||||
|
return strpos($this->userInput, 'file://') === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the link found with the properties
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return \Kanboard\Core\ExternalLink\ExternalLinkInterface
|
||||||
|
*/
|
||||||
|
public function getLink()
|
||||||
|
{
|
||||||
|
$link = new FileLink($this->container);
|
||||||
|
$link->setUrl($this->userInput);
|
||||||
|
|
||||||
|
return $link;
|
||||||
|
}
|
||||||
|
}
|
|
@ -65,7 +65,7 @@ class WebLinkProvider extends BaseLinkProvider implements ExternalLinkProviderIn
|
||||||
* Get the link found with the properties
|
* Get the link found with the properties
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @return ExternalLinkInterface
|
* @return \Kanboard\Core\ExternalLink\ExternalLinkInterface
|
||||||
*/
|
*/
|
||||||
public function getLink()
|
public function getLink()
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,12 +5,12 @@ namespace Kanboard\Helper;
|
||||||
use Kanboard\Core\Base;
|
use Kanboard\Core\Base;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Application helpers
|
* Application Helper
|
||||||
*
|
*
|
||||||
* @package helper
|
* @package helper
|
||||||
* @author Frederic Guillot
|
* @author Frederic Guillot
|
||||||
*/
|
*/
|
||||||
class App extends Base
|
class AppHelper extends Base
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Get config variable
|
* Get config variable
|
||||||
|
@ -116,11 +116,11 @@ class App extends Base
|
||||||
$failure_message = $this->flash->getMessage('failure');
|
$failure_message = $this->flash->getMessage('failure');
|
||||||
|
|
||||||
if (! empty($success_message)) {
|
if (! empty($success_message)) {
|
||||||
return '<div class="alert alert-success alert-fade-out">'.$this->helper->e($success_message).'</div>';
|
return '<div class="alert alert-success alert-fade-out">'.$this->helper->text->e($success_message).'</div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! empty($failure_message)) {
|
if (! empty($failure_message)) {
|
||||||
return '<div class="alert alert-error">'.$this->helper->e($failure_message).'</div>';
|
return '<div class="alert alert-error">'.$this->helper->text->e($failure_message).'</div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
return '';
|
return '';
|
|
@ -2,18 +2,21 @@
|
||||||
|
|
||||||
namespace Kanboard\Helper;
|
namespace Kanboard\Helper;
|
||||||
|
|
||||||
|
use Kanboard\Core\Base;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assets helpers
|
* Asset Helper
|
||||||
*
|
*
|
||||||
* @package helper
|
* @package helper
|
||||||
* @author Frederic Guillot
|
* @author Frederic Guillot
|
||||||
*/
|
*/
|
||||||
class Asset extends \Kanboard\Core\Base
|
class AssetHelper extends Base
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Add a Javascript asset
|
* Add a Javascript asset
|
||||||
*
|
*
|
||||||
* @param string $filename Filename
|
* @param string $filename Filename
|
||||||
|
* @param bool $async
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function js($filename, $async = false)
|
public function js($filename, $async = false)
|
68
sources/app/Helper/AvatarHelper.php
Normal file
68
sources/app/Helper/AvatarHelper.php
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Kanboard\Helper;
|
||||||
|
|
||||||
|
use Kanboard\Core\Base;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Avatar Helper
|
||||||
|
*
|
||||||
|
* @package helper
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class AvatarHelper extends Base
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Render user avatar
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $user_id
|
||||||
|
* @param string $username
|
||||||
|
* @param string $name
|
||||||
|
* @param string $email
|
||||||
|
* @param string $avatar_path
|
||||||
|
* @param string $css
|
||||||
|
* @param int $size
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function render($user_id, $username, $name, $email, $avatar_path, $css = 'avatar-left', $size = 48)
|
||||||
|
{
|
||||||
|
if (empty($user_id) && empty($username)) {
|
||||||
|
$html = $this->avatarManager->renderDefault($size);
|
||||||
|
} else {
|
||||||
|
$html = $this->avatarManager->render($user_id, $username, $name, $email, $avatar_path, $size);
|
||||||
|
}
|
||||||
|
|
||||||
|
return '<div class="avatar avatar-'.$size.' '.$css.'">'.$html.'</div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render small user avatar
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $user_id
|
||||||
|
* @param string $username
|
||||||
|
* @param string $name
|
||||||
|
* @param string $email
|
||||||
|
* @param string $avatar_path
|
||||||
|
* @param string $css
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function small($user_id, $username, $name, $email, $avatar_path, $css = '')
|
||||||
|
{
|
||||||
|
return $this->render($user_id, $username, $name, $email, $avatar_path, $css, 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a small avatar for the current user
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $css
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function currentUserSmall($css = '')
|
||||||
|
{
|
||||||
|
$user = $this->userSession->getAll();
|
||||||
|
return $this->small($user['id'], $user['username'], $user['name'], $user['email'], $user['avatar_path'], $css);
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,13 +2,15 @@
|
||||||
|
|
||||||
namespace Kanboard\Helper;
|
namespace Kanboard\Helper;
|
||||||
|
|
||||||
|
use Kanboard\Core\Base;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Board Helper
|
* Board Helper
|
||||||
*
|
*
|
||||||
* @package helper
|
* @package helper
|
||||||
* @author Frederic Guillot
|
* @author Frederic Guillot
|
||||||
*/
|
*/
|
||||||
class Board extends \Kanboard\Core\Base
|
class BoardHelper extends Base
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Return true if tasks are collapsed
|
* Return true if tasks are collapsed
|
|
@ -3,6 +3,7 @@
|
||||||
namespace Kanboard\Helper;
|
namespace Kanboard\Helper;
|
||||||
|
|
||||||
use DateTime;
|
use DateTime;
|
||||||
|
use Kanboard\Core\Base;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DateTime helpers
|
* DateTime helpers
|
||||||
|
@ -10,7 +11,7 @@ use DateTime;
|
||||||
* @package helper
|
* @package helper
|
||||||
* @author Frederic Guillot
|
* @author Frederic Guillot
|
||||||
*/
|
*/
|
||||||
class Dt extends \Kanboard\Core\Base
|
class DateHelper extends Base
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Get formatted time
|
* Get formatted time
|
|
@ -2,13 +2,15 @@
|
||||||
|
|
||||||
namespace Kanboard\Helper;
|
namespace Kanboard\Helper;
|
||||||
|
|
||||||
|
use Kanboard\Core\Base;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* File helpers
|
* File helpers
|
||||||
*
|
*
|
||||||
* @package helper
|
* @package helper
|
||||||
* @author Frederic Guillot
|
* @author Frederic Guillot
|
||||||
*/
|
*/
|
||||||
class File extends \Kanboard\Core\Base
|
class FileHelper extends Base
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Get file icon
|
* Get file icon
|
|
@ -10,7 +10,7 @@ use Kanboard\Core\Base;
|
||||||
* @package helper
|
* @package helper
|
||||||
* @author Frederic Guillot
|
* @author Frederic Guillot
|
||||||
*/
|
*/
|
||||||
class Form extends Base
|
class FormHelper extends Base
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Hidden CSRF token field
|
* Hidden CSRF token field
|
||||||
|
@ -44,6 +44,7 @@ class Form extends Base
|
||||||
* @param array $options Options
|
* @param array $options Options
|
||||||
* @param array $values Form values
|
* @param array $values Form values
|
||||||
* @param array $errors Form errors
|
* @param array $errors Form errors
|
||||||
|
* @param array $attributes
|
||||||
* @param string $class CSS class
|
* @param string $class CSS class
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
|
@ -52,7 +53,7 @@ class Form extends Base
|
||||||
$html = '<select name="'.$name.'" id="form-'.$name.'" class="'.$class.'" '.implode(' ', $attributes).'>';
|
$html = '<select name="'.$name.'" id="form-'.$name.'" class="'.$class.'" '.implode(' ', $attributes).'>';
|
||||||
|
|
||||||
foreach ($options as $id => $value) {
|
foreach ($options as $id => $value) {
|
||||||
$html .= '<option value="'.$this->helper->e($id).'"';
|
$html .= '<option value="'.$this->helper->text->e($id).'"';
|
||||||
|
|
||||||
if (isset($values->$name) && $id == $values->$name) {
|
if (isset($values->$name) && $id == $values->$name) {
|
||||||
$html .= ' selected="selected"';
|
$html .= ' selected="selected"';
|
||||||
|
@ -61,7 +62,7 @@ class Form extends Base
|
||||||
$html .= ' selected="selected"';
|
$html .= ' selected="selected"';
|
||||||
}
|
}
|
||||||
|
|
||||||
$html .= '>'.$this->helper->e($value).'</option>';
|
$html .= '>'.$this->helper->text->e($value).'</option>';
|
||||||
}
|
}
|
||||||
|
|
||||||
$html .= '</select>';
|
$html .= '</select>';
|
||||||
|
@ -103,7 +104,7 @@ class Form extends Base
|
||||||
*/
|
*/
|
||||||
public function radio($name, $label, $value, $selected = false, $class = '')
|
public function radio($name, $label, $value, $selected = false, $class = '')
|
||||||
{
|
{
|
||||||
return '<label><input type="radio" name="'.$name.'" class="'.$class.'" value="'.$this->helper->e($value).'" '.($selected ? 'checked="checked"' : '').'> '.$this->helper->e($label).'</label>';
|
return '<label><input type="radio" name="'.$name.'" class="'.$class.'" value="'.$this->helper->text->e($value).'" '.($selected ? 'checked="checked"' : '').'> '.$this->helper->text->e($label).'</label>';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -139,7 +140,7 @@ class Form extends Base
|
||||||
*/
|
*/
|
||||||
public function checkbox($name, $label, $value, $checked = false, $class = '')
|
public function checkbox($name, $label, $value, $checked = false, $class = '')
|
||||||
{
|
{
|
||||||
return '<label><input type="checkbox" name="'.$name.'" class="'.$class.'" value="'.$this->helper->e($value).'" '.($checked ? 'checked="checked"' : '').'> '.$this->helper->e($label).'</label>';
|
return '<label><input type="checkbox" name="'.$name.'" class="'.$class.'" value="'.$this->helper->text->e($value).'" '.($checked ? 'checked="checked"' : '').'> '.$this->helper->text->e($label).'</label>';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -153,7 +154,7 @@ class Form extends Base
|
||||||
*/
|
*/
|
||||||
public function label($label, $name, array $attributes = array())
|
public function label($label, $name, array $attributes = array())
|
||||||
{
|
{
|
||||||
return '<label for="form-'.$name.'" '.implode(' ', $attributes).'>'.$this->helper->e($label).'</label>';
|
return '<label for="form-'.$name.'" '.implode(' ', $attributes).'>'.$this->helper->text->e($label).'</label>';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -173,7 +174,7 @@ class Form extends Base
|
||||||
|
|
||||||
$html = '<textarea name="'.$name.'" id="form-'.$name.'" class="'.$class.'" ';
|
$html = '<textarea name="'.$name.'" id="form-'.$name.'" class="'.$class.'" ';
|
||||||
$html .= implode(' ', $attributes).'>';
|
$html .= implode(' ', $attributes).'>';
|
||||||
$html .= isset($values->$name) ? $this->helper->e($values->$name) : isset($values[$name]) ? $values[$name] : '';
|
$html .= isset($values->$name) ? $this->helper->text->e($values->$name) : isset($values[$name]) ? $values[$name] : '';
|
||||||
$html .= '</textarea>';
|
$html .= '</textarea>';
|
||||||
$html .= $this->errorList($errors, $name);
|
$html .= $this->errorList($errors, $name);
|
||||||
|
|
||||||
|
@ -334,7 +335,7 @@ class Form extends Base
|
||||||
$html .= '<ul class="form-errors">';
|
$html .= '<ul class="form-errors">';
|
||||||
|
|
||||||
foreach ($errors[$name] as $error) {
|
foreach ($errors[$name] as $error) {
|
||||||
$html .= '<li>'.$this->helper->e($error).'</li>';
|
$html .= '<li>'.$this->helper->text->e($error).'</li>';
|
||||||
}
|
}
|
||||||
|
|
||||||
$html .= '</ul>';
|
$html .= '</ul>';
|
||||||
|
@ -354,9 +355,9 @@ class Form extends Base
|
||||||
private function formValue($values, $name)
|
private function formValue($values, $name)
|
||||||
{
|
{
|
||||||
if (isset($values->$name)) {
|
if (isset($values->$name)) {
|
||||||
return 'value="'.$this->helper->e($values->$name).'"';
|
return 'value="'.$this->helper->text->e($values->$name).'"';
|
||||||
}
|
}
|
||||||
|
|
||||||
return isset($values[$name]) ? 'value="'.$this->helper->e($values[$name]).'"' : '';
|
return isset($values[$name]) ? 'value="'.$this->helper->text->e($values[$name]).'"' : '';
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,13 +2,15 @@
|
||||||
|
|
||||||
namespace Kanboard\Helper;
|
namespace Kanboard\Helper;
|
||||||
|
|
||||||
|
use Kanboard\Core\Base;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Template Hook helpers
|
* Template Hook helpers
|
||||||
*
|
*
|
||||||
* @package helper
|
* @package helper
|
||||||
* @author Frederic Guillot
|
* @author Frederic Guillot
|
||||||
*/
|
*/
|
||||||
class Hook extends \Kanboard\Core\Base
|
class HookHelper extends Base
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Add assets JS or CSS
|
* Add assets JS or CSS
|
||||||
|
@ -54,7 +56,7 @@ class Hook extends \Kanboard\Core\Base
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $hook
|
* @param string $hook
|
||||||
* @param string $template
|
* @param string $template
|
||||||
* @return \Helper\Hook
|
* @return \Kanboard\Helper\Hook
|
||||||
*/
|
*/
|
||||||
public function attach($hook, $template)
|
public function attach($hook, $template)
|
||||||
{
|
{
|
|
@ -5,12 +5,12 @@ namespace Kanboard\Helper;
|
||||||
use Kanboard\Core\Base;
|
use Kanboard\Core\Base;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Layout helpers
|
* Layout Helper
|
||||||
*
|
*
|
||||||
* @package helper
|
* @package helper
|
||||||
* @author Frederic Guillot
|
* @author Frederic Guillot
|
||||||
*/
|
*/
|
||||||
class Layout extends Base
|
class LayoutHelper extends Base
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Render a template without the layout if Ajax request
|
* Render a template without the layout if Ajax request
|
||||||
|
@ -30,7 +30,7 @@ class Layout extends Base
|
||||||
$params['board_selector'] = $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId());
|
$params['board_selector'] = $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->template->layout($template, $params);
|
return $this->pageLayout($template, $params);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -60,7 +60,7 @@ class Layout extends Base
|
||||||
*/
|
*/
|
||||||
public function task($template, array $params)
|
public function task($template, array $params)
|
||||||
{
|
{
|
||||||
$params['title'] = $params['task']['title'];
|
$params['title'] = $params['task']['project_name'];
|
||||||
return $this->subLayout('task/layout', 'task/sidebar', $template, $params);
|
return $this->subLayout('task/layout', 'task/sidebar', $template, $params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,7 +146,24 @@ class Layout extends Base
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Common method to generate a sublayout
|
* Render page layout
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $template Template name
|
||||||
|
* @param array $params Key/value dictionary
|
||||||
|
* @param string $layout Layout name
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function pageLayout($template, array $params = array(), $layout = 'layout')
|
||||||
|
{
|
||||||
|
return $this->template->render(
|
||||||
|
$layout,
|
||||||
|
$params + array('content_for_layout' => $this->template->render($template, $params))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common method to generate a sub-layout
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $sublayout
|
* @param string $sublayout
|
94
sources/app/Helper/ModelHelper.php
Normal file
94
sources/app/Helper/ModelHelper.php
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Kanboard\Helper;
|
||||||
|
|
||||||
|
use Kanboard\Core\Base;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model Helper
|
||||||
|
*
|
||||||
|
* @package helper
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class ModelHelper extends Base
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Remove keys from an array
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param array $values Input array
|
||||||
|
* @param string[] $keys List of keys to remove
|
||||||
|
*/
|
||||||
|
public function removeFields(array &$values, array $keys)
|
||||||
|
{
|
||||||
|
foreach ($keys as $key) {
|
||||||
|
if (array_key_exists($key, $values)) {
|
||||||
|
unset($values[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove keys from an array if empty
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param array $values Input array
|
||||||
|
* @param string[] $keys List of keys to remove
|
||||||
|
*/
|
||||||
|
public function removeEmptyFields(array &$values, array $keys)
|
||||||
|
{
|
||||||
|
foreach ($keys as $key) {
|
||||||
|
if (array_key_exists($key, $values) && empty($values[$key])) {
|
||||||
|
unset($values[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Force fields to be at 0 if empty
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param array $values Input array
|
||||||
|
* @param string[] $keys List of keys
|
||||||
|
*/
|
||||||
|
public function resetFields(array &$values, array $keys)
|
||||||
|
{
|
||||||
|
foreach ($keys as $key) {
|
||||||
|
if (isset($values[$key]) && empty($values[$key])) {
|
||||||
|
$values[$key] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Force some fields to be integer
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param array $values Input array
|
||||||
|
* @param string[] $keys List of keys
|
||||||
|
*/
|
||||||
|
public function convertIntegerFields(array &$values, array $keys)
|
||||||
|
{
|
||||||
|
foreach ($keys as $key) {
|
||||||
|
if (isset($values[$key])) {
|
||||||
|
$values[$key] = (int) $values[$key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Force some fields to be null if empty
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param array $values Input array
|
||||||
|
* @param string[] $keys List of keys
|
||||||
|
*/
|
||||||
|
public function convertNullFields(array &$values, array $keys)
|
||||||
|
{
|
||||||
|
foreach ($keys as $key) {
|
||||||
|
if (array_key_exists($key, $values) && empty($values[$key])) {
|
||||||
|
$values[$key] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
80
sources/app/Helper/ProjectHeaderHelper.php
Normal file
80
sources/app/Helper/ProjectHeaderHelper.php
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Kanboard\Helper;
|
||||||
|
|
||||||
|
use Kanboard\Core\Base;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Project Header Helper
|
||||||
|
*
|
||||||
|
* @package helper
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class ProjectHeaderHelper extends Base
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get current search query
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param array $project
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getSearchQuery(array $project)
|
||||||
|
{
|
||||||
|
$search = $this->request->getStringParam('search', $this->userSession->getFilters($project['id']));
|
||||||
|
$this->userSession->setFilters($project['id'], $search);
|
||||||
|
return urldecode($search);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render project header (views switcher and search box)
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param array $project
|
||||||
|
* @param string $controller
|
||||||
|
* @param string $action
|
||||||
|
* @param bool $boardView
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function render(array $project, $controller, $action, $boardView = false)
|
||||||
|
{
|
||||||
|
$filters = array(
|
||||||
|
'controller' => $controller,
|
||||||
|
'action' => $action,
|
||||||
|
'project_id' => $project['id'],
|
||||||
|
'search' => $this->getSearchQuery($project),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->template->render('project_header/header', array(
|
||||||
|
'project' => $project,
|
||||||
|
'filters' => $filters,
|
||||||
|
'categories_list' => $this->category->getList($project['id'], false),
|
||||||
|
'users_list' => $this->projectUserRole->getAssignableUsersList($project['id'], false),
|
||||||
|
'custom_filters_list' => $this->customFilter->getAll($project['id'], $this->userSession->getId()),
|
||||||
|
'board_view' => $boardView,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get project description
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param array &$project
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getDescription(array &$project)
|
||||||
|
{
|
||||||
|
if ($project['owner_id'] > 0) {
|
||||||
|
$description = t('Project owner: ').'**'.$this->helper->text->e($project['owner_name'] ?: $project['owner_username']).'**'.PHP_EOL.PHP_EOL;
|
||||||
|
|
||||||
|
if (! empty($project['description'])) {
|
||||||
|
$description .= '***'.PHP_EOL.PHP_EOL;
|
||||||
|
$description .= $project['description'];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$description = $project['description'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $description;
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,13 +2,15 @@
|
||||||
|
|
||||||
namespace Kanboard\Helper;
|
namespace Kanboard\Helper;
|
||||||
|
|
||||||
|
use Kanboard\Core\Base;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subtask helpers
|
* Subtask helpers
|
||||||
*
|
*
|
||||||
* @package helper
|
* @package helper
|
||||||
* @author Frederic Guillot
|
* @author Frederic Guillot
|
||||||
*/
|
*/
|
||||||
class Subtask extends \Kanboard\Core\Base
|
class SubtaskHelper extends Base
|
||||||
{
|
{
|
||||||
public function getTitle(array $subtask)
|
public function getTitle(array $subtask)
|
||||||
{
|
{
|
||||||
|
@ -20,7 +22,7 @@ class Subtask extends \Kanboard\Core\Base
|
||||||
$html = '<i class="fa fa-check-square-o fa-fw"></i>';
|
$html = '<i class="fa fa-check-square-o fa-fw"></i>';
|
||||||
}
|
}
|
||||||
|
|
||||||
return $html.$this->helper->e($subtask['title']);
|
return $html.$this->helper->text->e($subtask['title']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
|
@ -10,7 +10,7 @@ use Kanboard\Core\Base;
|
||||||
* @package helper
|
* @package helper
|
||||||
* @author Frederic Guillot
|
* @author Frederic Guillot
|
||||||
*/
|
*/
|
||||||
class Task extends Base
|
class TaskHelper extends Base
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Local cache for project columns
|
* Local cache for project columns
|
|
@ -11,8 +11,19 @@ use Kanboard\Core\Base;
|
||||||
* @package helper
|
* @package helper
|
||||||
* @author Frederic Guillot
|
* @author Frederic Guillot
|
||||||
*/
|
*/
|
||||||
class Text extends Base
|
class TextHelper extends Base
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* HTML escaping
|
||||||
|
*
|
||||||
|
* @param string $value Value to escape
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function e($value)
|
||||||
|
{
|
||||||
|
return htmlspecialchars($value, ENT_QUOTES, 'UTF-8', false);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Markdown transformation
|
* Markdown transformation
|
||||||
*
|
*
|
||||||
|
@ -88,7 +99,7 @@ class Text extends Base
|
||||||
public function in($id, array $listing, $default_value = '?')
|
public function in($id, array $listing, $default_value = '?')
|
||||||
{
|
{
|
||||||
if (isset($listing[$id])) {
|
if (isset($listing[$id])) {
|
||||||
return $this->helper->e($listing[$id]);
|
return $this->helper->text->e($listing[$id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $default_value;
|
return $default_value;
|
|
@ -5,12 +5,12 @@ namespace Kanboard\Helper;
|
||||||
use Kanboard\Core\Base;
|
use Kanboard\Core\Base;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Url helpers
|
* Url Helper
|
||||||
*
|
*
|
||||||
* @package helper
|
* @package helper
|
||||||
* @author Frederic Guillot
|
* @author Frederic Guillot
|
||||||
*/
|
*/
|
||||||
class Url extends Base
|
class UrlHelper extends Base
|
||||||
{
|
{
|
||||||
private $base = '';
|
private $base = '';
|
||||||
private $directory = '';
|
private $directory = '';
|
||||||
|
@ -29,7 +29,26 @@ class Url extends Base
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HTML Link tag
|
* Button Link Element
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $icon Font-Awesome icon
|
||||||
|
* @param string $label Link label
|
||||||
|
* @param string $controller Controller name
|
||||||
|
* @param string $action Action name
|
||||||
|
* @param array $params Url parameters
|
||||||
|
* @param string $class CSS class attribute
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function button($icon, $label, $controller, $action, array $params = array(), $class = '')
|
||||||
|
{
|
||||||
|
$icon = '<i class="fa '.$icon.' fa-fw"></i> ';
|
||||||
|
$class = 'btn '.$class;
|
||||||
|
return $this->link($icon.$label, $controller, $action, $params, false, $class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Link element
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $label Link label
|
* @param string $label Link label
|
||||||
|
@ -38,6 +57,7 @@ class Url extends Base
|
||||||
* @param array $params Url parameters
|
* @param array $params Url parameters
|
||||||
* @param boolean $csrf Add a CSRF token
|
* @param boolean $csrf Add a CSRF token
|
||||||
* @param string $class CSS class attribute
|
* @param string $class CSS class attribute
|
||||||
|
* @param string $title
|
||||||
* @param boolean $new_tab Open the link in a new tab
|
* @param boolean $new_tab Open the link in a new tab
|
||||||
* @param string $anchor Link Anchor
|
* @param string $anchor Link Anchor
|
||||||
* @return string
|
* @return string
|
|
@ -2,13 +2,15 @@
|
||||||
|
|
||||||
namespace Kanboard\Helper;
|
namespace Kanboard\Helper;
|
||||||
|
|
||||||
|
use Kanboard\Core\Base;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User helpers
|
* User helpers
|
||||||
*
|
*
|
||||||
* @package helper
|
* @package helper
|
||||||
* @author Frederic Guillot
|
* @author Frederic Guillot
|
||||||
*/
|
*/
|
||||||
class User extends \Kanboard\Core\Base
|
class UserHelper extends Base
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Return true if the logged user as unread notifications
|
* Return true if the logged user as unread notifications
|
||||||
|
@ -32,7 +34,7 @@ class User extends \Kanboard\Core\Base
|
||||||
{
|
{
|
||||||
$initials = '';
|
$initials = '';
|
||||||
|
|
||||||
foreach (explode(' ', $name) as $string) {
|
foreach (explode(' ', $name, 2) as $string) {
|
||||||
$initials .= mb_substr($string, 0, 1);
|
$initials .= mb_substr($string, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,23 +156,6 @@ class User extends \Kanboard\Core\Base
|
||||||
*/
|
*/
|
||||||
public function getFullname(array $user = array())
|
public function getFullname(array $user = array())
|
||||||
{
|
{
|
||||||
return $this->user->getFullname(empty($user) ? $this->sessionStorage->user : $user);
|
return $this->user->getFullname(empty($user) ? $this->userSession->getAll() : $user);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Display gravatar image
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @param string $email
|
|
||||||
* @param string $alt
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function avatar($email, $alt = '')
|
|
||||||
{
|
|
||||||
if (! empty($email) && $this->config->get('integration_gravatar') == 1) {
|
|
||||||
return '<img class="avatar" src="https://www.gravatar.com/avatar/'.md5(strtolower($email)).'?s=25" alt="'.$this->helper->e($alt).'" title="'.$this->helper->e($alt).'">';
|
|
||||||
}
|
|
||||||
|
|
||||||
return '';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,7 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Kanboard\Model;
|
namespace Kanboard\Import;
|
||||||
|
|
||||||
|
use Kanboard\Core\Base;
|
||||||
use Kanboard\Core\Csv;
|
use Kanboard\Core\Csv;
|
||||||
use SimpleValidator\Validator;
|
use SimpleValidator\Validator;
|
||||||
use SimpleValidator\Validators;
|
use SimpleValidator\Validators;
|
||||||
|
@ -9,7 +10,7 @@ use SimpleValidator\Validators;
|
||||||
/**
|
/**
|
||||||
* Task Import
|
* Task Import
|
||||||
*
|
*
|
||||||
* @package model
|
* @package import
|
||||||
* @author Frederic Guillot
|
* @author Frederic Guillot
|
||||||
*/
|
*/
|
||||||
class TaskImport extends Base
|
class TaskImport extends Base
|
||||||
|
@ -126,7 +127,7 @@ class TaskImport extends Base
|
||||||
$values['date_due'] = $this->dateParser->getTimestampFromIsoFormat($row['date_due']);
|
$values['date_due'] = $this->dateParser->getTimestampFromIsoFormat($row['date_due']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->removeEmptyFields(
|
$this->helper->model->removeEmptyFields(
|
||||||
$values,
|
$values,
|
||||||
array('owner_id', 'creator_id', 'color_id', 'column_id', 'category_id', 'swimlane_id', 'date_due')
|
array('owner_id', 'creator_id', 'color_id', 'column_id', 'category_id', 'swimlane_id', 'date_due')
|
||||||
);
|
);
|
|
@ -1,16 +1,18 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Kanboard\Model;
|
namespace Kanboard\Import;
|
||||||
|
|
||||||
|
use Kanboard\Model\User;
|
||||||
use SimpleValidator\Validator;
|
use SimpleValidator\Validator;
|
||||||
use SimpleValidator\Validators;
|
use SimpleValidator\Validators;
|
||||||
use Kanboard\Core\Security\Role;
|
use Kanboard\Core\Security\Role;
|
||||||
|
use Kanboard\Core\Base;
|
||||||
use Kanboard\Core\Csv;
|
use Kanboard\Core\Csv;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User Import
|
* User Import
|
||||||
*
|
*
|
||||||
* @package model
|
* @package import
|
||||||
* @author Frederic Guillot
|
* @author Frederic Guillot
|
||||||
*/
|
*/
|
||||||
class UserImport extends Base
|
class UserImport extends Base
|
||||||
|
@ -91,7 +93,7 @@ class UserImport extends Base
|
||||||
unset($row['is_admin']);
|
unset($row['is_admin']);
|
||||||
unset($row['is_manager']);
|
unset($row['is_manager']);
|
||||||
|
|
||||||
$this->removeEmptyFields($row, array('password', 'email', 'name'));
|
$this->helper->model->removeEmptyFields($row, array('password', 'email', 'name'));
|
||||||
|
|
||||||
return $row;
|
return $row;
|
||||||
}
|
}
|
|
@ -8,7 +8,6 @@ return array(
|
||||||
'Edit' => 'Uredi',
|
'Edit' => 'Uredi',
|
||||||
'remove' => 'ukloni',
|
'remove' => 'ukloni',
|
||||||
'Remove' => 'Ukloni',
|
'Remove' => 'Ukloni',
|
||||||
'Update' => 'Ažuriraj',
|
|
||||||
'Yes' => 'Da',
|
'Yes' => 'Da',
|
||||||
'No' => 'Ne',
|
'No' => 'Ne',
|
||||||
'cancel' => 'odustani',
|
'cancel' => 'odustani',
|
||||||
|
@ -56,25 +55,23 @@ return array(
|
||||||
'Project' => 'Projekat',
|
'Project' => 'Projekat',
|
||||||
'Status' => 'Status',
|
'Status' => 'Status',
|
||||||
'Tasks' => 'Zadatak',
|
'Tasks' => 'Zadatak',
|
||||||
'Board' => 'Tabla',
|
'Board' => 'Ploča',
|
||||||
'Actions' => 'Akcije',
|
'Actions' => 'Akcije',
|
||||||
'Inactive' => 'Neaktivan',
|
'Inactive' => 'Neaktivan',
|
||||||
'Active' => 'Aktivan',
|
'Active' => 'Aktivan',
|
||||||
'Add this column' => 'Dodaj kolonu',
|
|
||||||
'%d tasks on the board' => '%d zadataka na tabli',
|
'%d tasks on the board' => '%d zadataka na tabli',
|
||||||
'%d tasks in total' => '%d zadataka ukupno',
|
'%d tasks in total' => '%d zadataka ukupno',
|
||||||
'Unable to update this board.' => 'Nemogu da ažuriram ovu tablu.',
|
'Unable to update this board.' => 'Nemogu da ažuriram ovu ploču.',
|
||||||
'Edit board' => 'Izmijeni tablu',
|
'Edit board' => 'Izmijeni ploču',
|
||||||
'Disable' => 'Onemogući',
|
'Disable' => 'Onemogući',
|
||||||
'Enable' => 'Omogući',
|
'Enable' => 'Omogući',
|
||||||
'New project' => 'Novi projekat',
|
'New project' => 'Novi projekat',
|
||||||
'Do you really want to remove this project: "%s"?' => 'Da li želiš da ukloniš projekat: "%s"?',
|
'Do you really want to remove this project: "%s"?' => 'Da li želiš da ukloniš projekat: "%s"?',
|
||||||
'Remove project' => 'Ukloni projekat',
|
'Remove project' => 'Ukloni projekat',
|
||||||
'Edit the board for "%s"' => 'Uredi tablu za "%s"',
|
'Edit the board for "%s"' => 'Uredi ploču za "%s"',
|
||||||
'All projects' => 'Svi projekti',
|
'All projects' => 'Svi projekti',
|
||||||
'Add a new column' => 'Dodaj novu kolonu',
|
'Add a new column' => 'Dodaj novu kolonu',
|
||||||
'Title' => 'Naslov',
|
'Title' => 'Naslov',
|
||||||
'Nobody assigned' => 'Niko nije dodijeljen',
|
|
||||||
'Assigned to %s' => 'Dodijeljen korisniku %s',
|
'Assigned to %s' => 'Dodijeljen korisniku %s',
|
||||||
'Remove a column' => 'Ukloni kolonu',
|
'Remove a column' => 'Ukloni kolonu',
|
||||||
'Remove a column from a board' => 'Ukloni kolonu sa table',
|
'Remove a column from a board' => 'Ukloni kolonu sa table',
|
||||||
|
@ -100,7 +97,7 @@ return array(
|
||||||
'New task' => 'Novi zadatak',
|
'New task' => 'Novi zadatak',
|
||||||
'Open a task' => 'Otvori zadatak',
|
'Open a task' => 'Otvori zadatak',
|
||||||
'Do you really want to open this task: "%s"?' => 'Da li zaista želiš da otvoriš zadatak: "%s"?',
|
'Do you really want to open this task: "%s"?' => 'Da li zaista želiš da otvoriš zadatak: "%s"?',
|
||||||
'Back to the board' => 'Nazad na tablu',
|
'Back to the board' => 'Nazad na ploču',
|
||||||
'There is nobody assigned' => 'Niko nije dodijeljen!',
|
'There is nobody assigned' => 'Niko nije dodijeljen!',
|
||||||
'Column on the board:' => 'Kolona na tabli:',
|
'Column on the board:' => 'Kolona na tabli:',
|
||||||
'Close this task' => 'Zatvori ovaj zadatak',
|
'Close this task' => 'Zatvori ovaj zadatak',
|
||||||
|
@ -148,7 +145,7 @@ return array(
|
||||||
'Unable to update your user.' => 'Nije moguće ažuriranje korisnika.',
|
'Unable to update your user.' => 'Nije moguće ažuriranje korisnika.',
|
||||||
'User removed successfully.' => 'Korisnik uspješno uklonjen.',
|
'User removed successfully.' => 'Korisnik uspješno uklonjen.',
|
||||||
'Unable to remove this user.' => 'Nije moguće uklanjanje korisnika.',
|
'Unable to remove this user.' => 'Nije moguće uklanjanje korisnika.',
|
||||||
'Board updated successfully.' => 'Tabla uspješno ažurirana.',
|
'Board updated successfully.' => 'Ploča je uspješno ažurirana.',
|
||||||
'Ready' => 'Spreman',
|
'Ready' => 'Spreman',
|
||||||
'Backlog' => 'Zaliha',
|
'Backlog' => 'Zaliha',
|
||||||
'Work in progress' => 'U izradi',
|
'Work in progress' => 'U izradi',
|
||||||
|
@ -168,7 +165,6 @@ return array(
|
||||||
'Task count' => 'Broj zadataka',
|
'Task count' => 'Broj zadataka',
|
||||||
'User' => 'Korisnik',
|
'User' => 'Korisnik',
|
||||||
'Comments' => 'Komentari',
|
'Comments' => 'Komentari',
|
||||||
'Write your text in Markdown' => 'Pisanje teksta pomoću Markdown',
|
|
||||||
'Leave a comment' => 'Ostavi komentar',
|
'Leave a comment' => 'Ostavi komentar',
|
||||||
'Comment is required' => 'Komentar je obavezan',
|
'Comment is required' => 'Komentar je obavezan',
|
||||||
'Leave a description' => 'Dodaj opis',
|
'Leave a description' => 'Dodaj opis',
|
||||||
|
@ -184,7 +180,6 @@ return array(
|
||||||
'Unable to remove this action.' => 'Nije moguće obrisati akciju',
|
'Unable to remove this action.' => 'Nije moguće obrisati akciju',
|
||||||
'Action removed successfully.' => 'Akcija obrisana',
|
'Action removed successfully.' => 'Akcija obrisana',
|
||||||
'Automatic actions for the project "%s"' => 'Akcije za automatizaciju projekta "%s"',
|
'Automatic actions for the project "%s"' => 'Akcije za automatizaciju projekta "%s"',
|
||||||
'Defined actions' => 'Definisane akcje',
|
|
||||||
'Add an action' => 'dodaj akcju',
|
'Add an action' => 'dodaj akcju',
|
||||||
'Event name' => 'Naziv događaja',
|
'Event name' => 'Naziv događaja',
|
||||||
'Action name' => 'Naziv akcije',
|
'Action name' => 'Naziv akcije',
|
||||||
|
@ -194,7 +189,6 @@ return array(
|
||||||
'When the selected event occurs execute the corresponding action.' => 'Na izabrani događaj izvrši odgovarajuću akciju',
|
'When the selected event occurs execute the corresponding action.' => 'Na izabrani događaj izvrši odgovarajuću akciju',
|
||||||
'Next step' => 'Slijedeći korak',
|
'Next step' => 'Slijedeći korak',
|
||||||
'Define action parameters' => 'Definiši parametre akcije',
|
'Define action parameters' => 'Definiši parametre akcije',
|
||||||
'Save this action' => 'Snimi akciju',
|
|
||||||
'Do you really want to remove this action: "%s"?' => 'Da li da obrišem akciju "%s"?',
|
'Do you really want to remove this action: "%s"?' => 'Da li da obrišem akciju "%s"?',
|
||||||
'Remove an automatic action' => 'Obriši automatsku akciju',
|
'Remove an automatic action' => 'Obriši automatsku akciju',
|
||||||
'Assign the task to a specific user' => 'Dodijeli zadatak određenom korisniku',
|
'Assign the task to a specific user' => 'Dodijeli zadatak određenom korisniku',
|
||||||
|
@ -333,10 +327,10 @@ return array(
|
||||||
'Time tracking:' => 'Praćenje vremena:',
|
'Time tracking:' => 'Praćenje vremena:',
|
||||||
'New sub-task' => 'Novi pod-zadatak',
|
'New sub-task' => 'Novi pod-zadatak',
|
||||||
'New attachment added "%s"' => 'Ubačen novi prilog "%s"',
|
'New attachment added "%s"' => 'Ubačen novi prilog "%s"',
|
||||||
'Comment updated' => 'Komentar ažuriran',
|
|
||||||
'New comment posted by %s' => '%s ostavio novi komentar',
|
'New comment posted by %s' => '%s ostavio novi komentar',
|
||||||
'New attachment' => 'Novi prilog',
|
'New attachment' => 'Novi prilog',
|
||||||
'New comment' => 'Novi komentar',
|
'New comment' => 'Novi komentar',
|
||||||
|
'Comment updated' => 'Komentar ažuriran',
|
||||||
'New subtask' => 'Novi pod-zadatak',
|
'New subtask' => 'Novi pod-zadatak',
|
||||||
'Subtask updated' => 'Pod-zadatak ažuriran',
|
'Subtask updated' => 'Pod-zadatak ažuriran',
|
||||||
'Task updated' => 'Zadatak ažuriran',
|
'Task updated' => 'Zadatak ažuriran',
|
||||||
|
@ -404,7 +398,7 @@ return array(
|
||||||
'%s moved the task #%d to the position %d in the column "%s"' => '%s premjestio zadatak #%d na poziciju %d u koloni "%s"',
|
'%s moved the task #%d to the position %d in the column "%s"' => '%s premjestio zadatak #%d na poziciju %d u koloni "%s"',
|
||||||
'Activity' => 'Aktivnosti',
|
'Activity' => 'Aktivnosti',
|
||||||
'Default values are "%s"' => 'Podrazumijevane vrijednosti su: "%s"',
|
'Default values are "%s"' => 'Podrazumijevane vrijednosti su: "%s"',
|
||||||
'Default columns for new projects (Comma-separated)' => 'Podrazumijevane kolone za novi projekat (Odvojeni zarezom)',
|
'Default columns for new projects (Comma-separated)' => 'Podrazumijevane kolone za novi projekat (Odvojene zarezom)',
|
||||||
'Task assignee change' => 'Promijena izvršioca zadatka',
|
'Task assignee change' => 'Promijena izvršioca zadatka',
|
||||||
'%s change the assignee of the task #%d to %s' => '%s zamijeni izvršioca za zadatak #%d u %s',
|
'%s change the assignee of the task #%d to %s' => '%s zamijeni izvršioca za zadatak #%d u %s',
|
||||||
'%s changed the assignee of the task %s to %s' => '%s promijenio izvršioca za zadatak %s u %s',
|
'%s changed the assignee of the task %s to %s' => '%s promijenio izvršioca za zadatak %s u %s',
|
||||||
|
@ -416,7 +410,7 @@ return array(
|
||||||
'Reference' => 'Referenca',
|
'Reference' => 'Referenca',
|
||||||
'Label' => 'Etiketa',
|
'Label' => 'Etiketa',
|
||||||
'Database' => 'Baza',
|
'Database' => 'Baza',
|
||||||
'About' => 'O',
|
'About' => 'O Kanboardu',
|
||||||
'Database driver:' => 'Database driver:',
|
'Database driver:' => 'Database driver:',
|
||||||
'Board settings' => 'Postavke table',
|
'Board settings' => 'Postavke table',
|
||||||
'URL and token' => 'URL i token',
|
'URL and token' => 'URL i token',
|
||||||
|
@ -424,23 +418,22 @@ return array(
|
||||||
'URL for task creation:' => 'URL za kreiranje zadataka',
|
'URL for task creation:' => 'URL za kreiranje zadataka',
|
||||||
'Reset token' => 'Resetuj token',
|
'Reset token' => 'Resetuj token',
|
||||||
'API endpoint:' => 'API endpoint',
|
'API endpoint:' => 'API endpoint',
|
||||||
'Refresh interval for private board' => 'Interval osvježavanja privatnih tabli',
|
'Refresh interval for private board' => 'Interval osvježavanja privatnih ploča',
|
||||||
'Refresh interval for public board' => 'Interval osvježavanja javnih tabli',
|
'Refresh interval for public board' => 'Interval osvježavanja javnih ploča',
|
||||||
'Task highlight period' => 'Period naznačavanja zadatka',
|
'Task highlight period' => 'Period naznačavanja zadatka',
|
||||||
'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => 'Period (u sekundama) u kom su se događale promjene na zadatku (0 je onemogućeno, 2 dana je uobičajeno)',
|
'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => 'Period (u sekundama) u kom su se događale promjene na zadatku (0 je onemogućeno, 2 dana je uobičajeno)',
|
||||||
'Frequency in second (60 seconds by default)' => 'Frekvencija u sekundama (60 sekundi je uobičajeno)',
|
'Frequency in second (60 seconds by default)' => 'Frekvencija u sekundama (60 sekundi je uobičajeno)',
|
||||||
'Frequency in second (0 to disable this feature, 10 seconds by default)' => 'Frekvencija u sekundama (0 je onemogućeno u budućnosti, 10 sekundi je uobičajeno)',
|
'Frequency in second (0 to disable this feature, 10 seconds by default)' => 'Frekvencija u sekundama (0 je onemogućeno u budućnosti, 10 sekundi je uobičajeno)',
|
||||||
'Application URL' => 'URL aplikacje',
|
'Application URL' => 'URL aplikacije',
|
||||||
'Token regenerated.' => 'Token regenerisan.',
|
'Token regenerated.' => 'Token regenerisan.',
|
||||||
'Date format' => 'Format datuma',
|
'Date format' => 'Format datuma',
|
||||||
'ISO format is always accepted, example: "%s" and "%s"' => 'Format ISO je uvek prihvatljiv, primjer: "%s", "%s"',
|
'ISO format is always accepted, example: "%s" and "%s"' => 'Format ISO je uvijek prihvatljiv, primjer: "%s", "%s"',
|
||||||
'New private project' => 'Novi privatni projekat',
|
'New private project' => 'Novi privatni projekat',
|
||||||
'This project is private' => 'Ovaj projekat je privatan',
|
'This project is private' => 'Ovaj projekat je privatan',
|
||||||
'Type here to create a new sub-task' => 'Piši ovdje za kreiranje novog pod-zadatka',
|
|
||||||
'Add' => 'Dodaj',
|
'Add' => 'Dodaj',
|
||||||
'Start date' => 'Datum početka',
|
'Start date' => 'Datum početka',
|
||||||
'Time estimated' => 'Procijenjeno vrijeme',
|
'Time estimated' => 'Procijenjeno vrijeme',
|
||||||
'There is nothing assigned to you.' => 'Ništa vam nije dodijeljeno',
|
'There is nothing assigned to you.' => 'Ništa ti nije dodijeljeno',
|
||||||
'My tasks' => 'Moji zadaci',
|
'My tasks' => 'Moji zadaci',
|
||||||
'Activity stream' => 'Spisak aktivnosti',
|
'Activity stream' => 'Spisak aktivnosti',
|
||||||
'Dashboard' => 'Panel',
|
'Dashboard' => 'Panel',
|
||||||
|
@ -487,9 +480,6 @@ return array(
|
||||||
'Daily project summary export for "%s"' => 'Izvoz zbirnog pregleda po danima za "%s"',
|
'Daily project summary export for "%s"' => 'Izvoz zbirnog pregleda po danima za "%s"',
|
||||||
'Exports' => 'Izvozi',
|
'Exports' => 'Izvozi',
|
||||||
'This export contains the number of tasks per column grouped per day.' => 'Ovaj izvoz sadržava broj zadataka po koloni grupisanih po danima.',
|
'This export contains the number of tasks per column grouped per day.' => 'Ovaj izvoz sadržava broj zadataka po koloni grupisanih po danima.',
|
||||||
'Nothing to preview...' => 'Ništa za pokazati...',
|
|
||||||
'Preview' => 'Pregled',
|
|
||||||
'Write' => 'Piši',
|
|
||||||
'Active swimlanes' => 'Aktivne swimline trake',
|
'Active swimlanes' => 'Aktivne swimline trake',
|
||||||
'Add a new swimlane' => 'Dodaj novu swimline traku',
|
'Add a new swimlane' => 'Dodaj novu swimline traku',
|
||||||
'Change default swimlane' => 'Preimenuj podrazumijevanu swimline traku',
|
'Change default swimlane' => 'Preimenuj podrazumijevanu swimline traku',
|
||||||
|
@ -543,7 +533,6 @@ return array(
|
||||||
'Task age in days' => 'Trajanje zadatka u danima',
|
'Task age in days' => 'Trajanje zadatka u danima',
|
||||||
'Days in this column' => 'Dani u ovoj koloni',
|
'Days in this column' => 'Dani u ovoj koloni',
|
||||||
'%dd' => '%dd',
|
'%dd' => '%dd',
|
||||||
'Add a link' => 'Dodaj vezu',
|
|
||||||
'Add a new link' => 'Dodaj novu vezu',
|
'Add a new link' => 'Dodaj novu vezu',
|
||||||
'Do you really want to remove this link: "%s"?' => 'Da li zaista želite ukloniti ovu vezu: "%s"?',
|
'Do you really want to remove this link: "%s"?' => 'Da li zaista želite ukloniti ovu vezu: "%s"?',
|
||||||
'Do you really want to remove this link with task #%d?' => 'Da li zaista želite ukloniti ovu vezu sa zadatkom #%d?',
|
'Do you really want to remove this link with task #%d?' => 'Da li zaista želite ukloniti ovu vezu sa zadatkom #%d?',
|
||||||
|
@ -598,7 +587,7 @@ return array(
|
||||||
'CHF - Swiss Francs' => 'CHF - Švicarski franak',
|
'CHF - Swiss Francs' => 'CHF - Švicarski franak',
|
||||||
'Custom Stylesheet' => 'Prilagođeni stil',
|
'Custom Stylesheet' => 'Prilagođeni stil',
|
||||||
'download' => 'preuzmi',
|
'download' => 'preuzmi',
|
||||||
'EUR - Euro' => 'EUR - Evro',
|
'EUR - Euro' => 'EUR - Euro',
|
||||||
'GBP - British Pound' => 'GBP - Britanska funta',
|
'GBP - British Pound' => 'GBP - Britanska funta',
|
||||||
'INR - Indian Rupee' => 'INR - Indijski rupi',
|
'INR - Indian Rupee' => 'INR - Indijski rupi',
|
||||||
'JPY - Japanese Yen' => 'JPY - Japanski jen',
|
'JPY - Japanese Yen' => 'JPY - Japanski jen',
|
||||||
|
@ -619,7 +608,7 @@ return array(
|
||||||
'Rate' => 'Stopa',
|
'Rate' => 'Stopa',
|
||||||
'Change reference currency' => 'Promijeni referencu valute',
|
'Change reference currency' => 'Promijeni referencu valute',
|
||||||
'Add a new currency rate' => 'Dodaj novu stopu valute',
|
'Add a new currency rate' => 'Dodaj novu stopu valute',
|
||||||
'Reference currency' => 'Referenca valute',
|
'Reference currency' => 'Referentna valuta',
|
||||||
'The currency rate have been added successfully.' => 'Stopa valute je uspješno dodana.',
|
'The currency rate have been added successfully.' => 'Stopa valute je uspješno dodana.',
|
||||||
'Unable to add this currency rate.' => 'Nemoguće dodati stopu valute.',
|
'Unable to add this currency rate.' => 'Nemoguće dodati stopu valute.',
|
||||||
'Webhook URL' => 'Webhook URL',
|
'Webhook URL' => 'Webhook URL',
|
||||||
|
@ -734,7 +723,7 @@ return array(
|
||||||
'Time spent changed: %sh' => 'Utrošeno vrijeme je promijenjeno: %sh',
|
'Time spent changed: %sh' => 'Utrošeno vrijeme je promijenjeno: %sh',
|
||||||
'Time estimated changed: %sh' => 'Očekivano vrijeme je promijenjeno: %sh',
|
'Time estimated changed: %sh' => 'Očekivano vrijeme je promijenjeno: %sh',
|
||||||
'The field "%s" have been updated' => 'Polje "%s" je ažurirano',
|
'The field "%s" have been updated' => 'Polje "%s" je ažurirano',
|
||||||
'The description have been modified' => 'Promijenjen opis',
|
'The description has been modified:' => 'Promijenjen opis:',
|
||||||
'Do you really want to close the task "%s" as well as all subtasks?' => 'Da li zaista želiš zatvoriti zadatak "%s" kao i sve pod-zadatke?',
|
'Do you really want to close the task "%s" as well as all subtasks?' => 'Da li zaista želiš zatvoriti zadatak "%s" kao i sve pod-zadatke?',
|
||||||
'I want to receive notifications for:' => 'Želim dobijati obavještenja za:',
|
'I want to receive notifications for:' => 'Želim dobijati obavještenja za:',
|
||||||
'All tasks' => 'Sve zadatke',
|
'All tasks' => 'Sve zadatke',
|
||||||
|
@ -753,8 +742,6 @@ return array(
|
||||||
'My activity stream' => 'Tok mojih aktivnosti',
|
'My activity stream' => 'Tok mojih aktivnosti',
|
||||||
'My calendar' => 'Moj kalendar',
|
'My calendar' => 'Moj kalendar',
|
||||||
'Search tasks' => 'Pretraga zadataka',
|
'Search tasks' => 'Pretraga zadataka',
|
||||||
'Back to the calendar' => 'Vrati na kalendar',
|
|
||||||
'Filters' => 'Filteri',
|
|
||||||
'Reset filters' => 'Vrati filtere na početno',
|
'Reset filters' => 'Vrati filtere na početno',
|
||||||
'My tasks due tomorrow' => 'Moji zadaci koje treba završiti sutra',
|
'My tasks due tomorrow' => 'Moji zadaci koje treba završiti sutra',
|
||||||
'Tasks due today' => 'Zadaci koje treba završiti danas',
|
'Tasks due today' => 'Zadaci koje treba završiti danas',
|
||||||
|
@ -765,8 +752,8 @@ return array(
|
||||||
'Not assigned' => 'Bez izvršioca',
|
'Not assigned' => 'Bez izvršioca',
|
||||||
'View advanced search syntax' => 'Vidi naprednu sintaksu pretrage',
|
'View advanced search syntax' => 'Vidi naprednu sintaksu pretrage',
|
||||||
'Overview' => 'Opšti pregled',
|
'Overview' => 'Opšti pregled',
|
||||||
'Board/Calendar/List view' => 'Pregle Table/Kalendara/Liste',
|
'Board/Calendar/List view' => 'Pregled Ploče/Kalendara/Liste',
|
||||||
'Switch to the board view' => 'Promijeni da vidim tablu',
|
'Switch to the board view' => 'Promijeni da vidim ploču',
|
||||||
'Switch to the calendar view' => 'Promijeni da vidim kalendar',
|
'Switch to the calendar view' => 'Promijeni da vidim kalendar',
|
||||||
'Switch to the list view' => 'Promijeni da vidim listu',
|
'Switch to the list view' => 'Promijeni da vidim listu',
|
||||||
'Go to the search/filter box' => 'Idi na kutiju s pretragom/filterima',
|
'Go to the search/filter box' => 'Idi na kutiju s pretragom/filterima',
|
||||||
|
@ -850,11 +837,10 @@ return array(
|
||||||
'Gantt chart for all projects' => 'Gantogram za sve projekte',
|
'Gantt chart for all projects' => 'Gantogram za sve projekte',
|
||||||
'Projects list' => 'Lista projekata',
|
'Projects list' => 'Lista projekata',
|
||||||
'Gantt chart for this project' => 'Gantogram za ovaj projekat',
|
'Gantt chart for this project' => 'Gantogram za ovaj projekat',
|
||||||
'Project board' => 'Tabla projekta',
|
'Project board' => 'Ploča projekta',
|
||||||
'End date:' => 'Datum završetka:',
|
'End date:' => 'Datum završetka:',
|
||||||
'There is no start date or end date for this project.' => 'Nema početnog ili krajnjeg datuma za ovaj projekat.',
|
'There is no start date or end date for this project.' => 'Nema početnog ili krajnjeg datuma za ovaj projekat.',
|
||||||
'Projects Gantt chart' => 'Gantogram projekata',
|
'Projects Gantt chart' => 'Gantogram projekata',
|
||||||
'Link type' => 'Tip veze',
|
|
||||||
'Change task color when using a specific task link' => 'Promijeni boju zadatka kada se koristi određena veza na zadatku',
|
'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',
|
'Task link creation or modification' => 'Veza na zadatku je napravljena ili izmijenjena',
|
||||||
'Milestone' => 'Prekretnica',
|
'Milestone' => 'Prekretnica',
|
||||||
|
@ -895,18 +881,17 @@ return array(
|
||||||
'Assignee changed on task #%d' => 'Promijenjen izvršilac na zadatku #%d',
|
'Assignee changed on task #%d' => 'Promijenjen izvršilac na zadatku #%d',
|
||||||
'%d overdue tasks' => '%d zadataka kasni',
|
'%d overdue tasks' => '%d zadataka kasni',
|
||||||
'Task #%d is overdue' => 'Zadatak #%d kasni',
|
'Task #%d is overdue' => 'Zadatak #%d kasni',
|
||||||
'No new notifications.' => 'Nema novi obavještenja.',
|
'No new notifications.' => 'Nema novih obavještenja.',
|
||||||
'Mark all as read' => 'Označi sve kao pročitano',
|
'Mark all as read' => 'Označi sve kao pročitano',
|
||||||
'Mark as read' => 'Označi kao pročitano',
|
'Mark as read' => 'Označi kao pročitano',
|
||||||
'Total number of tasks in this column across all swimlanes' => 'Ukupan broj zadataka u ovoj koloni u svim swimline trakama',
|
'Total number of tasks in this column across all swimlanes' => 'Ukupan broj zadataka u ovoj koloni u svim swimline trakama',
|
||||||
'Collapse swimlane' => 'Skupi swimline trake',
|
'Collapse swimlane' => 'Skupi swimline trake',
|
||||||
'Expand swimlane' => 'Proširi swimline trake',
|
'Expand swimlane' => 'Proširi swimline trake',
|
||||||
'Add a new filter' => 'Dodaj novi filter',
|
'Add a new filter' => 'Dodaj novi filter',
|
||||||
'Share with all project members' => 'Podijeli s svim članovima projekta',
|
'Share with all project members' => 'Podijeli sa svim članovima projekta',
|
||||||
'Shared' => 'Podijeljeno',
|
'Shared' => 'Podijeljeno',
|
||||||
'Owner' => 'Vlasnik',
|
'Owner' => 'Vlasnik',
|
||||||
'Unread notifications' => 'Nepročitana obavještenja',
|
'Unread notifications' => 'Nepročitana obavještenja',
|
||||||
'My filters' => 'Moji filteri',
|
|
||||||
'Notification methods:' => 'Metode obavještenja:',
|
'Notification methods:' => 'Metode obavještenja:',
|
||||||
'Import tasks from CSV file' => 'Uvezi zadatke putem CSV fajla',
|
'Import tasks from CSV file' => 'Uvezi zadatke putem CSV fajla',
|
||||||
'Unable to read your file' => 'Nemoguće pročitati fajl',
|
'Unable to read your file' => 'Nemoguće pročitati fajl',
|
||||||
|
@ -936,216 +921,236 @@ return array(
|
||||||
'Your file must use the predefined CSV format' => 'File mora biti predefinisani CSV format',
|
'Your file must use the predefined CSV format' => 'File mora biti predefinisani CSV format',
|
||||||
'Your file must be encoded in UTF-8' => 'File mora biti u UTF-8 kodu',
|
'Your file must be encoded in UTF-8' => 'File mora biti u UTF-8 kodu',
|
||||||
'The first row must be the header' => 'Prvi red mora biti zaglavlje',
|
'The first row must be the header' => 'Prvi red mora biti zaglavlje',
|
||||||
'Duplicates are not verified for you' => 'Dipliciranje nisu potvrđena',
|
'Duplicates are not verified for you' => 'Dupliciranja neće biti provjeravana (to ćeš morati uraditi ručno)',
|
||||||
'The due date must use the ISO format: YYYY-MM-DD' => 'Datum do kog se treba izvršiti mora biti u ISO formatu: GGGG-MM-DD',
|
'The due date must use the ISO format: YYYY-MM-DD' => 'Datum do kog se treba izvršiti mora biti u ISO formatu: GGGG-MM-DD',
|
||||||
'Download CSV template' => 'Preuzmi CSV šablon',
|
'Download CSV template' => 'Preuzmi CSV šablon',
|
||||||
'No external integration registered.' => 'Nema registrovanih vanjskih integracija.',
|
'No external integration registered.' => 'Nema registrovanih vanjskih integracija.',
|
||||||
'Duplicates are not imported' => 'Duplikati nisu uvezeni',
|
'Duplicates are not imported' => 'Duplikati nisu uvezeni',
|
||||||
'Usernames must be lowercase and unique' => 'Korisničko ime mora biti malim slovima i jedinstveno',
|
'Usernames must be lowercase and unique' => 'Korisničko ime mora biti malim slovima i jedinstveno',
|
||||||
'Passwords will be encrypted if present' => 'Šifra će biti kriptovana',
|
'Passwords will be encrypted if present' => 'Šifra će biti kriptovana',
|
||||||
// '%s attached a new file to the task %s' => '',
|
'%s attached a new file to the task %s' => '%s je dodano novi fajl u zadatak %s',
|
||||||
|
'Link type' => 'Tip veze',
|
||||||
'Assign automatically a category based on a link' => 'Automatsko pridruživanje kategorije bazirano na vezi',
|
'Assign automatically a category based on a link' => 'Automatsko pridruživanje kategorije bazirano na vezi',
|
||||||
'BAM - Konvertible Mark' => 'BAM - Konvertibilna marka',
|
'BAM - Konvertible Mark' => 'BAM - Konvertibilna marka',
|
||||||
// 'Assignee Username' => '',
|
'Assignee Username' => 'Pridruži korisničko ime',
|
||||||
// 'Assignee Name' => '',
|
'Assignee Name' => 'Pridruži ime',
|
||||||
// 'Groups' => '',
|
'Groups' => 'Grupe',
|
||||||
// 'Members of %s' => '',
|
'Members of %s' => 'Članovi %s',
|
||||||
// 'New group' => '',
|
'New group' => 'Nova grupa',
|
||||||
// 'Group created successfully.' => '',
|
'Group created successfully.' => 'Grupa uspješno kreirana.',
|
||||||
// 'Unable to create your group.' => '',
|
'Unable to create your group.' => 'Nemoguće kreirati grupu.',
|
||||||
// 'Edit group' => '',
|
'Edit group' => 'Uredi grupu',
|
||||||
// 'Group updated successfully.' => '',
|
'Group updated successfully.' => 'Grupa uspješno ažurirana.',
|
||||||
// 'Unable to update your group.' => '',
|
'Unable to update your group.' => 'Nemoguće ažurirati grupu',
|
||||||
// 'Add group member to "%s"' => '',
|
'Add group member to "%s"' => 'Dodaj člana grupe u ""%s"',
|
||||||
// 'Group member added successfully.' => '',
|
'Group member added successfully.' => 'Uspješno dodan član grupe.',
|
||||||
// 'Unable to add group member.' => '',
|
'Unable to add group member.' => 'Nemoguće dodati člana grupe.',
|
||||||
// 'Remove user from group "%s"' => '',
|
'Remove user from group "%s"' => 'Ukloni korisnika iz grupe "%s"',
|
||||||
// 'User removed successfully from this group.' => '',
|
'User removed successfully from this group.' => 'Korisnik uspješno uklonjen iz grupe.',
|
||||||
// 'Unable to remove this user from the group.' => '',
|
'Unable to remove this user from the group.' => 'Nemoguće ukloniti korisnika iz grupe.',
|
||||||
// 'Remove group' => '',
|
'Remove group' => 'Ukloni grupu',
|
||||||
// 'Group removed successfully.' => '',
|
'Group removed successfully.' => 'Grupa uspješno uklonjena.',
|
||||||
// 'Unable to remove this group.' => '',
|
'Unable to remove this group.' => 'Nemoguće ukloniti grupu.',
|
||||||
// 'Project Permissions' => '',
|
'Project Permissions' => 'Prava na projektu',
|
||||||
// 'Manager' => '',
|
'Manager' => 'Menadžer',
|
||||||
// 'Project Manager' => '',
|
'Project Manager' => 'Menadžer projekta',
|
||||||
// 'Project Member' => '',
|
'Project Member' => 'Član projekta',
|
||||||
// 'Project Viewer' => '',
|
'Project Viewer' => 'Preglednik projekta',
|
||||||
// 'Your account is locked for %d minutes' => '',
|
'Your account is locked for %d minutes' => 'Tvoj korisnički račun je zaključan za narednih %d minuta',
|
||||||
// 'Invalid captcha' => '',
|
'Invalid captcha' => 'Pogrešna captcha',
|
||||||
// 'The name must be unique' => '',
|
'The name must be unique' => 'Ime mora biti jedinstveno',
|
||||||
// 'View all groups' => '',
|
'View all groups' => 'Pregledaj sve grupe',
|
||||||
// 'View group members' => '',
|
'View group members' => 'Pregledaj članove grupe',
|
||||||
// 'There is no user available.' => '',
|
'There is no user available.' => 'Trenutno nema dostupnih korisnika.',
|
||||||
// 'Do you really want to remove the user "%s" from the group "%s"?' => '',
|
'Do you really want to remove the user "%s" from the group "%s"?' => 'Da li zaista želiš ukloniti korisnika "%s" iz grupe "%s"?',
|
||||||
// 'There is no group.' => '',
|
'There is no group.' => 'Trenutno nema grupa.',
|
||||||
// 'External Id' => '',
|
'External Id' => 'Vanjski Id',
|
||||||
// 'Add group member' => '',
|
'Add group member' => 'Dodaj člana grupe',
|
||||||
// 'Do you really want to remove this group: "%s"?' => '',
|
'Do you really want to remove this group: "%s"?' => 'Da li zaista želiš ukloniti ovu grupu: "%s"?',
|
||||||
// 'There is no user in this group.' => '',
|
'There is no user in this group.' => 'Trenutno nema korisnika u grupi.',
|
||||||
// 'Remove this user' => '',
|
'Remove this user' => 'Ukloni ovog korisnika',
|
||||||
// 'Permissions' => '',
|
'Permissions' => 'Prava',
|
||||||
// 'Allowed Users' => '',
|
'Allowed Users' => 'Dozvoljeni korisnici',
|
||||||
// 'No user have been allowed specifically.' => '',
|
'No user have been allowed specifically.' => 'Nema korisnika sa specijalnim dozvolama.',
|
||||||
// 'Role' => '',
|
'Role' => 'Uloge',
|
||||||
// 'Enter user name...' => '',
|
'Enter user name...' => 'Unesi korisničko ime...',
|
||||||
// 'Allowed Groups' => '',
|
'Allowed Groups' => 'Dozvoljene grupe',
|
||||||
// 'No group have been allowed specifically.' => '',
|
'No group have been allowed specifically.' => 'Nema grupa sa specijalnim dozvolama.',
|
||||||
// 'Group' => '',
|
'Group' => 'Grupa',
|
||||||
// 'Group Name' => '',
|
'Group Name' => 'Ime grupe',
|
||||||
// 'Enter group name...' => '',
|
'Enter group name...' => 'Unesi ime grupe...',
|
||||||
// 'Role:' => '',
|
'Role:' => 'Uloga:',
|
||||||
'Project members' => 'Članovi projekta',
|
'Project members' => 'Članovi projekta',
|
||||||
// 'Compare hours for "%s"' => '',
|
'Compare hours for "%s"' => 'Poredi sate za "%s"',
|
||||||
// '%s mentioned you in the task #%d' => '',
|
'%s mentioned you in the task #%d' => '%s te spomenuo u zadatku #%d',
|
||||||
// '%s mentioned you in a comment on the task #%d' => '',
|
'%s mentioned you in a comment on the task #%d' => '%s te spomenuo u komentaru zadatka #%d',
|
||||||
// 'You were mentioned in the task #%d' => '',
|
'You were mentioned in the task #%d' => 'Spomenut si u zadatku #%d',
|
||||||
// 'You were mentioned in a comment on the task #%d' => '',
|
'You were mentioned in a comment on the task #%d' => 'Spomenut si u komentaru zadatka #%d',
|
||||||
// 'Mentioned' => '',
|
'Mentioned' => 'Spominjanja',
|
||||||
// 'Compare Estimated Time vs Actual Time' => '',
|
'Compare Estimated Time vs Actual Time' => 'Poređenje očekivanog i aktuelnog vremena',
|
||||||
// 'Estimated hours: ' => '',
|
'Estimated hours: ' => 'Očekivani sati:',
|
||||||
// 'Actual hours: ' => '',
|
'Actual hours: ' => 'Aktuelni sati:',
|
||||||
// 'Hours Spent' => '',
|
'Hours Spent' => 'Utrošeni sati:',
|
||||||
// 'Hours Estimated' => '',
|
'Hours Estimated' => 'Očekivani sati',
|
||||||
// 'Estimated Time' => '',
|
'Estimated Time' => 'Očekivano vrijeme',
|
||||||
// 'Actual Time' => '',
|
'Actual Time' => 'Aktuelno vrijeme',
|
||||||
// 'Estimated vs actual time' => '',
|
'Estimated vs actual time' => 'Očekivano nasuprot aktuelnog vremena',
|
||||||
// 'RUB - Russian Ruble' => '',
|
'RUB - Russian Ruble' => 'RUB - Ruski rubij',
|
||||||
// 'Assign the task to the person who does the action when the column is changed' => '',
|
'Assign the task to the person who does the action when the column is changed' => 'Dodijeli zadatak osobi koja izvrši akciju promjene kolone',
|
||||||
// 'Close a task in a specific column' => '',
|
'Close a task in a specific column' => 'Zatvori zadatak u određenoj koloni',
|
||||||
// 'Time-based One-time Password Algorithm' => '',
|
'Time-based One-time Password Algorithm' => 'Vremenski bazirani One-time Algoritam šifri',
|
||||||
// 'Two-Factor Provider: ' => '',
|
'Two-Factor Provider: ' => 'Two-Factor provajder',
|
||||||
// 'Disable two-factor authentication' => '',
|
'Disable two-factor authentication' => 'Onemogući two-factor autentifikaciju',
|
||||||
// 'Enable two-factor authentication' => '',
|
'Enable two-factor authentication' => 'Omogući two-factor autentifikaciju',
|
||||||
// 'There is no integration registered at the moment.' => '',
|
'There is no integration registered at the moment.' => 'Trenutno nema registrovanih integracija.',
|
||||||
// 'Password Reset for Kanboard' => '',
|
'Password Reset for Kanboard' => 'Promjena šifre za Kanboard',
|
||||||
// 'Forgot password?' => '',
|
'Forgot password?' => 'Ne mogu da se sjetim šifre?',
|
||||||
// 'Enable "Forget Password"' => '',
|
'Enable "Forget Password"' => 'Omogući "Ne mogu da se sjetim šifre"',
|
||||||
// 'Password Reset' => '',
|
'Password Reset' => 'Promijena šifre',
|
||||||
// 'New password' => '',
|
'New password' => 'Nova šifra',
|
||||||
// 'Change Password' => '',
|
'Change Password' => 'Promijeni šifru',
|
||||||
// 'To reset your password click on this link:' => '',
|
'To reset your password click on this link:' => 'Da bi promijenio šifru klikni na ovaj link:',
|
||||||
// 'Last Password Reset' => '',
|
'Last Password Reset' => 'Posljednja promjena šifre',
|
||||||
// 'The password has never been reinitialized.' => '',
|
'The password has never been reinitialized.' => 'Šifra nije nikada promijenjena.',
|
||||||
// 'Creation' => '',
|
'Creation' => 'Napravljena',
|
||||||
// 'Expiration' => '',
|
'Expiration' => 'Ističe',
|
||||||
// 'Password reset history' => '',
|
'Password reset history' => 'Hitorija promjena šifri',
|
||||||
// 'All tasks of the column "%s" and the swimlane "%s" have been closed successfully.' => '',
|
'All tasks of the column "%s" and the swimlane "%s" have been closed successfully.' => 'Svi zadaci kolone "%s" i swimline-a "%s" uspješno su zatvoreni.',
|
||||||
// 'Do you really want to close all tasks of this column?' => '',
|
'Do you really want to close all tasks of this column?' => 'Da li zaista želiš zatvoriti sve zadatke ove kolone?',
|
||||||
// '%d task(s) in the column "%s" and the swimlane "%s" will be closed.' => '',
|
'%d task(s) in the column "%s" and the swimlane "%s" will be closed.' => '%d zadatak(ci) u koloni "%s" i swimline-u "%s" će biti zatvoreni.',
|
||||||
// 'Close all tasks of this column' => '',
|
'Close all tasks of this column' => 'Zatvori sve zadatke ove kolone',
|
||||||
// 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => '',
|
'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => 'Nema posebnog plugin-a za obavještenja. Još uvijek možeš koristiti individualne postavke obavještenja na svom profilu.',
|
||||||
// 'My dashboard' => '',
|
'My dashboard' => 'Moj panel',
|
||||||
// 'My profile' => '',
|
'My profile' => 'Moj profil',
|
||||||
// 'Project owner: ' => '',
|
'Project owner: ' => 'Vlasnik projekta:',
|
||||||
// 'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => '',
|
'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => 'Identifikator projekta je opcionalan i mora biti alfanumerički, na primjer: MOJPROJEKAT.',
|
||||||
// 'Project owner' => '',
|
'Project owner' => 'Vlasnik projekta',
|
||||||
// 'Those dates are useful for the project Gantt chart.' => '',
|
'Those dates are useful for the project Gantt chart.' => 'Ovi datumi su korisni za pravljenje Gantt dijagrama za projekat.',
|
||||||
// 'Private projects do not have users and groups management.' => '',
|
'Private projects do not have users and groups management.' => 'Privatni projekti ne mogu imati korisnike ili grupe korisnika.',
|
||||||
// 'There is no project member.' => '',
|
'There is no project member.' => 'Nema članova projekta.',
|
||||||
// 'Priority' => '',
|
'Priority' => 'Prioritet',
|
||||||
// 'Task priority' => '',
|
'Task priority' => 'Prioritet zadatka',
|
||||||
// 'General' => '',
|
'General' => 'Opšte',
|
||||||
// 'Dates' => '',
|
'Dates' => 'Datumi',
|
||||||
// 'Default priority' => '',
|
'Default priority' => 'Podrazumijevani prioritet',
|
||||||
// 'Lowest priority' => '',
|
'Lowest priority' => 'Najmanji prioritet',
|
||||||
// 'Highest priority' => '',
|
'Highest priority' => 'Najveći prioritet',
|
||||||
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
|
'If you put zero to the low and high priority, this feature will be disabled.' => 'Ako upišeš nulu za najmanji i najveći prioritet, ova opcija će biti onemogućena.',
|
||||||
// 'Close a task when there is no activity' => '',
|
'Close a task when there is no activity' => 'Zatvori zadatak kada nema aktivnosti',
|
||||||
// 'Duration in days' => '',
|
'Duration in days' => 'Dužina trajanja u danima',
|
||||||
// 'Send email when there is no activity on a task' => '',
|
'Send email when there is no activity on a task' => 'Pošalji email kada nema aktivnosti na zadatku',
|
||||||
// 'List of external links' => '',
|
'Unable to fetch link information.' => 'Ne mogu da pribavim informacije o vezi.',
|
||||||
// 'Unable to fetch link information.' => '',
|
'Daily background job for tasks' => 'Dnevni pozadinski poslovi na zadacima',
|
||||||
// 'Daily background job for tasks' => '',
|
'Auto' => 'Automatski',
|
||||||
// 'Auto' => '',
|
'Related' => 'Povezani',
|
||||||
// 'Related' => '',
|
'Attachment' => 'Dodijeljeni',
|
||||||
// 'Attachment' => '',
|
'Title not found' => 'Bez naslova',
|
||||||
// 'Title not found' => '',
|
'Web Link' => 'Web veza',
|
||||||
// 'Web Link' => '',
|
'External links' => 'Vanjska veza',
|
||||||
// 'External links' => '',
|
'Add external link' => 'Dodaj vanjsku vezu',
|
||||||
// 'Add external link' => '',
|
'Type' => 'Vrsta',
|
||||||
// 'Type' => '',
|
'Dependency' => 'Zavisnost',
|
||||||
// 'Dependency' => '',
|
'Add internal link' => 'Dodaj unutrašnju vezu',
|
||||||
// 'Add internal link' => '',
|
'Add a new external link' => 'Dodaj novu vanjsku vezu',
|
||||||
// 'Add a new external link' => '',
|
'Edit external link' => 'Uredi vanjsku vezu',
|
||||||
// 'Edit external link' => '',
|
'External link' => 'Vanjska veza',
|
||||||
// 'External link' => '',
|
'Copy and paste your link here...' => 'Kopiraj i zalijepi svoju vezu ovdje...',
|
||||||
// 'Copy and paste your link here...' => '',
|
'URL' => 'URL',
|
||||||
// 'URL' => '',
|
'Internal links' => 'Unutrašnje veze',
|
||||||
// 'There is no external link for the moment.' => '',
|
'Assign to me' => 'Dodijeli meni',
|
||||||
// 'Internal links' => '',
|
'Me' => 'Za mene',
|
||||||
// 'There is no internal link for the moment.' => '',
|
'Do not duplicate anything' => 'Ništa ne dupliciraj',
|
||||||
// 'Assign to me' => '',
|
'Projects management' => 'Menadžment projekata',
|
||||||
// 'Me' => '',
|
'Users management' => 'Menadžment korisnika',
|
||||||
// 'Do not duplicate anything' => '',
|
'Groups management' => 'Menadžment grupa',
|
||||||
// 'Projects management' => '',
|
'Create from another project' => 'Napravi iz drugog projekta',
|
||||||
// 'Users management' => '',
|
'open' => 'otvoreno',
|
||||||
// 'Groups management' => '',
|
'closed' => 'zatvoreno',
|
||||||
// 'Create from another project' => '',
|
'Priority:' => 'Prioritet:',
|
||||||
// 'There is no subtask at the moment.' => '',
|
'Reference:' => 'Preporuka:',
|
||||||
// 'open' => '',
|
'Complexity:' => 'Složenost:',
|
||||||
// 'closed' => '',
|
'Swimlane:' => 'Swimline:',
|
||||||
// 'Priority:' => '',
|
'Column:' => 'Kolona:',
|
||||||
// 'Reference:' => '',
|
'Position:' => 'Pozicija:',
|
||||||
// 'Complexity:' => '',
|
'Creator:' => 'Kreator:',
|
||||||
// 'Swimlane:' => '',
|
'Time estimated:' => 'Očekivano vrijeme:',
|
||||||
// 'Column:' => '',
|
'%s hours' => '%s sati',
|
||||||
// 'Position:' => '',
|
'Time spent:' => 'Utrošeno vrijeme:',
|
||||||
// 'Creator:' => '',
|
'Created:' => 'Kreirao:',
|
||||||
// 'Time estimated:' => '',
|
'Modified:' => 'Uredio:',
|
||||||
// '%s hours' => '',
|
'Completed:' => 'Završio:',
|
||||||
// 'Time spent:' => '',
|
'Started:' => 'Početo:',
|
||||||
// 'Created:' => '',
|
'Moved:' => 'Pomjereno:',
|
||||||
// 'Modified:' => '',
|
'Task #%d' => 'Zadatak #%d',
|
||||||
// 'Completed:' => '',
|
'Date and time format' => 'Format za datum i vrijeme',
|
||||||
// 'Started:' => '',
|
'Time format' => 'Format za vrijeme',
|
||||||
// 'Moved:' => '',
|
'Start date: ' => 'Početni datum:',
|
||||||
// 'Task #%d' => '',
|
'End date: ' => 'Krajnji datum:',
|
||||||
// 'Sub-tasks' => '',
|
'New due date: ' => 'Novi datum očekivanja:',
|
||||||
// 'Date and time format' => '',
|
'Start date changed: ' => 'Početni datum promijenjen:',
|
||||||
// 'Time format' => '',
|
'Disable private projects' => 'Onemogući privatne projekte',
|
||||||
// 'Start date: ' => '',
|
'Do you really want to remove this custom filter: "%s"?' => 'Da li zaista želiš ukloniti ovaj prilagođeni filter "%s"?',
|
||||||
// 'End date: ' => '',
|
'Remove a custom filter' => 'Ukloni prilagođeni filter',
|
||||||
// 'New due date: ' => '',
|
'User activated successfully.' => 'Korisnik uspješno aktiviran.',
|
||||||
// 'Start date changed: ' => '',
|
'Unable to enable this user.' => 'Nemoguće omogućiti ovog korisnika.',
|
||||||
// 'Disable private projects' => '',
|
'User disabled successfully.' => 'Korisnik uspješno onemogućen.',
|
||||||
// 'Do you really want to remove this custom filter: "%s"?' => '',
|
'Unable to disable this user.' => 'Nemoguće onemogućiti ovog korisnika.',
|
||||||
// 'Remove a custom filter' => '',
|
'All files have been uploaded successfully.' => 'Svi fajlovi su uspješno dodani.',
|
||||||
// 'User activated successfully.' => '',
|
'View uploaded files' => 'Pregled dodanih fajlova',
|
||||||
// 'Unable to enable this user.' => '',
|
'The maximum allowed file size is %sB.' => 'Maksimalna dozvoljena veličina fajla je %sB.',
|
||||||
// 'User disabled successfully.' => '',
|
'Choose files again' => 'Izaberi ponovo fajlove',
|
||||||
// 'Unable to disable this user.' => '',
|
'Drag and drop your files here' => 'Povuci i spusti svoje fajlove ovdje',
|
||||||
// 'All files have been uploaded successfully.' => '',
|
'choose files' => 'izaberi fajlove',
|
||||||
// 'View uploaded files' => '',
|
'View profile' => 'Pregledaj profil',
|
||||||
// 'The maximum allowed file size is %sB.' => '',
|
'Two Factor' => 'Dva faktora',
|
||||||
// 'Choose files again' => '',
|
'Disable user' => 'Onemogući korisnika',
|
||||||
// 'Drag and drop your files here' => '',
|
'Do you really want to disable this user: "%s"?' => 'Da li zaista želiš onemogućiti ovog korisnika: "%s"?',
|
||||||
// 'choose files' => '',
|
'Enable user' => 'Omogući korisnika',
|
||||||
// 'View profile' => '',
|
'Do you really want to enable this user: "%s"?' => 'Da li zaista želiš omogućiti ovog korisnika: "%s"?',
|
||||||
// 'Two Factor' => '',
|
'Download' => 'Preuzeto',
|
||||||
// 'Disable user' => '',
|
'Uploaded: %s' => 'Dodano: %s',
|
||||||
// 'Do you really want to disable this user: "%s"?' => '',
|
'Size: %s' => 'Veličina: %s',
|
||||||
// 'Enable user' => '',
|
'Uploaded by %s' => 'Dodao %s',
|
||||||
// 'Do you really want to enable this user: "%s"?' => '',
|
'Filename' => 'Ime fajla',
|
||||||
// 'Download' => '',
|
'Size' => 'Veličina',
|
||||||
// 'Uploaded: %s' => '',
|
'Column created successfully.' => 'Kolona uspješno napravljena.',
|
||||||
// 'Size: %s' => '',
|
'Another column with the same name exists in the project' => 'Već postoji kolona s istim imenom u ovom projektu.',
|
||||||
// 'Uploaded by %s' => '',
|
'Default filters' => 'Podrazumijevani filteri',
|
||||||
// 'Filename' => '',
|
'Your board doesn\'t have any column!' => 'Vaš panel nema ni jednu kolonu!',
|
||||||
// 'Size' => '',
|
'Change column position' => 'Promijeni poziciju kolone',
|
||||||
// 'Column created successfully.' => '',
|
'Switch to the project overview' => 'Promijeni u pregled projekta',
|
||||||
// 'Another column with the same name exists in the project' => '',
|
'User filters' => 'Korisnički filteri',
|
||||||
// 'Default filters' => '',
|
'Category filters' => 'Kategorija filtera',
|
||||||
// 'Your board doesn\'t have any column!' => '',
|
'Upload a file' => 'Dodaj fajl',
|
||||||
// 'Change column position' => '',
|
'View file' => 'Pregled fajla',
|
||||||
// 'Switch to the project overview' => '',
|
'Last activity' => 'Posljednja aktivnost',
|
||||||
// 'User filters' => '',
|
'Change subtask position' => 'Promijeni poziciju pod-zadatka',
|
||||||
// 'Category filters' => '',
|
'This value must be greater than %d' => 'Ova vrijednost mora biti veća od %d',
|
||||||
// 'Upload a file' => '',
|
'Another swimlane with the same name exists in the project' => 'Već postoji swimline sa istim imenom u ovom projektu',
|
||||||
// 'There is no attachment at the moment.' => '',
|
'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => 'Na primjer: http://example.kanboard.net/ (koristi se za pravljenje apsolutnog URL-a)',
|
||||||
// 'View file' => '',
|
'Actions duplicated successfully.' => 'Akcije uspješno duplicirane.',
|
||||||
// 'Last activity' => '',
|
'Unable to duplicate actions.' => 'Nemoguće duplicirati akcije.',
|
||||||
// 'Change subtask position' => '',
|
'Add a new action' => 'Dodaj novu akciju',
|
||||||
// 'This value must be greater than %d' => '',
|
'Import from another project' => 'Uvezi iz drugog projekta',
|
||||||
// 'Another swimlane with the same name exists in the project' => '',
|
'There is no action at the moment.' => 'Trenutno nema akcija.',
|
||||||
// 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => '',
|
'Import actions from another project' => 'Uvezi akcije iz drugog projekta',
|
||||||
|
'There is no available project.' => 'Trenutno nema dostupnih projekata.',
|
||||||
|
// 'Local File' => '',
|
||||||
|
// 'Configuration' => '',
|
||||||
|
// 'PHP version:' => '',
|
||||||
|
// 'PHP SAPI:' => '',
|
||||||
|
// 'OS version:' => '',
|
||||||
|
// 'Database version:' => '',
|
||||||
|
// 'Browser:' => '',
|
||||||
|
// 'Task view' => '',
|
||||||
|
// 'Edit task' => '',
|
||||||
|
// 'Edit description' => '',
|
||||||
|
// 'New internal link' => '',
|
||||||
|
// 'Display list of keyboard shortcuts' => '',
|
||||||
|
// 'Menu' => '',
|
||||||
|
// 'Set start date' => '',
|
||||||
|
// 'Avatar' => '',
|
||||||
|
// 'Upload my avatar image' => '',
|
||||||
|
// 'Remove my image' => '',
|
||||||
|
// 'The OAuth2 state parameter is invalid' => '',
|
||||||
);
|
);
|
||||||
|
|
|
@ -8,7 +8,6 @@ return array(
|
||||||
'Edit' => 'Editovat',
|
'Edit' => 'Editovat',
|
||||||
'remove' => 'odstranit',
|
'remove' => 'odstranit',
|
||||||
'Remove' => 'Odstranit',
|
'Remove' => 'Odstranit',
|
||||||
'Update' => 'Akualizovat',
|
|
||||||
'Yes' => 'Ano',
|
'Yes' => 'Ano',
|
||||||
'No' => 'Ne',
|
'No' => 'Ne',
|
||||||
'cancel' => 'Zrušit',
|
'cancel' => 'Zrušit',
|
||||||
|
@ -60,7 +59,6 @@ return array(
|
||||||
'Actions' => 'Akce',
|
'Actions' => 'Akce',
|
||||||
'Inactive' => 'Neaktivní',
|
'Inactive' => 'Neaktivní',
|
||||||
'Active' => 'Aktivní',
|
'Active' => 'Aktivní',
|
||||||
'Add this column' => 'Přidat sloupec',
|
|
||||||
'%d tasks on the board' => '%d úkolů na nástěnce',
|
'%d tasks on the board' => '%d úkolů na nástěnce',
|
||||||
'%d tasks in total' => '%d úkolů celkem',
|
'%d tasks in total' => '%d úkolů celkem',
|
||||||
'Unable to update this board.' => 'Nástěnku není možné aktualizovat',
|
'Unable to update this board.' => 'Nástěnku není možné aktualizovat',
|
||||||
|
@ -74,7 +72,6 @@ return array(
|
||||||
'All projects' => 'Všechny projekty',
|
'All projects' => 'Všechny projekty',
|
||||||
'Add a new column' => 'Přidat nový sloupec',
|
'Add a new column' => 'Přidat nový sloupec',
|
||||||
'Title' => 'Název',
|
'Title' => 'Název',
|
||||||
'Nobody assigned' => 'Nepřiřazena žádná osoba',
|
|
||||||
'Assigned to %s' => 'Přiřazeno uživateli: %s',
|
'Assigned to %s' => 'Přiřazeno uživateli: %s',
|
||||||
'Remove a column' => 'Vyjmout sloupec',
|
'Remove a column' => 'Vyjmout sloupec',
|
||||||
'Remove a column from a board' => 'Vyjmout sloupec z nástěnky',
|
'Remove a column from a board' => 'Vyjmout sloupec z nástěnky',
|
||||||
|
@ -168,7 +165,6 @@ return array(
|
||||||
'Task count' => 'Počet úkolů',
|
'Task count' => 'Počet úkolů',
|
||||||
'User' => 'Uživatel',
|
'User' => 'Uživatel',
|
||||||
'Comments' => 'Komentáře',
|
'Comments' => 'Komentáře',
|
||||||
'Write your text in Markdown' => 'Můžete použít i Markdown-syntaxi',
|
|
||||||
'Leave a comment' => 'Zanechte komentář',
|
'Leave a comment' => 'Zanechte komentář',
|
||||||
'Comment is required' => 'Komentář je vyžadován',
|
'Comment is required' => 'Komentář je vyžadován',
|
||||||
'Leave a description' => 'Vložte popis',
|
'Leave a description' => 'Vložte popis',
|
||||||
|
@ -184,7 +180,6 @@ return array(
|
||||||
'Unable to remove this action.' => 'Tuto akci nelze odstranit.',
|
'Unable to remove this action.' => 'Tuto akci nelze odstranit.',
|
||||||
'Action removed successfully.' => 'Akce byla úspěšně odstraněna.',
|
'Action removed successfully.' => 'Akce byla úspěšně odstraněna.',
|
||||||
'Automatic actions for the project "%s"' => 'Automaticky vykonávané akce pro projekt "%s"',
|
'Automatic actions for the project "%s"' => 'Automaticky vykonávané akce pro projekt "%s"',
|
||||||
'Defined actions' => 'Definované akce',
|
|
||||||
'Add an action' => 'Přidat akci',
|
'Add an action' => 'Přidat akci',
|
||||||
'Event name' => 'Název události',
|
'Event name' => 'Název události',
|
||||||
'Action name' => 'Název akce',
|
'Action name' => 'Název akce',
|
||||||
|
@ -194,7 +189,6 @@ return array(
|
||||||
'When the selected event occurs execute the corresponding action.' => 'Kdykoliv se vybraná událost objeví, vykonat odpovídající akci.',
|
'When the selected event occurs execute the corresponding action.' => 'Kdykoliv se vybraná událost objeví, vykonat odpovídající akci.',
|
||||||
'Next step' => 'Další krok',
|
'Next step' => 'Další krok',
|
||||||
'Define action parameters' => 'Definovat parametry akce',
|
'Define action parameters' => 'Definovat parametry akce',
|
||||||
'Save this action' => 'Uložit akci',
|
|
||||||
'Do you really want to remove this action: "%s"?' => 'Skutečně chcete odebrat tuto akci: "%s"?',
|
'Do you really want to remove this action: "%s"?' => 'Skutečně chcete odebrat tuto akci: "%s"?',
|
||||||
'Remove an automatic action' => 'Odebrat automaticky prováděnou akci',
|
'Remove an automatic action' => 'Odebrat automaticky prováděnou akci',
|
||||||
'Assign the task to a specific user' => 'Přiřadit tento úkol konkrétnímu uživateli',
|
'Assign the task to a specific user' => 'Přiřadit tento úkol konkrétnímu uživateli',
|
||||||
|
@ -333,10 +327,10 @@ return array(
|
||||||
'Time tracking:' => 'Sledování času:',
|
'Time tracking:' => 'Sledování času:',
|
||||||
'New sub-task' => 'Nový dílčí úkol',
|
'New sub-task' => 'Nový dílčí úkol',
|
||||||
'New attachment added "%s"' => 'Byla přidána nová příloha "%s".',
|
'New attachment added "%s"' => 'Byla přidána nová příloha "%s".',
|
||||||
'Comment updated' => 'Komentář byl aktualizován.',
|
|
||||||
'New comment posted by %s' => 'Nový komentář publikovaný uživatelem %s',
|
'New comment posted by %s' => 'Nový komentář publikovaný uživatelem %s',
|
||||||
'New attachment' => 'Nová příloha',
|
'New attachment' => 'Nová příloha',
|
||||||
'New comment' => 'Nový komentář',
|
'New comment' => 'Nový komentář',
|
||||||
|
'Comment updated' => 'Komentář byl aktualizován.',
|
||||||
'New subtask' => 'Nový dílčí úkol',
|
'New subtask' => 'Nový dílčí úkol',
|
||||||
'Subtask updated' => 'Dílčí úkol byl aktualizován',
|
'Subtask updated' => 'Dílčí úkol byl aktualizován',
|
||||||
'Task updated' => 'Úkol byl aktualizován',
|
'Task updated' => 'Úkol byl aktualizován',
|
||||||
|
@ -436,7 +430,6 @@ return array(
|
||||||
'ISO format is always accepted, example: "%s" and "%s"' => 'ISO formát je vždy akceptován, například: "%s" a "%s"',
|
'ISO format is always accepted, example: "%s" and "%s"' => 'ISO formát je vždy akceptován, například: "%s" a "%s"',
|
||||||
'New private project' => 'Nový soukromý projekt',
|
'New private project' => 'Nový soukromý projekt',
|
||||||
'This project is private' => 'Tento projekt je soukromuý',
|
'This project is private' => 'Tento projekt je soukromuý',
|
||||||
'Type here to create a new sub-task' => 'Uveďte zde pro vytvoření nového dílčího úkolu',
|
|
||||||
'Add' => 'Přidat',
|
'Add' => 'Přidat',
|
||||||
'Start date' => 'Počáteční datum',
|
'Start date' => 'Počáteční datum',
|
||||||
'Time estimated' => 'Odhadovaný čas',
|
'Time estimated' => 'Odhadovaný čas',
|
||||||
|
@ -487,9 +480,6 @@ return array(
|
||||||
'Daily project summary export for "%s"' => 'Export denních přehledů pro "%s"',
|
'Daily project summary export for "%s"' => 'Export denních přehledů pro "%s"',
|
||||||
'Exports' => 'Exporty',
|
'Exports' => 'Exporty',
|
||||||
'This export contains the number of tasks per column grouped per day.' => 'Tento export obsahuje počet úkolů pro jednotlivé sloupce seskupených podle dní.',
|
'This export contains the number of tasks per column grouped per day.' => 'Tento export obsahuje počet úkolů pro jednotlivé sloupce seskupených podle dní.',
|
||||||
'Nothing to preview...' => 'Žádná položka k zobrazení ...',
|
|
||||||
'Preview' => 'Náhled',
|
|
||||||
'Write' => 'Režim psaní',
|
|
||||||
'Active swimlanes' => 'Aktive Swimlane',
|
'Active swimlanes' => 'Aktive Swimlane',
|
||||||
'Add a new swimlane' => 'Přidat nový řádek',
|
'Add a new swimlane' => 'Přidat nový řádek',
|
||||||
'Change default swimlane' => 'Standard Swimlane ändern',
|
'Change default swimlane' => 'Standard Swimlane ändern',
|
||||||
|
@ -543,7 +533,6 @@ return array(
|
||||||
'Task age in days' => 'Doba trvání úkolu ve dnech',
|
'Task age in days' => 'Doba trvání úkolu ve dnech',
|
||||||
'Days in this column' => 'Dní v tomto sloupci',
|
'Days in this column' => 'Dní v tomto sloupci',
|
||||||
'%dd' => '%d d',
|
'%dd' => '%d d',
|
||||||
'Add a link' => 'Přidat odkaz',
|
|
||||||
'Add a new link' => 'Přidat nový odkaz',
|
'Add a new link' => 'Přidat nový odkaz',
|
||||||
'Do you really want to remove this link: "%s"?' => 'Die Verbindung "%s" wirklich löschen?',
|
'Do you really want to remove this link: "%s"?' => 'Die Verbindung "%s" wirklich löschen?',
|
||||||
'Do you really want to remove this link with task #%d?' => 'Die Verbindung mit der Aufgabe #%d wirklich löschen?',
|
'Do you really want to remove this link with task #%d?' => 'Die Verbindung mit der Aufgabe #%d wirklich löschen?',
|
||||||
|
@ -734,7 +723,7 @@ return array(
|
||||||
'Time spent changed: %sh' => 'Verbrauchte Zeit geändert: %sh',
|
'Time spent changed: %sh' => 'Verbrauchte Zeit geändert: %sh',
|
||||||
'Time estimated changed: %sh' => 'Geschätzte Zeit geändert: %sh',
|
'Time estimated changed: %sh' => 'Geschätzte Zeit geändert: %sh',
|
||||||
'The field "%s" have been updated' => 'Das Feld "%s" wurde verändert',
|
'The field "%s" have been updated' => 'Das Feld "%s" wurde verändert',
|
||||||
'The description have been modified' => 'Die Beschreibung wurde geändert',
|
'The description has been modified:' => 'Die Beschreibung wurde geändert:',
|
||||||
'Do you really want to close the task "%s" as well as all subtasks?' => 'Soll die Aufgabe "%s" wirklich geschlossen werden? (einschließlich Teilaufgaben)',
|
'Do you really want to close the task "%s" as well as all subtasks?' => 'Soll die Aufgabe "%s" wirklich geschlossen werden? (einschließlich Teilaufgaben)',
|
||||||
'I want to receive notifications for:' => 'Chci dostávat upozornění na:',
|
'I want to receive notifications for:' => 'Chci dostávat upozornění na:',
|
||||||
'All tasks' => 'Všechny úkoly',
|
'All tasks' => 'Všechny úkoly',
|
||||||
|
@ -753,8 +742,6 @@ return array(
|
||||||
'My activity stream' => 'Přehled mých aktivit',
|
'My activity stream' => 'Přehled mých aktivit',
|
||||||
'My calendar' => 'Můj kalendář',
|
'My calendar' => 'Můj kalendář',
|
||||||
'Search tasks' => 'Hledání úkolů',
|
'Search tasks' => 'Hledání úkolů',
|
||||||
'Back to the calendar' => 'Zpět do kalendáře',
|
|
||||||
'Filters' => 'Filtry',
|
|
||||||
'Reset filters' => 'Resetovat filtry',
|
'Reset filters' => 'Resetovat filtry',
|
||||||
'My tasks due tomorrow' => 'Moje zítřejší úkoly',
|
'My tasks due tomorrow' => 'Moje zítřejší úkoly',
|
||||||
'Tasks due today' => 'Dnešní úkoly',
|
'Tasks due today' => 'Dnešní úkoly',
|
||||||
|
@ -854,7 +841,6 @@ return array(
|
||||||
// 'End date:' => '',
|
// 'End date:' => '',
|
||||||
// 'There is no start date or end date for this project.' => '',
|
// 'There is no start date or end date for this project.' => '',
|
||||||
// 'Projects Gantt chart' => '',
|
// 'Projects Gantt chart' => '',
|
||||||
// 'Link type' => '',
|
|
||||||
// 'Change task color when using a specific task link' => '',
|
// 'Change task color when using a specific task link' => '',
|
||||||
// 'Task link creation or modification' => '',
|
// 'Task link creation or modification' => '',
|
||||||
// 'Milestone' => '',
|
// 'Milestone' => '',
|
||||||
|
@ -906,7 +892,6 @@ return array(
|
||||||
// 'Shared' => '',
|
// 'Shared' => '',
|
||||||
// 'Owner' => '',
|
// 'Owner' => '',
|
||||||
// 'Unread notifications' => '',
|
// 'Unread notifications' => '',
|
||||||
// 'My filters' => '',
|
|
||||||
// 'Notification methods:' => '',
|
// 'Notification methods:' => '',
|
||||||
// 'Import tasks from CSV file' => '',
|
// 'Import tasks from CSV file' => '',
|
||||||
// 'Unable to read your file' => '',
|
// 'Unable to read your file' => '',
|
||||||
|
@ -944,6 +929,7 @@ return array(
|
||||||
// 'Usernames must be lowercase and unique' => '',
|
// 'Usernames must be lowercase and unique' => '',
|
||||||
// 'Passwords will be encrypted if present' => '',
|
// 'Passwords will be encrypted if present' => '',
|
||||||
// '%s attached a new file to the task %s' => '',
|
// '%s attached a new file to the task %s' => '',
|
||||||
|
// 'Link type' => '',
|
||||||
// 'Assign automatically a category based on a link' => '',
|
// 'Assign automatically a category based on a link' => '',
|
||||||
// 'BAM - Konvertible Mark' => '',
|
// 'BAM - Konvertible Mark' => '',
|
||||||
// 'Assignee Username' => '',
|
// 'Assignee Username' => '',
|
||||||
|
@ -1053,7 +1039,6 @@ return array(
|
||||||
// 'Close a task when there is no activity' => '',
|
// 'Close a task when there is no activity' => '',
|
||||||
// 'Duration in days' => '',
|
// 'Duration in days' => '',
|
||||||
// 'Send email when there is no activity on a task' => '',
|
// 'Send email when there is no activity on a task' => '',
|
||||||
// 'List of external links' => '',
|
|
||||||
// 'Unable to fetch link information.' => '',
|
// 'Unable to fetch link information.' => '',
|
||||||
// 'Daily background job for tasks' => '',
|
// 'Daily background job for tasks' => '',
|
||||||
// 'Auto' => '',
|
// 'Auto' => '',
|
||||||
|
@ -1071,9 +1056,7 @@ return array(
|
||||||
// 'External link' => '',
|
// 'External link' => '',
|
||||||
// 'Copy and paste your link here...' => '',
|
// 'Copy and paste your link here...' => '',
|
||||||
// 'URL' => '',
|
// 'URL' => '',
|
||||||
// 'There is no external link for the moment.' => '',
|
|
||||||
// 'Internal links' => '',
|
// 'Internal links' => '',
|
||||||
// 'There is no internal link for the moment.' => '',
|
|
||||||
// 'Assign to me' => '',
|
// 'Assign to me' => '',
|
||||||
// 'Me' => '',
|
// 'Me' => '',
|
||||||
// 'Do not duplicate anything' => '',
|
// 'Do not duplicate anything' => '',
|
||||||
|
@ -1081,7 +1064,6 @@ return array(
|
||||||
// 'Users management' => '',
|
// 'Users management' => '',
|
||||||
// 'Groups management' => '',
|
// 'Groups management' => '',
|
||||||
// 'Create from another project' => '',
|
// 'Create from another project' => '',
|
||||||
// 'There is no subtask at the moment.' => '',
|
|
||||||
// 'open' => '',
|
// 'open' => '',
|
||||||
// 'closed' => '',
|
// 'closed' => '',
|
||||||
// 'Priority:' => '',
|
// 'Priority:' => '',
|
||||||
|
@ -1100,7 +1082,6 @@ return array(
|
||||||
// 'Started:' => '',
|
// 'Started:' => '',
|
||||||
// 'Moved:' => '',
|
// 'Moved:' => '',
|
||||||
// 'Task #%d' => '',
|
// 'Task #%d' => '',
|
||||||
// 'Sub-tasks' => '',
|
|
||||||
// 'Date and time format' => '',
|
// 'Date and time format' => '',
|
||||||
// 'Time format' => '',
|
// 'Time format' => '',
|
||||||
// 'Start date: ' => '',
|
// 'Start date: ' => '',
|
||||||
|
@ -1141,11 +1122,35 @@ return array(
|
||||||
// 'User filters' => '',
|
// 'User filters' => '',
|
||||||
// 'Category filters' => '',
|
// 'Category filters' => '',
|
||||||
// 'Upload a file' => '',
|
// 'Upload a file' => '',
|
||||||
// 'There is no attachment at the moment.' => '',
|
|
||||||
// 'View file' => '',
|
// 'View file' => '',
|
||||||
// 'Last activity' => '',
|
// 'Last activity' => '',
|
||||||
// 'Change subtask position' => '',
|
// 'Change subtask position' => '',
|
||||||
// 'This value must be greater than %d' => '',
|
// 'This value must be greater than %d' => '',
|
||||||
// 'Another swimlane with the same name exists in the project' => '',
|
// 'Another swimlane with the same name exists in the project' => '',
|
||||||
// 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => '',
|
// 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => '',
|
||||||
|
// 'Actions duplicated successfully.' => '',
|
||||||
|
// 'Unable to duplicate actions.' => '',
|
||||||
|
// 'Add a new action' => '',
|
||||||
|
// 'Import from another project' => '',
|
||||||
|
// 'There is no action at the moment.' => '',
|
||||||
|
// 'Import actions from another project' => '',
|
||||||
|
// 'There is no available project.' => '',
|
||||||
|
// 'Local File' => '',
|
||||||
|
// 'Configuration' => '',
|
||||||
|
// 'PHP version:' => '',
|
||||||
|
// 'PHP SAPI:' => '',
|
||||||
|
// 'OS version:' => '',
|
||||||
|
// 'Database version:' => '',
|
||||||
|
// 'Browser:' => '',
|
||||||
|
// 'Task view' => '',
|
||||||
|
// 'Edit task' => '',
|
||||||
|
// 'Edit description' => '',
|
||||||
|
// 'New internal link' => '',
|
||||||
|
// 'Display list of keyboard shortcuts' => '',
|
||||||
|
// 'Menu' => '',
|
||||||
|
// 'Set start date' => '',
|
||||||
|
// 'Avatar' => '',
|
||||||
|
// 'Upload my avatar image' => '',
|
||||||
|
// 'Remove my image' => '',
|
||||||
|
// 'The OAuth2 state parameter is invalid' => '',
|
||||||
);
|
);
|
||||||
|
|
|
@ -8,7 +8,6 @@ return array(
|
||||||
'Edit' => 'Rediger',
|
'Edit' => 'Rediger',
|
||||||
'remove' => 'fjern',
|
'remove' => 'fjern',
|
||||||
'Remove' => 'Fjern',
|
'Remove' => 'Fjern',
|
||||||
'Update' => 'Opdater',
|
|
||||||
'Yes' => 'Ja',
|
'Yes' => 'Ja',
|
||||||
'No' => 'Nej',
|
'No' => 'Nej',
|
||||||
'cancel' => 'annuller',
|
'cancel' => 'annuller',
|
||||||
|
@ -60,7 +59,6 @@ return array(
|
||||||
'Actions' => 'Handlinger',
|
'Actions' => 'Handlinger',
|
||||||
'Inactive' => 'Inaktiv',
|
'Inactive' => 'Inaktiv',
|
||||||
'Active' => 'Aktiv',
|
'Active' => 'Aktiv',
|
||||||
'Add this column' => 'Tilføj denne kolonne',
|
|
||||||
'%d tasks on the board' => '%d Opgaver på boardet',
|
'%d tasks on the board' => '%d Opgaver på boardet',
|
||||||
'%d tasks in total' => '%d Opgaver i alt',
|
'%d tasks in total' => '%d Opgaver i alt',
|
||||||
'Unable to update this board.' => 'Ikke muligt at opdatere dette board',
|
'Unable to update this board.' => 'Ikke muligt at opdatere dette board',
|
||||||
|
@ -74,7 +72,6 @@ return array(
|
||||||
'All projects' => 'Alle Projekter',
|
'All projects' => 'Alle Projekter',
|
||||||
'Add a new column' => 'Tilføj en ny kolonne',
|
'Add a new column' => 'Tilføj en ny kolonne',
|
||||||
'Title' => 'Titel',
|
'Title' => 'Titel',
|
||||||
'Nobody assigned' => 'Ingen ansvarlig',
|
|
||||||
'Assigned to %s' => 'Ansvarlig: %s',
|
'Assigned to %s' => 'Ansvarlig: %s',
|
||||||
'Remove a column' => 'Fjern en kolonne',
|
'Remove a column' => 'Fjern en kolonne',
|
||||||
'Remove a column from a board' => 'Fjern en kolonne fra et board',
|
'Remove a column from a board' => 'Fjern en kolonne fra et board',
|
||||||
|
@ -168,7 +165,6 @@ return array(
|
||||||
// 'Task count' => '',
|
// 'Task count' => '',
|
||||||
'User' => 'Bruger',
|
'User' => 'Bruger',
|
||||||
'Comments' => 'Kommentarer',
|
'Comments' => 'Kommentarer',
|
||||||
'Write your text in Markdown' => 'Skriv din tekst i markdown',
|
|
||||||
'Leave a comment' => 'Efterlad en kommentar',
|
'Leave a comment' => 'Efterlad en kommentar',
|
||||||
'Comment is required' => 'Kommentar er krævet',
|
'Comment is required' => 'Kommentar er krævet',
|
||||||
'Leave a description' => 'Efterlad en beskrivelse...',
|
'Leave a description' => 'Efterlad en beskrivelse...',
|
||||||
|
@ -184,7 +180,6 @@ return array(
|
||||||
'Unable to remove this action.' => 'Handlingen kunne ikke fjernes.',
|
'Unable to remove this action.' => 'Handlingen kunne ikke fjernes.',
|
||||||
'Action removed successfully.' => 'Handlingen er fjernet.',
|
'Action removed successfully.' => 'Handlingen er fjernet.',
|
||||||
'Automatic actions for the project "%s"' => 'Automatiske handlinger for projektet "%s"',
|
'Automatic actions for the project "%s"' => 'Automatiske handlinger for projektet "%s"',
|
||||||
'Defined actions' => 'Defineret handlinger',
|
|
||||||
'Add an action' => 'Tilføj en handling',
|
'Add an action' => 'Tilføj en handling',
|
||||||
'Event name' => 'Begivenhed',
|
'Event name' => 'Begivenhed',
|
||||||
'Action name' => 'Handling',
|
'Action name' => 'Handling',
|
||||||
|
@ -194,7 +189,6 @@ return array(
|
||||||
'When the selected event occurs execute the corresponding action.' => 'Når den valgte begivenhed opstår, udfør den tilsvarende handling.',
|
'When the selected event occurs execute the corresponding action.' => 'Når den valgte begivenhed opstår, udfør den tilsvarende handling.',
|
||||||
'Next step' => 'Næste',
|
'Next step' => 'Næste',
|
||||||
'Define action parameters' => 'Definer Handlingsparametre',
|
'Define action parameters' => 'Definer Handlingsparametre',
|
||||||
'Save this action' => 'Gem denne handling',
|
|
||||||
'Do you really want to remove this action: "%s"?' => 'Vil du virkelig slette denne handling: "%s"?',
|
'Do you really want to remove this action: "%s"?' => 'Vil du virkelig slette denne handling: "%s"?',
|
||||||
'Remove an automatic action' => 'Fjern en automatisk handling',
|
'Remove an automatic action' => 'Fjern en automatisk handling',
|
||||||
'Assign the task to a specific user' => 'Tildel opgaven til en bestem bruger',
|
'Assign the task to a specific user' => 'Tildel opgaven til en bestem bruger',
|
||||||
|
@ -333,10 +327,10 @@ return array(
|
||||||
'Time tracking:' => 'Tidsmåling:',
|
'Time tracking:' => 'Tidsmåling:',
|
||||||
'New sub-task' => 'Ny under-opgave',
|
'New sub-task' => 'Ny under-opgave',
|
||||||
'New attachment added "%s"' => 'Ny vedhæftning tilføjet "%s"',
|
'New attachment added "%s"' => 'Ny vedhæftning tilføjet "%s"',
|
||||||
'Comment updated' => 'Kommentar opdateret',
|
|
||||||
'New comment posted by %s' => 'Ny kommentar af %s',
|
'New comment posted by %s' => 'Ny kommentar af %s',
|
||||||
// 'New attachment' => '',
|
// 'New attachment' => '',
|
||||||
// 'New comment' => '',
|
// 'New comment' => '',
|
||||||
|
'Comment updated' => 'Kommentar opdateret',
|
||||||
// 'New subtask' => '',
|
// 'New subtask' => '',
|
||||||
// 'Subtask updated' => '',
|
// 'Subtask updated' => '',
|
||||||
// 'Task updated' => '',
|
// 'Task updated' => '',
|
||||||
|
@ -436,7 +430,6 @@ return array(
|
||||||
'ISO format is always accepted, example: "%s" and "%s"' => 'ISO format er altid accepteret, eksempelvis: "%s" og "%s"',
|
'ISO format is always accepted, example: "%s" and "%s"' => 'ISO format er altid accepteret, eksempelvis: "%s" og "%s"',
|
||||||
'New private project' => 'Nyt privat projekt',
|
'New private project' => 'Nyt privat projekt',
|
||||||
'This project is private' => 'Dette projekt er privat',
|
'This project is private' => 'Dette projekt er privat',
|
||||||
'Type here to create a new sub-task' => 'Skriv her for at tilføje en ny under-opgave',
|
|
||||||
'Add' => 'Tilføj',
|
'Add' => 'Tilføj',
|
||||||
'Start date' => 'Start dato',
|
'Start date' => 'Start dato',
|
||||||
'Time estimated' => 'Tid estimeret',
|
'Time estimated' => 'Tid estimeret',
|
||||||
|
@ -487,9 +480,6 @@ return array(
|
||||||
// 'Daily project summary export for "%s"' => '',
|
// 'Daily project summary export for "%s"' => '',
|
||||||
// 'Exports' => '',
|
// 'Exports' => '',
|
||||||
// 'This export contains the number of tasks per column grouped per day.' => '',
|
// 'This export contains the number of tasks per column grouped per day.' => '',
|
||||||
// 'Nothing to preview...' => '',
|
|
||||||
// 'Preview' => '',
|
|
||||||
// 'Write' => '',
|
|
||||||
// 'Active swimlanes' => '',
|
// 'Active swimlanes' => '',
|
||||||
// 'Add a new swimlane' => '',
|
// 'Add a new swimlane' => '',
|
||||||
// 'Change default swimlane' => '',
|
// 'Change default swimlane' => '',
|
||||||
|
@ -543,7 +533,6 @@ return array(
|
||||||
// 'Task age in days' => '',
|
// 'Task age in days' => '',
|
||||||
// 'Days in this column' => '',
|
// 'Days in this column' => '',
|
||||||
// '%dd' => '',
|
// '%dd' => '',
|
||||||
// 'Add a link' => '',
|
|
||||||
// 'Add a new link' => '',
|
// 'Add a new link' => '',
|
||||||
// 'Do you really want to remove this link: "%s"?' => '',
|
// 'Do you really want to remove this link: "%s"?' => '',
|
||||||
// 'Do you really want to remove this link with task #%d?' => '',
|
// 'Do you really want to remove this link with task #%d?' => '',
|
||||||
|
@ -734,7 +723,7 @@ return array(
|
||||||
// 'Time spent changed: %sh' => '',
|
// 'Time spent changed: %sh' => '',
|
||||||
// 'Time estimated changed: %sh' => '',
|
// 'Time estimated changed: %sh' => '',
|
||||||
// 'The field "%s" have been updated' => '',
|
// 'The field "%s" have been updated' => '',
|
||||||
// 'The description have been modified' => '',
|
// 'The description has been modified:' => '',
|
||||||
// 'Do you really want to close the task "%s" as well as all subtasks?' => '',
|
// 'Do you really want to close the task "%s" as well as all subtasks?' => '',
|
||||||
// 'I want to receive notifications for:' => '',
|
// 'I want to receive notifications for:' => '',
|
||||||
// 'All tasks' => '',
|
// 'All tasks' => '',
|
||||||
|
@ -753,8 +742,6 @@ return array(
|
||||||
// 'My activity stream' => '',
|
// 'My activity stream' => '',
|
||||||
// 'My calendar' => '',
|
// 'My calendar' => '',
|
||||||
// 'Search tasks' => '',
|
// 'Search tasks' => '',
|
||||||
// 'Back to the calendar' => '',
|
|
||||||
// 'Filters' => '',
|
|
||||||
// 'Reset filters' => '',
|
// 'Reset filters' => '',
|
||||||
// 'My tasks due tomorrow' => '',
|
// 'My tasks due tomorrow' => '',
|
||||||
// 'Tasks due today' => '',
|
// 'Tasks due today' => '',
|
||||||
|
@ -854,7 +841,6 @@ return array(
|
||||||
// 'End date:' => '',
|
// 'End date:' => '',
|
||||||
// 'There is no start date or end date for this project.' => '',
|
// 'There is no start date or end date for this project.' => '',
|
||||||
// 'Projects Gantt chart' => '',
|
// 'Projects Gantt chart' => '',
|
||||||
// 'Link type' => '',
|
|
||||||
// 'Change task color when using a specific task link' => '',
|
// 'Change task color when using a specific task link' => '',
|
||||||
// 'Task link creation or modification' => '',
|
// 'Task link creation or modification' => '',
|
||||||
// 'Milestone' => '',
|
// 'Milestone' => '',
|
||||||
|
@ -906,7 +892,6 @@ return array(
|
||||||
// 'Shared' => '',
|
// 'Shared' => '',
|
||||||
// 'Owner' => '',
|
// 'Owner' => '',
|
||||||
// 'Unread notifications' => '',
|
// 'Unread notifications' => '',
|
||||||
// 'My filters' => '',
|
|
||||||
// 'Notification methods:' => '',
|
// 'Notification methods:' => '',
|
||||||
// 'Import tasks from CSV file' => '',
|
// 'Import tasks from CSV file' => '',
|
||||||
// 'Unable to read your file' => '',
|
// 'Unable to read your file' => '',
|
||||||
|
@ -944,6 +929,7 @@ return array(
|
||||||
// 'Usernames must be lowercase and unique' => '',
|
// 'Usernames must be lowercase and unique' => '',
|
||||||
// 'Passwords will be encrypted if present' => '',
|
// 'Passwords will be encrypted if present' => '',
|
||||||
// '%s attached a new file to the task %s' => '',
|
// '%s attached a new file to the task %s' => '',
|
||||||
|
// 'Link type' => '',
|
||||||
// 'Assign automatically a category based on a link' => '',
|
// 'Assign automatically a category based on a link' => '',
|
||||||
// 'BAM - Konvertible Mark' => '',
|
// 'BAM - Konvertible Mark' => '',
|
||||||
// 'Assignee Username' => '',
|
// 'Assignee Username' => '',
|
||||||
|
@ -1053,7 +1039,6 @@ return array(
|
||||||
// 'Close a task when there is no activity' => '',
|
// 'Close a task when there is no activity' => '',
|
||||||
// 'Duration in days' => '',
|
// 'Duration in days' => '',
|
||||||
// 'Send email when there is no activity on a task' => '',
|
// 'Send email when there is no activity on a task' => '',
|
||||||
// 'List of external links' => '',
|
|
||||||
// 'Unable to fetch link information.' => '',
|
// 'Unable to fetch link information.' => '',
|
||||||
// 'Daily background job for tasks' => '',
|
// 'Daily background job for tasks' => '',
|
||||||
// 'Auto' => '',
|
// 'Auto' => '',
|
||||||
|
@ -1071,9 +1056,7 @@ return array(
|
||||||
// 'External link' => '',
|
// 'External link' => '',
|
||||||
// 'Copy and paste your link here...' => '',
|
// 'Copy and paste your link here...' => '',
|
||||||
// 'URL' => '',
|
// 'URL' => '',
|
||||||
// 'There is no external link for the moment.' => '',
|
|
||||||
// 'Internal links' => '',
|
// 'Internal links' => '',
|
||||||
// 'There is no internal link for the moment.' => '',
|
|
||||||
// 'Assign to me' => '',
|
// 'Assign to me' => '',
|
||||||
// 'Me' => '',
|
// 'Me' => '',
|
||||||
// 'Do not duplicate anything' => '',
|
// 'Do not duplicate anything' => '',
|
||||||
|
@ -1081,7 +1064,6 @@ return array(
|
||||||
// 'Users management' => '',
|
// 'Users management' => '',
|
||||||
// 'Groups management' => '',
|
// 'Groups management' => '',
|
||||||
// 'Create from another project' => '',
|
// 'Create from another project' => '',
|
||||||
// 'There is no subtask at the moment.' => '',
|
|
||||||
// 'open' => '',
|
// 'open' => '',
|
||||||
// 'closed' => '',
|
// 'closed' => '',
|
||||||
// 'Priority:' => '',
|
// 'Priority:' => '',
|
||||||
|
@ -1100,7 +1082,6 @@ return array(
|
||||||
// 'Started:' => '',
|
// 'Started:' => '',
|
||||||
// 'Moved:' => '',
|
// 'Moved:' => '',
|
||||||
// 'Task #%d' => '',
|
// 'Task #%d' => '',
|
||||||
// 'Sub-tasks' => '',
|
|
||||||
// 'Date and time format' => '',
|
// 'Date and time format' => '',
|
||||||
// 'Time format' => '',
|
// 'Time format' => '',
|
||||||
// 'Start date: ' => '',
|
// 'Start date: ' => '',
|
||||||
|
@ -1141,11 +1122,35 @@ return array(
|
||||||
// 'User filters' => '',
|
// 'User filters' => '',
|
||||||
// 'Category filters' => '',
|
// 'Category filters' => '',
|
||||||
// 'Upload a file' => '',
|
// 'Upload a file' => '',
|
||||||
// 'There is no attachment at the moment.' => '',
|
|
||||||
// 'View file' => '',
|
// 'View file' => '',
|
||||||
// 'Last activity' => '',
|
// 'Last activity' => '',
|
||||||
// 'Change subtask position' => '',
|
// 'Change subtask position' => '',
|
||||||
// 'This value must be greater than %d' => '',
|
// 'This value must be greater than %d' => '',
|
||||||
// 'Another swimlane with the same name exists in the project' => '',
|
// 'Another swimlane with the same name exists in the project' => '',
|
||||||
// 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => '',
|
// 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => '',
|
||||||
|
// 'Actions duplicated successfully.' => '',
|
||||||
|
// 'Unable to duplicate actions.' => '',
|
||||||
|
// 'Add a new action' => '',
|
||||||
|
// 'Import from another project' => '',
|
||||||
|
// 'There is no action at the moment.' => '',
|
||||||
|
// 'Import actions from another project' => '',
|
||||||
|
// 'There is no available project.' => '',
|
||||||
|
// 'Local File' => '',
|
||||||
|
// 'Configuration' => '',
|
||||||
|
// 'PHP version:' => '',
|
||||||
|
// 'PHP SAPI:' => '',
|
||||||
|
// 'OS version:' => '',
|
||||||
|
// 'Database version:' => '',
|
||||||
|
// 'Browser:' => '',
|
||||||
|
// 'Task view' => '',
|
||||||
|
// 'Edit task' => '',
|
||||||
|
// 'Edit description' => '',
|
||||||
|
// 'New internal link' => '',
|
||||||
|
// 'Display list of keyboard shortcuts' => '',
|
||||||
|
// 'Menu' => '',
|
||||||
|
// 'Set start date' => '',
|
||||||
|
// 'Avatar' => '',
|
||||||
|
// 'Upload my avatar image' => '',
|
||||||
|
// 'Remove my image' => '',
|
||||||
|
// 'The OAuth2 state parameter is invalid' => '',
|
||||||
);
|
);
|
||||||
|
|
|
@ -8,7 +8,6 @@ return array(
|
||||||
'Edit' => 'Bearbeiten',
|
'Edit' => 'Bearbeiten',
|
||||||
'remove' => 'Entfernen',
|
'remove' => 'Entfernen',
|
||||||
'Remove' => 'Entfernen',
|
'Remove' => 'Entfernen',
|
||||||
'Update' => 'Aktualisieren',
|
|
||||||
'Yes' => 'Ja',
|
'Yes' => 'Ja',
|
||||||
'No' => 'Nein',
|
'No' => 'Nein',
|
||||||
'cancel' => 'Abbrechen',
|
'cancel' => 'Abbrechen',
|
||||||
|
@ -60,7 +59,6 @@ return array(
|
||||||
'Actions' => 'Aktionen',
|
'Actions' => 'Aktionen',
|
||||||
'Inactive' => 'Inaktiv',
|
'Inactive' => 'Inaktiv',
|
||||||
'Active' => 'Aktiv',
|
'Active' => 'Aktiv',
|
||||||
'Add this column' => 'Diese Spalte hinzufügen',
|
|
||||||
'%d tasks on the board' => '%d Aufgaben auf dieser Pinnwand',
|
'%d tasks on the board' => '%d Aufgaben auf dieser Pinnwand',
|
||||||
'%d tasks in total' => '%d Aufgaben insgesamt',
|
'%d tasks in total' => '%d Aufgaben insgesamt',
|
||||||
'Unable to update this board.' => 'Ändern dieser Pinnwand nicht möglich.',
|
'Unable to update this board.' => 'Ändern dieser Pinnwand nicht möglich.',
|
||||||
|
@ -74,7 +72,6 @@ return array(
|
||||||
'All projects' => 'Alle Projekte',
|
'All projects' => 'Alle Projekte',
|
||||||
'Add a new column' => 'Neue Spalte hinzufügen',
|
'Add a new column' => 'Neue Spalte hinzufügen',
|
||||||
'Title' => 'Titel',
|
'Title' => 'Titel',
|
||||||
'Nobody assigned' => 'Nicht zugeordnet',
|
|
||||||
'Assigned to %s' => 'Zuständig: %s',
|
'Assigned to %s' => 'Zuständig: %s',
|
||||||
'Remove a column' => 'Spalte löschen',
|
'Remove a column' => 'Spalte löschen',
|
||||||
'Remove a column from a board' => 'Spalte einer Pinnwand löschen',
|
'Remove a column from a board' => 'Spalte einer Pinnwand löschen',
|
||||||
|
@ -168,7 +165,6 @@ return array(
|
||||||
'Task count' => 'Aufgabenanzahl',
|
'Task count' => 'Aufgabenanzahl',
|
||||||
'User' => 'Benutzer',
|
'User' => 'Benutzer',
|
||||||
'Comments' => 'Kommentare',
|
'Comments' => 'Kommentare',
|
||||||
'Write your text in Markdown' => 'Schreibe deinen Text in Markdown-Syntax',
|
|
||||||
'Leave a comment' => 'Kommentar eingeben',
|
'Leave a comment' => 'Kommentar eingeben',
|
||||||
'Comment is required' => 'Ein Kommentar wird benötigt',
|
'Comment is required' => 'Ein Kommentar wird benötigt',
|
||||||
'Leave a description' => 'Beschreibung eingeben',
|
'Leave a description' => 'Beschreibung eingeben',
|
||||||
|
@ -184,7 +180,6 @@ return array(
|
||||||
'Unable to remove this action.' => 'Löschen der Aktion nicht möglich.',
|
'Unable to remove this action.' => 'Löschen der Aktion nicht möglich.',
|
||||||
'Action removed successfully.' => 'Aktion erfolgreich gelöscht.',
|
'Action removed successfully.' => 'Aktion erfolgreich gelöscht.',
|
||||||
'Automatic actions for the project "%s"' => 'Automatische Aktionen für das Projekt "%s"',
|
'Automatic actions for the project "%s"' => 'Automatische Aktionen für das Projekt "%s"',
|
||||||
'Defined actions' => 'Definierte Aktionen',
|
|
||||||
'Add an action' => 'Aktion hinzufügen',
|
'Add an action' => 'Aktion hinzufügen',
|
||||||
'Event name' => 'Ereignisname',
|
'Event name' => 'Ereignisname',
|
||||||
'Action name' => 'Aktionsname',
|
'Action name' => 'Aktionsname',
|
||||||
|
@ -194,7 +189,6 @@ return array(
|
||||||
'When the selected event occurs execute the corresponding action.' => 'Wenn das gewählte Ereignis eintritt, führe die zugehörige Aktion aus.',
|
'When the selected event occurs execute the corresponding action.' => 'Wenn das gewählte Ereignis eintritt, führe die zugehörige Aktion aus.',
|
||||||
'Next step' => 'Weiter',
|
'Next step' => 'Weiter',
|
||||||
'Define action parameters' => 'Aktionsparameter definieren',
|
'Define action parameters' => 'Aktionsparameter definieren',
|
||||||
'Save this action' => 'Aktion speichern',
|
|
||||||
'Do you really want to remove this action: "%s"?' => 'Soll diese Aktion wirklich gelöscht werden: "%s"?',
|
'Do you really want to remove this action: "%s"?' => 'Soll diese Aktion wirklich gelöscht werden: "%s"?',
|
||||||
'Remove an automatic action' => 'Löschen einer automatischen Aktion',
|
'Remove an automatic action' => 'Löschen einer automatischen Aktion',
|
||||||
'Assign the task to a specific user' => 'Aufgabe einem Benutzer zuordnen',
|
'Assign the task to a specific user' => 'Aufgabe einem Benutzer zuordnen',
|
||||||
|
@ -333,10 +327,10 @@ return array(
|
||||||
'Time tracking:' => 'Zeittracking',
|
'Time tracking:' => 'Zeittracking',
|
||||||
'New sub-task' => 'Neue Teilaufgabe',
|
'New sub-task' => 'Neue Teilaufgabe',
|
||||||
'New attachment added "%s"' => 'Neuer Anhang "%s" wurde hinzugefügt.',
|
'New attachment added "%s"' => 'Neuer Anhang "%s" wurde hinzugefügt.',
|
||||||
'Comment updated' => 'Kommentar wurde aktualisiert',
|
|
||||||
'New comment posted by %s' => 'Neuer Kommentar verfasst durch %s',
|
'New comment posted by %s' => 'Neuer Kommentar verfasst durch %s',
|
||||||
'New attachment' => 'Neuer Anhang',
|
'New attachment' => 'Neuer Anhang',
|
||||||
'New comment' => 'Neuer Kommentar',
|
'New comment' => 'Neuer Kommentar',
|
||||||
|
'Comment updated' => 'Kommentar wurde aktualisiert',
|
||||||
'New subtask' => 'Neue Teilaufgabe',
|
'New subtask' => 'Neue Teilaufgabe',
|
||||||
'Subtask updated' => 'Teilaufgabe aktualisiert',
|
'Subtask updated' => 'Teilaufgabe aktualisiert',
|
||||||
'Task updated' => 'Aufgabe aktualisiert',
|
'Task updated' => 'Aufgabe aktualisiert',
|
||||||
|
@ -436,7 +430,6 @@ return array(
|
||||||
'ISO format is always accepted, example: "%s" and "%s"' => 'ISO Format wird immer akzeptiert, z.B.: "%s" und "%s"',
|
'ISO format is always accepted, example: "%s" and "%s"' => 'ISO Format wird immer akzeptiert, z.B.: "%s" und "%s"',
|
||||||
'New private project' => 'Neues privates Projekt',
|
'New private project' => 'Neues privates Projekt',
|
||||||
'This project is private' => 'Dieses Projekt ist privat',
|
'This project is private' => 'Dieses Projekt ist privat',
|
||||||
'Type here to create a new sub-task' => 'Hier tippen, um eine neue Teilaufgabe zu erstellen',
|
|
||||||
'Add' => 'Hinzufügen',
|
'Add' => 'Hinzufügen',
|
||||||
'Start date' => 'Startdatum',
|
'Start date' => 'Startdatum',
|
||||||
'Time estimated' => 'Geschätzte Zeit',
|
'Time estimated' => 'Geschätzte Zeit',
|
||||||
|
@ -487,9 +480,6 @@ return array(
|
||||||
'Daily project summary export for "%s"' => 'Export der täglichen Projektzusammenfassung für "%s"',
|
'Daily project summary export for "%s"' => 'Export der täglichen Projektzusammenfassung für "%s"',
|
||||||
'Exports' => 'Exporte',
|
'Exports' => 'Exporte',
|
||||||
'This export contains the number of tasks per column grouped per day.' => 'Dieser Export enthält die Anzahl der Aufgaben pro Spalte nach Tagen gruppiert.',
|
'This export contains the number of tasks per column grouped per day.' => 'Dieser Export enthält die Anzahl der Aufgaben pro Spalte nach Tagen gruppiert.',
|
||||||
'Nothing to preview...' => 'Nichts in der Vorschau anzuzeigen ...',
|
|
||||||
'Preview' => 'Vorschau',
|
|
||||||
'Write' => 'Ändern',
|
|
||||||
'Active swimlanes' => 'Aktive Swimlane',
|
'Active swimlanes' => 'Aktive Swimlane',
|
||||||
'Add a new swimlane' => 'Eine neue Swimlane hinzufügen',
|
'Add a new swimlane' => 'Eine neue Swimlane hinzufügen',
|
||||||
'Change default swimlane' => 'Standard-Swimlane ändern',
|
'Change default swimlane' => 'Standard-Swimlane ändern',
|
||||||
|
@ -543,7 +533,6 @@ return array(
|
||||||
'Task age in days' => 'Aufgabenalter in Tagen',
|
'Task age in days' => 'Aufgabenalter in Tagen',
|
||||||
'Days in this column' => 'Tage in dieser Spalte',
|
'Days in this column' => 'Tage in dieser Spalte',
|
||||||
'%dd' => '%dT',
|
'%dd' => '%dT',
|
||||||
'Add a link' => 'Verbindung hinzufügen',
|
|
||||||
'Add a new link' => 'Neue Verbindung hinzufügen',
|
'Add a new link' => 'Neue Verbindung hinzufügen',
|
||||||
'Do you really want to remove this link: "%s"?' => 'Die Verbindung "%s" wirklich löschen?',
|
'Do you really want to remove this link: "%s"?' => 'Die Verbindung "%s" wirklich löschen?',
|
||||||
'Do you really want to remove this link with task #%d?' => 'Die Verbindung mit der Aufgabe #%d wirklich löschen?',
|
'Do you really want to remove this link with task #%d?' => 'Die Verbindung mit der Aufgabe #%d wirklich löschen?',
|
||||||
|
@ -641,7 +630,7 @@ return array(
|
||||||
'Burndown chart' => 'Burndown-Diagramm',
|
'Burndown chart' => 'Burndown-Diagramm',
|
||||||
'This chart show the task complexity over the time (Work Remaining).' => 'Dieses Diagramm zeigt die Aufgabenkomplexität über den Faktor Zeit (Verbleibende Arbeit).',
|
'This chart show the task complexity over the time (Work Remaining).' => 'Dieses Diagramm zeigt die Aufgabenkomplexität über den Faktor Zeit (Verbleibende Arbeit).',
|
||||||
'Screenshot taken %s' => 'Screenshot aufgenommen %s ',
|
'Screenshot taken %s' => 'Screenshot aufgenommen %s ',
|
||||||
'Add a screenshot' => 'Füge einen Screenshot hinzu',
|
'Add a screenshot' => 'Screenshot hinzufügen',
|
||||||
'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => 'Nimm einen Screenshot auf und drücke STRG+V oder ⌘+V um ihn hier einzufügen.',
|
'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => 'Nimm einen Screenshot auf und drücke STRG+V oder ⌘+V um ihn hier einzufügen.',
|
||||||
'Screenshot uploaded successfully.' => 'Screenshot erfolgreich hochgeladen.',
|
'Screenshot uploaded successfully.' => 'Screenshot erfolgreich hochgeladen.',
|
||||||
'SEK - Swedish Krona' => 'SEK - Schwedische Kronen',
|
'SEK - Swedish Krona' => 'SEK - Schwedische Kronen',
|
||||||
|
@ -734,7 +723,7 @@ return array(
|
||||||
'Time spent changed: %sh' => 'Verbrauchte Zeit geändert: %sh',
|
'Time spent changed: %sh' => 'Verbrauchte Zeit geändert: %sh',
|
||||||
'Time estimated changed: %sh' => 'Geschätzte Zeit geändert: %sh',
|
'Time estimated changed: %sh' => 'Geschätzte Zeit geändert: %sh',
|
||||||
'The field "%s" have been updated' => 'Das Feld "%s" wurde verändert',
|
'The field "%s" have been updated' => 'Das Feld "%s" wurde verändert',
|
||||||
'The description have been modified' => 'Die Beschreibung wurde geändert',
|
'The description has been modified:' => 'Die Beschreibung wurde geändert:',
|
||||||
'Do you really want to close the task "%s" as well as all subtasks?' => 'Soll die Aufgabe "%s" wirklich geschlossen werden? (einschließlich Teilaufgaben)',
|
'Do you really want to close the task "%s" as well as all subtasks?' => 'Soll die Aufgabe "%s" wirklich geschlossen werden? (einschließlich Teilaufgaben)',
|
||||||
'I want to receive notifications for:' => 'Ich möchte Benachrichtigungen erhalten für:',
|
'I want to receive notifications for:' => 'Ich möchte Benachrichtigungen erhalten für:',
|
||||||
'All tasks' => 'Alle Aufgaben',
|
'All tasks' => 'Alle Aufgaben',
|
||||||
|
@ -753,8 +742,6 @@ return array(
|
||||||
'My activity stream' => 'Aktivitätsstream',
|
'My activity stream' => 'Aktivitätsstream',
|
||||||
'My calendar' => 'Mein Kalender',
|
'My calendar' => 'Mein Kalender',
|
||||||
'Search tasks' => 'Suche nach Aufgaben',
|
'Search tasks' => 'Suche nach Aufgaben',
|
||||||
'Back to the calendar' => 'Zurück zum Kalender',
|
|
||||||
'Filters' => 'Filter',
|
|
||||||
'Reset filters' => 'Filter zurücksetzen',
|
'Reset filters' => 'Filter zurücksetzen',
|
||||||
'My tasks due tomorrow' => 'Meine morgen fälligen Aufgaben',
|
'My tasks due tomorrow' => 'Meine morgen fälligen Aufgaben',
|
||||||
'Tasks due today' => 'Heute fällige Aufgaben',
|
'Tasks due today' => 'Heute fällige Aufgaben',
|
||||||
|
@ -854,7 +841,6 @@ return array(
|
||||||
'End date:' => 'Endedatum:',
|
'End date:' => 'Endedatum:',
|
||||||
'There is no start date or end date for this project.' => 'Es gibt kein Startdatum oder Endedatum für dieses Projekt',
|
'There is no start date or end date for this project.' => 'Es gibt kein Startdatum oder Endedatum für dieses Projekt',
|
||||||
'Projects Gantt chart' => 'Projekt Gantt Diagramm',
|
'Projects Gantt chart' => 'Projekt Gantt Diagramm',
|
||||||
'Link type' => 'Verbindungstyp',
|
|
||||||
'Change task color when using a specific task link' => 'Aufgabefarbe ändern bei bestimmter Aufgabenverbindung',
|
'Change task color when using a specific task link' => 'Aufgabefarbe ändern bei bestimmter Aufgabenverbindung',
|
||||||
'Task link creation or modification' => 'Aufgabenverbindung erstellen oder bearbeiten',
|
'Task link creation or modification' => 'Aufgabenverbindung erstellen oder bearbeiten',
|
||||||
'Milestone' => 'Meilenstein',
|
'Milestone' => 'Meilenstein',
|
||||||
|
@ -906,7 +892,6 @@ return array(
|
||||||
'Shared' => 'Geteilt',
|
'Shared' => 'Geteilt',
|
||||||
'Owner' => 'Eigentümer',
|
'Owner' => 'Eigentümer',
|
||||||
'Unread notifications' => 'Ungelesene Benachrichtigungen',
|
'Unread notifications' => 'Ungelesene Benachrichtigungen',
|
||||||
'My filters' => 'Meine Filter',
|
|
||||||
'Notification methods:' => 'Benachrichtigungs-Methoden:',
|
'Notification methods:' => 'Benachrichtigungs-Methoden:',
|
||||||
'Import tasks from CSV file' => 'Importiere Aufgaben aus CSV Datei',
|
'Import tasks from CSV file' => 'Importiere Aufgaben aus CSV Datei',
|
||||||
'Unable to read your file' => 'Die Datei kann nicht gelesen werden',
|
'Unable to read your file' => 'Die Datei kann nicht gelesen werden',
|
||||||
|
@ -930,7 +915,7 @@ return array(
|
||||||
'change sorting' => 'Sortierung ändern',
|
'change sorting' => 'Sortierung ändern',
|
||||||
'Tasks Importation' => 'Aufgaben Import',
|
'Tasks Importation' => 'Aufgaben Import',
|
||||||
'Delimiter' => 'Trennzeichen',
|
'Delimiter' => 'Trennzeichen',
|
||||||
'Enclosure' => 'Anlage',
|
'Enclosure' => 'Textbegrenzer',
|
||||||
'CSV File' => 'CSV Datei',
|
'CSV File' => 'CSV Datei',
|
||||||
'Instructions' => 'Anweisungen',
|
'Instructions' => 'Anweisungen',
|
||||||
'Your file must use the predefined CSV format' => 'Ihre Datei muss das vorgegebene CSV Format haben',
|
'Your file must use the predefined CSV format' => 'Ihre Datei muss das vorgegebene CSV Format haben',
|
||||||
|
@ -944,6 +929,7 @@ return array(
|
||||||
'Usernames must be lowercase and unique' => 'Benutzernamen müssen in Kleinbuschstaben und eindeutig sein',
|
'Usernames must be lowercase and unique' => 'Benutzernamen müssen in Kleinbuschstaben und eindeutig sein',
|
||||||
'Passwords will be encrypted if present' => 'Passwörter werden verschlüsselt wenn vorhanden',
|
'Passwords will be encrypted if present' => 'Passwörter werden verschlüsselt wenn vorhanden',
|
||||||
'%s attached a new file to the task %s' => '%s hat eine neue Datei zur Aufgabe %s hinzufgefügt',
|
'%s attached a new file to the task %s' => '%s hat eine neue Datei zur Aufgabe %s hinzufgefügt',
|
||||||
|
'Link type' => 'Verbindungstyp',
|
||||||
'Assign automatically a category based on a link' => 'Linkbasiert eine Kategorie automatisch zuordnen',
|
'Assign automatically a category based on a link' => 'Linkbasiert eine Kategorie automatisch zuordnen',
|
||||||
'BAM - Konvertible Mark' => 'BAM - Konvertible Mark',
|
'BAM - Konvertible Mark' => 'BAM - Konvertible Mark',
|
||||||
'Assignee Username' => 'Benutzername des Zuständigen',
|
'Assignee Username' => 'Benutzername des Zuständigen',
|
||||||
|
@ -1053,7 +1039,6 @@ return array(
|
||||||
'Close a task when there is no activity' => 'Schliesse eine Aufgabe, wenn keine Aktivitäten vorhanden sind',
|
'Close a task when there is no activity' => 'Schliesse eine Aufgabe, wenn keine Aktivitäten vorhanden sind',
|
||||||
'Duration in days' => 'Dauer in Tagen',
|
'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',
|
'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',
|
'Unable to fetch link information.' => 'Kann keine Informationen über Verbindungen holen',
|
||||||
'Daily background job for tasks' => 'Tägliche Hintergrundarbeit für Aufgaben',
|
'Daily background job for tasks' => 'Tägliche Hintergrundarbeit für Aufgaben',
|
||||||
'Auto' => 'Auto',
|
'Auto' => 'Auto',
|
||||||
|
@ -1065,15 +1050,13 @@ return array(
|
||||||
'Add external link' => 'Externe Verbindung hinzufügen',
|
'Add external link' => 'Externe Verbindung hinzufügen',
|
||||||
'Type' => 'Typ',
|
'Type' => 'Typ',
|
||||||
'Dependency' => 'Abhängigkeit',
|
'Dependency' => 'Abhängigkeit',
|
||||||
'Add internal link' => 'Füge interne Verbindung hinzu',
|
'Add internal link' => 'Interne Verbindung hinzufügen',
|
||||||
'Add a new external link' => 'Füge eine neue externe Verbindung hinzu',
|
'Add a new external link' => 'Füge eine neue externe Verbindung hinzu',
|
||||||
'Edit external link' => 'Externe Verbindung bearbeiten',
|
'Edit external link' => 'Externe Verbindung bearbeiten',
|
||||||
'External link' => 'Externe Verbindung',
|
'External link' => 'Externe Verbindung',
|
||||||
'Copy and paste your link here...' => 'Kopieren Sie Ihren Link hier...',
|
'Copy and paste your link here...' => 'Kopieren Sie Ihren Link hier...',
|
||||||
'URL' => 'URL',
|
'URL' => 'URL',
|
||||||
'There is no external link for the moment.' => 'Es gibt im Moment keine externe Verbindung.',
|
|
||||||
'Internal links' => 'Interne Verbindungen',
|
'Internal links' => 'Interne Verbindungen',
|
||||||
'There is no internal link for the moment.' => 'Es gibt im Moment keine interne Verbindung.',
|
|
||||||
'Assign to me' => 'Mir zuweisen',
|
'Assign to me' => 'Mir zuweisen',
|
||||||
'Me' => 'Mich',
|
'Me' => 'Mich',
|
||||||
'Do not duplicate anything' => 'Nichts duplizieren',
|
'Do not duplicate anything' => 'Nichts duplizieren',
|
||||||
|
@ -1081,7 +1064,6 @@ return array(
|
||||||
'Users management' => 'Benutzermanagement',
|
'Users management' => 'Benutzermanagement',
|
||||||
'Groups management' => 'Gruppenmanagement',
|
'Groups management' => 'Gruppenmanagement',
|
||||||
'Create from another project' => 'Von einem anderen Projekt erstellen',
|
'Create from another project' => 'Von einem anderen Projekt erstellen',
|
||||||
'There is no subtask at the moment.' => 'Es gibt im Moment keine Teilaufgabe',
|
|
||||||
'open' => 'offen',
|
'open' => 'offen',
|
||||||
'closed' => 'geschlossen',
|
'closed' => 'geschlossen',
|
||||||
'Priority:' => 'Priorität:',
|
'Priority:' => 'Priorität:',
|
||||||
|
@ -1100,7 +1082,6 @@ return array(
|
||||||
'Started:' => 'Gestarted:',
|
'Started:' => 'Gestarted:',
|
||||||
'Moved:' => 'Verschoben:',
|
'Moved:' => 'Verschoben:',
|
||||||
'Task #%d' => 'Aufgabe #%d',
|
'Task #%d' => 'Aufgabe #%d',
|
||||||
'Sub-tasks' => 'Teilaufgaben',
|
|
||||||
'Date and time format' => 'Datums- und Zeitformat',
|
'Date and time format' => 'Datums- und Zeitformat',
|
||||||
'Time format' => 'Zeitformat',
|
'Time format' => 'Zeitformat',
|
||||||
'Start date: ' => 'Anfangsdatum:',
|
'Start date: ' => 'Anfangsdatum:',
|
||||||
|
@ -1141,11 +1122,35 @@ return array(
|
||||||
'User filters' => 'Benutzer-Filter',
|
'User filters' => 'Benutzer-Filter',
|
||||||
'Category filters' => 'Kategorie-Filter',
|
'Category filters' => 'Kategorie-Filter',
|
||||||
'Upload a file' => 'Eine Datei hochladen',
|
'Upload a file' => 'Eine Datei hochladen',
|
||||||
'There is no attachment at the moment.' => 'Es gibt zur Zeit keine Anhänge',
|
|
||||||
'View file' => 'Datei ansehen',
|
'View file' => 'Datei ansehen',
|
||||||
'Last activity' => 'Letzte Aktivität',
|
'Last activity' => 'Letzte Aktivität',
|
||||||
'Change subtask position' => 'Position der Unteraufgabe ändern',
|
'Change subtask position' => 'Position der Unteraufgabe ändern',
|
||||||
'This value must be greater than %d' => 'Dieser Wert muss größer als %d sein',
|
'This value must be greater than %d' => 'Dieser Wert muss größer als %d sein',
|
||||||
'Another swimlane with the same name exists in the project' => 'Es gibt bereits eine Swimlane mit diesem Namen im Projekt',
|
'Another swimlane with the same name exists in the project' => 'Es gibt bereits eine Swimlane mit diesem Namen im Projekt',
|
||||||
'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => 'Beispiel: http://example.kanboard.net (wird zum Erstellen absoluter URLs genutzt)',
|
'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => 'Beispiel: http://example.kanboard.net (wird zum Erstellen absoluter URLs genutzt)',
|
||||||
|
'Actions duplicated successfully.' => 'Aktionen erfolgreich dupliziert',
|
||||||
|
'Unable to duplicate actions.' => 'Aktionen können nicht dupliziert werden.',
|
||||||
|
'Add a new action' => 'Neue Aktion hinzufügen',
|
||||||
|
'Import from another project' => 'Von einem anderen Projekt importieren',
|
||||||
|
'There is no action at the moment.' => 'Es gibt zur Zeit keine Aktionen.',
|
||||||
|
'Import actions from another project' => 'Aktionen von einem anderen Projekt importieren',
|
||||||
|
'There is no available project.' => 'Es ist kein Projekt verfügbar.',
|
||||||
|
// 'Local File' => '',
|
||||||
|
// 'Configuration' => '',
|
||||||
|
// 'PHP version:' => '',
|
||||||
|
// 'PHP SAPI:' => '',
|
||||||
|
// 'OS version:' => '',
|
||||||
|
// 'Database version:' => '',
|
||||||
|
// 'Browser:' => '',
|
||||||
|
// 'Task view' => '',
|
||||||
|
// 'Edit task' => '',
|
||||||
|
// 'Edit description' => '',
|
||||||
|
// 'New internal link' => '',
|
||||||
|
// 'Display list of keyboard shortcuts' => '',
|
||||||
|
// 'Menu' => '',
|
||||||
|
// 'Set start date' => '',
|
||||||
|
// 'Avatar' => '',
|
||||||
|
// 'Upload my avatar image' => '',
|
||||||
|
// 'Remove my image' => '',
|
||||||
|
// 'The OAuth2 state parameter is invalid' => '',
|
||||||
);
|
);
|
||||||
|
|
|
@ -8,7 +8,6 @@ return array(
|
||||||
'Edit' => 'Διόρθωση',
|
'Edit' => 'Διόρθωση',
|
||||||
'remove' => 'αφαιρετής',
|
'remove' => 'αφαιρετής',
|
||||||
'Remove' => 'Αφαίρεση',
|
'Remove' => 'Αφαίρεση',
|
||||||
'Update' => 'Ενημέρωση',
|
|
||||||
'Yes' => 'Ναι',
|
'Yes' => 'Ναι',
|
||||||
'No' => 'Όχι',
|
'No' => 'Όχι',
|
||||||
'cancel' => 'ακύρωση',
|
'cancel' => 'ακύρωση',
|
||||||
|
@ -18,13 +17,13 @@ return array(
|
||||||
'Green' => 'Πράσινο',
|
'Green' => 'Πράσινο',
|
||||||
'Purple' => 'Βιολετί',
|
'Purple' => 'Βιολετί',
|
||||||
'Red' => 'Κόκκινο',
|
'Red' => 'Κόκκινο',
|
||||||
'Orange' => 'Ποστοκαλί',
|
'Orange' => 'Πορτοκαλί',
|
||||||
'Grey' => 'Γκρίζο',
|
'Grey' => 'Γκρίζο',
|
||||||
'Brown' => 'Καφέ',
|
'Brown' => 'Καφέ',
|
||||||
'Deep Orange' => 'Βαθύ πορτοκαλί',
|
'Deep Orange' => 'Βαθύ πορτοκαλί',
|
||||||
'Dark Grey' => 'Βαθύ γκρί',
|
'Dark Grey' => 'Βαθύ γκρί',
|
||||||
'Pink' => 'Ρόζ',
|
'Pink' => 'Ρόζ',
|
||||||
'Teal' => 'Τουρκουάζ',
|
'Teal' => 'Τυρκουάζ',
|
||||||
'Cyan' => 'Γαλάζιο',
|
'Cyan' => 'Γαλάζιο',
|
||||||
'Lime' => 'Λεμονί',
|
'Lime' => 'Λεμονί',
|
||||||
'Light Green' => 'Ανοιχτό πράσινο',
|
'Light Green' => 'Ανοιχτό πράσινο',
|
||||||
|
@ -60,7 +59,6 @@ return array(
|
||||||
'Actions' => 'Ενέργειες',
|
'Actions' => 'Ενέργειες',
|
||||||
'Inactive' => 'Ανενεργός',
|
'Inactive' => 'Ανενεργός',
|
||||||
'Active' => 'Ενεργός',
|
'Active' => 'Ενεργός',
|
||||||
'Add this column' => 'Προσθήκη αυτής της στήλης',
|
|
||||||
'%d tasks on the board' => '%d εργασίες στον κεντρικό πίνακα έργου',
|
'%d tasks on the board' => '%d εργασίες στον κεντρικό πίνακα έργου',
|
||||||
'%d tasks in total' => '%d εργασιών στο σύνολο',
|
'%d tasks in total' => '%d εργασιών στο σύνολο',
|
||||||
'Unable to update this board.' => 'Αδύνατη η ενημέρωση αυτού του πίνακα',
|
'Unable to update this board.' => 'Αδύνατη η ενημέρωση αυτού του πίνακα',
|
||||||
|
@ -74,7 +72,6 @@ return array(
|
||||||
'All projects' => 'Όλα τα έργα',
|
'All projects' => 'Όλα τα έργα',
|
||||||
'Add a new column' => 'Πρόσθήκη στήλης',
|
'Add a new column' => 'Πρόσθήκη στήλης',
|
||||||
'Title' => 'Τίτλος',
|
'Title' => 'Τίτλος',
|
||||||
'Nobody assigned' => 'Δεν έχει ανατεθεί',
|
|
||||||
'Assigned to %s' => 'Ανατιθεμένο στον %s',
|
'Assigned to %s' => 'Ανατιθεμένο στον %s',
|
||||||
'Remove a column' => 'Αφαίρεση στήλης',
|
'Remove a column' => 'Αφαίρεση στήλης',
|
||||||
'Remove a column from a board' => 'Αφαίρεση στήλης από τον πίνακα',
|
'Remove a column from a board' => 'Αφαίρεση στήλης από τον πίνακα',
|
||||||
|
@ -95,7 +92,7 @@ return array(
|
||||||
'Edit a task' => 'Διόρθωση εργασίας',
|
'Edit a task' => 'Διόρθωση εργασίας',
|
||||||
'Column' => 'Στήλη',
|
'Column' => 'Στήλη',
|
||||||
'Color' => 'Χρώμα',
|
'Color' => 'Χρώμα',
|
||||||
'Assignee' => 'Ανατεθιμένα',
|
'Assignee' => 'Ανατεθιμένο στον χρήστη',
|
||||||
'Create another task' => 'Δημιουργία και άλλης εργασίας',
|
'Create another task' => 'Δημιουργία και άλλης εργασίας',
|
||||||
'New task' => 'Νέα εργασία',
|
'New task' => 'Νέα εργασία',
|
||||||
'Open a task' => 'Άνοιγμα εργασίας',
|
'Open a task' => 'Άνοιγμα εργασίας',
|
||||||
|
@ -168,7 +165,6 @@ return array(
|
||||||
'Task count' => 'Αρίθμηση εργασιών',
|
'Task count' => 'Αρίθμηση εργασιών',
|
||||||
'User' => 'Χρήστης',
|
'User' => 'Χρήστης',
|
||||||
'Comments' => 'Σχόλια',
|
'Comments' => 'Σχόλια',
|
||||||
'Write your text in Markdown' => 'Δυνατότητα γραφής και σε Markdown',
|
|
||||||
'Leave a comment' => 'Αφήστε ένα σχόλιο',
|
'Leave a comment' => 'Αφήστε ένα σχόλιο',
|
||||||
'Comment is required' => 'Το σχόλιο απαιτείται',
|
'Comment is required' => 'Το σχόλιο απαιτείται',
|
||||||
'Leave a description' => 'Αφήστε μια περιγραφή',
|
'Leave a description' => 'Αφήστε μια περιγραφή',
|
||||||
|
@ -184,7 +180,6 @@ return array(
|
||||||
'Unable to remove this action.' => 'Δεν είναι δυνατή η αφαίρεση αυτής της ενέργειας',
|
'Unable to remove this action.' => 'Δεν είναι δυνατή η αφαίρεση αυτής της ενέργειας',
|
||||||
'Action removed successfully.' => 'Η ενέργεια αφαιρέθηκε με επιτυχία.',
|
'Action removed successfully.' => 'Η ενέργεια αφαιρέθηκε με επιτυχία.',
|
||||||
'Automatic actions for the project "%s"' => 'Αυτόματες ενέργειες για το έργο « %s »',
|
'Automatic actions for the project "%s"' => 'Αυτόματες ενέργειες για το έργο « %s »',
|
||||||
'Defined actions' => 'Ορισμένες ενέργειες',
|
|
||||||
'Add an action' => 'Προσθήκη ενέργειας',
|
'Add an action' => 'Προσθήκη ενέργειας',
|
||||||
'Event name' => 'Ονομασία συμβάντος',
|
'Event name' => 'Ονομασία συμβάντος',
|
||||||
'Action name' => 'Ονομασία ενέργειας',
|
'Action name' => 'Ονομασία ενέργειας',
|
||||||
|
@ -194,7 +189,6 @@ return array(
|
||||||
'When the selected event occurs execute the corresponding action.' => 'Όταν εμφανίζεται το επιλεγμένο συμβάν εκτελέστε την αντίστοιχη ενέργεια.',
|
'When the selected event occurs execute the corresponding action.' => 'Όταν εμφανίζεται το επιλεγμένο συμβάν εκτελέστε την αντίστοιχη ενέργεια.',
|
||||||
'Next step' => 'Επόμενο βήμα',
|
'Next step' => 'Επόμενο βήμα',
|
||||||
'Define action parameters' => 'Ορισμός παραμέτρων ενέργειας',
|
'Define action parameters' => 'Ορισμός παραμέτρων ενέργειας',
|
||||||
'Save this action' => 'Αποθήκευση ενέργειας',
|
|
||||||
'Do you really want to remove this action: "%s"?' => 'Αφαίρεση της ενέργειας: « %s » ?',
|
'Do you really want to remove this action: "%s"?' => 'Αφαίρεση της ενέργειας: « %s » ?',
|
||||||
'Remove an automatic action' => 'Αφαίρεση της αυτόματης ενέργειας',
|
'Remove an automatic action' => 'Αφαίρεση της αυτόματης ενέργειας',
|
||||||
'Assign the task to a specific user' => 'Ανάθεση της εργασίας σε συγκεκριμένο χρήστη',
|
'Assign the task to a specific user' => 'Ανάθεση της εργασίας σε συγκεκριμένο χρήστη',
|
||||||
|
@ -228,7 +222,7 @@ return array(
|
||||||
'Persistent connections' => 'Μόνιμες συνδέσεις',
|
'Persistent connections' => 'Μόνιμες συνδέσεις',
|
||||||
'No session.' => 'Καμμία συνεδρία',
|
'No session.' => 'Καμμία συνεδρία',
|
||||||
'Expiration date' => 'Ημερομηνία λήξης',
|
'Expiration date' => 'Ημερομηνία λήξης',
|
||||||
'Remember Me' => 'Remember Me',
|
'Remember Me' => 'Να με θυμάσαι',
|
||||||
'Creation date' => 'Ημερομηνία δημιουργίας',
|
'Creation date' => 'Ημερομηνία δημιουργίας',
|
||||||
'Everybody' => 'Όλα',
|
'Everybody' => 'Όλα',
|
||||||
'Open' => 'Ανοικτά',
|
'Open' => 'Ανοικτά',
|
||||||
|
@ -292,7 +286,7 @@ return array(
|
||||||
'estimated' => 'κατ\' εκτίμηση',
|
'estimated' => 'κατ\' εκτίμηση',
|
||||||
'Sub-Tasks' => 'Υπο-Εργασίες',
|
'Sub-Tasks' => 'Υπο-Εργασίες',
|
||||||
'Add a sub-task' => 'Προσθήκη υπο-εργασίας',
|
'Add a sub-task' => 'Προσθήκη υπο-εργασίας',
|
||||||
'Original estimate' => 'Original estimate',
|
'Original estimate' => 'Αρχική πρόβλεψη χρόνου',
|
||||||
'Create another sub-task' => 'Δημιουργία κι άλλης υπο-εργασίας',
|
'Create another sub-task' => 'Δημιουργία κι άλλης υπο-εργασίας',
|
||||||
'Time spent' => 'Χρόνος που ξοδεύτηκε',
|
'Time spent' => 'Χρόνος που ξοδεύτηκε',
|
||||||
'Edit a sub-task' => 'Διόρθωση υπο-εργασίας',
|
'Edit a sub-task' => 'Διόρθωση υπο-εργασίας',
|
||||||
|
@ -333,12 +327,12 @@ return array(
|
||||||
'Time tracking:' => 'Παρακολούθηση του χρόνου:',
|
'Time tracking:' => 'Παρακολούθηση του χρόνου:',
|
||||||
'New sub-task' => 'Νέα υπο-εργασία',
|
'New sub-task' => 'Νέα υπο-εργασία',
|
||||||
'New attachment added "%s"' => 'Νέα επικόλληση προστέθηκε « %s »',
|
'New attachment added "%s"' => 'Νέα επικόλληση προστέθηκε « %s »',
|
||||||
'Comment updated' => 'Το σχόλιο ενημερώθηκε',
|
|
||||||
'New comment posted by %s' => 'Νέο σχόλιο από τον χρήστη « %s »',
|
'New comment posted by %s' => 'Νέο σχόλιο από τον χρήστη « %s »',
|
||||||
'New attachment' => 'New attachment',
|
'New attachment' => 'New attachment',
|
||||||
'New comment' => 'Νέο σχόλιο',
|
'New comment' => 'Νέο σχόλιο',
|
||||||
|
'Comment updated' => 'Το σχόλιο ενημερώθηκε',
|
||||||
'New subtask' => 'Νέα υπο-εργασία',
|
'New subtask' => 'Νέα υπο-εργασία',
|
||||||
'Subtask updated' => 'Υπο-Εργασία ενημερώθηκε',
|
'Subtask updated' => 'Η Υπο-Εργασία ενημερώθηκε',
|
||||||
'Task updated' => 'Η εργασία ενημερώθηκε',
|
'Task updated' => 'Η εργασία ενημερώθηκε',
|
||||||
'Task closed' => 'Η εργασία έκλεισε',
|
'Task closed' => 'Η εργασία έκλεισε',
|
||||||
'Task opened' => 'Η εργασία άνοιξε',
|
'Task opened' => 'Η εργασία άνοιξε',
|
||||||
|
@ -394,8 +388,8 @@ return array(
|
||||||
'RSS feed' => 'RSS feed',
|
'RSS feed' => 'RSS feed',
|
||||||
'%s updated a comment on the task #%d' => '%s ενημέρωσε ένα σχόλιο στην εργασία n°%d',
|
'%s updated a comment on the task #%d' => '%s ενημέρωσε ένα σχόλιο στην εργασία n°%d',
|
||||||
'%s commented on the task #%d' => '%s σχολίασε την εργασία n°%d',
|
'%s commented on the task #%d' => '%s σχολίασε την εργασία n°%d',
|
||||||
'%s updated a subtask for the task #%d' => '%s ενημέρωσε μια υπο-εργασία στην εργασία n °%d',
|
'%s updated a subtask for the task #%d' => '%s ενημερώθηκε μια υπο-εργασία στην εργασία n °%d',
|
||||||
'%s created a subtask for the task #%d' => '%s δημιούργησε μια υπο-εργασία στην εργασία n°%d',
|
'%s created a subtask for the task #%d' => '%s δημιουργήθηκε μια υπο-εργασία στην εργασία n°%d',
|
||||||
'%s updated the task #%d' => '%s ενημέρωσε την εργασία n°%d',
|
'%s updated the task #%d' => '%s ενημέρωσε την εργασία n°%d',
|
||||||
'%s created the task #%d' => '%s δημιούργησε την εργασία n°%d',
|
'%s created the task #%d' => '%s δημιούργησε την εργασία n°%d',
|
||||||
'%s closed the task #%d' => '%s έκλεισε την εργασία n°%d',
|
'%s closed the task #%d' => '%s έκλεισε την εργασία n°%d',
|
||||||
|
@ -421,7 +415,7 @@ return array(
|
||||||
'Board settings' => 'Board settings',
|
'Board settings' => 'Board settings',
|
||||||
'URL and token' => 'URL / token',
|
'URL and token' => 'URL / token',
|
||||||
'Webhook settings' => 'Webhook settings',
|
'Webhook settings' => 'Webhook settings',
|
||||||
'URL for task creation:' => 'URL για δημιουργία εργασίας: :',
|
'URL for task creation:' => 'URL για δημιουργία εργασίας:',
|
||||||
'Reset token' => 'Reset token',
|
'Reset token' => 'Reset token',
|
||||||
'API endpoint:' => 'URL API:',
|
'API endpoint:' => 'URL API:',
|
||||||
'Refresh interval for private board' => 'Ανανέωση interval στο private board',
|
'Refresh interval for private board' => 'Ανανέωση interval στο private board',
|
||||||
|
@ -436,7 +430,6 @@ return array(
|
||||||
'ISO format is always accepted, example: "%s" and "%s"' => 'ISO format είναι πάντα αποδεκτό, π.χ.: « %s » και « %s »',
|
'ISO format is always accepted, example: "%s" and "%s"' => 'ISO format είναι πάντα αποδεκτό, π.χ.: « %s » και « %s »',
|
||||||
'New private project' => 'Νέο ιδιωτικό έργο',
|
'New private project' => 'Νέο ιδιωτικό έργο',
|
||||||
'This project is private' => 'Αυτό το έργο είναι ιδιωτικό',
|
'This project is private' => 'Αυτό το έργο είναι ιδιωτικό',
|
||||||
'Type here to create a new sub-task' => 'Πληκτρολογήστε εδώ για να δημιουργήσετε μια νέα υπο-εργασία',
|
|
||||||
'Add' => 'Προσθήκη',
|
'Add' => 'Προσθήκη',
|
||||||
'Start date' => 'Ημερομηνία έναρξης',
|
'Start date' => 'Ημερομηνία έναρξης',
|
||||||
'Time estimated' => 'Εκτιμώμενος χρόνος',
|
'Time estimated' => 'Εκτιμώμενος χρόνος',
|
||||||
|
@ -487,21 +480,18 @@ return array(
|
||||||
'Daily project summary export for "%s"' => 'Εξαγωγή της καθημερινής περίληψης του έργου « %s »',
|
'Daily project summary export for "%s"' => 'Εξαγωγή της καθημερινής περίληψης του έργου « %s »',
|
||||||
'Exports' => 'Εξαγωγές',
|
'Exports' => 'Εξαγωγές',
|
||||||
'This export contains the number of tasks per column grouped per day.' => 'Αυτή η κατάσταση περιέχει τον αριθμό των εργασιών ανά στήλη ομαδοποιημένα ανά ημέρα.',
|
'This export contains the number of tasks per column grouped per day.' => 'Αυτή η κατάσταση περιέχει τον αριθμό των εργασιών ανά στήλη ομαδοποιημένα ανά ημέρα.',
|
||||||
'Nothing to preview...' => 'Τίποτα για προεπισκόπηση...',
|
'Active swimlanes' => 'Ενεργές λωρίδες',
|
||||||
'Preview' => 'Προεπισκόπηση',
|
'Add a new swimlane' => 'Προσθήκη λωρίδας',
|
||||||
'Write' => 'Write',
|
'Change default swimlane' => 'Αλλαγή της εξ\' ορισμού λωρίδας',
|
||||||
'Active swimlanes' => 'Ενεργά swimlanes',
|
'Default swimlane' => 'Εξ\' ορισμού λωρίδα',
|
||||||
'Add a new swimlane' => 'Πρόσθεσε ένα νέο λωρίδα',
|
|
||||||
'Change default swimlane' => 'Αλλαγή του default λωρίδα',
|
|
||||||
'Default swimlane' => 'Default λωρίδα',
|
|
||||||
'Do you really want to remove this swimlane: "%s"?' => 'Σίγουρα θέλετε να αφαιρέσετε τη λωρίδα : « %s » ?',
|
'Do you really want to remove this swimlane: "%s"?' => 'Σίγουρα θέλετε να αφαιρέσετε τη λωρίδα : « %s » ?',
|
||||||
'Inactive swimlanes' => 'Λωρίδες ανενεργές',
|
'Inactive swimlanes' => 'Ανενεργές Λωρίδες',
|
||||||
'Remove a swimlane' => 'Αφαιρέστε μια λωρίδα',
|
'Remove a swimlane' => 'Αφαίρεση λωρίδας',
|
||||||
'Show default swimlane' => 'Εμφάνιση προεπιλεγμένων λωρίδων',
|
'Show default swimlane' => 'Εμφάνιση προεπιλεγμένων λωρίδων',
|
||||||
'Swimlane modification for the project "%s"' => 'Τροποποίηση λωρίδας για το έργο « %s »',
|
'Swimlane modification for the project "%s"' => 'Τροποποίηση λωρίδας για το έργο « %s »',
|
||||||
'Swimlane not found.' => 'Η λωρίδα δεν βρέθηκε.',
|
'Swimlane not found.' => 'Η λωρίδα δεν βρέθηκε.',
|
||||||
'Swimlane removed successfully.' => 'Η λωρίδα αφαιρέθηκε με επιτυχία.',
|
'Swimlane removed successfully.' => 'Η λωρίδα αφαιρέθηκε με επιτυχία.',
|
||||||
'Swimlanes' => 'Swimlanes',
|
'Swimlanes' => 'Λωρίδες',
|
||||||
'Swimlane updated successfully.' => 'Η λωρίδα ενημερώθηκε με επιτυχία.',
|
'Swimlane updated successfully.' => 'Η λωρίδα ενημερώθηκε με επιτυχία.',
|
||||||
'The default swimlane have been updated successfully.' => 'Η προεπιλεγμένη λωρίδα ενημερώθηκε με επιτυχία.',
|
'The default swimlane have been updated successfully.' => 'Η προεπιλεγμένη λωρίδα ενημερώθηκε με επιτυχία.',
|
||||||
'Unable to remove this swimlane.' => 'Αδύνατο να αφαιρεθεί η λωρίδα.',
|
'Unable to remove this swimlane.' => 'Αδύνατο να αφαιρεθεί η λωρίδα.',
|
||||||
|
@ -535,7 +525,7 @@ return array(
|
||||||
'Subtask timesheet' => 'Πρόγραμμα υπο-εργασίας',
|
'Subtask timesheet' => 'Πρόγραμμα υπο-εργασίας',
|
||||||
'There is nothing to show.' => 'Δεν υπάρχει κάτι.',
|
'There is nothing to show.' => 'Δεν υπάρχει κάτι.',
|
||||||
'Time Tracking' => 'Παρακολούθηση χρονοδιαγράμματος',
|
'Time Tracking' => 'Παρακολούθηση χρονοδιαγράμματος',
|
||||||
'You already have one subtask in progress' => 'Έχτε ήδη μια υπο-εργασία σε εξέλιξη',
|
'You already have one subtask in progress' => 'Έχετε ήδη μια υπο-εργασία σε εξέλιξη',
|
||||||
'Which parts of the project do you want to duplicate?' => 'Ποιά κομμάτια του έργου θέλετε να αντιγράψετε ?',
|
'Which parts of the project do you want to duplicate?' => 'Ποιά κομμάτια του έργου θέλετε να αντιγράψετε ?',
|
||||||
'Disallow login form' => 'Απαγόρευση φόρμας σύνδεσης',
|
'Disallow login form' => 'Απαγόρευση φόρμας σύνδεσης',
|
||||||
'Start' => 'Εκκίνηση',
|
'Start' => 'Εκκίνηση',
|
||||||
|
@ -543,7 +533,6 @@ return array(
|
||||||
'Task age in days' => 'Χρόνος εργασίας σε μέρες',
|
'Task age in days' => 'Χρόνος εργασίας σε μέρες',
|
||||||
'Days in this column' => 'Μέρες σε αυτή την στήλη',
|
'Days in this column' => 'Μέρες σε αυτή την στήλη',
|
||||||
'%dd' => '%dημ',
|
'%dd' => '%dημ',
|
||||||
'Add a link' => 'Προσθήκη ενός link',
|
|
||||||
'Add a new link' => 'Προσθήκη ενός νέου link',
|
'Add a new link' => 'Προσθήκη ενός νέου link',
|
||||||
'Do you really want to remove this link: "%s"?' => 'Θέλετε σίγουρα να αφαιρέσετε αυτό το link : « %s » ?',
|
'Do you really want to remove this link: "%s"?' => 'Θέλετε σίγουρα να αφαιρέσετε αυτό το link : « %s » ?',
|
||||||
'Do you really want to remove this link with task #%d?' => 'Θέλετε σίγουρα να αφαιρέσετε αυτό το link του έργου n°%d ?',
|
'Do you really want to remove this link with task #%d?' => 'Θέλετε σίγουρα να αφαιρέσετε αυτό το link του έργου n°%d ?',
|
||||||
|
@ -587,9 +576,9 @@ return array(
|
||||||
'Keyboard shortcuts' => 'Συντομεύσεις πληκτρολογίου',
|
'Keyboard shortcuts' => 'Συντομεύσεις πληκτρολογίου',
|
||||||
'Open board switcher' => 'Άνοιγμα μεταγωγέα κεντρικού πίνακα',
|
'Open board switcher' => 'Άνοιγμα μεταγωγέα κεντρικού πίνακα',
|
||||||
'Application' => 'Εφαρμογή',
|
'Application' => 'Εφαρμογή',
|
||||||
'Compact view' => 'Συμπηκνωμένη προβολή',
|
'Compact view' => 'Συμπυκνωμένη προβολή',
|
||||||
'Horizontal scrolling' => 'Οριζόντια ολίσθηση',
|
'Horizontal scrolling' => 'Οριζόντια ολίσθηση',
|
||||||
'Compact/wide view' => 'Συμπηκνωμένη/Ευρεία Προβολή',
|
'Compact/wide view' => 'Συμπυκνωμένη/Ευρεία Προβολή',
|
||||||
'No results match:' => 'Δεν ταιριάζει κανένα αποτέλεσμα:',
|
'No results match:' => 'Δεν ταιριάζει κανένα αποτέλεσμα:',
|
||||||
'Currency' => 'Νόμισμα',
|
'Currency' => 'Νόμισμα',
|
||||||
'Private project' => 'Ιδιωτικό έργο',
|
'Private project' => 'Ιδιωτικό έργο',
|
||||||
|
@ -734,7 +723,7 @@ return array(
|
||||||
'Time spent changed: %sh' => 'Ο χρόνος που πέρασε έχει αλλάξει: %sh',
|
'Time spent changed: %sh' => 'Ο χρόνος που πέρασε έχει αλλάξει: %sh',
|
||||||
'Time estimated changed: %sh' => 'Ο εκτιμώμενος χρόνος άλλαξε: %sh',
|
'Time estimated changed: %sh' => 'Ο εκτιμώμενος χρόνος άλλαξε: %sh',
|
||||||
'The field "%s" have been updated' => 'Το πεδίο « %s » έχει ενημερωθεί',
|
'The field "%s" have been updated' => 'Το πεδίο « %s » έχει ενημερωθεί',
|
||||||
'The description have been modified' => 'Η περιγραφή έχει ενημερωθεί',
|
'The description has been modified:' => 'Η περιγραφή έχει ενημερωθεί',
|
||||||
'Do you really want to close the task "%s" as well as all subtasks?' => 'Σίγουρα θέλετε να κλείσετε την εργασία « %s » και την υπο-εργασία ?',
|
'Do you really want to close the task "%s" as well as all subtasks?' => 'Σίγουρα θέλετε να κλείσετε την εργασία « %s » και την υπο-εργασία ?',
|
||||||
'I want to receive notifications for:' => 'Επιθυμώ να λαμβάνω ενημερώσεις για :',
|
'I want to receive notifications for:' => 'Επιθυμώ να λαμβάνω ενημερώσεις για :',
|
||||||
'All tasks' => 'Όλες οι εργασίες',
|
'All tasks' => 'Όλες οι εργασίες',
|
||||||
|
@ -753,8 +742,6 @@ return array(
|
||||||
'My activity stream' => 'Η ροή δραστηριοτήτων μου',
|
'My activity stream' => 'Η ροή δραστηριοτήτων μου',
|
||||||
'My calendar' => 'Το ημερολόγιο μου',
|
'My calendar' => 'Το ημερολόγιο μου',
|
||||||
'Search tasks' => 'Αναζήτηση εργασιών',
|
'Search tasks' => 'Αναζήτηση εργασιών',
|
||||||
'Back to the calendar' => 'Πίσω στο ημερολόγιο',
|
|
||||||
'Filters' => 'Φίλτρα',
|
|
||||||
'Reset filters' => 'Επαναφορά φίλτρων',
|
'Reset filters' => 'Επαναφορά φίλτρων',
|
||||||
'My tasks due tomorrow' => 'Οι εργασίες καθηκόντων μου αύριο',
|
'My tasks due tomorrow' => 'Οι εργασίες καθηκόντων μου αύριο',
|
||||||
'Tasks due today' => 'Οι εργασίες καθηκόντων μου αύριο',
|
'Tasks due today' => 'Οι εργασίες καθηκόντων μου αύριο',
|
||||||
|
@ -830,8 +817,8 @@ return array(
|
||||||
'Sort by position' => 'Ταξινόμηση κατά Θέση',
|
'Sort by position' => 'Ταξινόμηση κατά Θέση',
|
||||||
'Sort by date' => 'Ταξινόμηση κατά ημέρα',
|
'Sort by date' => 'Ταξινόμηση κατά ημέρα',
|
||||||
'Add task' => 'Προσθήκη εργασίας',
|
'Add task' => 'Προσθήκη εργασίας',
|
||||||
'Start date:' => 'Ημέρα εκκίνησης :',
|
'Start date:' => 'Ημερομηνία εκκίνησης :',
|
||||||
'Due date:' => 'Ημέρα καθηκόντων :',
|
'Due date:' => 'Ημερομηνία λήξης:',
|
||||||
'There is no start date or due date for this task.' => 'Δεν υπάρχει ημερομηνία έναρξης ή ημερομηνία λήξης καθηκόντων για το έργο αυτό.',
|
'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.' => 'Μετακίνηση ή αλλαγή μεγέθους μιας εργασίας θα αλλάξει την ώρα έναρξης και ημερομηνία λήξης της εργασίας.',
|
'Moving or resizing a task will change the start and due date of the task.' => 'Μετακίνηση ή αλλαγή μεγέθους μιας εργασίας θα αλλάξει την ώρα έναρξης και ημερομηνία λήξης της εργασίας.',
|
||||||
'There is no task in your project.' => 'Δεν υπάρχει καμία εργασία στο έργο σας.',
|
'There is no task in your project.' => 'Δεν υπάρχει καμία εργασία στο έργο σας.',
|
||||||
|
@ -854,7 +841,6 @@ return array(
|
||||||
'End date:' => 'Ημερομηνία λήξης :',
|
'End date:' => 'Ημερομηνία λήξης :',
|
||||||
'There is no start date or end date for this project.' => 'Δεν υπάρχει ημερομηνία έναρξης ή λήξης για το έργο αυτό.',
|
'There is no start date or end date for this project.' => 'Δεν υπάρχει ημερομηνία έναρξης ή λήξης για το έργο αυτό.',
|
||||||
'Projects Gantt chart' => 'Διάγραμμα Gantt έργων',
|
'Projects Gantt chart' => 'Διάγραμμα Gantt έργων',
|
||||||
'Link type' => 'Τύπος συνδέσμου',
|
|
||||||
'Change task color when using a specific task link' => 'Αλλαγή χρώματος εργασίας χρησιμοποιώντας συγκεκριμένο σύνδεσμο εργασίας',
|
'Change task color when using a specific task link' => 'Αλλαγή χρώματος εργασίας χρησιμοποιώντας συγκεκριμένο σύνδεσμο εργασίας',
|
||||||
'Task link creation or modification' => 'Σύνδεσμος δημιουργίας ή τροποποίησης εργασίας',
|
'Task link creation or modification' => 'Σύνδεσμος δημιουργίας ή τροποποίησης εργασίας',
|
||||||
'Milestone' => 'Ορόσημο',
|
'Milestone' => 'Ορόσημο',
|
||||||
|
@ -906,7 +892,6 @@ return array(
|
||||||
'Shared' => 'Διαμοιρασμένα',
|
'Shared' => 'Διαμοιρασμένα',
|
||||||
'Owner' => 'Ιδιοκτήτης',
|
'Owner' => 'Ιδιοκτήτης',
|
||||||
'Unread notifications' => 'Αδιάβαστες ειδοποιήσεις',
|
'Unread notifications' => 'Αδιάβαστες ειδοποιήσεις',
|
||||||
'My filters' => 'Τα φίλτρα μου',
|
|
||||||
'Notification methods:' => 'Μέθοδοι ειδοποίησης:',
|
'Notification methods:' => 'Μέθοδοι ειδοποίησης:',
|
||||||
'Import tasks from CSV file' => 'Εισαγωγή εργασιών μέσω αρχείου CSV',
|
'Import tasks from CSV file' => 'Εισαγωγή εργασιών μέσω αρχείου CSV',
|
||||||
'Unable to read your file' => 'Δεν είναι δυνατή η ανάγνωση του αρχείου',
|
'Unable to read your file' => 'Δεν είναι δυνατή η ανάγνωση του αρχείου',
|
||||||
|
@ -944,6 +929,7 @@ return array(
|
||||||
'Usernames must be lowercase and unique' => 'Οι ονομασίες χρηστών πρέπει να είναι σε μικρά γράμματα (lowercase) και μοναδικά',
|
'Usernames must be lowercase and unique' => 'Οι ονομασίες χρηστών πρέπει να είναι σε μικρά γράμματα (lowercase) και μοναδικά',
|
||||||
'Passwords will be encrypted if present' => 'Οι κωδικοί πρόσβασης κρυπτογραφούνται, αν υπάρχουν',
|
'Passwords will be encrypted if present' => 'Οι κωδικοί πρόσβασης κρυπτογραφούνται, αν υπάρχουν',
|
||||||
'%s attached a new file to the task %s' => '%s νέο συνημμένο αρχείο της εργασίας %s',
|
'%s attached a new file to the task %s' => '%s νέο συνημμένο αρχείο της εργασίας %s',
|
||||||
|
'Link type' => 'Τύπος συνδέσμου',
|
||||||
'Assign automatically a category based on a link' => 'Ανατίθεται αυτόματα κατηγορία, βασισμένη στον σύνδεσμο',
|
'Assign automatically a category based on a link' => 'Ανατίθεται αυτόματα κατηγορία, βασισμένη στον σύνδεσμο',
|
||||||
'BAM - Konvertible Mark' => 'BAM - Konvertible Mark',
|
'BAM - Konvertible Mark' => 'BAM - Konvertible Mark',
|
||||||
'Assignee Username' => 'Δικαιοδόχο όνομα χρήστη',
|
'Assignee Username' => 'Δικαιοδόχο όνομα χρήστη',
|
||||||
|
@ -1014,8 +1000,8 @@ return array(
|
||||||
'Close a task in a specific column' => 'Κλείσιμο εργασίας σε συγκεκριμένη στήλη',
|
'Close a task in a specific column' => 'Κλείσιμο εργασίας σε συγκεκριμένη στήλη',
|
||||||
'Time-based One-time Password Algorithm' => 'Time-based One-time Password Algorithm',
|
'Time-based One-time Password Algorithm' => 'Time-based One-time Password Algorithm',
|
||||||
'Two-Factor Provider: ' => 'Two-Factor Provider: ',
|
'Two-Factor Provider: ' => 'Two-Factor Provider: ',
|
||||||
'Disable two-factor authentication' => 'Disable two-factor authentication',
|
'Disable two-factor authentication' => 'Απενεργοποίηση two-factor authentication',
|
||||||
'Enable two-factor authentication' => 'Enable two-factor authentication',
|
'Enable two-factor authentication' => 'Ενεργοποίηση two-factor authentication',
|
||||||
'There is no integration registered at the moment.' => 'There is no integration registered at the moment.',
|
'There is no integration registered at the moment.' => 'There is no integration registered at the moment.',
|
||||||
'Password Reset for Kanboard' => 'Αρχικοποίηση κωδικών πρόσβασης για την εφαρμογή Kanboard',
|
'Password Reset for Kanboard' => 'Αρχικοποίηση κωδικών πρόσβασης για την εφαρμογή Kanboard',
|
||||||
'Forgot password?' => 'Ξεχάσατε τον κωδικό πρόσβασης ?',
|
'Forgot password?' => 'Ξεχάσατε τον κωδικό πρόσβασης ?',
|
||||||
|
@ -1036,116 +1022,135 @@ return array(
|
||||||
'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => 'Κανένα plugin δεν έχει καταχωρηθεί με τη μέθοδο της κοινοποίησης του έργου. Μπορείτε ακόμα να διαμορφώσετε τις μεμονωμένες κοινοποιήσεις στο προφίλ χρήστη σας.',
|
'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => 'Κανένα plugin δεν έχει καταχωρηθεί με τη μέθοδο της κοινοποίησης του έργου. Μπορείτε ακόμα να διαμορφώσετε τις μεμονωμένες κοινοποιήσεις στο προφίλ χρήστη σας.',
|
||||||
'My dashboard' => 'Το κεντρικό ταμπλό μου',
|
'My dashboard' => 'Το κεντρικό ταμπλό μου',
|
||||||
'My profile' => 'Το προφίλ μου',
|
'My profile' => 'Το προφίλ μου',
|
||||||
// 'Project owner: ' => '',
|
'Project owner: ' => 'Ιδιοκτήτης έργου: ',
|
||||||
// 'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => '',
|
'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => 'Το αναγνωριστικό έργου είναι προαιρετικό και πρέπει να είναι αλφαριθμητικό, για παράδειγμα: MYPROJECT',
|
||||||
// 'Project owner' => '',
|
'Project owner' => 'Ιδιοκτήτης έργου',
|
||||||
// 'Those dates are useful for the project Gantt chart.' => '',
|
'Those dates are useful for the project Gantt chart.' => 'Οι ημερομηνίες αυτές είανι χρήσιμες για το διάγραμμα Gantt του έργου',
|
||||||
// 'Private projects do not have users and groups management.' => '',
|
'Private projects do not have users and groups management.' => 'Τα ιδιωτικά έργα δεν έχουν χρήστες και διαχείριση ομάδων',
|
||||||
// 'There is no project member.' => '',
|
'There is no project member.' => 'Δεν υπάρχει μέλος στο έργο',
|
||||||
// 'Priority' => '',
|
'Priority' => 'Προτεραιότητα',
|
||||||
// 'Task priority' => '',
|
'Task priority' => 'Προτεραιότητα εργασίας',
|
||||||
// 'General' => '',
|
'General' => 'Γενικά',
|
||||||
// 'Dates' => '',
|
'Dates' => 'Ημερομηνίες',
|
||||||
// 'Default priority' => '',
|
'Default priority' => 'Εξ ορισμού προτεραιότητα',
|
||||||
// 'Lowest priority' => '',
|
'Lowest priority' => 'η χαμηλότερη προτεραιότητα',
|
||||||
// 'Highest priority' => '',
|
'Highest priority' => 'η υψηλότερη προτεραιότητα',
|
||||||
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
|
'If you put zero to the low and high priority, this feature will be disabled.' => 'Αν βάλετε μηδέν στη χαμηλή και στην υψηλή προτεραιότητα, το χαρακτηριστικό αυτό απενεργοποιείται.',
|
||||||
// 'Close a task when there is no activity' => '',
|
'Close a task when there is no activity' => 'Κλείσιμο εργασίας όταν δεν υπάρχει δραστηριότητα',
|
||||||
// 'Duration in days' => '',
|
'Duration in days' => 'Διάρκεια σε ημέρες',
|
||||||
// 'Send email when there is no activity on a task' => '',
|
'Send email when there is no activity on a task' => 'Αποστολή email όταν δεν υπάρχει δραστηριότητα σε εργασία',
|
||||||
// 'List of external links' => '',
|
'Unable to fetch link information.' => 'Δεν είναι δυνατή η ανάλυση της πληροφορίας συνδεσμου',
|
||||||
// 'Unable to fetch link information.' => '',
|
'Daily background job for tasks' => 'Ημερήσια παρασκηνιακή δουλειά για τις εργασίες',
|
||||||
// 'Daily background job for tasks' => '',
|
'Auto' => 'Αυτόματο',
|
||||||
// 'Auto' => '',
|
'Related' => 'Σχετίζεται',
|
||||||
// 'Related' => '',
|
'Attachment' => 'Συνημμένο',
|
||||||
// 'Attachment' => '',
|
'Title not found' => 'Ο τίτλος δεν βρέθηκε',
|
||||||
// 'Title not found' => '',
|
'Web Link' => 'Σύνδεσμος web',
|
||||||
// 'Web Link' => '',
|
'External links' => 'Εξωτερικοί σύνδεσμοι',
|
||||||
// 'External links' => '',
|
'Add external link' => 'Προσθήκη εξωτερικού συνδέσμου',
|
||||||
// 'Add external link' => '',
|
'Type' => 'Τύπος',
|
||||||
// 'Type' => '',
|
'Dependency' => 'Εξάρτηση',
|
||||||
// 'Dependency' => '',
|
'Add internal link' => 'Προσθήκη εσωτερικού συνδέσμου',
|
||||||
// 'Add internal link' => '',
|
'Add a new external link' => 'Προσθήκη νέου εξωτερικού συνδέσμου',
|
||||||
// 'Add a new external link' => '',
|
'Edit external link' => 'Διόρθωση εξωτερικού συνδέσμου',
|
||||||
// 'Edit external link' => '',
|
'External link' => 'Εξωτερικός σύνδεσμος',
|
||||||
// 'External link' => '',
|
'Copy and paste your link here...' => 'Κάντε αντιγραφή και επικόλληση εδώ',
|
||||||
// 'Copy and paste your link here...' => '',
|
'URL' => 'URL',
|
||||||
// 'URL' => '',
|
'Internal links' => 'Εσωτερικοί σύνδεσμοι',
|
||||||
// 'There is no external link for the moment.' => '',
|
'Assign to me' => 'Αναττίθεται σε εμένα',
|
||||||
// 'Internal links' => '',
|
'Me' => 'Σε μένα',
|
||||||
// 'There is no internal link for the moment.' => '',
|
'Do not duplicate anything' => 'Να μην γίνει κλωνοποίηση από άλλο έργο',
|
||||||
// 'Assign to me' => '',
|
'Projects management' => 'Διαχείριση έργων',
|
||||||
// 'Me' => '',
|
'Users management' => 'Διαχείριση χρηστών',
|
||||||
// 'Do not duplicate anything' => '',
|
'Groups management' => 'Διαχείριση ομάδων',
|
||||||
// 'Projects management' => '',
|
'Create from another project' => 'Δημιουργία από άλλο έργο',
|
||||||
// 'Users management' => '',
|
'open' => 'Ανοικτό',
|
||||||
// 'Groups management' => '',
|
'closed' => 'Κλειστό',
|
||||||
// 'Create from another project' => '',
|
'Priority:' => 'Προτεραιότητα:',
|
||||||
// 'There is no subtask at the moment.' => '',
|
'Reference:' => 'Αναφορά:',
|
||||||
// 'open' => '',
|
'Complexity:' => 'Πολυπλοκότητα:',
|
||||||
// 'closed' => '',
|
'Swimlane:' => 'Λωρίδα:',
|
||||||
// 'Priority:' => '',
|
'Column:' => 'Στήλη:',
|
||||||
// 'Reference:' => '',
|
'Position:' => 'Θέση:',
|
||||||
// 'Complexity:' => '',
|
'Creator:' => 'Δημιουργός:',
|
||||||
// 'Swimlane:' => '',
|
'Time estimated:' => 'Προβλεπόμενη ώρα:',
|
||||||
// 'Column:' => '',
|
'%s hours' => '%s ώρες',
|
||||||
// 'Position:' => '',
|
'Time spent:' => 'χρόνος που καταναλώθηκε:',
|
||||||
// 'Creator:' => '',
|
'Created:' => 'Δημιουργήθηκε:',
|
||||||
// 'Time estimated:' => '',
|
'Modified:' => 'Διορθώθηκε:',
|
||||||
// '%s hours' => '',
|
'Completed:' => 'Ολοκληρώθηκε:',
|
||||||
// 'Time spent:' => '',
|
'Started:' => 'Ξεκίνησε:',
|
||||||
// 'Created:' => '',
|
'Moved:' => 'Μετακινήθηκε:',
|
||||||
// 'Modified:' => '',
|
'Task #%d' => 'Εργασία #%d',
|
||||||
// 'Completed:' => '',
|
'Date and time format' => 'Μορφή ημερομηνίας και ώρας',
|
||||||
// 'Started:' => '',
|
'Time format' => 'Μορφή ώρας',
|
||||||
// 'Moved:' => '',
|
'Start date: ' => 'Ημερομηνία έναρξης: ',
|
||||||
// 'Task #%d' => '',
|
'End date: ' => 'Ημερομηνία λήξης: ',
|
||||||
// 'Sub-tasks' => '',
|
'New due date: ' => 'Νέα ημερομηνία λήξης: ',
|
||||||
// 'Date and time format' => '',
|
'Start date changed: ' => 'Αλλαγμένη ημερομηνία έναρξης: ',
|
||||||
// 'Time format' => '',
|
'Disable private projects' => 'Απενεργοποίηση ιδιωτικών έργων',
|
||||||
// 'Start date: ' => '',
|
'Do you really want to remove this custom filter: "%s"?' => 'Αφαίρεση αυτού του οριζόμενου από το χρήστη φίλτρου %s ?',
|
||||||
// 'End date: ' => '',
|
'Remove a custom filter' => 'Αφαίρεση του οριζόμενου από το χρήστη φίλτρου',
|
||||||
// 'New due date: ' => '',
|
'User activated successfully.' => 'Ο χρήστης ενεργοποιήθηκε με επιτυχία',
|
||||||
// 'Start date changed: ' => '',
|
'Unable to enable this user.' => 'Δεν είναι δυνατή η ενεργοποίηση του χρήστη',
|
||||||
// 'Disable private projects' => '',
|
'User disabled successfully.' => 'Η απενεργοποίηση του χρήστη έγινε με επιτυχία',
|
||||||
// 'Do you really want to remove this custom filter: "%s"?' => '',
|
'Unable to disable this user.' => 'Δεν είναι δυνατή η απενεργοποίηση του χρήστη',
|
||||||
// 'Remove a custom filter' => '',
|
'All files have been uploaded successfully.' => 'Όλα τα αρχεία ανέβηκαν με επιτυχία',
|
||||||
// 'User activated successfully.' => '',
|
'View uploaded files' => 'Προβολή ανεβασμένων αρχείων',
|
||||||
// 'Unable to enable this user.' => '',
|
'The maximum allowed file size is %sB.' => 'Το μέγιστο μέγεθος αρχείου που επιτρέπεται είναι %sB.',
|
||||||
// 'User disabled successfully.' => '',
|
'Choose files again' => 'Επιλογή κι άλλων αρχείων',
|
||||||
// 'Unable to disable this user.' => '',
|
'Drag and drop your files here' => 'Σύρετε τα αρχεία σας εδώ',
|
||||||
// 'All files have been uploaded successfully.' => '',
|
'choose files' => 'Επιλογή αρχείων',
|
||||||
// 'View uploaded files' => '',
|
'View profile' => 'Προβολή προφίλ',
|
||||||
// 'The maximum allowed file size is %sB.' => '',
|
'Two Factor' => 'Δύο παραγόντων',
|
||||||
// 'Choose files again' => '',
|
'Disable user' => 'Απενεργοποίηση χρήστη',
|
||||||
// 'Drag and drop your files here' => '',
|
'Do you really want to disable this user: "%s"?' => 'Απενεργοποίηση του χρήστη: "%s";',
|
||||||
// 'choose files' => '',
|
'Enable user' => 'Ενεργοποίηση χρήστη',
|
||||||
// 'View profile' => '',
|
'Do you really want to enable this user: "%s"?' => 'Ενεργοποίηση του χρήστη "%s";',
|
||||||
// 'Two Factor' => '',
|
'Download' => 'Κατέβασμα',
|
||||||
// 'Disable user' => '',
|
'Uploaded: %s' => 'Ανέβηκε το αρχείο: %s',
|
||||||
// 'Do you really want to disable this user: "%s"?' => '',
|
'Size: %s' => 'Μέγεθος: %s',
|
||||||
// 'Enable user' => '',
|
'Uploaded by %s' => 'Ανέβασμα από τον χρήστη: %s',
|
||||||
// 'Do you really want to enable this user: "%s"?' => '',
|
'Filename' => 'Όνομα αρχείου',
|
||||||
// 'Download' => '',
|
'Size' => 'Μέγεθος',
|
||||||
// 'Uploaded: %s' => '',
|
'Column created successfully.' => 'Η στήλη δημιουργήθηκε με επιτυχία.',
|
||||||
// 'Size: %s' => '',
|
'Another column with the same name exists in the project' => 'Μια άλλη στήλη με το ίδιο όνομα υπάρχει στο έργο',
|
||||||
// 'Uploaded by %s' => '',
|
'Default filters' => 'Εξ\' ορισμού φίλτρα',
|
||||||
// 'Filename' => '',
|
'Your board doesn\'t have any column!' => 'Το ταμπλό δεν έχει καμία στήλη!!=',
|
||||||
// 'Size' => '',
|
'Change column position' => 'Αλλαγή θέσης στήλης',
|
||||||
// 'Column created successfully.' => '',
|
'Switch to the project overview' => 'Αλλαγή προβολής σε επισκόπηση έργου',
|
||||||
// 'Another column with the same name exists in the project' => '',
|
'User filters' => 'Φίλτρα οριζόμενα από τον χρήστη',
|
||||||
// 'Default filters' => '',
|
'Category filters' => 'Κατηγορία φίλτρων',
|
||||||
// 'Your board doesn\'t have any column!' => '',
|
'Upload a file' => 'Ανέβασμα αρχείου',
|
||||||
// 'Change column position' => '',
|
'View file' => 'Προβολή αρχείου',
|
||||||
// 'Switch to the project overview' => '',
|
'Last activity' => 'Τελευταία δραστηριότητα',
|
||||||
// 'User filters' => '',
|
'Change subtask position' => 'Αλλαγή θέσης υπο-εργασίας',
|
||||||
// 'Category filters' => '',
|
'This value must be greater than %d' => 'Η τιμή πρέπει να είναι μεγαλύτερη από %d',
|
||||||
// 'Upload a file' => '',
|
'Another swimlane with the same name exists in the project' => 'Μια άλλη λωρίδα, με το ίδιο όνομα υπάρχει στο έργο',
|
||||||
// 'There is no attachment at the moment.' => '',
|
'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => 'Παράδειγμα: http://example.kanboard.net/ (χρησιμοποιείται για τη δημιουργία απόλυτων URLs)',
|
||||||
// 'View file' => '',
|
// 'Actions duplicated successfully.' => '',
|
||||||
// 'Last activity' => '',
|
// 'Unable to duplicate actions.' => '',
|
||||||
// 'Change subtask position' => '',
|
// 'Add a new action' => '',
|
||||||
// 'This value must be greater than %d' => '',
|
// 'Import from another project' => '',
|
||||||
// 'Another swimlane with the same name exists in the project' => '',
|
// 'There is no action at the moment.' => '',
|
||||||
// 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => '',
|
// 'Import actions from another project' => '',
|
||||||
|
// 'There is no available project.' => '',
|
||||||
|
// 'Local File' => '',
|
||||||
|
// 'Configuration' => '',
|
||||||
|
// 'PHP version:' => '',
|
||||||
|
// 'PHP SAPI:' => '',
|
||||||
|
// 'OS version:' => '',
|
||||||
|
// 'Database version:' => '',
|
||||||
|
// 'Browser:' => '',
|
||||||
|
// 'Task view' => '',
|
||||||
|
// 'Edit task' => '',
|
||||||
|
// 'Edit description' => '',
|
||||||
|
// 'New internal link' => '',
|
||||||
|
// 'Display list of keyboard shortcuts' => '',
|
||||||
|
// 'Menu' => '',
|
||||||
|
// 'Set start date' => '',
|
||||||
|
// 'Avatar' => '',
|
||||||
|
// 'Upload my avatar image' => '',
|
||||||
|
// 'Remove my image' => '',
|
||||||
|
// 'The OAuth2 state parameter is invalid' => '',
|
||||||
);
|
);
|
||||||
|
|
|
@ -8,7 +8,6 @@ return array(
|
||||||
'Edit' => 'Modificar',
|
'Edit' => 'Modificar',
|
||||||
'remove' => 'suprimir',
|
'remove' => 'suprimir',
|
||||||
'Remove' => 'Suprimir',
|
'Remove' => 'Suprimir',
|
||||||
'Update' => 'Actualizar',
|
|
||||||
'Yes' => 'Sí',
|
'Yes' => 'Sí',
|
||||||
'No' => 'No',
|
'No' => 'No',
|
||||||
'cancel' => 'cancelar',
|
'cancel' => 'cancelar',
|
||||||
|
@ -60,7 +59,6 @@ return array(
|
||||||
'Actions' => 'Acciones',
|
'Actions' => 'Acciones',
|
||||||
'Inactive' => 'Inactivo',
|
'Inactive' => 'Inactivo',
|
||||||
'Active' => 'Activo',
|
'Active' => 'Activo',
|
||||||
'Add this column' => 'Añadir esta columna',
|
|
||||||
'%d tasks on the board' => '%d tareas en el tablero',
|
'%d tasks on the board' => '%d tareas en el tablero',
|
||||||
'%d tasks in total' => '%d tareas en total',
|
'%d tasks in total' => '%d tareas en total',
|
||||||
'Unable to update this board.' => 'No se puede actualizar este tablero.',
|
'Unable to update this board.' => 'No se puede actualizar este tablero.',
|
||||||
|
@ -74,7 +72,6 @@ return array(
|
||||||
'All projects' => 'Todos los proyectos',
|
'All projects' => 'Todos los proyectos',
|
||||||
'Add a new column' => 'Añadir una nueva columna',
|
'Add a new column' => 'Añadir una nueva columna',
|
||||||
'Title' => 'Título',
|
'Title' => 'Título',
|
||||||
'Nobody assigned' => 'Nadie asignado',
|
|
||||||
'Assigned to %s' => 'Asignada a %s',
|
'Assigned to %s' => 'Asignada a %s',
|
||||||
'Remove a column' => 'Suprimir esta columna',
|
'Remove a column' => 'Suprimir esta columna',
|
||||||
'Remove a column from a board' => 'Suprimir una columna de un tablero',
|
'Remove a column from a board' => 'Suprimir una columna de un tablero',
|
||||||
|
@ -168,7 +165,6 @@ return array(
|
||||||
'Task count' => 'Contador de tareas',
|
'Task count' => 'Contador de tareas',
|
||||||
'User' => 'Usuario',
|
'User' => 'Usuario',
|
||||||
'Comments' => 'Comentarios',
|
'Comments' => 'Comentarios',
|
||||||
'Write your text in Markdown' => 'Redacta el texto en Markdown',
|
|
||||||
'Leave a comment' => 'Dejar un comentario',
|
'Leave a comment' => 'Dejar un comentario',
|
||||||
'Comment is required' => 'El comentario es obligatorio',
|
'Comment is required' => 'El comentario es obligatorio',
|
||||||
'Leave a description' => 'Dejar una descripción',
|
'Leave a description' => 'Dejar una descripción',
|
||||||
|
@ -184,7 +180,6 @@ return array(
|
||||||
'Unable to remove this action.' => 'No se puede suprimir esta accción.',
|
'Unable to remove this action.' => 'No se puede suprimir esta accción.',
|
||||||
'Action removed successfully.' => 'La acción ha sido borrada correctamente.',
|
'Action removed successfully.' => 'La acción ha sido borrada correctamente.',
|
||||||
'Automatic actions for the project "%s"' => 'Acciones automatizadas para este proyecto « %s »',
|
'Automatic actions for the project "%s"' => 'Acciones automatizadas para este proyecto « %s »',
|
||||||
'Defined actions' => 'Acciones definidas',
|
|
||||||
'Add an action' => 'Agregar una acción',
|
'Add an action' => 'Agregar una acción',
|
||||||
'Event name' => 'Nombre del evento',
|
'Event name' => 'Nombre del evento',
|
||||||
'Action name' => 'Nombre de la acción',
|
'Action name' => 'Nombre de la acción',
|
||||||
|
@ -194,7 +189,6 @@ return array(
|
||||||
'When the selected event occurs execute the corresponding action.' => 'Cuando tiene lugar el evento seleccionado, ejecutar la acción correspondiente.',
|
'When the selected event occurs execute the corresponding action.' => 'Cuando tiene lugar el evento seleccionado, ejecutar la acción correspondiente.',
|
||||||
'Next step' => 'Etapa siguiente',
|
'Next step' => 'Etapa siguiente',
|
||||||
'Define action parameters' => 'Definición de los parametros de la acción',
|
'Define action parameters' => 'Definición de los parametros de la acción',
|
||||||
'Save this action' => 'Guardar esta acción',
|
|
||||||
'Do you really want to remove this action: "%s"?' => '¿Realmente desea suprimir esta acción « %s » ?',
|
'Do you really want to remove this action: "%s"?' => '¿Realmente desea suprimir esta acción « %s » ?',
|
||||||
'Remove an automatic action' => 'Suprimir una acción automatizada',
|
'Remove an automatic action' => 'Suprimir una acción automatizada',
|
||||||
'Assign the task to a specific user' => 'Asignar una tarea a un usuario especifico',
|
'Assign the task to a specific user' => 'Asignar una tarea a un usuario especifico',
|
||||||
|
@ -333,10 +327,10 @@ return array(
|
||||||
'Time tracking:' => 'Control de tiempo:',
|
'Time tracking:' => 'Control de tiempo:',
|
||||||
'New sub-task' => 'Nueva subtarea',
|
'New sub-task' => 'Nueva subtarea',
|
||||||
'New attachment added "%s"' => 'Nuevo adjunto agregado "%s"',
|
'New attachment added "%s"' => 'Nuevo adjunto agregado "%s"',
|
||||||
'Comment updated' => 'Comentario actualizado',
|
|
||||||
'New comment posted by %s' => 'Nuevo comentario agregado por %s',
|
'New comment posted by %s' => 'Nuevo comentario agregado por %s',
|
||||||
'New attachment' => 'Nuevo adjunto',
|
'New attachment' => 'Nuevo adjunto',
|
||||||
'New comment' => 'Nuevo comentario',
|
'New comment' => 'Nuevo comentario',
|
||||||
|
'Comment updated' => 'Comentario actualizado',
|
||||||
'New subtask' => 'Nueva subtarea',
|
'New subtask' => 'Nueva subtarea',
|
||||||
'Subtask updated' => 'Subtarea actualizada',
|
'Subtask updated' => 'Subtarea actualizada',
|
||||||
'Task updated' => 'Tarea actualizada',
|
'Task updated' => 'Tarea actualizada',
|
||||||
|
@ -436,7 +430,6 @@ return array(
|
||||||
'ISO format is always accepted, example: "%s" and "%s"' => 'El formato ISO siempre es aceptado, ejemplo: "%s" y "%s"',
|
'ISO format is always accepted, example: "%s" and "%s"' => 'El formato ISO siempre es aceptado, ejemplo: "%s" y "%s"',
|
||||||
'New private project' => 'Nuevo proyecto privado',
|
'New private project' => 'Nuevo proyecto privado',
|
||||||
'This project is private' => 'Este proyecto es privado',
|
'This project is private' => 'Este proyecto es privado',
|
||||||
'Type here to create a new sub-task' => 'Escriba aquí para crear una nueva sub-tarea',
|
|
||||||
'Add' => 'Añadir',
|
'Add' => 'Añadir',
|
||||||
'Start date' => 'Fecha de inicio',
|
'Start date' => 'Fecha de inicio',
|
||||||
'Time estimated' => 'Tiempo estimado',
|
'Time estimated' => 'Tiempo estimado',
|
||||||
|
@ -487,9 +480,6 @@ return array(
|
||||||
'Daily project summary export for "%s"' => 'Exportar sumario diario del proyecto para "%s"',
|
'Daily project summary export for "%s"' => 'Exportar sumario diario del proyecto para "%s"',
|
||||||
'Exports' => 'Exportaciones',
|
'Exports' => 'Exportaciones',
|
||||||
'This export contains the number of tasks per column grouped per day.' => 'Esta exportación contiene el número de tereas por columna agrupada por día.',
|
'This export contains the number of tasks per column grouped per day.' => 'Esta exportación contiene el número de tereas por columna agrupada por día.',
|
||||||
'Nothing to preview...' => 'Nada que previsualizar...',
|
|
||||||
'Preview' => 'Previsualizar',
|
|
||||||
'Write' => 'Grabar',
|
|
||||||
'Active swimlanes' => 'Calles activas',
|
'Active swimlanes' => 'Calles activas',
|
||||||
'Add a new swimlane' => 'Añadir nueva calle',
|
'Add a new swimlane' => 'Añadir nueva calle',
|
||||||
'Change default swimlane' => 'Cambiar la calle por defecto',
|
'Change default swimlane' => 'Cambiar la calle por defecto',
|
||||||
|
@ -543,7 +533,6 @@ return array(
|
||||||
'Task age in days' => 'Edad de la tarea en días',
|
'Task age in days' => 'Edad de la tarea en días',
|
||||||
'Days in this column' => 'Días en esta columna',
|
'Days in this column' => 'Días en esta columna',
|
||||||
'%dd' => '%dd',
|
'%dd' => '%dd',
|
||||||
'Add a link' => 'Añadir enlace',
|
|
||||||
'Add a new link' => 'Añadir nuevo enlace',
|
'Add a new link' => 'Añadir nuevo enlace',
|
||||||
'Do you really want to remove this link: "%s"?' => '¿Realmente quiere quitar este enlace: "%s"?',
|
'Do you really want to remove this link: "%s"?' => '¿Realmente quiere quitar este enlace: "%s"?',
|
||||||
'Do you really want to remove this link with task #%d?' => '¿Realmente quiere quitar este enlace con esta tarea: #%d?',
|
'Do you really want to remove this link with task #%d?' => '¿Realmente quiere quitar este enlace con esta tarea: #%d?',
|
||||||
|
@ -734,7 +723,7 @@ return array(
|
||||||
'Time spent changed: %sh' => 'Se ha cambiado el tiempo empleado: %sh',
|
'Time spent changed: %sh' => 'Se ha cambiado el tiempo empleado: %sh',
|
||||||
'Time estimated changed: %sh' => 'Se ha cambiado el tiempo estimado: %sh',
|
'Time estimated changed: %sh' => 'Se ha cambiado el tiempo estimado: %sh',
|
||||||
'The field "%s" have been updated' => 'Se ha actualizado el campo "%s"',
|
'The field "%s" have been updated' => 'Se ha actualizado el campo "%s"',
|
||||||
'The description have been modified' => 'Se ha modificado la descripción',
|
'The description has been modified:' => 'Se ha modificado la descripción',
|
||||||
'Do you really want to close the task "%s" as well as all subtasks?' => '¿De verdad que quiere cerra la tarea "%s" así como todas las subtareas?',
|
'Do you really want to close the task "%s" as well as all subtasks?' => '¿De verdad que quiere cerra la tarea "%s" así como todas las subtareas?',
|
||||||
'I want to receive notifications for:' => 'Deseo recibir notificaciones para:',
|
'I want to receive notifications for:' => 'Deseo recibir notificaciones para:',
|
||||||
'All tasks' => 'Todas las tareas',
|
'All tasks' => 'Todas las tareas',
|
||||||
|
@ -753,8 +742,6 @@ return array(
|
||||||
'My activity stream' => 'Mi flujo de actividad',
|
'My activity stream' => 'Mi flujo de actividad',
|
||||||
'My calendar' => 'Mi calendario',
|
'My calendar' => 'Mi calendario',
|
||||||
'Search tasks' => 'Buscar tareas',
|
'Search tasks' => 'Buscar tareas',
|
||||||
'Back to the calendar' => 'Volver al calendario',
|
|
||||||
'Filters' => 'Filtros',
|
|
||||||
'Reset filters' => 'Limpiar filtros',
|
'Reset filters' => 'Limpiar filtros',
|
||||||
'My tasks due tomorrow' => 'Mis tareas a entregar mañana',
|
'My tasks due tomorrow' => 'Mis tareas a entregar mañana',
|
||||||
'Tasks due today' => 'Tareas a antregar hoy',
|
'Tasks due today' => 'Tareas a antregar hoy',
|
||||||
|
@ -854,7 +841,6 @@ return array(
|
||||||
'End date:' => 'Fecha final',
|
'End date:' => 'Fecha final',
|
||||||
'There is no start date or end date for this project.' => 'No existe fecha de inicio o de fin para este proyecto.',
|
'There is no start date or end date for this project.' => 'No existe fecha de inicio o de fin para este proyecto.',
|
||||||
'Projects Gantt chart' => 'Diagramas de Gantt de los proyectos',
|
'Projects Gantt chart' => 'Diagramas de Gantt de los proyectos',
|
||||||
'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',
|
'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',
|
'Task link creation or modification' => 'Creación o modificación de enlace a tarea',
|
||||||
'Milestone' => 'Hito',
|
'Milestone' => 'Hito',
|
||||||
|
@ -906,7 +892,6 @@ return array(
|
||||||
'Shared' => 'Compartido',
|
'Shared' => 'Compartido',
|
||||||
'Owner' => 'Dueño',
|
'Owner' => 'Dueño',
|
||||||
'Unread notifications' => 'Notificaciones sin leer',
|
'Unread notifications' => 'Notificaciones sin leer',
|
||||||
'My filters' => 'Mis filtros',
|
|
||||||
'Notification methods:' => 'Métodos de notificación',
|
'Notification methods:' => 'Métodos de notificación',
|
||||||
'Import tasks from CSV file' => 'Importar tareas desde archivo CSV',
|
'Import tasks from CSV file' => 'Importar tareas desde archivo CSV',
|
||||||
'Unable to read your file' => 'No es posible leer el archivo',
|
'Unable to read your file' => 'No es posible leer el archivo',
|
||||||
|
@ -930,7 +915,7 @@ return array(
|
||||||
'change sorting' => 'Cambiar orden',
|
'change sorting' => 'Cambiar orden',
|
||||||
'Tasks Importation' => 'Importación de tareas',
|
'Tasks Importation' => 'Importación de tareas',
|
||||||
'Delimiter' => 'Delimitador',
|
'Delimiter' => 'Delimitador',
|
||||||
// 'Enclosure' => '',
|
'Enclosure' => 'Recinto',
|
||||||
'CSV File' => 'Archivo CSV',
|
'CSV File' => 'Archivo CSV',
|
||||||
'Instructions' => 'Indicaciones',
|
'Instructions' => 'Indicaciones',
|
||||||
'Your file must use the predefined CSV format' => 'Su archivo debe utilizar el formato CSV predeterminado',
|
'Your file must use the predefined CSV format' => 'Su archivo debe utilizar el formato CSV predeterminado',
|
||||||
|
@ -944,6 +929,7 @@ return array(
|
||||||
'Usernames must be lowercase and unique' => 'Los nombres de usuario deben ser únicos y contener sólo minúsculas',
|
'Usernames must be lowercase and unique' => 'Los nombres de usuario deben ser únicos y contener sólo minúsculas',
|
||||||
'Passwords will be encrypted if present' => 'Las contraseñas serán cifradas si es que existen',
|
'Passwords will be encrypted if present' => 'Las contraseñas serán cifradas si es que existen',
|
||||||
'%s attached a new file to the task %s' => '%s adjuntó un nuevo archivo a la tarea %s',
|
'%s attached a new file to the task %s' => '%s adjuntó un nuevo archivo a la tarea %s',
|
||||||
|
'Link type' => 'Tipo de enlace',
|
||||||
'Assign automatically a category based on a link' => 'Asignar una categoría automáticamente basado en un enlace',
|
'Assign automatically a category based on a link' => 'Asignar una categoría automáticamente basado en un enlace',
|
||||||
'BAM - Konvertible Mark' => 'BAM - marco convertible',
|
'BAM - Konvertible Mark' => 'BAM - marco convertible',
|
||||||
'Assignee Username' => 'Nombre de usuario del concesionario',
|
'Assignee Username' => 'Nombre de usuario del concesionario',
|
||||||
|
@ -995,19 +981,19 @@ return array(
|
||||||
'Enter group name...' => 'Ingresa el nombre del grupo...',
|
'Enter group name...' => 'Ingresa el nombre del grupo...',
|
||||||
'Role:' => 'Rol:',
|
'Role:' => 'Rol:',
|
||||||
'Project members' => 'Miembros del proyecto',
|
'Project members' => 'Miembros del proyecto',
|
||||||
// 'Compare hours for "%s"' => '',
|
'Compare hours for "%s"' => 'Compara horas con "%s"',
|
||||||
'%s mentioned you in the task #%d' => '%s te mencionó en la tarea #%d',
|
'%s mentioned you in the task #%d' => '%s te mencionó en la tarea #%d',
|
||||||
'%s mentioned you in a comment on the task #%d' => '%s te mencionó en un comentario en la tarea #%d',
|
'%s mentioned you in a comment on the task #%d' => '%s te mencionó en un comentario en la tarea #%d',
|
||||||
'You were mentioned in the task #%d' => 'Te mencionaron en la tarea #%d',
|
'You were mentioned in the task #%d' => 'Te mencionaron en la tarea #%d',
|
||||||
'You were mentioned in a comment on the task #%d' => 'Te mencionaron en un comentario en la tarea #%d',
|
'You were mentioned in a comment on the task #%d' => 'Te mencionaron en un comentario en la tarea #%d',
|
||||||
'Mentioned' => 'Mencionado',
|
'Mentioned' => 'Mencionado',
|
||||||
// 'Compare Estimated Time vs Actual Time' => '',
|
'Compare Estimated Time vs Actual Time' => 'Comparar Tiempo Estimado vs Tiempo Actual',
|
||||||
// 'Estimated hours: ' => '',
|
'Estimated hours: ' => 'Horas estimadas: ',
|
||||||
// 'Actual hours: ' => '',
|
'Actual hours: ' => 'Horas actuales: ',
|
||||||
// 'Hours Spent' => '',
|
'Hours Spent' => 'Horas gastadas',
|
||||||
// 'Hours Estimated' => '',
|
'Hours Estimated' => 'Hora Estimada',
|
||||||
// 'Estimated Time' => '',
|
'Estimated Time' => 'Tiempo Estimado',
|
||||||
// 'Actual Time' => '',
|
'Actual Time' => 'Tiempo Actual',
|
||||||
'Estimated vs actual time' => 'Tiempo estimado vs real',
|
'Estimated vs actual time' => 'Tiempo estimado vs real',
|
||||||
'RUB - Russian Ruble' => 'RUB - rublo ruso',
|
'RUB - Russian Ruble' => 'RUB - rublo ruso',
|
||||||
'Assign the task to the person who does the action when the column is changed' => 'Asignar la tarea a la persona que haga la acción al cambiar de columna',
|
'Assign the task to the person who does the action when the column is changed' => 'Asignar la tarea a la persona que haga la acción al cambiar de columna',
|
||||||
|
@ -1025,7 +1011,7 @@ return array(
|
||||||
'Change Password' => 'Cambiar contraseña',
|
'Change Password' => 'Cambiar contraseña',
|
||||||
'To reset your password click on this link:' => 'Para cambiar tu contraseña haz clic en el siguiente enlace:',
|
'To reset your password click on this link:' => 'Para cambiar tu contraseña haz clic en el siguiente enlace:',
|
||||||
'Last Password Reset' => 'Último cambio de contraseña',
|
'Last Password Reset' => 'Último cambio de contraseña',
|
||||||
// 'The password has never been reinitialized.' => '',
|
'The password has never been reinitialized.' => 'La contraseña nunca se ha reinicializado.',
|
||||||
'Creation' => 'Creación',
|
'Creation' => 'Creación',
|
||||||
'Expiration' => 'Vencimiento',
|
'Expiration' => 'Vencimiento',
|
||||||
'Password reset history' => 'Historial de restablecimiento de contraseña',
|
'Password reset history' => 'Historial de restablecimiento de contraseña',
|
||||||
|
@ -1053,7 +1039,6 @@ return array(
|
||||||
'Close a task when there is no activity' => 'Cerrar tarea cuando no haya actividad',
|
'Close a task when there is no activity' => 'Cerrar tarea cuando no haya actividad',
|
||||||
'Duration in days' => 'Duración en días',
|
'Duration in days' => 'Duración en días',
|
||||||
'Send email when there is no activity on a task' => 'Enviar correo cuando no haya actividad en una tarea',
|
'Send email when there is no activity on a task' => 'Enviar correo cuando no haya actividad en una tarea',
|
||||||
'List of external links' => 'Lista de enlaces externos',
|
|
||||||
'Unable to fetch link information.' => 'No es posible obtener información sobre el enlace',
|
'Unable to fetch link information.' => 'No es posible obtener información sobre el enlace',
|
||||||
'Daily background job for tasks' => 'Tarea de fondo diaria para las tareas',
|
'Daily background job for tasks' => 'Tarea de fondo diaria para las tareas',
|
||||||
'Auto' => 'Automático',
|
'Auto' => 'Automático',
|
||||||
|
@ -1071,9 +1056,7 @@ return array(
|
||||||
'External link' => 'Enlace externo',
|
'External link' => 'Enlace externo',
|
||||||
'Copy and paste your link here...' => 'Copia y pega tu enlace aquí...',
|
'Copy and paste your link here...' => 'Copia y pega tu enlace aquí...',
|
||||||
'URL' => 'URL',
|
'URL' => 'URL',
|
||||||
'There is no external link for the moment.' => 'No existe un enlace externo por el momento',
|
|
||||||
'Internal links' => 'Enlaces internos',
|
'Internal links' => 'Enlaces internos',
|
||||||
'There is no internal link for the moment.' => 'No existe un enlace interno por el momento',
|
|
||||||
'Assign to me' => 'Asignar a mí',
|
'Assign to me' => 'Asignar a mí',
|
||||||
'Me' => 'Yo',
|
'Me' => 'Yo',
|
||||||
'Do not duplicate anything' => 'No duplicar nada',
|
'Do not duplicate anything' => 'No duplicar nada',
|
||||||
|
@ -1081,26 +1064,24 @@ return array(
|
||||||
'Users management' => 'Administración de usuarios',
|
'Users management' => 'Administración de usuarios',
|
||||||
'Groups management' => 'Administración de grupos',
|
'Groups management' => 'Administración de grupos',
|
||||||
'Create from another project' => 'Crear de otro proyecto',
|
'Create from another project' => 'Crear de otro proyecto',
|
||||||
'There is no subtask at the moment.' => 'No existe subtarea por el momento',
|
|
||||||
'open' => 'abierto',
|
'open' => 'abierto',
|
||||||
'closed' => 'cerrado',
|
'closed' => 'cerrado',
|
||||||
'Priority:' => 'Prioridad',
|
'Priority:' => 'Prioridad',
|
||||||
'Reference:' => 'Referencia',
|
'Reference:' => 'Referencia',
|
||||||
// 'Complexity:' => 'Complejidad',
|
'Complexity:' => 'Complejidad:',
|
||||||
// 'Swimlane:' => 'Swimlane',
|
'Swimlane:' => 'Swimlane:',
|
||||||
// 'Column:' => 'Columna',
|
'Column:' => 'Columna:',
|
||||||
// 'Position:' => 'Posición',
|
'Position:' => 'Posición:',
|
||||||
// 'Creator:' => 'Creador',
|
'Creator:' => 'Creador:',
|
||||||
// 'Time estimated:' => '',
|
'Time estimated:' => 'Tiempo estimado:',
|
||||||
'%s hours' => '%s horas',
|
'%s hours' => '%s horas',
|
||||||
// 'Time spent:' => '',
|
'Time spent:' => 'Tiempo gastado:',
|
||||||
'Created:' => 'Creado',
|
'Created:' => 'Creado',
|
||||||
'Modified:' => 'Modificado',
|
'Modified:' => 'Modificado',
|
||||||
'Completed:' => 'Terminado',
|
'Completed:' => 'Terminado',
|
||||||
'Started:' => 'Iniciado',
|
'Started:' => 'Iniciado',
|
||||||
'Moved:' => 'Movido',
|
'Moved:' => 'Movido',
|
||||||
'Task #%d' => 'Tarea #%d',
|
'Task #%d' => 'Tarea #%d',
|
||||||
'Sub-tasks' => 'Subtareas',
|
|
||||||
'Date and time format' => 'Formato de hora y fecha',
|
'Date and time format' => 'Formato de hora y fecha',
|
||||||
'Time format' => 'Formato de hora',
|
'Time format' => 'Formato de hora',
|
||||||
'Start date: ' => 'Fecha de inicio',
|
'Start date: ' => 'Fecha de inicio',
|
||||||
|
@ -1135,17 +1116,41 @@ return array(
|
||||||
'Column created successfully.' => 'Columna creada exitosamente',
|
'Column created successfully.' => 'Columna creada exitosamente',
|
||||||
'Another column with the same name exists in the project' => 'Ya existe una columna con el mismo nombre en el proyecto',
|
'Another column with the same name exists in the project' => 'Ya existe una columna con el mismo nombre en el proyecto',
|
||||||
'Default filters' => 'Filtros predeterminados',
|
'Default filters' => 'Filtros predeterminados',
|
||||||
'Your board doesn\'t have any column!' => '¡Tu tablero no tiene ninguna columna',
|
'Your board doesn\'t have any column!' => '¡Tu tablero no tiene ninguna columna!',
|
||||||
'Change column position' => 'Cambiar posición de la columna',
|
'Change column position' => 'Cambiar posición de la columna',
|
||||||
'Switch to the project overview' => 'Cambiar a vista general del proyecto',
|
'Switch to the project overview' => 'Cambiar a vista general del proyecto',
|
||||||
'User filters' => 'Usar filtros',
|
'User filters' => 'Usar filtros',
|
||||||
'Category filters' => 'Categoría y filtros',
|
'Category filters' => 'Categoría y filtros',
|
||||||
'Upload a file' => 'Subir archivo',
|
'Upload a file' => 'Subir archivo',
|
||||||
'There is no attachment at the moment.' => 'No existe ningún adjunto por el momento',
|
|
||||||
'View file' => 'Ver archivo',
|
'View file' => 'Ver archivo',
|
||||||
'Last activity' => 'Última actividad',
|
'Last activity' => 'Última actividad',
|
||||||
'Change subtask position' => 'Cambiar posición de la subtarea',
|
'Change subtask position' => 'Cambiar posición de la subtarea',
|
||||||
'This value must be greater than %d' => 'Este valor debe ser mayor a %d',
|
'This value must be greater than %d' => 'Este valor debe ser mayor a %d',
|
||||||
'Another swimlane with the same name exists in the project' => 'Ya existe otro swimlane con el mismo nombre en el proyecto',
|
'Another swimlane with the same name exists in the project' => 'Ya existe otro swimlane con el mismo nombre en el proyecto',
|
||||||
'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => 'Ejemplo: http://ejemplo.kanboard.net/ (Usado para generar URLs absolutas)',
|
'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => 'Ejemplo: http://ejemplo.kanboard.net/ (Usado para generar URLs absolutas)',
|
||||||
|
'Actions duplicated successfully.' => 'Acción duplicada con exito.',
|
||||||
|
'Unable to duplicate actions.' => 'No se ha podido duplicar la acción.',
|
||||||
|
'Add a new action' => 'Añadir una nueva acción',
|
||||||
|
'Import from another project' => 'Importar de otro proyecto',
|
||||||
|
'There is no action at the moment.' => 'No hay ninguna acción en este momento.',
|
||||||
|
'Import actions from another project' => 'Importar acciones de otro proyecto',
|
||||||
|
'There is no available project.' => 'No hay proyectos disponibles.',
|
||||||
|
// 'Local File' => '',
|
||||||
|
// 'Configuration' => '',
|
||||||
|
// 'PHP version:' => '',
|
||||||
|
// 'PHP SAPI:' => '',
|
||||||
|
// 'OS version:' => '',
|
||||||
|
// 'Database version:' => '',
|
||||||
|
// 'Browser:' => '',
|
||||||
|
// 'Task view' => '',
|
||||||
|
// 'Edit task' => '',
|
||||||
|
// 'Edit description' => '',
|
||||||
|
// 'New internal link' => '',
|
||||||
|
// 'Display list of keyboard shortcuts' => '',
|
||||||
|
// 'Menu' => '',
|
||||||
|
// 'Set start date' => '',
|
||||||
|
// 'Avatar' => '',
|
||||||
|
// 'Upload my avatar image' => '',
|
||||||
|
// 'Remove my image' => '',
|
||||||
|
// 'The OAuth2 state parameter is invalid' => '',
|
||||||
);
|
);
|
||||||
|
|
|
@ -8,7 +8,6 @@ return array(
|
||||||
'Edit' => 'Muokkaa',
|
'Edit' => 'Muokkaa',
|
||||||
'remove' => 'poista',
|
'remove' => 'poista',
|
||||||
'Remove' => 'Poista',
|
'Remove' => 'Poista',
|
||||||
'Update' => 'Päivitä',
|
|
||||||
'Yes' => 'Kyllä',
|
'Yes' => 'Kyllä',
|
||||||
'No' => 'Ei',
|
'No' => 'Ei',
|
||||||
'cancel' => 'peruuta',
|
'cancel' => 'peruuta',
|
||||||
|
@ -60,7 +59,6 @@ return array(
|
||||||
'Actions' => 'Toiminnot',
|
'Actions' => 'Toiminnot',
|
||||||
'Inactive' => 'Ei aktiivinen',
|
'Inactive' => 'Ei aktiivinen',
|
||||||
'Active' => 'Aktiivinen',
|
'Active' => 'Aktiivinen',
|
||||||
'Add this column' => 'Lisää tämä sarake',
|
|
||||||
'%d tasks on the board' => '%d tehtävää taululla',
|
'%d tasks on the board' => '%d tehtävää taululla',
|
||||||
'%d tasks in total' => '%d tehtävää yhteensä',
|
'%d tasks in total' => '%d tehtävää yhteensä',
|
||||||
'Unable to update this board.' => 'Taulun muuttaminen ei onnistunut.',
|
'Unable to update this board.' => 'Taulun muuttaminen ei onnistunut.',
|
||||||
|
@ -74,7 +72,6 @@ return array(
|
||||||
'All projects' => 'Kaikki projektit',
|
'All projects' => 'Kaikki projektit',
|
||||||
'Add a new column' => 'Lisää uusi sarake',
|
'Add a new column' => 'Lisää uusi sarake',
|
||||||
'Title' => 'Nimi',
|
'Title' => 'Nimi',
|
||||||
'Nobody assigned' => 'Ei suorittajaa',
|
|
||||||
'Assigned to %s' => 'Tekijä: %s',
|
'Assigned to %s' => 'Tekijä: %s',
|
||||||
'Remove a column' => 'Poista sarake',
|
'Remove a column' => 'Poista sarake',
|
||||||
'Remove a column from a board' => 'Poista sarake taulusta',
|
'Remove a column from a board' => 'Poista sarake taulusta',
|
||||||
|
@ -168,7 +165,6 @@ return array(
|
||||||
'Task count' => 'Tehtävien määrä',
|
'Task count' => 'Tehtävien määrä',
|
||||||
'User' => 'Käyttäjät',
|
'User' => 'Käyttäjät',
|
||||||
'Comments' => 'Kommentit',
|
'Comments' => 'Kommentit',
|
||||||
'Write your text in Markdown' => 'Kirjoita kommenttisi Markdownilla',
|
|
||||||
'Leave a comment' => 'Lisää kommentti',
|
'Leave a comment' => 'Lisää kommentti',
|
||||||
'Comment is required' => 'Kommentti vaaditaan',
|
'Comment is required' => 'Kommentti vaaditaan',
|
||||||
'Leave a description' => 'Lisää kuvaus',
|
'Leave a description' => 'Lisää kuvaus',
|
||||||
|
@ -184,7 +180,6 @@ return array(
|
||||||
'Unable to remove this action.' => 'Toiminnon poistaminen epäonnistui.',
|
'Unable to remove this action.' => 'Toiminnon poistaminen epäonnistui.',
|
||||||
'Action removed successfully.' => 'Toiminto poistettiin onnistuneesti.',
|
'Action removed successfully.' => 'Toiminto poistettiin onnistuneesti.',
|
||||||
'Automatic actions for the project "%s"' => 'Automaattiset toiminnot projektille "%s"',
|
'Automatic actions for the project "%s"' => 'Automaattiset toiminnot projektille "%s"',
|
||||||
'Defined actions' => 'Määritellyt toiminnot',
|
|
||||||
// 'Add an action' => '',
|
// 'Add an action' => '',
|
||||||
'Event name' => 'Tapahtuman nimi',
|
'Event name' => 'Tapahtuman nimi',
|
||||||
'Action name' => 'Toiminnon nimi',
|
'Action name' => 'Toiminnon nimi',
|
||||||
|
@ -194,7 +189,6 @@ return array(
|
||||||
'When the selected event occurs execute the corresponding action.' => 'Kun valittu tapahtuma tapahtuu, suorita vastaava toiminto.',
|
'When the selected event occurs execute the corresponding action.' => 'Kun valittu tapahtuma tapahtuu, suorita vastaava toiminto.',
|
||||||
'Next step' => 'Seuraava vaihe',
|
'Next step' => 'Seuraava vaihe',
|
||||||
'Define action parameters' => 'Määrittele toiminnon parametrit',
|
'Define action parameters' => 'Määrittele toiminnon parametrit',
|
||||||
'Save this action' => 'Tallenna toiminto',
|
|
||||||
'Do you really want to remove this action: "%s"?' => 'Oletko varma että haluat poistaa toiminnon "%s"?',
|
'Do you really want to remove this action: "%s"?' => 'Oletko varma että haluat poistaa toiminnon "%s"?',
|
||||||
'Remove an automatic action' => 'Poista automaattintn toiminto',
|
'Remove an automatic action' => 'Poista automaattintn toiminto',
|
||||||
'Assign the task to a specific user' => 'Osoita tehtävä käyttäjälle',
|
'Assign the task to a specific user' => 'Osoita tehtävä käyttäjälle',
|
||||||
|
@ -333,10 +327,10 @@ return array(
|
||||||
'Time tracking:' => 'Ajan seuranta:',
|
'Time tracking:' => 'Ajan seuranta:',
|
||||||
'New sub-task' => 'Uusi alitehtävä',
|
'New sub-task' => 'Uusi alitehtävä',
|
||||||
'New attachment added "%s"' => 'Uusi liite lisätty "%s"',
|
'New attachment added "%s"' => 'Uusi liite lisätty "%s"',
|
||||||
'Comment updated' => 'Kommentti päivitetty',
|
|
||||||
'New comment posted by %s' => '%s lisäsi uuden kommentin',
|
'New comment posted by %s' => '%s lisäsi uuden kommentin',
|
||||||
// 'New attachment' => '',
|
// 'New attachment' => '',
|
||||||
// 'New comment' => '',
|
// 'New comment' => '',
|
||||||
|
'Comment updated' => 'Kommentti päivitetty',
|
||||||
// 'New subtask' => '',
|
// 'New subtask' => '',
|
||||||
// 'Subtask updated' => '',
|
// 'Subtask updated' => '',
|
||||||
// 'Task updated' => '',
|
// 'Task updated' => '',
|
||||||
|
@ -436,7 +430,6 @@ return array(
|
||||||
'ISO format is always accepted, example: "%s" and "%s"' => 'ISO-muoto on aina hyväksytty, esimerkiksi %s ja %s',
|
'ISO format is always accepted, example: "%s" and "%s"' => 'ISO-muoto on aina hyväksytty, esimerkiksi %s ja %s',
|
||||||
'New private project' => 'Uusi yksityinen projekti',
|
'New private project' => 'Uusi yksityinen projekti',
|
||||||
'This project is private' => 'Tämä projekti on yksityinen',
|
'This project is private' => 'Tämä projekti on yksityinen',
|
||||||
'Type here to create a new sub-task' => 'Kirjoita tähän luodaksesi uuden alitehtävän',
|
|
||||||
'Add' => 'Lisää',
|
'Add' => 'Lisää',
|
||||||
'Start date' => 'Aloituspäivä',
|
'Start date' => 'Aloituspäivä',
|
||||||
'Time estimated' => 'Arvioitu aika',
|
'Time estimated' => 'Arvioitu aika',
|
||||||
|
@ -487,9 +480,6 @@ return array(
|
||||||
'Daily project summary export for "%s"' => 'Päivittäisen yhteenvedon vienti kohteeseen "%s"',
|
'Daily project summary export for "%s"' => 'Päivittäisen yhteenvedon vienti kohteeseen "%s"',
|
||||||
'Exports' => 'Viennit',
|
'Exports' => 'Viennit',
|
||||||
'This export contains the number of tasks per column grouped per day.' => 'Tämä tiedosto sisältää tehtäviä sarakkeisiin päiväkohtaisesti ryhmilteltyinä',
|
'This export contains the number of tasks per column grouped per day.' => 'Tämä tiedosto sisältää tehtäviä sarakkeisiin päiväkohtaisesti ryhmilteltyinä',
|
||||||
'Nothing to preview...' => 'Ei esikatselua...',
|
|
||||||
'Preview' => 'Ei esikatselua',
|
|
||||||
'Write' => 'Kirjoita',
|
|
||||||
'Active swimlanes' => 'Aktiiviset kaistat',
|
'Active swimlanes' => 'Aktiiviset kaistat',
|
||||||
'Add a new swimlane' => 'Lisää uusi kaista',
|
'Add a new swimlane' => 'Lisää uusi kaista',
|
||||||
'Change default swimlane' => 'Vaihda oletuskaistaa',
|
'Change default swimlane' => 'Vaihda oletuskaistaa',
|
||||||
|
@ -543,7 +533,6 @@ return array(
|
||||||
// 'Task age in days' => '',
|
// 'Task age in days' => '',
|
||||||
// 'Days in this column' => '',
|
// 'Days in this column' => '',
|
||||||
// '%dd' => '',
|
// '%dd' => '',
|
||||||
// 'Add a link' => '',
|
|
||||||
// 'Add a new link' => '',
|
// 'Add a new link' => '',
|
||||||
// 'Do you really want to remove this link: "%s"?' => '',
|
// 'Do you really want to remove this link: "%s"?' => '',
|
||||||
// 'Do you really want to remove this link with task #%d?' => '',
|
// 'Do you really want to remove this link with task #%d?' => '',
|
||||||
|
@ -734,7 +723,7 @@ return array(
|
||||||
// 'Time spent changed: %sh' => '',
|
// 'Time spent changed: %sh' => '',
|
||||||
// 'Time estimated changed: %sh' => '',
|
// 'Time estimated changed: %sh' => '',
|
||||||
// 'The field "%s" have been updated' => '',
|
// 'The field "%s" have been updated' => '',
|
||||||
// 'The description have been modified' => '',
|
// 'The description has been modified:' => '',
|
||||||
// 'Do you really want to close the task "%s" as well as all subtasks?' => '',
|
// 'Do you really want to close the task "%s" as well as all subtasks?' => '',
|
||||||
// 'I want to receive notifications for:' => '',
|
// 'I want to receive notifications for:' => '',
|
||||||
// 'All tasks' => '',
|
// 'All tasks' => '',
|
||||||
|
@ -753,8 +742,6 @@ return array(
|
||||||
// 'My activity stream' => '',
|
// 'My activity stream' => '',
|
||||||
// 'My calendar' => '',
|
// 'My calendar' => '',
|
||||||
// 'Search tasks' => '',
|
// 'Search tasks' => '',
|
||||||
// 'Back to the calendar' => '',
|
|
||||||
// 'Filters' => '',
|
|
||||||
// 'Reset filters' => '',
|
// 'Reset filters' => '',
|
||||||
// 'My tasks due tomorrow' => '',
|
// 'My tasks due tomorrow' => '',
|
||||||
// 'Tasks due today' => '',
|
// 'Tasks due today' => '',
|
||||||
|
@ -854,7 +841,6 @@ return array(
|
||||||
// 'End date:' => '',
|
// 'End date:' => '',
|
||||||
// 'There is no start date or end date for this project.' => '',
|
// 'There is no start date or end date for this project.' => '',
|
||||||
// 'Projects Gantt chart' => '',
|
// 'Projects Gantt chart' => '',
|
||||||
// 'Link type' => '',
|
|
||||||
// 'Change task color when using a specific task link' => '',
|
// 'Change task color when using a specific task link' => '',
|
||||||
// 'Task link creation or modification' => '',
|
// 'Task link creation or modification' => '',
|
||||||
// 'Milestone' => '',
|
// 'Milestone' => '',
|
||||||
|
@ -906,7 +892,6 @@ return array(
|
||||||
// 'Shared' => '',
|
// 'Shared' => '',
|
||||||
// 'Owner' => '',
|
// 'Owner' => '',
|
||||||
// 'Unread notifications' => '',
|
// 'Unread notifications' => '',
|
||||||
// 'My filters' => '',
|
|
||||||
// 'Notification methods:' => '',
|
// 'Notification methods:' => '',
|
||||||
// 'Import tasks from CSV file' => '',
|
// 'Import tasks from CSV file' => '',
|
||||||
// 'Unable to read your file' => '',
|
// 'Unable to read your file' => '',
|
||||||
|
@ -944,6 +929,7 @@ return array(
|
||||||
// 'Usernames must be lowercase and unique' => '',
|
// 'Usernames must be lowercase and unique' => '',
|
||||||
// 'Passwords will be encrypted if present' => '',
|
// 'Passwords will be encrypted if present' => '',
|
||||||
// '%s attached a new file to the task %s' => '',
|
// '%s attached a new file to the task %s' => '',
|
||||||
|
// 'Link type' => '',
|
||||||
// 'Assign automatically a category based on a link' => '',
|
// 'Assign automatically a category based on a link' => '',
|
||||||
// 'BAM - Konvertible Mark' => '',
|
// 'BAM - Konvertible Mark' => '',
|
||||||
// 'Assignee Username' => '',
|
// 'Assignee Username' => '',
|
||||||
|
@ -1053,7 +1039,6 @@ return array(
|
||||||
// 'Close a task when there is no activity' => '',
|
// 'Close a task when there is no activity' => '',
|
||||||
// 'Duration in days' => '',
|
// 'Duration in days' => '',
|
||||||
// 'Send email when there is no activity on a task' => '',
|
// 'Send email when there is no activity on a task' => '',
|
||||||
// 'List of external links' => '',
|
|
||||||
// 'Unable to fetch link information.' => '',
|
// 'Unable to fetch link information.' => '',
|
||||||
// 'Daily background job for tasks' => '',
|
// 'Daily background job for tasks' => '',
|
||||||
// 'Auto' => '',
|
// 'Auto' => '',
|
||||||
|
@ -1071,9 +1056,7 @@ return array(
|
||||||
// 'External link' => '',
|
// 'External link' => '',
|
||||||
// 'Copy and paste your link here...' => '',
|
// 'Copy and paste your link here...' => '',
|
||||||
// 'URL' => '',
|
// 'URL' => '',
|
||||||
// 'There is no external link for the moment.' => '',
|
|
||||||
// 'Internal links' => '',
|
// 'Internal links' => '',
|
||||||
// 'There is no internal link for the moment.' => '',
|
|
||||||
// 'Assign to me' => '',
|
// 'Assign to me' => '',
|
||||||
// 'Me' => '',
|
// 'Me' => '',
|
||||||
// 'Do not duplicate anything' => '',
|
// 'Do not duplicate anything' => '',
|
||||||
|
@ -1081,7 +1064,6 @@ return array(
|
||||||
// 'Users management' => '',
|
// 'Users management' => '',
|
||||||
// 'Groups management' => '',
|
// 'Groups management' => '',
|
||||||
// 'Create from another project' => '',
|
// 'Create from another project' => '',
|
||||||
// 'There is no subtask at the moment.' => '',
|
|
||||||
// 'open' => '',
|
// 'open' => '',
|
||||||
// 'closed' => '',
|
// 'closed' => '',
|
||||||
// 'Priority:' => '',
|
// 'Priority:' => '',
|
||||||
|
@ -1100,7 +1082,6 @@ return array(
|
||||||
// 'Started:' => '',
|
// 'Started:' => '',
|
||||||
// 'Moved:' => '',
|
// 'Moved:' => '',
|
||||||
// 'Task #%d' => '',
|
// 'Task #%d' => '',
|
||||||
// 'Sub-tasks' => '',
|
|
||||||
// 'Date and time format' => '',
|
// 'Date and time format' => '',
|
||||||
// 'Time format' => '',
|
// 'Time format' => '',
|
||||||
// 'Start date: ' => '',
|
// 'Start date: ' => '',
|
||||||
|
@ -1141,11 +1122,35 @@ return array(
|
||||||
// 'User filters' => '',
|
// 'User filters' => '',
|
||||||
// 'Category filters' => '',
|
// 'Category filters' => '',
|
||||||
// 'Upload a file' => '',
|
// 'Upload a file' => '',
|
||||||
// 'There is no attachment at the moment.' => '',
|
|
||||||
// 'View file' => '',
|
// 'View file' => '',
|
||||||
// 'Last activity' => '',
|
// 'Last activity' => '',
|
||||||
// 'Change subtask position' => '',
|
// 'Change subtask position' => '',
|
||||||
// 'This value must be greater than %d' => '',
|
// 'This value must be greater than %d' => '',
|
||||||
// 'Another swimlane with the same name exists in the project' => '',
|
// 'Another swimlane with the same name exists in the project' => '',
|
||||||
// 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => '',
|
// 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => '',
|
||||||
|
// 'Actions duplicated successfully.' => '',
|
||||||
|
// 'Unable to duplicate actions.' => '',
|
||||||
|
// 'Add a new action' => '',
|
||||||
|
// 'Import from another project' => '',
|
||||||
|
// 'There is no action at the moment.' => '',
|
||||||
|
// 'Import actions from another project' => '',
|
||||||
|
// 'There is no available project.' => '',
|
||||||
|
// 'Local File' => '',
|
||||||
|
// 'Configuration' => '',
|
||||||
|
// 'PHP version:' => '',
|
||||||
|
// 'PHP SAPI:' => '',
|
||||||
|
// 'OS version:' => '',
|
||||||
|
// 'Database version:' => '',
|
||||||
|
// 'Browser:' => '',
|
||||||
|
// 'Task view' => '',
|
||||||
|
// 'Edit task' => '',
|
||||||
|
// 'Edit description' => '',
|
||||||
|
// 'New internal link' => '',
|
||||||
|
// 'Display list of keyboard shortcuts' => '',
|
||||||
|
// 'Menu' => '',
|
||||||
|
// 'Set start date' => '',
|
||||||
|
// 'Avatar' => '',
|
||||||
|
// 'Upload my avatar image' => '',
|
||||||
|
// 'Remove my image' => '',
|
||||||
|
// 'The OAuth2 state parameter is invalid' => '',
|
||||||
);
|
);
|
||||||
|
|
|
@ -8,7 +8,6 @@ return array(
|
||||||
'Edit' => 'Modifier',
|
'Edit' => 'Modifier',
|
||||||
'remove' => 'supprimer',
|
'remove' => 'supprimer',
|
||||||
'Remove' => 'Supprimer',
|
'Remove' => 'Supprimer',
|
||||||
'Update' => 'Mettre à jour',
|
|
||||||
'Yes' => 'Oui',
|
'Yes' => 'Oui',
|
||||||
'No' => 'Non',
|
'No' => 'Non',
|
||||||
'cancel' => 'annuler',
|
'cancel' => 'annuler',
|
||||||
|
@ -60,7 +59,6 @@ return array(
|
||||||
'Actions' => 'Actions',
|
'Actions' => 'Actions',
|
||||||
'Inactive' => 'Inactif',
|
'Inactive' => 'Inactif',
|
||||||
'Active' => 'Actif',
|
'Active' => 'Actif',
|
||||||
'Add this column' => 'Ajouter cette colonne',
|
|
||||||
'%d tasks on the board' => '%d tâches sur le tableau',
|
'%d tasks on the board' => '%d tâches sur le tableau',
|
||||||
'%d tasks in total' => '%d tâches au total',
|
'%d tasks in total' => '%d tâches au total',
|
||||||
'Unable to update this board.' => 'Impossible de mettre à jour ce tableau.',
|
'Unable to update this board.' => 'Impossible de mettre à jour ce tableau.',
|
||||||
|
@ -74,7 +72,6 @@ return array(
|
||||||
'All projects' => 'Tous les projets',
|
'All projects' => 'Tous les projets',
|
||||||
'Add a new column' => 'Ajouter une nouvelle colonne',
|
'Add a new column' => 'Ajouter une nouvelle colonne',
|
||||||
'Title' => 'Titre',
|
'Title' => 'Titre',
|
||||||
'Nobody assigned' => 'Personne assignée',
|
|
||||||
'Assigned to %s' => 'Assigné à %s',
|
'Assigned to %s' => 'Assigné à %s',
|
||||||
'Remove a column' => 'Supprimer une colonne',
|
'Remove a column' => 'Supprimer une colonne',
|
||||||
'Remove a column from a board' => 'Supprimer une colonne d\'un tableau',
|
'Remove a column from a board' => 'Supprimer une colonne d\'un tableau',
|
||||||
|
@ -95,7 +92,7 @@ return array(
|
||||||
'Edit a task' => 'Modifier une tâche',
|
'Edit a task' => 'Modifier une tâche',
|
||||||
'Column' => 'Colonne',
|
'Column' => 'Colonne',
|
||||||
'Color' => 'Couleur',
|
'Color' => 'Couleur',
|
||||||
'Assignee' => 'Personne assigné',
|
'Assignee' => 'Personne assignée',
|
||||||
'Create another task' => 'Créer une autre tâche',
|
'Create another task' => 'Créer une autre tâche',
|
||||||
'New task' => 'Nouvelle tâche',
|
'New task' => 'Nouvelle tâche',
|
||||||
'Open a task' => 'Ouvrir une tâche',
|
'Open a task' => 'Ouvrir une tâche',
|
||||||
|
@ -168,7 +165,6 @@ return array(
|
||||||
'Task count' => 'Nombre de tâches',
|
'Task count' => 'Nombre de tâches',
|
||||||
'User' => 'Utilisateur',
|
'User' => 'Utilisateur',
|
||||||
'Comments' => 'Commentaires',
|
'Comments' => 'Commentaires',
|
||||||
'Write your text in Markdown' => 'Écrivez votre texte en Markdown',
|
|
||||||
'Leave a comment' => 'Laissez un commentaire',
|
'Leave a comment' => 'Laissez un commentaire',
|
||||||
'Comment is required' => 'Le commentaire est obligatoire',
|
'Comment is required' => 'Le commentaire est obligatoire',
|
||||||
'Leave a description' => 'Laissez une description',
|
'Leave a description' => 'Laissez une description',
|
||||||
|
@ -184,7 +180,6 @@ return array(
|
||||||
'Unable to remove this action.' => 'Impossible de supprimer cette action',
|
'Unable to remove this action.' => 'Impossible de supprimer cette action',
|
||||||
'Action removed successfully.' => 'Action supprimée avec succès.',
|
'Action removed successfully.' => 'Action supprimée avec succès.',
|
||||||
'Automatic actions for the project "%s"' => 'Actions automatisées pour le projet « %s »',
|
'Automatic actions for the project "%s"' => 'Actions automatisées pour le projet « %s »',
|
||||||
'Defined actions' => 'Actions définies',
|
|
||||||
'Add an action' => 'Ajouter une action',
|
'Add an action' => 'Ajouter une action',
|
||||||
'Event name' => 'Nom de l\'événement',
|
'Event name' => 'Nom de l\'événement',
|
||||||
'Action name' => 'Nom de l\'action',
|
'Action name' => 'Nom de l\'action',
|
||||||
|
@ -194,7 +189,6 @@ return array(
|
||||||
'When the selected event occurs execute the corresponding action.' => 'Lorsque l\'événement sélectionné se déclenche, exécuter l\'action correspondante.',
|
'When the selected event occurs execute the corresponding action.' => 'Lorsque l\'événement sélectionné se déclenche, exécuter l\'action correspondante.',
|
||||||
'Next step' => 'Étape suivante',
|
'Next step' => 'Étape suivante',
|
||||||
'Define action parameters' => 'Définition des paramètres de l\'action',
|
'Define action parameters' => 'Définition des paramètres de l\'action',
|
||||||
'Save this action' => 'Sauvegarder cette action',
|
|
||||||
'Do you really want to remove this action: "%s"?' => 'Voulez-vous vraiment supprimer cette action « %s » ?',
|
'Do you really want to remove this action: "%s"?' => 'Voulez-vous vraiment supprimer cette action « %s » ?',
|
||||||
'Remove an automatic action' => 'Supprimer une action automatisée',
|
'Remove an automatic action' => 'Supprimer une action automatisée',
|
||||||
'Assign the task to a specific user' => 'Assigner la tâche à un utilisateur spécifique',
|
'Assign the task to a specific user' => 'Assigner la tâche à un utilisateur spécifique',
|
||||||
|
@ -333,14 +327,12 @@ return array(
|
||||||
'Time tracking:' => 'Gestion du temps :',
|
'Time tracking:' => 'Gestion du temps :',
|
||||||
'New sub-task' => 'Nouvelle sous-tâche',
|
'New sub-task' => 'Nouvelle sous-tâche',
|
||||||
'New attachment added "%s"' => 'Nouvelle pièce-jointe ajoutée « %s »',
|
'New attachment added "%s"' => 'Nouvelle pièce-jointe ajoutée « %s »',
|
||||||
'Comment updated' => 'Commentaire ajouté',
|
|
||||||
'New comment posted by %s' => 'Nouveau commentaire ajouté par « %s »',
|
'New comment posted by %s' => 'Nouveau commentaire ajouté par « %s »',
|
||||||
'New attachment' => 'Nouveau document',
|
'New attachment' => 'Nouveau document',
|
||||||
'New comment' => 'Nouveau commentaire',
|
'New comment' => 'Nouveau commentaire',
|
||||||
'Comment updated' => 'Commentaire mis à jour',
|
'Comment updated' => 'Commentaire mis à jour',
|
||||||
'New subtask' => 'Nouvelle sous-tâche',
|
'New subtask' => 'Nouvelle sous-tâche',
|
||||||
'Subtask updated' => 'Sous-tâche mise à jour',
|
'Subtask updated' => 'Sous-tâche mise à jour',
|
||||||
'New task' => 'Nouvelle tâche',
|
|
||||||
'Task updated' => 'Tâche mise à jour',
|
'Task updated' => 'Tâche mise à jour',
|
||||||
'Task closed' => 'Tâche fermée',
|
'Task closed' => 'Tâche fermée',
|
||||||
'Task opened' => 'Tâche ouverte',
|
'Task opened' => 'Tâche ouverte',
|
||||||
|
@ -438,7 +430,6 @@ return array(
|
||||||
'ISO format is always accepted, example: "%s" and "%s"' => 'Le format ISO est toujours accepté, exemple : « %s » et « %s »',
|
'ISO format is always accepted, example: "%s" and "%s"' => 'Le format ISO est toujours accepté, exemple : « %s » et « %s »',
|
||||||
'New private project' => 'Nouveau projet privé',
|
'New private project' => 'Nouveau projet privé',
|
||||||
'This project is private' => 'Ce projet est privé',
|
'This project is private' => 'Ce projet est privé',
|
||||||
'Type here to create a new sub-task' => 'Créer une sous-tâche en écrivant le titre ici',
|
|
||||||
'Add' => 'Ajouter',
|
'Add' => 'Ajouter',
|
||||||
'Start date' => 'Date de début',
|
'Start date' => 'Date de début',
|
||||||
'Time estimated' => 'Temps estimé',
|
'Time estimated' => 'Temps estimé',
|
||||||
|
@ -489,9 +480,6 @@ return array(
|
||||||
'Daily project summary export for "%s"' => 'Export du résumé quotidien du projet pour « %s »',
|
'Daily project summary export for "%s"' => 'Export du résumé quotidien du projet pour « %s »',
|
||||||
'Exports' => 'Exports',
|
'Exports' => 'Exports',
|
||||||
'This export contains the number of tasks per column grouped per day.' => 'Cet export contient le nombre de tâches par colonne groupé par jour.',
|
'This export contains the number of tasks per column grouped per day.' => 'Cet export contient le nombre de tâches par colonne groupé par jour.',
|
||||||
'Nothing to preview...' => 'Rien à prévisualiser...',
|
|
||||||
'Preview' => 'Prévisualiser',
|
|
||||||
'Write' => 'Écrire',
|
|
||||||
'Active swimlanes' => 'Swimlanes actives',
|
'Active swimlanes' => 'Swimlanes actives',
|
||||||
'Add a new swimlane' => 'Ajouter une nouvelle swimlane',
|
'Add a new swimlane' => 'Ajouter une nouvelle swimlane',
|
||||||
'Change default swimlane' => 'Modifier la swimlane par défaut',
|
'Change default swimlane' => 'Modifier la swimlane par défaut',
|
||||||
|
@ -545,7 +533,6 @@ return array(
|
||||||
'Task age in days' => 'Âge de la tâche en jours',
|
'Task age in days' => 'Âge de la tâche en jours',
|
||||||
'Days in this column' => 'Jours dans cette colonne',
|
'Days in this column' => 'Jours dans cette colonne',
|
||||||
'%dd' => '%dj',
|
'%dd' => '%dj',
|
||||||
'Add a link' => 'Ajouter un lien',
|
|
||||||
'Add a new link' => 'Ajouter un nouveau lien',
|
'Add a new link' => 'Ajouter un nouveau lien',
|
||||||
'Do you really want to remove this link: "%s"?' => 'Voulez-vous vraiment supprimer ce lien : « %s » ?',
|
'Do you really want to remove this link: "%s"?' => 'Voulez-vous vraiment supprimer ce lien : « %s » ?',
|
||||||
'Do you really want to remove this link with task #%d?' => 'Voulez-vous vraiment supprimer ce lien avec la tâche n°%d ?',
|
'Do you really want to remove this link with task #%d?' => 'Voulez-vous vraiment supprimer ce lien avec la tâche n°%d ?',
|
||||||
|
@ -736,7 +723,7 @@ return array(
|
||||||
'Time spent changed: %sh' => 'Le temps passé a été changé : %sh',
|
'Time spent changed: %sh' => 'Le temps passé a été changé : %sh',
|
||||||
'Time estimated changed: %sh' => 'Le temps estimé a été changé : %sh',
|
'Time estimated changed: %sh' => 'Le temps estimé a été changé : %sh',
|
||||||
'The field "%s" have been updated' => 'Le champ « %s » a été mis à jour',
|
'The field "%s" have been updated' => 'Le champ « %s » a été mis à jour',
|
||||||
'The description have been modified' => 'La description a été modifiée',
|
'The description has been modified:' => 'La description a été modifiée',
|
||||||
'Do you really want to close the task "%s" as well as all subtasks?' => 'Voulez-vous vraiment fermer la tâche « %s » ainsi que toutes ses sous-tâches ?',
|
'Do you really want to close the task "%s" as well as all subtasks?' => 'Voulez-vous vraiment fermer la tâche « %s » ainsi que toutes ses sous-tâches ?',
|
||||||
'I want to receive notifications for:' => 'Je veux reçevoir les notifications pour :',
|
'I want to receive notifications for:' => 'Je veux reçevoir les notifications pour :',
|
||||||
'All tasks' => 'Toutes les Tâches',
|
'All tasks' => 'Toutes les Tâches',
|
||||||
|
@ -755,8 +742,6 @@ return array(
|
||||||
'My activity stream' => 'Mon flux d\'activité',
|
'My activity stream' => 'Mon flux d\'activité',
|
||||||
'My calendar' => 'Mon agenda',
|
'My calendar' => 'Mon agenda',
|
||||||
'Search tasks' => 'Rechercher des tâches',
|
'Search tasks' => 'Rechercher des tâches',
|
||||||
'Back to the calendar' => 'Retour au calendrier',
|
|
||||||
'Filters' => 'Filtres',
|
|
||||||
'Reset filters' => 'Réinitialiser les filtres',
|
'Reset filters' => 'Réinitialiser les filtres',
|
||||||
'My tasks due tomorrow' => 'Mes tâches qui arrivent à échéance demain',
|
'My tasks due tomorrow' => 'Mes tâches qui arrivent à échéance demain',
|
||||||
'Tasks due today' => 'Tâches qui arrivent à échéance aujourd\'hui',
|
'Tasks due today' => 'Tâches qui arrivent à échéance aujourd\'hui',
|
||||||
|
@ -856,7 +841,6 @@ return array(
|
||||||
'End date:' => 'Date de fin :',
|
'End date:' => 'Date de fin :',
|
||||||
'There is no start date or end date for this project.' => 'Il n\'y a pas de date de début ou de date de fin pour ce projet.',
|
'There is no start date or end date for this project.' => 'Il n\'y a pas de date de début ou de date de fin pour ce projet.',
|
||||||
'Projects Gantt chart' => 'Diagramme de Gantt des projets',
|
'Projects Gantt chart' => 'Diagramme de Gantt des projets',
|
||||||
'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é',
|
'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',
|
'Task link creation or modification' => 'Création ou modification d\'un lien sur une tâche',
|
||||||
'Milestone' => 'Étape importante',
|
'Milestone' => 'Étape importante',
|
||||||
|
@ -908,7 +892,6 @@ return array(
|
||||||
'Shared' => 'Partagé',
|
'Shared' => 'Partagé',
|
||||||
'Owner' => 'Propriétaire',
|
'Owner' => 'Propriétaire',
|
||||||
'Unread notifications' => 'Notifications non lus',
|
'Unread notifications' => 'Notifications non lus',
|
||||||
'My filters' => 'Mes filtres',
|
|
||||||
'Notification methods:' => 'Méthodes de notifications :',
|
'Notification methods:' => 'Méthodes de notifications :',
|
||||||
'Import tasks from CSV file' => 'Importer les tâches depuis un fichier CSV',
|
'Import tasks from CSV file' => 'Importer les tâches depuis un fichier CSV',
|
||||||
'Unable to read your file' => 'Impossible de lire votre fichier',
|
'Unable to read your file' => 'Impossible de lire votre fichier',
|
||||||
|
@ -1038,7 +1021,7 @@ return array(
|
||||||
'Close all tasks of this column' => 'Fermer toutes les tâches de cette colonne',
|
'Close all tasks of this column' => 'Fermer toutes les tâches de cette colonne',
|
||||||
'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => 'Aucun plugin n\'a enregistré une méthode de notification de projet. Vous pouvez toujours configurer les notifications individuelles dans votre profil d\'utilisateur.',
|
'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => 'Aucun plugin n\'a enregistré une méthode de notification de projet. Vous pouvez toujours configurer les notifications individuelles dans votre profil d\'utilisateur.',
|
||||||
'My dashboard' => 'Mon tableau de bord',
|
'My dashboard' => 'Mon tableau de bord',
|
||||||
'My profile' => 'Mon profile',
|
'My profile' => 'Mon profil',
|
||||||
'Project owner: ' => 'Responsable du projet : ',
|
'Project owner: ' => 'Responsable du projet : ',
|
||||||
'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => 'L\'identifiant du projet est optionnel et doit être alphanumérique, example: MONPROJET.',
|
'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => 'L\'identifiant du projet est optionnel et doit être alphanumérique, example: MONPROJET.',
|
||||||
'Project owner' => 'Responsable du projet',
|
'Project owner' => 'Responsable du projet',
|
||||||
|
@ -1056,7 +1039,6 @@ return array(
|
||||||
'Close a task when there is no activity' => 'Fermer une tâche sans activité',
|
'Close a task when there is no activity' => 'Fermer une tâche sans activité',
|
||||||
'Duration in days' => 'Durée en jours',
|
'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',
|
'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.',
|
'Unable to fetch link information.' => 'Impossible de récupérer les informations sur le lien.',
|
||||||
'Daily background job for tasks' => 'Tâche planifiée quotidienne pour les tâches',
|
'Daily background job for tasks' => 'Tâche planifiée quotidienne pour les tâches',
|
||||||
'Auto' => 'Auto',
|
'Auto' => 'Auto',
|
||||||
|
@ -1074,9 +1056,7 @@ return array(
|
||||||
'External link' => 'Lien externe',
|
'External link' => 'Lien externe',
|
||||||
'Copy and paste your link here...' => 'Copier-coller vôtre lien ici...',
|
'Copy and paste your link here...' => 'Copier-coller vôtre lien ici...',
|
||||||
'URL' => 'URL',
|
'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',
|
'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',
|
'Assign to me' => 'Assigner à moi',
|
||||||
'Me' => 'Moi',
|
'Me' => 'Moi',
|
||||||
'Do not duplicate anything' => 'Ne rien dupliquer',
|
'Do not duplicate anything' => 'Ne rien dupliquer',
|
||||||
|
@ -1084,7 +1064,6 @@ return array(
|
||||||
'Users management' => 'Gestion des utilisateurs',
|
'Users management' => 'Gestion des utilisateurs',
|
||||||
'Groups management' => 'Gestion des groupes',
|
'Groups management' => 'Gestion des groupes',
|
||||||
'Create from another project' => 'Créer depuis un autre projet',
|
'Create from another project' => 'Créer depuis un autre projet',
|
||||||
'There is no subtask at the moment.' => 'Il n\'y a aucune sous-tâche pour le moment.',
|
|
||||||
'open' => 'ouvert',
|
'open' => 'ouvert',
|
||||||
'closed' => 'fermé',
|
'closed' => 'fermé',
|
||||||
'Priority:' => 'Priorité :',
|
'Priority:' => 'Priorité :',
|
||||||
|
@ -1103,7 +1082,6 @@ return array(
|
||||||
'Started:' => 'Commençé le :',
|
'Started:' => 'Commençé le :',
|
||||||
'Moved:' => 'Déplacé le : ',
|
'Moved:' => 'Déplacé le : ',
|
||||||
'Task #%d' => 'Tâche n°%d',
|
'Task #%d' => 'Tâche n°%d',
|
||||||
'Sub-tasks' => 'Sous-tâches',
|
|
||||||
'Date and time format' => 'Format de la date et de l\'heure',
|
'Date and time format' => 'Format de la date et de l\'heure',
|
||||||
'Time format' => 'Format de l\'heure',
|
'Time format' => 'Format de l\'heure',
|
||||||
'Start date: ' => 'Date de début : ',
|
'Start date: ' => 'Date de début : ',
|
||||||
|
@ -1123,7 +1101,7 @@ return array(
|
||||||
'Choose files again' => 'Choisir de nouveau des fichiers',
|
'Choose files again' => 'Choisir de nouveau des fichiers',
|
||||||
'Drag and drop your files here' => 'Glissez-déposez vos fichiers ici',
|
'Drag and drop your files here' => 'Glissez-déposez vos fichiers ici',
|
||||||
'choose files' => 'choisissez des fichiers',
|
'choose files' => 'choisissez des fichiers',
|
||||||
'View profile' => 'Voir le profile',
|
'View profile' => 'Voir le profil',
|
||||||
'Two Factor' => 'Deux-Facteurs',
|
'Two Factor' => 'Deux-Facteurs',
|
||||||
'Disable user' => 'Désactiver l\'utilisateur',
|
'Disable user' => 'Désactiver l\'utilisateur',
|
||||||
'Do you really want to disable this user: "%s"?' => 'Voulez-vous vraiment désactiver cet utilisateur : « %s » ?',
|
'Do you really want to disable this user: "%s"?' => 'Voulez-vous vraiment désactiver cet utilisateur : « %s » ?',
|
||||||
|
@ -1144,11 +1122,35 @@ return array(
|
||||||
'User filters' => 'Filtres des utilisateurs',
|
'User filters' => 'Filtres des utilisateurs',
|
||||||
'Category filters' => 'Filtres des catégories',
|
'Category filters' => 'Filtres des catégories',
|
||||||
'Upload a file' => 'Uploader un fichier',
|
'Upload a file' => 'Uploader un fichier',
|
||||||
'There is no attachment at the moment.' => 'Il n\'y a aucune pièce-jointe pour le moment.',
|
|
||||||
'View file' => 'Voir le fichier',
|
'View file' => 'Voir le fichier',
|
||||||
'Last activity' => 'Dernières activités',
|
'Last activity' => 'Dernières activités',
|
||||||
'Change subtask position' => 'Changer la position de la sous-tâche',
|
'Change subtask position' => 'Changer la position de la sous-tâche',
|
||||||
'This value must be greater than %d' => 'Cette valeur doit être plus grande que %d',
|
'This value must be greater than %d' => 'Cette valeur doit être plus grande que %d',
|
||||||
'Another swimlane with the same name exists in the project' => 'Une autre swimlane existe avec le même nom dans le projet',
|
'Another swimlane with the same name exists in the project' => 'Une autre swimlane existe avec le même nom dans le projet',
|
||||||
'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => 'Exemple : http://exemple.kanboard.net/ (utilisé pour générer les URLs absolues)',
|
'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => 'Exemple : http://exemple.kanboard.net/ (utilisé pour générer les URLs absolues)',
|
||||||
|
'Actions duplicated successfully.' => 'Actions dupliquées avec succès.',
|
||||||
|
'Unable to duplicate actions.' => 'Impossible de dupliquer les actions.',
|
||||||
|
'Add a new action' => 'Ajouter une nouvelle action',
|
||||||
|
'Import from another project' => 'Importer depuis un autre projet',
|
||||||
|
'There is no action at the moment.' => 'Il n\'y a aucune action pour le moment.',
|
||||||
|
'Import actions from another project' => 'Importer les actions depuis un autre projet',
|
||||||
|
'There is no available project.' => 'Il n\'y a pas de projet disponible.',
|
||||||
|
'Local File' => 'Fichier local',
|
||||||
|
'Configuration' => 'Configuration',
|
||||||
|
'PHP version:' => 'Version de PHP :',
|
||||||
|
'PHP SAPI:' => 'PHP SAPI :',
|
||||||
|
'OS version:' => 'Version du système d\'exploitation :',
|
||||||
|
'Database version:' => 'Version de la base de donnée :',
|
||||||
|
'Browser:' => 'Navigateur web :',
|
||||||
|
'Task view' => 'Vue détaillée d\'une tâche',
|
||||||
|
'Edit task' => 'Modifier la tâche',
|
||||||
|
'Edit description' => 'Modifier la description',
|
||||||
|
'New internal link' => 'Nouveau lien interne',
|
||||||
|
'Display list of keyboard shortcuts' => 'Afficher la liste des raccourcis claviers',
|
||||||
|
'Menu' => 'Menu',
|
||||||
|
'Set start date' => 'Définir la date de début',
|
||||||
|
'Avatar' => 'Avatar',
|
||||||
|
'Upload my avatar image' => 'Uploader mon image d\'avatar',
|
||||||
|
'Remove my image' => 'Supprimer mon image',
|
||||||
|
'The OAuth2 state parameter is invalid' => 'Le paramètre "state" de OAuth2 est invalide',
|
||||||
);
|
);
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue