diff options
54 files changed, 2315 insertions, 326 deletions
diff --git a/README.markdown b/README.markdown index 7fe2c58d..866ccb7d 100644 --- a/README.markdown +++ b/README.markdown @@ -33,7 +33,7 @@ Features - Host anywhere (shared hosting, VPS, Raspberry Pi or localhost) - No external dependencies - **Super easy setup**, copy and paste files and you are done! -- Translated in 15 languages (Brazilian, Chinese, Danish, English, Finnish, French, German, Hungarian, Italian, Japanese, Polish, Russian, Spanish, Swedish, Thai) +- Translated in 16 languages (Brazilian, Chinese, Danish, English, Finnish, French, German, Hungarian, Italian, Japanese, Polish, Russian, Spanish, Swedish, Thai, Turkish) Known bugs and feature requests ------------------------------- @@ -172,6 +172,7 @@ Contributors: - [Cmer](https://github.com/chncsu) - [Colin Williams](https://github.com/crwilliams) - [Crash5](https://github.com/crash5) +- [Creador30](https://github.com/creador30) - [Cynthia Pereira](https://github.com/cynthiapereira) - [David-Norris](https://github.com/David-Norris) - [Esteban Monge](https://github.com/EstebanMonge) diff --git a/app/Controller/Board.php b/app/Controller/Board.php index 90b7f357..a6e002f2 100644 --- a/app/Controller/Board.php +++ b/app/Controller/Board.php @@ -127,6 +127,7 @@ class Board extends Base 'swimlanes' => $this->board->getBoard($project['id']), 'categories' => $this->category->getList($project['id'], false), 'title' => $project['name'], + 'description' => $project['description'], 'no_layout' => true, 'not_editable' => true, 'board_public_refresh_interval' => $this->config->get('board_public_refresh_interval'), @@ -187,6 +188,7 @@ class Board extends Base 'swimlanes' => $this->board->getBoard($project['id']), 'categories' => $this->category->getList($project['id'], true, true), 'title' => $project['name'], + 'description' => $project['description'], 'board_selector' => $board_selector, 'board_private_refresh_interval' => $this->config->get('board_private_refresh_interval'), 'board_highlight_period' => $this->config->get('board_highlight_period'), diff --git a/app/Controller/Subtask.php b/app/Controller/Subtask.php index c7ec00d1..385785a1 100644 --- a/app/Controller/Subtask.php +++ b/app/Controller/Subtask.php @@ -185,7 +185,7 @@ class Subtask extends Base if ($redirect === 'board') { $this->session['has_subtask_inprogress'] = $this->subtask->hasSubtaskInProgress($this->userSession->getId()); - + $this->response->html($this->template->render('board/subtasks', array( 'subtasks' => $this->subtask->getAll($task['id']), 'task' => $task, @@ -259,4 +259,22 @@ class Subtask extends Base $this->response->redirect($this->helper->url('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']))); } } + + /** + * Move subtask position + * + * @access public + */ + public function movePosition() + { + $this->checkCSRFParam(); + $project_id = $this->request->getIntegerParam('project_id'); + $task_id = $this->request->getIntegerParam('task_id'); + $subtask_id = $this->request->getIntegerParam('subtask_id'); + $direction = $this->request->getStringParam('direction'); + $method = $direction === 'up' ? 'moveUp' : 'moveDown'; + + $this->subtask->$method($task_id, $subtask_id); + $this->response->redirect($this->helper->url('task', 'show', array('project_id' => $project_id, 'task_id' => $task_id)).'#subtasks'); + } } diff --git a/app/Locale/da_DK/translations.php b/app/Locale/da_DK/translations.php index 75f27a7c..9d6c7343 100644 --- a/app/Locale/da_DK/translations.php +++ b/app/Locale/da_DK/translations.php @@ -734,4 +734,8 @@ return array( // 'Filter recently updated' => '', // 'since %B %e, %Y at %k:%M %p' => '', // 'More filters' => '', + // 'Compact view' => '', + // 'Horizontal scrolling' => '', + // 'Compact/wide view' => '', + // 'No results match:' => '', ); diff --git a/app/Locale/de_DE/translations.php b/app/Locale/de_DE/translations.php index 54503b64..44619315 100644 --- a/app/Locale/de_DE/translations.php +++ b/app/Locale/de_DE/translations.php @@ -734,4 +734,8 @@ return array( 'Filter recently updated' => 'Zuletzt geänderte anzeigen', 'since %B %e, %Y at %k:%M %p' => 'seit %B %e, %Y um %k:%M %p', 'More filters' => 'Mehr Filter', + // 'Compact view' => '', + // 'Horizontal scrolling' => '', + // 'Compact/wide view' => '', + // 'No results match:' => '', ); diff --git a/app/Locale/es_ES/translations.php b/app/Locale/es_ES/translations.php index 3981f12d..91ffe5e8 100644 --- a/app/Locale/es_ES/translations.php +++ b/app/Locale/es_ES/translations.php @@ -734,4 +734,8 @@ return array( // 'Filter recently updated' => '', // 'since %B %e, %Y at %k:%M %p' => '', // 'More filters' => '', + // 'Compact view' => '', + // 'Horizontal scrolling' => '', + // 'Compact/wide view' => '', + // 'No results match:' => '', ); diff --git a/app/Locale/fi_FI/translations.php b/app/Locale/fi_FI/translations.php index 06b21953..28f96069 100644 --- a/app/Locale/fi_FI/translations.php +++ b/app/Locale/fi_FI/translations.php @@ -734,4 +734,8 @@ return array( // 'Filter recently updated' => '', // 'since %B %e, %Y at %k:%M %p' => '', // 'More filters' => '', + // 'Compact view' => '', + // 'Horizontal scrolling' => '', + // 'Compact/wide view' => '', + // 'No results match:' => '', ); diff --git a/app/Locale/fr_FR/translations.php b/app/Locale/fr_FR/translations.php index b05f7076..30531d78 100644 --- a/app/Locale/fr_FR/translations.php +++ b/app/Locale/fr_FR/translations.php @@ -736,4 +736,8 @@ return array( 'Filter recently updated' => 'Récemment modifié', 'since %B %e, %Y at %k:%M %p' => 'depuis le %d/%m/%Y à %H:%M', 'More filters' => 'Plus de filtres', + 'Compact view' => 'Vue compacte', + 'Horizontal scrolling' => 'Défilement horizontal', + 'Compact/wide view' => 'Basculer entre la vue compacte et étendue', + 'No results match:' => 'Aucun résultat :', ); diff --git a/app/Locale/hu_HU/translations.php b/app/Locale/hu_HU/translations.php index 1780505f..07d7ec3b 100644 --- a/app/Locale/hu_HU/translations.php +++ b/app/Locale/hu_HU/translations.php @@ -104,7 +104,7 @@ return array( 'Open a task' => 'Feladat felnyitás', 'Do you really want to open this task: "%s"?' => 'Tényleg meg akarja nyitni ezt a feladatot: "%s"?', 'Back to the board' => 'Vissza a táblához', - 'Created on %B %e, %Y at %k:%M %p' => 'Létrehozva: %Y.%m.%d %H:%M', + 'Created on %B %e, %Y at %k:%M %p' => 'Létrehozva: %Y. %m. %d. %H:%M', 'There is nobody assigned' => 'Nincs felelős', 'Column on the board:' => 'Tábla oszlopa: ', 'Status is open' => 'Nyitott állapot', @@ -133,12 +133,12 @@ return array( 'The title is required' => 'A címet meg kell adni', 'The language is required' => 'A nyelvet meg kell adni', 'There is no active project, the first step is to create a new project.' => 'Nincs aktív projekt. Először létre kell hozni egy projektet.', - 'Settings saved successfully.' => 'A beállítások mentése sikeres.', + 'Settings saved successfully.' => 'A beállítások sikeresen mentve.', 'Unable to save your settings.' => 'A beállítások mentése sikertelen.', 'Database optimization done.' => 'Adatbázis optimalizálás kész.', 'Your project have been created successfully.' => 'Projekt sikeresen létrehozva', 'Unable to create your project.' => 'Projekt létrehozása sikertelen.', - 'Project updated successfully.' => 'Projekt frissítése sikeres.', + 'Project updated successfully.' => 'Projekt sikeresen frissítve.', 'Unable to update this project.' => 'Projekt frissítése sikertelen.', 'Unable to remove this project.' => 'Projekt törlése sikertelen.', 'Project removed successfully.' => 'Projekt sikeresen törölve.', @@ -146,7 +146,7 @@ return array( 'Unable to activate this project.' => 'Projekt aktiválása sikertelen.', 'Project disabled successfully.' => 'Projekt sikeresen letiltva.', 'Unable to disable this project.' => 'Projekt letiltása sikertelen.', - 'Unable to open this task.' => 'A feladat felnyitása nem sikerült.', + 'Unable to open this task.' => 'A feladat felnyitása sikertelen.', 'Task opened successfully.' => 'Feladat sikeresen megnyitva .', 'Unable to close this task.' => 'A feladat lezárása sikertelen.', 'Task closed successfully.' => 'Feladat sikeresen lezárva.', @@ -166,8 +166,8 @@ return array( 'Work in progress' => 'Folyamatban', 'Done' => 'Kész', 'Application version:' => 'Alkalmazás verzió:', - 'Completed on %B %e, %Y at %k:%M %p' => 'Elkészült %Y.%m.%d %H:%M ..', - '%B %e, %Y at %k:%M %p' => '%Y.%m.%d %H:%M', + 'Completed on %B %e, %Y at %k:%M %p' => 'Elkészült: %Y. %m. %d. %H:%M', + '%B %e, %Y at %k:%M %p' => '%Y. %m. %d. %H:%M', 'Date created' => 'Létrehozás időpontja', 'Date completed' => 'Befejezés időpontja', 'Id' => 'ID', @@ -211,9 +211,9 @@ return array( 'Edit this task' => 'Feladat módosítása', 'Due Date' => 'Határidő', 'Invalid date' => 'Érvénytelen dátum', - 'Must be done before %B %e, %Y' => 'Kész kell lennie %Y.%m.%d előtt', - '%B %e, %Y' => '%Y.%m.%d', - '%b %e, %Y' => '%Y.%m.%d', + 'Must be done before %B %e, %Y' => 'Kész kell lennie %Y. %m. %d. előtt', + '%B %e, %Y' => '%Y. %m. %d.', + '%b %e, %Y' => '%Y. %m. %d.', 'Automatic actions' => 'Automatikus intézkedések', 'Your automatic action have been created successfully.' => 'Az automatikus intézkedés sikeresen elkészült.', 'Unable to create your automatic action.' => 'Automatikus intézkedés létrehozása nem lehetséges.', @@ -254,7 +254,7 @@ return array( 'link' => 'link', 'Update this comment' => 'Hozzászólás frissítése', 'Comment updated successfully.' => 'Megjegyzés sikeresen frissítve.', - 'Unable to update your comment.' => 'Megjegyzés frissítése nem sikerült.', + 'Unable to update your comment.' => 'Megjegyzés frissítése sikertelen.', 'Remove a comment' => 'Megjegyzés törlése', 'Comment removed successfully.' => 'Megjegyzés sikeresen törölve.', 'Unable to remove this comment.' => 'Megjegyzés törölése nem lehetséges.', @@ -294,8 +294,8 @@ return array( 'Your Google Account is not linked anymore to your profile.' => 'Google Fiók már nincs a profilhoz kapcsolva.', 'Unable to unlink your Google Account.' => 'Leválasztás a Google fiókról nem lehetséges.', 'Google authentication failed' => 'Google azonosítás sikertelen', - 'Unable to link your Google Account.' => 'Google profilhoz kapcsolás nem sikerült.', - 'Your Google Account is linked to your profile successfully.' => 'Sikeresen összekapcsolva a Google fiókkal.', + 'Unable to link your Google Account.' => 'A Google profilhoz kapcsolás sikertelen.', + 'Your Google Account is linked to your profile successfully.' => 'Google fiókkal sikeresen összekapcsolva.', 'Email' => 'E-mail', 'Link my Google Account' => 'Kapcsold össze a Google fiókkal', 'Unlink my Google Account' => 'Válaszd le a Google fiókomat', @@ -377,7 +377,7 @@ return array( 'Link my GitHub Account' => 'GitHub fiók csatolása', 'Unlink my GitHub Account' => 'GitHub fiók leválasztása', 'Created by %s' => 'Készítette: %s', - 'Last modified on %B %e, %Y at %k:%M %p' => 'Utolsó módosítás: %Y.%m.%d %H:%M', + 'Last modified on %B %e, %Y at %k:%M %p' => 'Utolsó módosítás: %Y. %m. %d. %H:%M', 'Tasks Export' => 'Feladatok exportálása', 'Tasks exportation for "%s"' => 'Feladatok exportálása: "%s"', 'Start Date' => 'Kezdés dátuma', @@ -391,7 +391,7 @@ return array( 'Webhook URL for task modification' => 'Webhook URL a feladatot módosításakor', 'Clone' => 'Másolat', 'Clone Project' => 'Projekt másolása', - 'Project cloned successfully.' => 'A projekt másolása sikeres', + 'Project cloned successfully.' => 'A projekt sikeresen másolva.', 'Unable to clone this project.' => 'A projekt másolása sikertelen.', 'Email notifications' => 'E-mail értesítések', 'Enable email notifications' => 'E-mail értesítések engedélyezése', @@ -541,7 +541,7 @@ return array( 'Add' => 'Hozzáadás', 'Estimated time: %s hours' => 'Becsült idő: %s óra', 'Time spent: %s hours' => 'Eltöltött idő: %s óra', - 'Started on %B %e, %Y' => 'Elkezdve: %Y.%m.%d', + 'Started on %B %e, %Y' => 'Elkezdve: %Y. %m. %d.', 'Start date' => 'Kezdés dátuma', 'Time estimated' => 'Becsült időtartam', 'There is nothing assigned to you.' => 'Nincs kiosztott feladat.', @@ -670,7 +670,7 @@ return array( 'Time Tracking' => 'Idő követés', 'You already have one subtask in progress' => 'Már van egy folyamatban levő részfeladata', 'Which parts of the project do you want to duplicate?' => 'A projekt mely részeit szeretné duplikálni?', - 'Change dashboard view' => 'Vezérlőpult megjelenítés változtatás', + 'Change dashboard view' => 'Vezérlőpult megjelenés változtatás', 'Show/hide activities' => 'Tevékenységek megjelenítése/elrejtése', 'Show/hide projects' => 'Projektek megjelenítése/elrejtése', 'Show/hide subtasks' => 'Részfeladatok megjelenítése/elrejtése', @@ -730,8 +730,12 @@ return array( 'Board view' => 'Tábla nézet', 'Keyboard shortcuts' => 'Billentyű kombináció', 'Open board switcher' => 'Tábla választó lenyitása', - // 'Application' => '', - // 'Filter recently updated' => '', - // 'since %B %e, %Y at %k:%M %p' => '', - // 'More filters' => '', + 'Application' => 'Alkalmazás', + 'Filter recently updated' => 'Szűrés az utolsó módosítás ideje szerint', + 'since %B %e, %Y at %k:%M %p' => '%Y. %m. %d. %H:%M óta', + 'More filters' => 'További szűrők', + // 'Compact view' => '', + // 'Horizontal scrolling' => '', + // 'Compact/wide view' => '', + // 'No results match:' => '', ); diff --git a/app/Locale/it_IT/translations.php b/app/Locale/it_IT/translations.php index 525c828b..c72dc9e0 100644 --- a/app/Locale/it_IT/translations.php +++ b/app/Locale/it_IT/translations.php @@ -734,4 +734,8 @@ return array( // 'Filter recently updated' => '', // 'since %B %e, %Y at %k:%M %p' => '', // 'More filters' => '', + // 'Compact view' => '', + // 'Horizontal scrolling' => '', + // 'Compact/wide view' => '', + // 'No results match:' => '', ); diff --git a/app/Locale/ja_JP/translations.php b/app/Locale/ja_JP/translations.php index 90af6a02..2cfab36a 100644 --- a/app/Locale/ja_JP/translations.php +++ b/app/Locale/ja_JP/translations.php @@ -734,4 +734,8 @@ return array( // 'Filter recently updated' => '', // 'since %B %e, %Y at %k:%M %p' => '', // 'More filters' => '', + // 'Compact view' => '', + // 'Horizontal scrolling' => '', + // 'Compact/wide view' => '', + // 'No results match:' => '', ); diff --git a/app/Locale/pl_PL/translations.php b/app/Locale/pl_PL/translations.php index c6becf4c..39e3bb85 100644 --- a/app/Locale/pl_PL/translations.php +++ b/app/Locale/pl_PL/translations.php @@ -734,4 +734,8 @@ return array( // 'Filter recently updated' => '', // 'since %B %e, %Y at %k:%M %p' => '', // 'More filters' => '', + // 'Compact view' => '', + // 'Horizontal scrolling' => '', + // 'Compact/wide view' => '', + // 'No results match:' => '', ); diff --git a/app/Locale/pt_BR/translations.php b/app/Locale/pt_BR/translations.php index 89f7e294..8436514e 100644 --- a/app/Locale/pt_BR/translations.php +++ b/app/Locale/pt_BR/translations.php @@ -734,4 +734,8 @@ return array( 'Filter recently updated' => 'Filtro recentemente atualizado', // 'since %B %e, %Y at %k:%M %p' => '', 'More filters' => 'Mais filtros', + // 'Compact view' => '', + // 'Horizontal scrolling' => '', + // 'Compact/wide view' => '', + // 'No results match:' => '', ); diff --git a/app/Locale/ru_RU/translations.php b/app/Locale/ru_RU/translations.php index 02a66b56..199160c0 100644 --- a/app/Locale/ru_RU/translations.php +++ b/app/Locale/ru_RU/translations.php @@ -734,4 +734,8 @@ return array( // 'Filter recently updated' => '', // 'since %B %e, %Y at %k:%M %p' => '', // 'More filters' => '', + // 'Compact view' => '', + // 'Horizontal scrolling' => '', + // 'Compact/wide view' => '', + // 'No results match:' => '', ); diff --git a/app/Locale/sv_SE/translations.php b/app/Locale/sv_SE/translations.php index 2fcc3ce5..0fc9dfeb 100644 --- a/app/Locale/sv_SE/translations.php +++ b/app/Locale/sv_SE/translations.php @@ -408,13 +408,13 @@ return array( 'Comment updated' => 'Kommentaren har uppdaterats', 'New comment posted by %s' => 'Ny kommentar postad av %s', 'List of due tasks for the project "%s"' => 'Lista med uppgifter för projektet "%s"', - // 'New attachment' => '', - // 'New comment' => '', - // 'New subtask' => '', - // 'Subtask updated' => '', - // 'Task updated' => '', - // 'Task closed' => '', - // 'Task opened' => '', + 'New attachment' => 'Ny bifogning', + 'New comment' => 'Ny kommentar', + 'New subtask' => 'Ny deluppgift', + 'Subtask updated' => 'Deluppgiften har uppdaterats', + 'Task updated' => 'Uppgiften har uppdaterats', + 'Task closed' => 'Uppgiften har stängts', + 'Task opened' => 'Uppgiften har öppnats', '[%s][Due tasks]' => '[%s][Förfallen uppgift]', '[Kanboard] Notification' => '[Kanboard] Notis', 'I want to receive notifications only for those projects:' => 'Jag vill endast få notiser för dessa projekt:', @@ -498,9 +498,9 @@ return array( 'Task assignee change' => 'Ändra tilldelning av uppgiften', '%s change the assignee of the task #%d to %s' => '%s byt tilldelning av uppgiften #%d till %s', '%s changed the assignee of the task %s to %s' => '%s byt tilldelning av uppgiften %s till %s', - // 'Column Change' => '', - // 'Position Change' => '', - // 'Assignee Change' => '', + 'Column Change' => 'Ändring av kolumn', + 'Position Change' => 'Ändring av position', + 'Assignee Change' => 'Ändring av tilldelning', 'New password for the user "%s"' => 'Nytt lösenord för användaren "%s"', 'Choose an event' => 'Välj en händelse', 'Github commit received' => 'Github-bidrag mottaget', @@ -645,93 +645,97 @@ return array( 'Application default' => 'Applikationsstandard', 'Language:' => 'Språk', 'Timezone:' => 'Tidszon', - // 'All columns' => '', - // 'Calendar for "%s"' => '', - // 'Filter by column' => '', - // 'Filter by status' => '', - // 'Calendar' => '', + 'All columns' => 'Alla kolumner', + 'Calendar for "%s"' => 'Kalender för "%s"', + 'Filter by column' => 'Filtrera på kolumn', + 'Filter by status' => 'Filtrera på status', + 'Calendar' => 'Kalender', 'Next' => 'Nästa', - // '#%d' => '', - // 'Filter by color' => '', - // 'Filter by swimlane' => '', - // 'All swimlanes' => '', - // 'All colors' => '', - // 'All status' => '', - // 'Add a comment logging moving the task between columns' => '', - // 'Moved to column %s' => '', - // 'Change description' => '', - // 'User dashboard' => '', - // 'Allow only one subtask in progress at the same time for a user' => '', - // 'Edit column "%s"' => '', - // 'Enable time tracking for subtasks' => '', - // 'Select the new status of the subtask: "%s"' => '', - // 'Subtask timesheet' => '', - // 'There is nothing to show.' => '', - // 'Time Tracking' => '', - // 'You already have one subtask in progress' => '', - // 'Which parts of the project do you want to duplicate?' => '', - // 'Change dashboard view' => '', - // 'Show/hide activities' => '', - // 'Show/hide projects' => '', - // 'Show/hide subtasks' => '', - // 'Show/hide tasks' => '', - // 'Disable login form' => '', - // 'Show/hide calendar' => '', - // 'User calendar' => '', - // 'Bitbucket commit received' => '', - // 'Bitbucket webhooks' => '', - // 'Help on Bitbucket webhooks' => '', - // 'Start' => '', - // 'End' => '', - // 'Task age in days' => '', - // 'Days in this column' => '', - // '%dd' => '', - // 'Add a link' => '', - // 'Add a new link' => '', - // 'Do you really want to remove this link: "%s"?' => '', - // 'Do you really want to remove this link with task #%d?' => '', - // 'Field required' => '', - // 'Link added successfully.' => '', - // 'Link updated successfully.' => '', - // 'Link removed successfully.' => '', - // 'Link labels' => '', - // 'Link modification' => '', - // 'Links' => '', - // 'Link settings' => '', - // 'Opposite label' => '', - // 'Remove a link' => '', - // 'Task\'s links' => '', - // 'The labels must be different' => '', - // 'There is no link.' => '', - // 'This label must be unique' => '', - // 'Unable to create your link.' => '', - // 'Unable to update your link.' => '', - // 'Unable to remove this link.' => '', - // 'relates to' => '', - // 'blocks' => '', - // 'is blocked by' => '', - // 'duplicates' => '', - // 'is duplicated by' => '', - // 'is a child of' => '', - // 'is a parent of' => '', - // 'targets milestone' => '', - // 'is a milestone of' => '', - // 'fixes' => '', - // 'is fixed by' => '', - // 'This task' => '', - // '<1h' => '', - // '%dh' => '', - // '%b %e' => '', - // 'Expand tasks' => '', - // 'Collapse tasks' => '', - // 'Expand/collapse tasks' => '', - // 'Close dialog box' => '', - // 'Submit a form' => '', - // 'Board view' => '', - // 'Keyboard shortcuts' => '', - // 'Open board switcher' => '', - // 'Application' => '', - // 'Filter recently updated' => '', - // 'since %B %e, %Y at %k:%M %p' => '', - // 'More filters' => '', + '#%d' => '#%d', + 'Filter by color' => 'Filtrera på färg', + 'Filter by swimlane' => 'Filtrera på swimlane', + 'All swimlanes' => 'Alla swimlanes', + 'All colors' => 'Alla färger', + 'All status' => 'Alla status', + 'Add a comment logging moving the task between columns' => 'Lägg till en kommentar för att logga förflyttning av en uppgift mellan kolumner', + 'Moved to column %s' => 'Flyttad till kolumn %s', + 'Change description' => 'Ändra beskrivning', + 'User dashboard' => 'Användardashboard', + 'Allow only one subtask in progress at the same time for a user' => 'Tillåt endast en deluppgift igång samtidigt för en användare', + 'Edit column "%s"' => 'Ändra kolumn "%s"', + 'Enable time tracking for subtasks' => 'Aktivera tidsbevakning för deluppgifter', + 'Select the new status of the subtask: "%s"' => 'Välj ny status för deluppgiften: "%s"', + 'Subtask timesheet' => 'Tidrapport för deluppgiften', + 'There is nothing to show.' => 'Det finns inget att visa', + 'Time Tracking' => 'Tidsbevakning', + 'You already have one subtask in progress' => 'Du har redan en deluppgift igång', + 'Which parts of the project do you want to duplicate?' => 'Vilka delar av projektet vill du duplicera?', + 'Change dashboard view' => 'Ändra dashboard vy', + 'Show/hide activities' => 'Visa/dölj aktiviteter', + 'Show/hide projects' => 'Visa/dölj projekt', + 'Show/hide subtasks' => 'Visa/dölj deluppgifter', + 'Show/hide tasks' => 'Visa/dölj uppgifter', + 'Disable login form' => 'Inaktivera loginformuläret', + 'Show/hide calendar' => 'Visa/dölj kalender', + 'User calendar' => 'Användarkalender', + 'Bitbucket commit received' => 'Bitbucket bidrag mottaget', + 'Bitbucket webhooks' => 'Bitbucket webhooks', + 'Help on Bitbucket webhooks' => 'Hjälp för Bitbucket webhooks', + 'Start' => 'Start', + 'End' => 'Slut', + 'Task age in days' => 'Uppgiftsålder i dagar', + 'Days in this column' => 'Dagar i denna kolumn', + '%dd' => '%dd', + 'Add a link' => 'Lägg till länk', + 'Add a new link' => 'Lägg till ny länk', + 'Do you really want to remove this link: "%s"?' => 'Vill du verkligen ta bort länken: "%s"?', + 'Do you really want to remove this link with task #%d?' => 'Vill du verkligen ta bort länken till uppgiften #%d?', + 'Field required' => 'Fältet krävs', + 'Link added successfully.' => 'Länken har lagts till', + 'Link updated successfully.' => 'Länken har uppdaterats', + 'Link removed successfully.' => 'Länken har tagits bort', + 'Link labels' => 'Länketiketter', + 'Link modification' => 'Länkändring', + 'Links' => 'Länkar', + 'Link settings' => 'Länkinställningar', + 'Opposite label' => 'Motpartslänk', + 'Remove a link' => 'Ta bort en länk', + 'Task\'s links' => 'Uppgiftslänkar', + 'The labels must be different' => 'Etiketterna måste vara olika', + 'There is no link.' => 'Det finns ingen länk', + 'This label must be unique' => 'Länken måste vara unik', + 'Unable to create your link.' => 'Kunde inte skapa din länk', + 'Unable to update your link.' => 'Kunde inte uppdatera din länk', + 'Unable to remove this link.' => 'Kunde inte ta bort din länk', + 'relates to' => 'relaterar till', + 'blocks' => 'blockerar', + 'is blocked by' => 'blockeras av', + 'duplicates' => 'dupplicerar', + 'is duplicated by' => 'är duplicerad av', + 'is a child of' => 'är underliggande till', + 'is a parent of' => 'är överliggande till', + 'targets milestone' => 'milstolpemål', + 'is a milestone of' => 'är en milstolpe för', + 'fixes' => 'åtgärdar', + 'is fixed by' => 'åtgärdas av', + 'This task' => 'Denna uppgift', + '<1h' => '<1h', + '%dh' => '%dh', + '%b %e' => '%b %e', + 'Expand tasks' => 'Expandera uppgifter', + 'Collapse tasks' => 'Minimera uppgifter', + 'Expand/collapse tasks' => 'Expandera/minimera uppgifter', + 'Close dialog box' => 'Stäng dialogruta', + 'Submit a form' => 'Sänd formulär', + 'Board view' => 'Tavelvy', + 'Keyboard shortcuts' => 'Tangentbordsgenvägar', + 'Open board switcher' => 'Växling av öppen tavla', + 'Application' => 'Applikation', + 'Filter recently updated' => 'Filter som uppdaterats nyligen', + 'since %B %e, %Y at %k:%M %p' => 'sedan %B %e, %Y at %k:%M %p', + 'More filters' => 'Fler filter', + // 'Compact view' => '', + // 'Horizontal scrolling' => '', + // 'Compact/wide view' => '', + // 'No results match:' => '', ); diff --git a/app/Locale/th_TH/translations.php b/app/Locale/th_TH/translations.php index 1945f043..5f3d7c3d 100644 --- a/app/Locale/th_TH/translations.php +++ b/app/Locale/th_TH/translations.php @@ -734,4 +734,8 @@ return array( // 'Filter recently updated' => '', // 'since %B %e, %Y at %k:%M %p' => '', // 'More filters' => '', + // 'Compact view' => '', + // 'Horizontal scrolling' => '', + // 'Compact/wide view' => '', + // 'No results match:' => '', ); diff --git a/app/Locale/tr_TR/translations.php b/app/Locale/tr_TR/translations.php new file mode 100644 index 00000000..3ea8c80c --- /dev/null +++ b/app/Locale/tr_TR/translations.php @@ -0,0 +1,741 @@ +<?php + +return array( + 'None' => 'Hiçbiri', + 'edit' => 'düzenle', + 'Edit' => 'Düzenle', + 'remove' => 'sil', + 'Remove' => 'Sil', + 'Update' => 'Güncelle', + 'Yes' => 'Evet', + 'No' => 'Hayır', + 'cancel' => 'İptal', + 'or' => 'veya', + 'Yellow' => 'Sarı', + 'Blue' => 'Mavi', + 'Green' => 'Yeşil', + 'Purple' => 'Mor', + 'Red' => 'Kırmızı', + 'Orange' => 'Turuncu', + 'Grey' => 'Gri', + 'Save' => 'Kaydet', + 'Login' => 'Giriş', + 'Official website:' => 'Resmi internet sitesi:', + 'Unassigned' => 'Atanmamış', + 'View this task' => 'Bu görevi görüntüle', + 'Remove user' => 'Kullanıcıyı kaldır', + 'Do you really want to remove this user: "%s"?' => 'Bu kullanıcıyı gerçekten silmek istiyor musunuz: "%s"?', + 'New user' => 'Yeni kullanıcı', + 'All users' => 'Tüm kullanıcılar', + 'Username' => 'Kullanıcı adı', + 'Password' => 'Şifre', + // 'Default project' => '', + 'Administrator' => 'Yönetici', + 'Sign in' => 'Giriş yap', + 'Users' => 'Kullanıcılar', + 'No user' => 'Kullanıcı yok', + 'Forbidden' => 'Yasak', + 'Access Forbidden' => 'Erişim yasak', + 'Only administrators can access to this page.' => 'Bu sayfaya yalnızca yöneticiler erişebilir.', + 'Edit user' => 'Kullanıcıyı düzenle', + 'Logout' => 'Çıkış yap', + 'Bad username or password' => 'Hatalı kullanıcı adı veya şifre', + 'users' => 'kullanıcılar', + 'projects' => 'projeler', + 'Edit project' => 'Projeyi düzenle', + 'Name' => 'İsim', + 'Activated' => 'Aktif', + 'Projects' => 'Projeler', + 'No project' => 'Proje yok', + 'Project' => 'Proje', + 'Status' => 'Durum', + 'Tasks' => 'Görevler', + 'Board' => 'Tablo', + 'Actions' => 'İşlemler', + 'Inactive' => 'Aktif değil', + 'Active' => 'Aktif', + 'Column %d' => 'Sütun %d', + 'Add this column' => 'Bu sütunu ekle', + '%d tasks on the board' => '%d görev bu tabloda', + '%d tasks in total' => '%d görev toplam', + 'Unable to update this board.' => 'Bu tablo güncellenemiyor.', + 'Edit board' => 'Tabloyu düzenle', + 'Disable' => 'Devre dışı bırak', + 'Enable' => 'Etkinleştir', + 'New project' => 'Yeni proje', + 'Do you really want to remove this project: "%s"?' => 'Bu projeyi gerçekten silmek istiyor musunuz: "%s"?', + 'Remove project' => 'Projeyi sil', + 'Boards' => 'Tablolar', + 'Edit the board for "%s"' => 'Tabloyu "%s" için güncelle', + 'All projects' => 'Tüm projeler', + 'Change columns' => 'Sütunları değiştir', + 'Add a new column' => 'Yeni sütun ekle', + 'Title' => 'Başlık', + 'Add Column' => 'Sütun ekle', + 'Project "%s"' => 'Proje "%s"', + 'Nobody assigned' => 'Kullanıcı atanmamış', + 'Assigned to %s' => '%s kullanıcısına atanmış', + 'Remove a column' => 'Bir sütunu sil', + 'Remove a column from a board' => 'Tablodan bir sütunu sil', + 'Unable to remove this column.' => 'Bu sütun silinemiyor.', + 'Do you really want to remove this column: "%s"?' => 'Bu sütunu gerçekten silmek istiyor musunuz: "%s"?', + 'This action will REMOVE ALL TASKS associated to this column!' => 'Bu komut sütun içindeki TÜM GÖREVLERİ silecek!', + 'Settings' => 'Ayarlar', + 'Application settings' => 'Uygulama ayarları', + 'Language' => 'Dil', + // 'Webhook token:' => '', + 'API token:' => 'API Token:', + 'More information' => 'Daha fazla bilgi', + 'Database size:' => 'Veritabanı boyutu :', + 'Download the database' => 'Veritabanını indir', + 'Optimize the database' => 'Veritabanını optimize et', + '(VACUUM command)' => '(VACUUM komutu)', + '(Gzip compressed Sqlite file)' => '(Gzip ile sıkıştırılmış Sqlite dosyası)', + 'User settings' => 'Kullanıcı ayarları', + 'My default project:' => 'Benim varsayılan projem:', + 'Close a task' => 'Bir görevi kapat', + 'Do you really want to close this task: "%s"?' => 'Bu görevi gerçekten kapatmak istiyor musunuz: "%s"?', + 'Edit a task' => 'Bir görevi düzenle', + 'Column' => 'Sütun', + 'Color' => 'Renk', + 'Assignee' => 'Atanan', + 'Create another task' => 'Başka bir görev oluştur', + 'New task' => 'Nouvelle tâche', + 'Open a task' => 'Bir görevi aç', + 'Do you really want to open this task: "%s"?' => 'Bu görevi gerçekten açmak istiyor musunuz: "%s"?', + 'Back to the board' => 'Tabloya dön', + // 'Created on %B %e, %Y at %k:%M %p' => '', + 'There is nobody assigned' => 'Kimse atanmamış', + 'Column on the board:' => 'Tablodaki sütun:', + 'Status is open' => 'Açık durumda', + 'Status is closed' => 'Kapalı durumda', + 'Close this task' => 'Görevi kapat', + 'Open this task' => 'Görevi aç', + 'There is no description.' => 'Açıklama yok.', + 'Add a new task' => 'Yeni görev ekle', + 'The username is required' => 'Kullanıcı adı gerekli', + 'The maximum length is %d characters' => 'Maksimum uzunluk %d karakterdir', + 'The minimum length is %d characters' => 'Minimum uzunluk %d karakterdir', + 'The password is required' => 'Şifre gerekli', + 'This value must be an integer' => 'Bu değer bir rakam olmak zorunda', + 'The username must be unique' => 'Kullanıcı adı daha önceden var', + 'The username must be alphanumeric' => 'Kullanıcı adı alfanumerik olmalı (geçersiz karakter var)', + 'The user id is required' => 'Kullanıcı kodu gerekli', + 'Passwords don\'t match' => 'Şifreler uyuşmuyor', + 'The confirmation is required' => 'Onay gerekli', + 'The column is required' => 'Sütun gerekli', + 'The project is required' => 'Proje gerekli', + 'The color is required' => 'Renk gerekli', + 'The id is required' => 'Kod gerekli', + 'The project id is required' => 'Proje kodu gerekli', + 'The project name is required' => 'Proje adı gerekli', + 'This project must be unique' => 'Bu projenin tekil olması gerekli', + 'The title is required' => 'Başlık gerekli', + 'The language is required' => 'Dil seçimi gerekli', + 'There is no active project, the first step is to create a new project.' => 'Aktif bir proje yok. İlk aşama yeni bir proje oluşturmak olmalı.', + 'Settings saved successfully.' => 'Ayarlar başarıyla kaydedildi.', + 'Unable to save your settings.' => 'Ayarlarınız kaydedilemedi.', + 'Database optimization done.' => 'Veritabanı optimizasyonu tamamlandı.', + 'Your project have been created successfully.' => 'Projeniz başarıyla oluşturuldu.', + 'Unable to create your project.' => 'Proje oluşturulamadı.', + 'Project updated successfully.' => 'Proje başarıyla güncellendi.', + 'Unable to update this project.' => 'Bu proje güncellenemedi.', + 'Unable to remove this project.' => 'Bu proje silinemedi.', + 'Project removed successfully.' => 'Proje başarıyla silindi.', + 'Project activated successfully.' => 'Proje başarıyla aktive edildi.', + 'Unable to activate this project.' => 'Bu proje aktive edilemedi.', + 'Project disabled successfully.' => 'Proje devre dışı bırakıldı.', + 'Unable to disable this project.' => 'Bu proje devre dışı bırakılamadı.', + 'Unable to open this task.' => 'Bu görev açılamıyor.', + 'Task opened successfully.' => 'Görev başarıyla açıldı.', + 'Unable to close this task.' => 'Bu görev kapatılamıyor.', + 'Task closed successfully.' => 'Görev başarıyla kapatıldı.', + 'Unable to update your task.' => 'Görev güncellenemiyor.', + 'Task updated successfully.' => 'Görev başarıyla güncellendi.', + 'Unable to create your task.' => 'Görev oluşturulamadı.', + 'Task created successfully.' => 'Görev başarıyla oluşturuldu.', + 'User created successfully.' => 'Kullanıcı başarıyla oluşturuldu', + 'Unable to create your user.' => 'Kullanıcı oluşturulamıyor.', + 'User updated successfully.' => 'Kullanıcı başarıyla güncellendi.', + 'Unable to update your user.' => 'Kullanıcı güncellenemiyor.', + 'User removed successfully.' => 'Kullanıcı silindi.', + 'Unable to remove this user.' => 'Bu kullanıcı silinemiyor.', + 'Board updated successfully.' => 'Tablo başarıyla güncellendi.', + 'Ready' => 'Hazır', + 'Backlog' => 'Bekleme listesi', + 'Work in progress' => 'İşlemde', + 'Done' => 'Tamamlandı', + 'Application version:' => 'Uygulama versiyonu:', + // 'Completed on %B %e, %Y at %k:%M %p' => '', + // '%B %e, %Y at %k:%M %p' => '', + 'Date created' => 'Oluşturulma tarihi', + 'Date completed' => 'Tamamlanma tarihi', + 'Id' => 'Kod', + 'No task' => 'Görev yok', + 'Completed tasks' => 'Tamamlanan görevler', + 'List of projects' => 'Proje listesi', + 'Completed tasks for "%s"' => '"%s" için tamamlanan görevler', + '%d closed tasks' => '%d kapatılmış görevler', + // 'No task for this project' => '', + 'Public link' => 'Dışa açık link', + 'There is no column in your project!' => 'Projenizde hiç sütun yok', + 'Change assignee' => 'Atanmış Kullanıcıyı değiştir', + 'Change assignee for the task "%s"' => '"%s" görevi için atanmış kullanıcıyı değiştir', + 'Timezone' => 'Saat dilimi', + // 'Sorry, I didn\'t find this information in my database!' => '', + 'Page not found' => 'Sayfa bulunamadı', + 'Complexity' => 'Zorluk seviyesi', + 'limit' => 'limit', + 'Task limit' => 'Görev limiti', + 'Task count' => 'Görev sayısı', + 'This value must be greater than %d' => 'Bu değer %d den büyük olmalı', + 'Edit project access list' => 'Proje erişim listesini düzenle', + 'Edit users access' => 'Kullanıcı erişim haklarını düzenle', + 'Allow this user' => 'Bu kullanıcıya izin ver', + 'Only those users have access to this project:' => 'Bu projeye yalnızca şu kullanıcılar erişebilir:', + 'Don\'t forget that administrators have access to everything.' => 'Dikkat: Yöneticilerin herşeye erişimi olduğunu unutmayın!', + 'Revoke' => 'Iptal et', + 'List of authorized users' => 'Yetkili kullanıcıların listesi', + 'User' => 'Kullanıcı', + 'Nobody have access to this project.' => 'Bu projeye kimsenin erişimi yok.', + 'You are not allowed to access to this project.' => 'Bu projeye giriş yetkiniz yok.', + 'Comments' => 'Yorumlar', + 'Post comment' => 'Yorum ekle', + 'Write your text in Markdown' => 'Yazınızı Markdown ile yazın', + 'Leave a comment' => 'Bir yorum ekle', + 'Comment is required' => 'Yorum gerekli', + 'Leave a description' => 'Açıklama ekleyin', + 'Comment added successfully.' => 'Yorum eklendi', + 'Unable to create your comment.' => 'Yorumunuz oluşturulamadı', + 'The description is required' => 'Açıklama gerekli', + 'Edit this task' => 'Bu görevi değiştir', + 'Due Date' => 'Termin', + 'Invalid date' => 'Geçersiz tarihi', + // 'Must be done before %B %e, %Y' => '', + '%B %e, %Y' => '%d %B %Y', + '%b %e, %Y' => '%d/%m/%Y', + 'Automatic actions' => 'Otomatik işlemler', + 'Your automatic action have been created successfully.' => 'Otomatik işlem başarıyla oluşturuldu', + 'Unable to create your automatic action.' => 'Otomatik işleminiz oluşturulamadı', + 'Remove an action' => 'Bir işlemi sil', + 'Unable to remove this action.' => 'Bu işlem silinemedi', + 'Action removed successfully.' => 'İşlem başarıyla silindi', + 'Automatic actions for the project "%s"' => '"%s" projesi için otomatik işlemler', + 'Defined actions' => 'Tanımlanan işlemler', + 'Add an action' => 'İşlem ekle', + 'Event name' => 'Durum adı', + 'Action name' => 'İşlem adı', + 'Action parameters' => 'İşlem parametreleri', + 'Action' => 'İşlem', + 'Event' => 'Durum', + 'When the selected event occurs execute the corresponding action.' => 'Seçilen durum oluştuğunda ilgili eylemi gerçekleştir.', + 'Next step' => 'Sonraki adım', + 'Define action parameters' => 'İşlem parametrelerini düzenle', + 'Save this action' => 'Bu işlemi kaydet', + 'Do you really want to remove this action: "%s"?' => 'Bu işlemi silmek istediğinize emin misiniz: "%s"?', + 'Remove an automatic action' => 'Bir otomatik işlemi sil', + 'Close the task' => 'Görevi kapat', + 'Assign the task to a specific user' => 'Görevi bir kullanıcıya ata', + 'Assign the task to the person who does the action' => 'Görevi, işlemi gerçekleştiren kullanıcıya ata', + 'Duplicate the task to another project' => 'Görevi bir başka projeye kopyala', + 'Move a task to another column' => 'Bir görevi başka bir sütuna taşı', + 'Move a task to another position in the same column' => 'Bir görevin aynı sütunda yerini değiştir', + 'Task modification' => 'Görev düzenleme', + 'Task creation' => 'Görev oluşturma', + 'Open a closed task' => 'Kapalı bir görevi aç', + 'Closing a task' => 'Bir görev kapatılıyor', + 'Assign a color to a specific user' => 'Bir kullanıcıya renk tanımla', + 'Column title' => 'Sütun başlığı', + 'Position' => 'Pozisyon', + 'Move Up' => 'Yukarı taşı', + 'Move Down' => 'Aşağı taşı', + 'Duplicate to another project' => 'Başka bir projeye kopyala', + 'Duplicate' => 'Kopya oluştur', + 'link' => 'link', + 'Update this comment' => 'Bu yorumu güncelle', + 'Comment updated successfully.' => 'Yorum güncellendi.', + 'Unable to update your comment.' => 'Yorum güncellenemedi.', + 'Remove a comment' => 'Bir yorumu sil', + 'Comment removed successfully.' => 'Yorum silindi.', + 'Unable to remove this comment.' => 'Bu yorum silinemiyor.', + 'Do you really want to remove this comment?' => 'Bu yorumu silmek istediğinize emin misiniz?', + 'Only administrators or the creator of the comment can access to this page.' => 'Bu sayfaya yalnızca yorum sahibi ve yöneticiler erişebilir.', + 'Details' => 'Detaylar', + 'Current password for the user "%s"' => 'Kullanıcı için mevcut şifre "%s"', + 'The current password is required' => 'Mevcut şifre gerekli', + 'Wrong password' => 'Yanlış Şifre', + 'Reset all tokens' => 'Tüm fişleri sıfırla', + 'All tokens have been regenerated.' => 'Tüm fişler yeniden oluşturuldu.', + 'Unknown' => 'Bilinmeyen', + 'Last logins' => 'Son kullanıcı girişleri', + 'Login date' => 'Giriş tarihi', + 'Authentication method' => 'Doğrulama yöntemi', + 'IP address' => 'IP adresi', + 'User agent' => 'Kullanıcı sistemi', + 'Persistent connections' => 'Kalıcı bağlantılar', + // 'No session.' => '', + 'Expiration date' => 'Geçerlilik sonu', + 'Remember Me' => 'Beni hatırla', + 'Creation date' => 'Oluşturulma tarihi', + 'Filter by user' => 'Kullanıcıya göre filtrele', + 'Filter by due date' => 'Termine göre filtrele', + 'Everybody' => 'Herkes', + 'Open' => 'Açık', + 'Closed' => 'Kapalı', + 'Search' => 'Ara', + 'Nothing found.' => 'Hiçbir şey bulunamadı', + 'Search in the project "%s"' => '"%s" Projesinde ara', + 'Due date' => 'Termin', + 'Others formats accepted: %s and %s' => 'Diğer kabul edilen formatlar: %s ve %s', + 'Description' => 'Açıklama', + '%d comments' => '%d yorumlar', + '%d comment' => '%d yorum', + 'Email address invalid' => 'E-Posta adresi geçersiz', + 'Your Google Account is not linked anymore to your profile.' => 'Google hesabınız artık profilinize bağlı değil', + 'Unable to unlink your Google Account.' => 'Google hesabınızla bağ koparılamadı', + 'Google authentication failed' => 'Google hesap doğrulaması başarısız', + 'Unable to link your Google Account.' => 'Google hesabınızla bağ oluşturulamadı', + 'Your Google Account is linked to your profile successfully.' => 'Google hesabınız profilinize başarıyla bağlandı', + 'Email' => 'E-Posta', + 'Link my Google Account' => 'Google hesabımla bağ oluştur', + 'Unlink my Google Account' => 'Google hesabımla bağı kaldır', + 'Login with my Google Account' => 'Google hesabımla giriş yap', + 'Project not found.' => 'Proje bulunamadı', + 'Task #%d' => 'Görev #%d', + 'Task removed successfully.' => 'Görev silindi', + 'Unable to remove this task.' => 'Görev silinemiyor', + 'Remove a task' => 'Bir görevi sil', + 'Do you really want to remove this task: "%s"?' => 'Bu görevi silmek istediğinize emin misiniz: "%s"?', + 'Assign automatically a color based on a category' => 'Kategoriye göre otomatik renk ata', + 'Assign automatically a category based on a color' => 'Rengine göre otomatik kategori ata', + 'Task creation or modification' => 'Görev oluşturma veya değiştirme', + 'Category' => 'Kategori', + 'Category:' => 'Kategori:', + 'Categories' => 'Kategoriler', + 'Category not found.' => 'Kategori bulunamadı', + 'Your category have been created successfully.' => 'Kategori oluşturuldu', + 'Unable to create your category.' => 'Kategori oluşturulamadı', + 'Your category have been updated successfully.' => 'Kategori başarıyla güncellendi', + 'Unable to update your category.' => 'Kategori güncellenemedi', + 'Remove a category' => 'Bir kategoriyi sil', + 'Category removed successfully.' => 'Kategori silindi', + 'Unable to remove this category.' => 'Bu kategori silinemedi', + 'Category modification for the project "%s"' => '"%s" projesi için kategori değiştirme', + 'Category Name' => 'Kategori adı', + 'Categories for the project "%s"' => '"%s" Projesi için kategoriler', + 'Add a new category' => 'Yeni kategori ekle', + 'Do you really want to remove this category: "%s"?' => 'Bu kategoriyi silmek istediğinize emin misiniz: "%s"?', + 'Filter by category' => 'Kategoriye göre filtrele', + 'All categories' => 'Tüm kategoriler', + 'No category' => 'Kategori Yok', + 'The name is required' => 'İsim gerekli', + 'Remove a file' => 'Dosya sil', + 'Unable to remove this file.' => 'Dosya silinemedi', + 'File removed successfully.' => 'Dosya silindi', + 'Attach a document' => 'Dosya ekle', + 'Do you really want to remove this file: "%s"?' => 'Bu dosyayı silmek istediğinize emin misiniz: "%s"?', + 'open' => 'aç', + 'Attachments' => 'Ekler', + 'Edit the task' => 'Görevi değiştir', + 'Edit the description' => 'Açıklamayı değiştir', + 'Add a comment' => 'Yorum ekle', + 'Edit a comment' => 'Yorum değiştir', + 'Summary' => 'Özet', + 'Time tracking' => 'Zaman takibi', + 'Estimate:' => 'Tahmini:', + 'Spent:' => 'Harcanan:', + 'Do you really want to remove this sub-task?' => 'Bu alt görevi silmek istediğinize emin misiniz', + 'Remaining:' => 'Kalan', + 'hours' => 'saat', + 'spent' => 'harcanan', + 'estimated' => 'tahmini', + 'Sub-Tasks' => 'Alt Görev', + 'Add a sub-task' => 'Alt görev ekle', + // 'Original estimate' => '', + 'Create another sub-task' => 'Başka bir alt görev daha oluştur', + // 'Time spent' => '', + 'Edit a sub-task' => 'Alt görev düzenle', + 'Remove a sub-task' => 'Alt görev sil', + 'The time must be a numeric value' => 'Zaman alfanumerik bir değer olmalı', + 'Todo' => 'Yapılacaklar', + 'In progress' => 'İşlemde', + 'Sub-task removed successfully.' => 'Alt görev silindi', + 'Unable to remove this sub-task.' => 'Alt görev silinemedi', + 'Sub-task updated successfully.' => 'Alt görev güncellendi', + 'Unable to update your sub-task.' => 'Alt görev güncellenemiyor', + 'Unable to create your sub-task.' => 'Alt görev oluşturulamadı', + 'Sub-task added successfully.' => 'Alt görev başarıyla eklendii', + 'Maximum size: ' => 'Maksimum boyutu', + 'Unable to upload the file.' => 'Karşıya yükleme başarısız', + 'Display another project' => 'Başka bir proje göster', + 'Your GitHub account was successfully linked to your profile.' => 'GitHub Hesabınız Profilinize bağlandı.', + 'Unable to link your GitHub Account.' => 'GitHub hesabınızla bağ oluşturulamadı.', + // 'GitHub authentication failed' => '', + // 'Your GitHub account is no longer linked to your profile.' => '', + // 'Unable to unlink your GitHub Account.' => '', + // 'Login with my GitHub Account' => '', + // 'Link my GitHub Account' => '', + // 'Unlink my GitHub Account' => '', + 'Created by %s' => '%s tarafından oluşturuldu', + 'Last modified on %B %e, %Y at %k:%M %p' => 'Son değişiklik tarihi %d.%m.%Y, saati %H:%M', + 'Tasks Export' => 'Görevleri dışa aktar', + 'Tasks exportation for "%s"' => '"%s" için görevleri dışa aktar', + 'Start Date' => 'Başlangıç tarihi', + 'End Date' => 'Bitiş tarihi', + 'Execute' => 'Gerçekleştir', + 'Task Id' => 'Görev No', + 'Creator' => 'Oluşturan', + 'Modification date' => 'Değişiklik tarihi', + 'Completion date' => 'Tamamlanma tarihi', + // 'Webhook URL for task creation' => '', + // 'Webhook URL for task modification' => '', + 'Clone' => 'Kopya oluştur', + 'Clone Project' => 'Projenin kopyasını oluştur', + 'Project cloned successfully.' => 'Proje kopyası başarıyla oluşturuldu.', + 'Unable to clone this project.' => 'Proje kopyası oluşturulamadı.', + 'Email notifications' => 'E-Posta bilgilendirmesi', + 'Enable email notifications' => 'E-Posta bilgilendirmesini aç', + 'Task position:' => 'Görev pozisyonu', + 'The task #%d have been opened.' => '#%d numaralı görev açıldı.', + 'The task #%d have been closed.' => '#%d numaralı görev kapatıldı.', + 'Sub-task updated' => 'Alt görev güncellendi', + 'Title:' => 'Başlık', + 'Status:' => 'Durum', + 'Assignee:' => 'Sorumlu:', + 'Time tracking:' => 'Zaman takibi', + 'New sub-task' => 'Yeni alt görev', + 'New attachment added "%s"' => 'Yeni dosya "%s" eklendi.', + 'Comment updated' => 'Yorum güncellendi', + 'New comment posted by %s' => '%s tarafından yeni yorum eklendi', + 'List of due tasks for the project "%s"' => '"%s" projesi için ilgili görevlerin listesi', + 'New attachment' => 'Yeni dosya eki', + 'New comment' => 'Yeni yorum', + 'New subtask' => 'Yeni alt görev', + 'Subtask updated' => 'Alt görev güncellendi', + 'Task updated' => 'Görev güncellendi', + 'Task closed' => 'Görev kapatıldı', + 'Task opened' => 'Görev açıldı', + '[%s][Due tasks]' => '[%s][İlgili görevler]', + '[Kanboard] Notification' => '[Kanboard] Bildirim', + 'I want to receive notifications only for those projects:' => 'Yalnızca bu projelerle ilgili bildirim almak istiyorum:', + 'view the task on Kanboard' => 'bu görevi Kanboard\'da göster', + 'Public access' => 'Dışa açık erişim', + 'Category management' => 'Kategori yönetimi', + 'User management' => 'Kullanıcı yönetimi', + 'Active tasks' => 'Aktif görevler', + 'Disable public access' => 'Dışa açık erişimi kapat', + 'Enable public access' => 'Dışa açık erişimi aç', + 'Active projects' => 'Aktif projeler', + 'Inactive projects' => 'Aktif olmayan projeler', + 'Public access disabled' => 'Dışa açık erişim kapatıldı', + 'Do you really want to disable this project: "%s"?' => 'Bu projeyi devre dışı bırakmak istediğinize emin misiniz?: "%s"', + 'Do you really want to duplicate this project: "%s"?' => 'Bu projenin kopyasını oluşturmak istediğinize emin misiniz?: "%s"', + 'Do you really want to enable this project: "%s"?' => 'Bu projeyi aktive etmek istediğinize emin misiniz?: "%s"', + 'Project activation' => 'Proje aktivasyonu', + 'Move the task to another project' => 'Görevi başka projeye taşı', + 'Move to another project' => 'Başka projeye taşı', + 'Do you really want to duplicate this task?' => 'Bu görevin kopyasını oluşturmak istediğinize emin misiniz?', + 'Duplicate a task' => 'Görevin kopyasını oluştur', + 'External accounts' => 'Dış hesaplar', + 'Account type' => 'Hesap türü', + 'Local' => 'Yerel', + 'Remote' => 'Uzak', + 'Enabled' => 'Etkinleştirildi', + 'Disabled' => 'Devre dışı bırakıldı', + 'Google account linked' => 'Google hesabıyla bağlı', + 'Github account linked' => 'Github hesabıyla bağlı', + 'Username:' => 'Kullanıcı adı', + 'Name:' => 'Ad', + 'Email:' => 'E-Posta', + 'Default project:' => 'Varsayılan Proje:', + 'Notifications:' => 'Bildirimler:', + 'Notifications' => 'Bildirimler', + 'Group:' => 'Grup', + 'Regular user' => 'Varsayılan kullanıcı', + 'Account type:' => 'Hesap türü:', + 'Edit profile' => 'Profili değiştir', + 'Change password' => 'Şifre değiştir', + 'Password modification' => 'Şifre değişimi', + 'External authentications' => 'Dış kimlik doğrulamaları', + 'Google Account' => 'Google hesabı', + 'Github Account' => 'Github hesabı', + 'Never connected.' => 'Hiç bağlanmamış.', + 'No account linked.' => 'Bağlanmış hesap yok.', + 'Account linked.' => 'Hesap bağlandı', + 'No external authentication enabled.' => 'Dış kimlik doğrulama kapalı.', + 'Password modified successfully.' => 'Şifre başarıyla değiştirildi.', + 'Unable to change the password.' => 'Şifre değiştirilemedi.', + 'Change category for the task "%s"' => '"%s" görevi için kategori değiştirme', + 'Change category' => 'Kategori değiştirme', + '%s updated the task %s' => '%s kullanıcısı %s görevini güncelledi', + '%s opened the task %s' => '%s kullanıcısı %s görevini açtı', + '%s moved the task %s to the position #%d in the column "%s"' => '%s kullanıcısı %s görevini #%d pozisyonu "%s" sütununa taşıdı', + '%s moved the task %s to the column "%s"' => '%s kullanıcısı %s görevini "%s" sütununa taşıdı', + '%s created the task %s' => '%s kullanıcısı %s görevini oluşturdu', + '%s closed the task %s' => '%s kullanıcısı %s görevini kapattı', + '%s created a subtask for the task %s' => '%s kullanıcısı %s görevi için bir alt görev oluşturdu', + '%s updated a subtask for the task %s' => '%s kullanıcısı %s görevinin bir alt görevini güncelledi', + 'Assigned to %s with an estimate of %s/%sh' => '%s kullanıcısına tahmini %s/%s saat tamamlanma süresi ile atanmış', + 'Not assigned, estimate of %sh' => 'Kimseye atanmamış, tahmini süre %s saat', + '%s updated a comment on the task %s' => '%s kullanıcısı %s görevinde bir yorumu güncelledi', + '%s commented the task %s' => '%s kullanıcısı %s görevine yorum ekledi', + '%s\'s activity' => '%s\'in aktivitesi', + 'No activity.' => 'Aktivite yok.', + 'RSS feed' => 'RSS kaynağı', + '%s updated a comment on the task #%d' => '%s kullanıcısı #%d nolu görevde bir yorumu güncelledi', + '%s commented on the task #%d' => '%s kullanıcısı #%d nolu göreve yorum ekledi', + '%s updated a subtask for the task #%d' => '%s kullanıcısı #%d nolu görevin bir alt görevini güncelledi', + '%s created a subtask for the task #%d' => '%s kullanıcısı #%d nolu göreve bir alt görev ekledi', + '%s updated the task #%d' => '%s kullanıcısı #%d nolu görevi güncelledi', + '%s created the task #%d' => '%s kullanıcısı #%d nolu görevi oluşturdu', + '%s closed the task #%d' => '%s kullanıcısı #%d nolu görevi kapattı', + '%s open the task #%d' => '%s kullanıcısı #%d nolu görevi açtı', + '%s moved the task #%d to the column "%s"' => '%s kullanıcısı #%d nolu görevi "%s" sütununa taşıdı', + '%s moved the task #%d to the position %d in the column "%s"' => '%s kullanıcısı #%d nolu görevi %d pozisyonu "%s" sütununa taşıdı', + 'Activity' => 'Aktivite', + 'Default values are "%s"' => 'Varsayılan değerler "%s"', + 'Default columns for new projects (Comma-separated)' => 'Yeni projeler için varsayılan sütunlar (virgül ile ayrılmış)', + 'Task assignee change' => 'Göreve atanan kullanıcı değişikliği', + '%s change the assignee of the task #%d to %s' => '%s kullanıcısı #%d nolu görevin sorumlusunu %s olarak değiştirdi', + '%s changed the assignee of the task %s to %s' => '%s kullanıcısı %s görevinin sorumlusunu %s olarak değiştirdi', + 'Column Change' => 'Sütun değişikliği', + 'Position Change' => 'Konum değişikliği', + 'Assignee Change' => 'Sorumlu değişikliği', + 'New password for the user "%s"' => '"%s" kullanıcısı için yeni şifre', + 'Choose an event' => 'Bir durum seçin', + // 'Github commit received' => '', + // 'Github issue opened' => '', + // 'Github issue closed' => '', + // 'Github issue reopened' => '', + // 'Github issue assignee change' => '', + // 'Github issue label change' => '', + 'Create a task from an external provider' => 'Dış sağlayıcı ile bir görev oluştur', + 'Change the assignee based on an external username' => 'Dış kaynaklı kullanıcı adı ile göreve atananı değiştir', + 'Change the category based on an external label' => 'Dış kaynaklı bir etiket ile kategori değiştir', + 'Reference' => 'Referans', + 'Reference: %s' => 'Referans: %s', + 'Label' => 'Etiket', + 'Database' => 'Veri bankası', + 'About' => 'Hakkında', + 'Database driver:' => 'Veri bankası sürücüsü', + 'Board settings' => 'Tablo ayarları', + 'URL and token' => 'URL veya Token', + 'Webhook settings' => 'Webhook ayarları', + 'URL for task creation:' => 'Görev oluşturma için URL', + 'Reset token' => 'Reset Token', + 'API endpoint:' => 'API endpoint', + 'Refresh interval for private board' => 'Özel tablolar için yenileme sıklığı', + 'Refresh interval for public board' => 'Dışa açık tablolar için yenileme sıklığı', + 'Task highlight period' => 'Görevi öne çıkarma süresi', + 'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => 'Bir görevin yeni değiştirilmiş sayılması için süre (saniye olarak) (Bu özelliği iptal etmek için 0, varsayılan değer 2 gün)', + 'Frequency in second (60 seconds by default)' => 'Saniye olarak frekans (varsayılan 60 saniye)', + 'Frequency in second (0 to disable this feature, 10 seconds by default)' => 'Saniye olarak frekans (Bu özelliği iptal etmek için 0, varsayılan değer 10 saniye)', + 'Application URL' => 'Uygulama URL', + 'Example: http://example.kanboard.net/ (used by email notifications)' => 'Örneğin: http://example.kanboard.net/ (E-posta bildirimleri için kullanılıyor)', + 'Token regenerated.' => 'Token yeniden oluşturuldu.', + 'Date format' => 'Tarih formatı', + 'ISO format is always accepted, example: "%s" and "%s"' => 'ISO formatı her zaman kabul edilir, örneğin: "%s" ve "%s"', + 'New private project' => 'Yeni özel proje', + 'This project is private' => 'Bu proje özel', + 'Type here to create a new sub-task' => 'Yeni bir alt görev oluşturmak için buraya yazın', + 'Add' => 'Ekle', + 'Estimated time: %s hours' => 'Tahmini süre: %s Saat', + 'Time spent: %s hours' => 'Kullanılan süre: %s Saat', + 'Started on %B %e, %Y' => '%B %e %Y tarihinde başlatıldı', + 'Start date' => 'Başlangıç tarihi', + 'Time estimated' => 'Tahmini süre', + 'There is nothing assigned to you.' => 'Size atanan hiçbir şey yok.', + 'My tasks' => 'Görevlerim', + 'Activity stream' => 'Güncel olay akışı', + 'Dashboard' => 'Anasayfa', + 'Confirmation' => 'Onay', + 'Allow everybody to access to this project' => 'Bu projeye herkesin erişimine izin ver', + 'Everybody have access to this project.' => 'Bu projeye herkesin erişimi var.', + 'Webhooks' => 'Webhooks', + 'API' => 'API', + 'Integration' => 'Entegrasyon', + 'Github webhooks' => 'Github Webhook', + 'Help on Github webhooks' => 'Github Webhooks hakkında yardım', + 'Create a comment from an external provider' => 'Dış sağlayıcı ile bir yorum oluştur', + 'Github issue comment created' => 'Github hata yorumu oluşturuldu', + 'Configure' => 'Ayarla', + 'Project management' => 'Proje yönetimi', + 'My projects' => 'Projelerim', + 'Columns' => 'Sütunlar', + 'Task' => 'Görev', + 'Your are not member of any project.' => 'Hiç bir projenin üyesi değilsiniz.', + 'Percentage' => 'Yüzde', + 'Number of tasks' => 'Görev sayısı', + 'Task distribution' => 'Görev dağılımı', + 'Reportings' => 'Raporlar', + 'Task repartition for "%s"' => '"%s" için görev dağılımı', + 'Analytics' => 'Analiz', + 'Subtask' => 'Alt görev', + 'My subtasks' => 'Alt görevlerim', + 'User repartition' => 'Kullanıcı dağılımı', + 'User repartition for "%s"' => '"%s" için kullanıcı dağılımı', + 'Clone this project' => 'Projenin kopyasını oluştur', + 'Column removed successfully.' => 'Sütun başarıyla kaldırıldı.', + 'Edit Project' => 'Projeyi düzenle', + 'Github Issue' => 'Github Issue', + 'Not enough data to show the graph.' => 'Grafik gösterimi için yeterli veri yok.', + 'Previous' => 'Önceki', + 'The id must be an integer' => 'ID bir tamsayı olmalı', + 'The project id must be an integer' => 'Proje numarası bir tam sayı olmalı', + 'The status must be an integer' => 'Durum bir tam sayı olmalı', + 'The subtask id is required' => 'Alt görev numarası gerekli', + 'The subtask id must be an integer' => 'Alt görev numarası bir tam sayı olmalı', + 'The task id is required' => 'Görev numarası gerekli', + 'The task id must be an integer' => 'Görev numarası bir tam sayı olmalı', + 'The user id must be an integer' => 'Kullanıcı numarası bir tam sayı olmalı', + 'This value is required' => 'Bu değer gerekli', + 'This value must be numeric' => 'Bu değer sayı olmalı', + 'Unable to create this task.' => 'Bu görev oluşturulamıyor.', + 'Cumulative flow diagram' => 'Kümülatif akış diyagramı', + 'Cumulative flow diagram for "%s"' => '"%s" için kümülatif akış diyagramı', + 'Daily project summary' => 'Günlük proje özeti', + 'Daily project summary export' => 'Günlük proje özetini dışa aktar', + 'Daily project summary export for "%s"' => '"%s" için günlük proje özetinin dışa', + 'Exports' => 'Dışa aktarımlar', + 'This export contains the number of tasks per column grouped per day.' => 'Bu dışa aktarım günlük gruplanmış olarak her sütundaki görev sayısını içerir.', + 'Nothing to preview...' => 'Önizleme yapılacak bir şey yok ...', + 'Preview' => 'Önizleme', + 'Write' => 'Değiştir', + 'Active swimlanes' => 'Aktif Kulvar', + 'Add a new swimlane' => 'Yeni bir Kulvar ekle', + 'Change default swimlane' => 'Varsayılan Kulvarı değiştir', + 'Default swimlane' => 'Varsayılan Kulvar', + 'Do you really want to remove this swimlane: "%s"?' => 'Bu Kulvarı silmek istediğinize emin misiniz?: "%s"?', + 'Inactive swimlanes' => 'Pasif Kulvarlar', + 'Set project manager' => 'Proje yöneticisi olarak ata', + 'Set project member' => 'Proje üyesi olarak ata', + 'Remove a swimlane' => 'Kulvarı sil', + 'Rename' => 'Yeniden adlandır', + 'Show default swimlane' => 'Varsayılan Kulvarı göster', + 'Swimlane modification for the project "%s"' => '"% s" Projesi için Kulvar değişikliği', + 'Swimlane not found.' => 'Kulvar bulunamadı', + 'Swimlane removed successfully.' => 'Kulvar başarıyla kaldırıldı.', + 'Swimlanes' => 'Kulvarlar', + 'Swimlane updated successfully.' => 'Kulvar başarıyla güncellendi.', + 'The default swimlane have been updated successfully.' => 'Varsayılan Kulvarlar başarıyla güncellendi.', + 'Unable to create your swimlane.' => 'Bu Kulvarı oluşturmak mümkün değil.', + 'Unable to remove this swimlane.' => 'Bu Kulvarı silmek mümkün değil.', + 'Unable to update this swimlane.' => 'Bu Kulvarı değiştirmek mümkün değil.', + 'Your swimlane have been created successfully.' => 'Kulvar başarıyla oluşturuldu.', + 'Example: "Bug, Feature Request, Improvement"' => 'Örnek: "Sorun, Özellik talebi, İyileştirme"', + 'Default categories for new projects (Comma-separated)' => 'Yeni projeler için varsayılan kategoriler (Virgül ile ayrılmış)', + // 'Gitlab commit received' => '', + // 'Gitlab issue opened' => '', + // 'Gitlab issue closed' => '', + // 'Gitlab webhooks' => '', + // 'Help on Gitlab webhooks' => '', + 'Integrations' => 'Entegrasyon', + 'Integration with third-party services' => 'Dış servislerle entegrasyon', + 'Role for this project' => 'Bu proje için rol', + 'Project manager' => 'Proje Yöneticisi', + 'Project member' => 'Proje Üyesi', + 'A project manager can change the settings of the project and have more privileges than a standard user.' => 'Bir Proje Yöneticisi proje ayarlarını değiştirebilir ve bir üyeden daha fazla yetkiye sahiptir.', + // 'Gitlab Issue' => '', + 'Subtask Id' => 'Alt görev No:', + 'Subtasks' => 'Alt görevler', + 'Subtasks Export' => 'Alt görevleri dışa aktar', + 'Subtasks exportation for "%s"' => '"%s" için alt görevleri dışa aktarımı', + 'Task Title' => 'Görev Başlığı', + 'Untitled' => 'Başlıksız', + 'Application default' => 'Uygulama varsayılanları', + 'Language:' => 'Dil:', + 'Timezone:' => 'Saat dilimi:', + 'All columns' => 'Tüm sütunlar', + 'Calendar for "%s"' => '"%s" için takvim', + 'Filter by column' => 'Sütuna göre filtrele', + 'Filter by status' => 'Duruma göre filtrele', + 'Calendar' => 'Takvim', + 'Next' => 'Sonraki', + '#%d' => '#%d', + 'Filter by color' => 'Renklere göre filtrele', + 'Filter by swimlane' => 'Kulvara göre filtrele', + 'All swimlanes' => 'Tüm Kulvarlar', + 'All colors' => 'Tüm Renkler', + 'All status' => 'Tüm Durumlar', + 'Add a comment logging moving the task between columns' => 'Sütun değiştiğinde kayıt olarak yorum ekle', + 'Moved to column %s' => '%s Sütununa taşındı', + 'Change description' => 'Açıklamayı değiştir', + 'User dashboard' => 'Kullanıcı Anasayfası', + 'Allow only one subtask in progress at the same time for a user' => 'Bir kullanıcı için aynı anda yalnızca bir alt göreve izin ver', + 'Edit column "%s"' => '"%s" sütununu değiştir', + 'Enable time tracking for subtasks' => 'Alt görevler için zaman takibini etkinleştir', + 'Select the new status of the subtask: "%s"' => '"%s" alt görevi için yeni durum seçin.', + 'Subtask timesheet' => 'Alt görev için zaman takip tablosu', + 'There is nothing to show.' => 'Gösterilecek hiçbir şey yok.', + 'Time Tracking' => 'Zaman takibi', + 'You already have one subtask in progress' => 'Zaten işlemde olan bir alt görev var', + 'Which parts of the project do you want to duplicate?' => 'Projenin hangi kısımlarının kopyasını oluşturmak istiyorsunuz?', + 'Change dashboard view' => 'Anasayfa görünümünü değiştir', + 'Show/hide activities' => 'Aktiviteleri göster/gizle', + 'Show/hide projects' => 'Projeleri göster/gizle', + 'Show/hide subtasks' => 'Alt görevleri göster/gizle', + 'Show/hide tasks' => 'Görevleri göster/gizle', + 'Disable login form' => 'Giriş formunu devre dışı bırak', + 'Show/hide calendar' => 'Takvimi göster/gizle', + 'User calendar' => 'Kullanıcı takvimi', + 'Bitbucket commit received' => 'Bitbucket commit alındı', + 'Bitbucket webhooks' => 'Bitbucket webhooks', + 'Help on Bitbucket webhooks' => 'Bitbucket webhooks için yardım', + 'Start' => 'Başlangıç', + 'End' => 'Son', + 'Task age in days' => 'Görev yaşı gün olarak', + 'Days in this column' => 'Bu sütunda geçirilen gün', + '%dd' => '%dG', + 'Add a link' => 'Link ekle', + 'Add a new link' => 'Yeni link ekle', + 'Do you really want to remove this link: "%s"?' => '"%s" linkini gerçekten silmek istiyor musunuz?', + 'Do you really want to remove this link with task #%d?' => '#%d numaralı görev ile linki gerçekten silmek istiyor musunuz?', + 'Field required' => 'Bu alan gerekli', + 'Link added successfully.' => 'Link başarıyla eklendi.', + 'Link updated successfully.' => 'Link başarıyla güncellendi.', + 'Link removed successfully.' => 'Link başarıyla silindi.', + 'Link labels' => 'Link etiketleri', + 'Link modification' => 'Link değiştirme', + 'Links' => 'Links', + 'Link settings' => 'Link ayarları', + 'Opposite label' => 'Zıt etiket', + 'Remove a link' => 'Bir link silmek', + 'Task\'s links' => 'Görevin linkleri', + 'The labels must be different' => 'Etiketler farklı olmalı', + 'There is no link.' => 'Hiç bir bağ yok', + 'This label must be unique' => 'Bu etiket tek olmalı', + 'Unable to create your link.' => 'Link oluşturulamadı.', + 'Unable to update your link.' => 'Link güncellenemiyor.', + 'Unable to remove this link.' => 'Link kaldırılamıyor', + 'relates to' => 'şununla ilgili', + 'blocks' => 'şunu engelliyor', + 'is blocked by' => 'şunun tarafından engelleniyor', + 'duplicates' => 'şunun kopyasını oluşturuyor', + 'is duplicated by' => 'şunun tarafından kopyası oluşturuluyor', + 'is a child of' => 'şunun astı', + 'is a parent of' => 'şunun üstü', + 'targets milestone' => 'şu kilometre taşını hedefliyor', + 'is a milestone of' => 'şunun için bir kilometre taşı', + 'fixes' => 'düzeltiyor', + 'is fixed by' => 'şunun tarafından düzeltildi', + 'This task' => 'Bu görev', + '<1h' => '<1s', + '%dh' => '%ds', + // '%b %e' => '', + 'Expand tasks' => 'Görevleri genişlet', + 'Collapse tasks' => 'Görevleri daralt', + 'Expand/collapse tasks' => 'Görevleri genişlet/daralt', + 'Close dialog box' => 'İletiyi kapat', + 'Submit a form' => 'Formu gönder', + 'Board view' => 'Tablo görünümü', + 'Keyboard shortcuts' => 'Klavye kısayolları', + 'Open board switcher' => 'Tablo seçim listesini aç', + 'Application' => 'Uygulama', + 'Filter recently updated' => 'Son güncellenenleri göster', + 'since %B %e, %Y at %k:%M %p' => '%B %e, %Y saat %k:%M %p\'den beri', + 'More filters' => 'Daha fazla filtre', + 'Compact view' => 'Ekrana sığdır', + 'Horizontal scrolling' => 'Geniş görünüm', + 'Compact/wide view' => 'Ekrana sığdır / Geniş görünüm', + // 'No results match:' => '', +); diff --git a/app/Locale/zh_CN/translations.php b/app/Locale/zh_CN/translations.php index cd1e2ebe..575fe442 100644 --- a/app/Locale/zh_CN/translations.php +++ b/app/Locale/zh_CN/translations.php @@ -379,7 +379,7 @@ return array( 'Created by %s' => '创建者:%s', 'Last modified on %B %e, %Y at %k:%M %p' => '最后修改:%Y/%m/%d/ %H:%M', 'Tasks Export' => '任务导出', - 'Tasks exportation for "%s"' => '导出任务"%s"', + 'Tasks exportation for "%s"' => '导出"%s"的任务', 'Start Date' => '开始时间', 'End Date' => '结束时间', 'Execute' => '执行', @@ -408,13 +408,13 @@ return array( 'Comment updated' => '更新了评论', 'New comment posted by %s' => '%s 的新评论', 'List of due tasks for the project "%s"' => '项目"%s"的到期任务列表', - // 'New attachment' => '', - // 'New comment' => '', - // 'New subtask' => '', - // 'Subtask updated' => '', - // 'Task updated' => '', - // 'Task closed' => '', - // 'Task opened' => '', + 'New attachment' => '新建附件', + 'New comment' => '新建评论', + 'New subtask' => '新建子任务', + 'Subtask updated' => '子任务更新', + 'Task updated' => '任务更新', + 'Task closed' => '任务关闭', + 'Task opened' => '任务开启', '[%s][Due tasks]' => '[%s][到期任务]', '[Kanboard] Notification' => '[Kanboard] 通知', 'I want to receive notifications only for those projects:' => '我仅需要收到下面项目的通知:', @@ -498,9 +498,9 @@ return array( 'Task assignee change' => '任务分配变更', '%s change the assignee of the task #%d to %s' => '%s 将任务 #%d 分配给了 %s', '%s changed the assignee of the task %s to %s' => '%s 将任务 %s 分配给 %s', - // 'Column Change' => '', - // 'Position Change' => '', - // 'Assignee Change' => '', + 'Column Change' => '栏目变更', + 'Position Change' => '位置变更', + 'Assignee Change' => '负责人变更', 'New password for the user "%s"' => '用户"%s"的新密码', 'Choose an event' => '选择一个事件', 'Github commit received' => '收到了Github提交', @@ -607,8 +607,8 @@ return array( 'Default swimlane' => '默认泳道', 'Do you really want to remove this swimlane: "%s"?' => '确定要删除泳道:"%s"?', 'Inactive swimlanes' => '非活动泳道', - // 'Set project manager' => '', - // 'Set project member' => '', + 'Set project manager' => '设为项目经理', + 'Set project member' => '设为项目成员', 'Remove a swimlane' => '删除泳道', 'Rename' => '重命名', 'Show default swimlane' => '显示默认泳道', @@ -622,92 +622,92 @@ return array( 'Unable to remove this swimlane.' => '无法删除此泳道', 'Unable to update this swimlane.' => '无法更新此泳道', 'Your swimlane have been created successfully.' => '已经成功创建泳道。', - // 'Example: "Bug, Feature Request, Improvement"' => '', - // 'Default categories for new projects (Comma-separated)' => '', - // 'Gitlab commit received' => '', - // 'Gitlab issue opened' => '', - // 'Gitlab issue closed' => '', - // 'Gitlab webhooks' => '', - // 'Help on Gitlab webhooks' => '', - // 'Integrations' => '', - // 'Integration with third-party services' => '', - // 'Role for this project' => '', - // 'Project manager' => '', - // 'Project member' => '', - // 'A project manager can change the settings of the project and have more privileges than a standard user.' => '', - // 'Gitlab Issue' => '', - // 'Subtask Id' => '', - // 'Subtasks' => '', - // 'Subtasks Export' => '', - // 'Subtasks exportation for "%s"' => '', - // 'Task Title' => '', - // 'Untitled' => '', - // 'Application default' => '', - // 'Language:' => '', - // 'Timezone:' => '', - // 'All columns' => '', - // 'Calendar for "%s"' => '', - // 'Filter by column' => '', - // 'Filter by status' => '', - // 'Calendar' => '', - // 'Next' => '', - // '#%d' => '', - // 'Filter by color' => '', - // 'Filter by swimlane' => '', - // 'All swimlanes' => '', - // 'All colors' => '', - // 'All status' => '', - // 'Add a comment logging moving the task between columns' => '', - // 'Moved to column %s' => '', - // 'Change description' => '', - // 'User dashboard' => '', - // 'Allow only one subtask in progress at the same time for a user' => '', - // 'Edit column "%s"' => '', - // 'Enable time tracking for subtasks' => '', - // 'Select the new status of the subtask: "%s"' => '', - // 'Subtask timesheet' => '', - // 'There is nothing to show.' => '', - // 'Time Tracking' => '', - // 'You already have one subtask in progress' => '', - // 'Which parts of the project do you want to duplicate?' => '', - // 'Change dashboard view' => '', - // 'Show/hide activities' => '', - // 'Show/hide projects' => '', - // 'Show/hide subtasks' => '', - // 'Show/hide tasks' => '', - // 'Disable login form' => '', - // 'Show/hide calendar' => '', - // 'User calendar' => '', - // 'Bitbucket commit received' => '', - // 'Bitbucket webhooks' => '', - // 'Help on Bitbucket webhooks' => '', - // 'Start' => '', - // 'End' => '', - // 'Task age in days' => '', - // 'Days in this column' => '', - // '%dd' => '', - // 'Add a link' => '', - // 'Add a new link' => '', - // 'Do you really want to remove this link: "%s"?' => '', - // 'Do you really want to remove this link with task #%d?' => '', - // 'Field required' => '', - // 'Link added successfully.' => '', - // 'Link updated successfully.' => '', - // 'Link removed successfully.' => '', - // 'Link labels' => '', - // 'Link modification' => '', - // 'Links' => '', - // 'Link settings' => '', - // 'Opposite label' => '', - // 'Remove a link' => '', - // 'Task\'s links' => '', - // 'The labels must be different' => '', - // 'There is no link.' => '', - // 'This label must be unique' => '', - // 'Unable to create your link.' => '', - // 'Unable to update your link.' => '', - // 'Unable to remove this link.' => '', - // 'relates to' => '', + 'Example: "Bug, Feature Request, Improvement"' => '示例:“缺陷,功能需求,提升', + 'Default categories for new projects (Comma-separated)' => '新项目的默认分类(用逗号分隔)', + 'Gitlab commit received' => '收到 Gitlab 提交', + 'Gitlab issue opened' => '开启 Gitlab 问题', + 'Gitlab issue closed' => '关闭 Gitlab 问题', + 'Gitlab webhooks' => 'Gitlab 网络钩子', + 'Help on Gitlab webhooks' => 'Gitlab 网络钩子帮助', + 'Integrations' => '整合', + 'Integration with third-party services' => '与第三方服务进行整合', + 'Role for this project' => '项目角色', + 'Project manager' => '项目管理员', + 'Project member' => '项目成员', + 'A project manager can change the settings of the project and have more privileges than a standard user.' => '项目经理可以修改项目的设置,比标准用户多了一些权限', + 'Gitlab Issue' => 'Gitlab 问题', + 'Subtask Id' => '子任务 Id', + 'Subtasks' => '子任务', + 'Subtasks Export' => '子任务导出', + 'Subtasks exportation for "%s"' => '导出"%s"的子任务', + 'Task Title' => '任务标题', + 'Untitled' => '无标题', + 'Application default' => '程序默认', + 'Language:' => '语言:', + 'Timezone:' => '时区:', + 'All columns' => '全部栏目', + 'Calendar for "%s"' => '"%s"的日程表', + 'Filter by column' => '按栏目过滤', + 'Filter by status' => '按状态过滤', + 'Calendar' => '日程表', + 'Next' => '前进', + '#%d' => '#%d', + 'Filter by color' => '按颜色过滤', + 'Filter by swimlane' => '按泳道过滤', + 'All swimlanes' => '全部泳道', + 'All colors' => '全部颜色', + 'All status' => '全部状态', + 'Add a comment logging moving the task between columns' => '在不同栏目间移动任务时添加一个评论', + 'Moved to column %s' => '移动到栏目 %s', + 'Change description' => '修改描述', + 'User dashboard' => '用户仪表板', + 'Allow only one subtask in progress at the same time for a user' => '每用户同时仅有一个活动子任务', + 'Edit column "%s"' => '编辑栏目"%s"', + 'Enable time tracking for subtasks' => '启用子任务的时间记录', + 'Select the new status of the subtask: "%s"' => '选择子任务的新状态:"%s"', + 'Subtask timesheet' => '子任务时间', + 'There is nothing to show.' => '无内容。', + 'Time Tracking' => '时间记录', + 'You already have one subtask in progress' => '你已经有了一个进行中的子任务', + 'Which parts of the project do you want to duplicate?' => '要复制项目的哪些内容?', + 'Change dashboard view' => '修改仪表板视图', + 'Show/hide activities' => '显示/隐藏活动', + 'Show/hide projects' => '显示/隐藏项目', + 'Show/hide subtasks' => '显示/隐藏子任务', + 'Show/hide tasks' => '显示/隐藏任务', + 'Disable login form' => '禁用登录界面', + 'Show/hide calendar' => '显示/隐藏日程表', + 'User calendar' => '用户日程表', + 'Bitbucket commit received' => '收到Bitbucket提交', + 'Bitbucket webhooks' => 'Bitbucket网络钩子', + 'Help on Bitbucket webhooks' => 'Bitbucket网络钩子帮助', + 'Start' => '开始', + 'End' => '结束', + 'Task age in days' => '任务存在天数', + 'Days in this column' => '在此栏目的天数', + '%dd' => '%d天', + 'Add a link' => '添加一个关联', + 'Add a new link' => '添加一个新关联', + 'Do you really want to remove this link: "%s"?' => '确认要删除此关联吗:"%s"?', + 'Do you really want to remove this link with task #%d?' => '确认要删除到任务 #%d 的关联吗?', + 'Field required' => '必须的字段', + 'Link added successfully.' => '成功添加关联。', + 'Link updated successfully.' => '成功更新关联。', + 'Link removed successfully.' => '成功删除关联。', + 'Link labels' => '关联标签', + 'Link modification' => '关联修改', + 'Links' => '关联', + 'Link settings' => '关联设置', + 'Opposite label' => '反向标签', + 'Remove a link' => '删除关联', + 'Task\'s links' => '任务的关联', + 'The labels must be different' => '标签不能一样', + 'There is no link.' => '没有关联', + 'This label must be unique' => '关联必须唯一', + 'Unable to create your link.' => '无法创建关联。', + 'Unable to update your link.' => '无法更新关联。', + 'Unable to remove this link.' => '无法删除关联。', + 'relates to' => '关联到', // 'blocks' => '', // 'is blocked by' => '', // 'duplicates' => '', @@ -718,20 +718,24 @@ return array( // 'is a milestone of' => '', // 'fixes' => '', // 'is fixed by' => '', - // 'This task' => '', + 'This task' => '此任务', // '<1h' => '', // '%dh' => '', // '%b %e' => '', - // 'Expand tasks' => '', - // 'Collapse tasks' => '', - // 'Expand/collapse tasks' => '', - // 'Close dialog box' => '', - // 'Submit a form' => '', - // 'Board view' => '', - // 'Keyboard shortcuts' => '', - // 'Open board switcher' => '', - // 'Application' => '', - // 'Filter recently updated' => '', + 'Expand tasks' => '展开任务', + 'Collapse tasks' => '收缩任务', + 'Expand/collapse tasks' => '展开/收缩任务', + 'Close dialog box' => '关闭对话框', + 'Submit a form' => '提交表单', + 'Board view' => '面板视图', + 'Keyboard shortcuts' => '键盘快捷方式', + 'Open board switcher' => '打开面板切换器', + 'Application' => '应用程序', + 'Filter recently updated' => '过滤最近的更新', // 'since %B %e, %Y at %k:%M %p' => '', - // 'More filters' => '', + 'More filters' => '更多过滤', + // 'Compact view' => '', + // 'Horizontal scrolling' => '', + // 'Compact/wide view' => '', + // 'No results match:' => '', ); diff --git a/app/Model/Action.php b/app/Model/Action.php index 6fb2a2f1..99fb8b73 100644 --- a/app/Model/Action.php +++ b/app/Model/Action.php @@ -211,7 +211,7 @@ class Action extends Base * * @access public * @param array $values Required parameters to save an action - * @return bool Success or not + * @return integer */ public function create(array $values) { @@ -248,7 +248,7 @@ class Action extends Base // $this->container['fileCache']->remove('proxy_action_getAll'); - return true; + return $action_id; } /** diff --git a/app/Model/Config.php b/app/Model/Config.php index 48640f4e..3ee6bfdf 100644 --- a/app/Model/Config.php +++ b/app/Model/Config.php @@ -63,6 +63,7 @@ class Config extends Base 'ru_RU' => 'Русский', 'fi_FI' => 'Suomi', 'sv_SE' => 'Svenska', + 'tr_TR' => 'Türkçe', 'zh_CN' => '中文(简体)', 'ja_JP' => '日本語', 'th_TH' => 'ไทย', @@ -99,6 +100,7 @@ class Config extends Base 'zh_CN' => 'zh-cn', 'ja_JP' => 'ja', 'th_TH' => 'th', + 'tr_TR' => 'tr', ); $lang = $this->getCurrentLanguage(); diff --git a/app/Model/File.php b/app/Model/File.php index 1b9351db..f069c8cf 100644 --- a/app/Model/File.php +++ b/app/Model/File.php @@ -17,7 +17,7 @@ class File extends Base * * @var string */ - const TABLE = 'task_has_files'; + const TABLE = 'files'; /** * Events diff --git a/app/Model/Subtask.php b/app/Model/Subtask.php index 048594bd..2d108eab 100644 --- a/app/Model/Subtask.php +++ b/app/Model/Subtask.php @@ -19,7 +19,7 @@ class Subtask extends Base * * @var string */ - const TABLE = 'task_has_subtasks'; + const TABLE = 'subtasks'; /** * Task "done" status @@ -122,7 +122,7 @@ class Subtask extends Base ->eq('task_id', $task_id) ->columns(self::TABLE.'.*', User::TABLE.'.username', User::TABLE.'.name') ->join(User::TABLE, 'id', 'user_id') - ->asc(self::TABLE.'.id') + ->asc(self::TABLE.'.position') ->filter(array($this, 'addStatusName')) ->findAll(); } @@ -164,6 +164,22 @@ class Subtask extends Base } /** + * Get the position of the last column for a given project + * + * @access public + * @param integer $task_id Task id + * @return integer + */ + public function getLastPosition($task_id) + { + return (int) $this->db + ->table(self::TABLE) + ->eq('task_id', $task_id) + ->desc('position') + ->findOneColumn('position'); + } + + /** * Create a new subtask * * @access public @@ -173,6 +189,8 @@ class Subtask extends Base public function create(array $values) { $this->prepare($values); + $values['position'] = $this->getLastPosition($values['task_id']) + 1; + $subtask_id = $this->persist(self::TABLE, $values); if ($subtask_id) { @@ -209,6 +227,64 @@ class Subtask extends Base } /** + * Move a subtask down, increment the position value + * + * @access public + * @param integer $task_id + * @param integer $subtask_id + * @return boolean + */ + public function moveDown($task_id, $subtask_id) + { + $subtasks = $this->db->hashtable(self::TABLE)->eq('task_id', $task_id)->asc('position')->getAll('id', 'position'); + $positions = array_flip($subtasks); + + if (isset($subtasks[$subtask_id]) && $subtasks[$subtask_id] < count($subtasks)) { + + $position = ++$subtasks[$subtask_id]; + $subtasks[$positions[$position]]--; + + $this->db->startTransaction(); + $this->db->table(self::TABLE)->eq('id', $subtask_id)->update(array('position' => $position)); + $this->db->table(self::TABLE)->eq('id', $positions[$position])->update(array('position' => $subtasks[$positions[$position]])); + $this->db->closeTransaction(); + + return true; + } + + return false; + } + + /** + * Move a subtask up, decrement the position value + * + * @access public + * @param integer $task_id + * @param integer $subtask_id + * @return boolean + */ + public function moveUp($task_id, $subtask_id) + { + $subtasks = $this->db->hashtable(self::TABLE)->eq('task_id', $task_id)->asc('position')->getAll('id', 'position'); + $positions = array_flip($subtasks); + + if (isset($subtasks[$subtask_id]) && $subtasks[$subtask_id] > 1) { + + $position = --$subtasks[$subtask_id]; + $subtasks[$positions[$position]]++; + + $this->db->startTransaction(); + $this->db->table(self::TABLE)->eq('id', $subtask_id)->update(array('position' => $position)); + $this->db->table(self::TABLE)->eq('id', $positions[$position])->update(array('position' => $subtasks[$positions[$position]])); + $this->db->closeTransaction(); + + return true; + } + + return false; + } + + /** * Change the status of subtask * * Todo -> In progress -> Done -> Todo -> etc... @@ -286,9 +362,9 @@ class Subtask extends Base return $this->db->transaction(function ($db) use ($src_task_id, $dst_task_id) { $subtasks = $db->table(Subtask::TABLE) - ->columns('title', 'time_estimated') + ->columns('title', 'time_estimated', 'position') ->eq('task_id', $src_task_id) - ->asc('id') // Explicit sorting for postgresql + ->asc('position') ->findAll(); foreach ($subtasks as &$subtask) { diff --git a/app/Model/Swimlane.php b/app/Model/Swimlane.php index c9bc43e1..8f417fca 100644 --- a/app/Model/Swimlane.php +++ b/app/Model/Swimlane.php @@ -75,6 +75,22 @@ class Swimlane extends Base } /** + * Get a swimlane by the project and the name + * + * @access public + * @param integer $project_id Project id + * @param string $name Swimlane name + * @return array + */ + public function getByName($project_id, $name) + { + return $this->db->table(self::TABLE) + ->eq('project_id', $project_id) + ->eq('name', $name) + ->findAll(); + } + + /** * Get default swimlane properties * * @access public diff --git a/app/Model/TaskFinder.php b/app/Model/TaskFinder.php index 98ece4e1..7216e92a 100644 --- a/app/Model/TaskFinder.php +++ b/app/Model/TaskFinder.php @@ -80,11 +80,11 @@ class TaskFinder extends Base return $this->db ->table(Task::TABLE) ->columns( - '(SELECT count(*) FROM comments WHERE task_id=tasks.id) AS nb_comments', - '(SELECT count(*) FROM task_has_files WHERE task_id=tasks.id) AS nb_files', - '(SELECT count(*) FROM task_has_subtasks WHERE task_id=tasks.id) AS nb_subtasks', - '(SELECT count(*) FROM task_has_subtasks WHERE task_id=tasks.id AND status=2) AS nb_completed_subtasks', - '(SELECT count(*) FROM ' . TaskLink::TABLE . ' WHERE ' . TaskLink::TABLE . '.task_id = tasks.id) AS nb_links', + '(SELECT count(*) FROM '.Comment::TABLE.' WHERE task_id=tasks.id) AS nb_comments', + '(SELECT count(*) FROM '.File::TABLE.' WHERE task_id=tasks.id) AS nb_files', + '(SELECT count(*) FROM '.Subtask::TABLE.' WHERE '.Subtask::TABLE.'.task_id=tasks.id) AS nb_subtasks', + '(SELECT count(*) FROM '.Subtask::TABLE.' WHERE '.Subtask::TABLE.'.task_id=tasks.id AND status=2) AS nb_completed_subtasks', + '(SELECT count(*) FROM '.TaskLink::TABLE.' WHERE '.TaskLink::TABLE.'.task_id = tasks.id) AS nb_links', 'tasks.id', 'tasks.reference', 'tasks.title', diff --git a/app/Schema/Mysql.php b/app/Schema/Mysql.php index 947a62b3..21c304c1 100644 --- a/app/Schema/Mysql.php +++ b/app/Schema/Mysql.php @@ -6,7 +6,40 @@ use PDO; use Core\Security; use Model\Link; -const VERSION = 46; +const VERSION = 49; + +function version_49($pdo) +{ + $pdo->exec('ALTER TABLE subtasks ADD COLUMN position INTEGER DEFAULT 1'); + + $task_id = 0; + $urq = $pdo->prepare('UPDATE subtasks SET position=? WHERE id=?'); + + $rq = $pdo->prepare('SELECT * FROM subtasks ORDER BY task_id, id ASC'); + $rq->execute(); + + foreach ($rq->fetchAll(PDO::FETCH_ASSOC) as $subtask) { + + if ($task_id != $subtask['task_id']) { + $position = 1; + $task_id = $subtask['task_id']; + } + + $urq->execute(array($position, $subtask['id'])); + $position++; + } +} + +function version_48($pdo) +{ + $pdo->exec('RENAME TABLE task_has_files TO files'); + $pdo->exec('RENAME TABLE task_has_subtasks TO subtasks'); +} + +function version_47($pdo) +{ + $pdo->exec('ALTER TABLE projects ADD COLUMN description TEXT'); +} function version_46($pdo) { diff --git a/app/Schema/Postgres.php b/app/Schema/Postgres.php index 027401ff..df003267 100644 --- a/app/Schema/Postgres.php +++ b/app/Schema/Postgres.php @@ -6,7 +6,40 @@ use PDO; use Core\Security; use Model\Link; -const VERSION = 27; +const VERSION = 30; + +function version_30($pdo) +{ + $pdo->exec('ALTER TABLE subtasks ADD COLUMN position INTEGER DEFAULT 1'); + + $task_id = 0; + $urq = $pdo->prepare('UPDATE subtasks SET position=? WHERE id=?'); + + $rq = $pdo->prepare('SELECT * FROM subtasks ORDER BY task_id, id ASC'); + $rq->execute(); + + foreach ($rq->fetchAll(PDO::FETCH_ASSOC) as $subtask) { + + if ($task_id != $subtask['task_id']) { + $position = 1; + $task_id = $subtask['task_id']; + } + + $urq->execute(array($position, $subtask['id'])); + $position++; + } +} + +function version_29($pdo) +{ + $pdo->exec('ALTER TABLE task_has_files RENAME TO files'); + $pdo->exec('ALTER TABLE task_has_subtasks RENAME TO subtasks'); +} + +function version_28($pdo) +{ + $pdo->exec('ALTER TABLE projects ADD COLUMN description TEXT'); +} function version_27($pdo) { diff --git a/app/Schema/Sqlite.php b/app/Schema/Sqlite.php index c6dec33f..9134760f 100644 --- a/app/Schema/Sqlite.php +++ b/app/Schema/Sqlite.php @@ -6,7 +6,42 @@ use Core\Security; use PDO; use Model\Link; -const VERSION = 45; +const VERSION = 48; + +function version_48($pdo) +{ + $pdo->exec('ALTER TABLE subtasks ADD COLUMN position INTEGER DEFAULT 1'); + + // Migrate all subtasks position + + $task_id = 0; + $urq = $pdo->prepare('UPDATE subtasks SET position=? WHERE id=?'); + + $rq = $pdo->prepare('SELECT * FROM subtasks ORDER BY task_id, id ASC'); + $rq->execute(); + + foreach ($rq->fetchAll(PDO::FETCH_ASSOC) as $subtask) { + + if ($task_id != $subtask['task_id']) { + $position = 1; + $task_id = $subtask['task_id']; + } + + $urq->execute(array($position, $subtask['id'])); + $position++; + } +} + +function version_47($pdo) +{ + $pdo->exec('ALTER TABLE task_has_files RENAME TO files'); + $pdo->exec('ALTER TABLE task_has_subtasks RENAME TO subtasks'); +} + +function version_46($pdo) +{ + $pdo->exec('ALTER TABLE projects ADD COLUMN description TEXT'); +} function version_45($pdo) { diff --git a/app/Template/app/dashboard.php b/app/Template/app/dashboard.php index e6f124e1..5b83540c 100644 --- a/app/Template/app/dashboard.php +++ b/app/Template/app/dashboard.php @@ -11,8 +11,8 @@ <li><i class="fa fa-cog fa-fw"></i><?= $this->a(t('Settings'), 'config', 'index') ?></li> <?php endif ?> <li> - <ul class="dropdown"> - <li> + <span class="dropdown"> + <span> <i class="fa fa-caret-down"></i> <a href="#" class="dropdown-menu"><?= t('Change dashboard view') ?></a> <ul> <li> @@ -31,8 +31,8 @@ <a href="#" class="dashboard-toggle" data-toggle="activities"><?= t('Show/hide activities') ?></a> </li> </ul> - </li> - </ul> + </span> + </span> </li> </ul> </div> diff --git a/app/Template/app/projects.php b/app/Template/app/projects.php index 4740c4b8..b2744644 100644 --- a/app/Template/app/projects.php +++ b/app/Template/app/projects.php @@ -17,9 +17,15 @@ <?php if ($this->isManager($project['id'])): ?> <?= $this->a('<i class="fa fa-cog"></i>', 'project', 'show', array('project_id' => $project['id']), false, 'dashboard-table-link', t('Settings')) ?> <?php endif ?> - + <?= $this->a('<i class="fa fa-calendar"></i>', 'calendar', 'show', array('project_id' => $project['id']), false, 'dashboard-table-link', t('Calendar')) ?> + <?= $this->a($this->e($project['name']), 'board', 'show', array('project_id' => $project['id'])) ?> + <?php if (! empty($project['description'])): ?> + <span class="column-tooltip" title='<?= $this->e($this->markdown($project['description'])) ?>'> + <i class="fa fa-info-circle"></i> + </span> + <?php endif ?> </td> <td class="dashboard-project-stats"> <?php foreach ($project['columns'] as $column): ?> @@ -32,4 +38,4 @@ </table> <?= $paginator ?> -<?php endif ?>
\ No newline at end of file +<?php endif ?> diff --git a/app/Template/board/edit.php b/app/Template/board/edit.php index b9b1788a..a6df1000 100644 --- a/app/Template/board/edit.php +++ b/app/Template/board/edit.php @@ -13,7 +13,7 @@ <tr> <td class="column-60"><?= $this->e($column['title']) ?> <?php if (! empty($column['description'])): ?> - <span class="column-tooltip" title="<?= $this->markdown($column['description']) ?>"> + <span class="column-tooltip" title='<?= $this->e($this->markdown($column['description'])) ?>'> <i class="fa fa-info-circle"></i> </span> <?php endif ?> @@ -52,12 +52,12 @@ <?= $this->formLabel(t('Title'), 'title') ?> <?= $this->formText('title', $values, $errors, array('required', 'maxlength="50"')) ?> - + <?= $this->formLabel(t('Task limit'), 'task_limit') ?> <?= $this->formNumber('task_limit', $values, $errors) ?> - + <?= $this->formLabel(t('Description'), 'description') ?> - + <div class="form-tabs"> <div class="write-area"> <?= $this->formTextarea('description', $values, $errors) ?> diff --git a/app/Template/board/filters.php b/app/Template/board/filters.php index a0de5fd9..2dd559b9 100644 --- a/app/Template/board/filters.php +++ b/app/Template/board/filters.php @@ -1,8 +1,8 @@ <div class="page-header"> <ul class="board-filters"> <li> - <ul class="dropdown"> - <li> + <span class="dropdown"> + <span> <i class="fa fa-caret-down"></i> <a href="#" class="dropdown-menu"><?= t('Actions') ?></a> <ul> <li> @@ -14,6 +14,14 @@ </span> </li> <li> + <span class="filter-compact"> + <i class="fa fa-th fa-fw"></i> <a href="#" class="filter-toggle-scrolling"><?= t('Compact view') ?></a> + </span> + <span class="filter-wide" style="display: none"> + <i class="fa fa-arrows-h fa-fw"></i> <a href="#" class="filter-toggle-scrolling"><?= t('Horizontal scrolling') ?></a> + </span> + </li> + <li> <i class="fa fa-search fa-fw"></i> <?= $this->a(t('Search'), 'project', 'search', array('project_id' => $project['id'])) ?> </li> @@ -45,17 +53,17 @@ </li> <?php endif ?> </ul> - </li> - </ul> + </span> + </span> </li> <li> - <?= $this->formSelect('user_id', $users, array(), array(), array('data-placeholder="'.t('Filter by user').'"'), 'apply-filters chosen-select') ?> + <?= $this->formSelect('user_id', $users, array(), array(), array('data-placeholder="'.t('Filter by user').'"', 'data-notfound="'.t('No results match:').'"'), 'apply-filters chosen-select') ?> </li> <li> - <?= $this->formSelect('category_id', $categories, array(), array(), array('data-placeholder="'.t('Filter by category').'"'), 'apply-filters chosen-select') ?> + <?= $this->formSelect('category_id', $categories, array(), array(), array('data-placeholder="'.t('Filter by category').'"', 'data-notfound="'.t('No results match:').'"'), 'apply-filters chosen-select') ?> </li> <li> - <select id="more-filters" multiple data-placeholder="<?= t('More filters') ?>" class="apply-filters chosen-select hide-mobile"> + <select id="more-filters" multiple data-placeholder="<?= t('More filters') ?>" data-notfound="<?= t('No results match:') ?>" class="apply-filters chosen-select hide-mobile"> <option value=""></option> <option value="filter-due-date"><?= t('Filter by due date') ?></option> <option value="filter-recent"><?= t('Filter recently updated') ?></option> diff --git a/app/Template/board/swimlane.php b/app/Template/board/swimlane.php index ec298e24..744610ab 100644 --- a/app/Template/board/swimlane.php +++ b/app/Template/board/swimlane.php @@ -28,7 +28,7 @@ <?= $this->e($column['title']) ?> <?php if (! empty($column['description'])): ?> - <span class="column-tooltip pull-right" title="<?= $this->markdown($column['description']) ?>"> + <span class="column-tooltip pull-right" title='<?= $this->e($this->markdown($column['description'])) ?>'> <i class="fa fa-info-circle"></i> </span> <?php endif ?> diff --git a/app/Template/board/task_footer.php b/app/Template/board/task_footer.php index d413692c..8abea043 100644 --- a/app/Template/board/task_footer.php +++ b/app/Template/board/task_footer.php @@ -22,19 +22,19 @@ <?php endif ?> <?php if (! empty($task['nb_links'])): ?> - <span title="<?= t('Links') ?>" class="task-board-tooltip" data-href="<?= $this->u('board', 'tasklinks', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>"><?= $task['nb_links'] ?> <i class="fa fa-code-fork"></i></span> + <span title="<?= t('Links') ?>" class="task-board-tooltip" data-href="<?= $this->u('board', 'tasklinks', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>"><i class="fa fa-code-fork"></i> <?= $task['nb_links'] ?></span> <?php endif ?> <?php if (! empty($task['nb_subtasks'])): ?> - <span title="<?= t('Sub-Tasks') ?>" class="task-board-tooltip" data-href="<?= $this->u('board', 'subtasks', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>"><?= round($task['nb_completed_subtasks']/$task['nb_subtasks']*100, 0).'%' ?> <i class="fa fa-bars"></i></span> + <span title="<?= t('Sub-Tasks') ?>" class="task-board-tooltip" data-href="<?= $this->u('board', 'subtasks', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>"><i class="fa fa-bars"></i> <?= round($task['nb_completed_subtasks']/$task['nb_subtasks']*100, 0).'%' ?></span> <?php endif ?> <?php if (! empty($task['nb_files'])): ?> - <span title="<?= t('Attachments') ?>" class="task-board-tooltip" data-href="<?= $this->u('board', 'attachments', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>"><?= $task['nb_files'] ?> <i class="fa fa-paperclip"></i></span> + <span title="<?= t('Attachments') ?>" class="task-board-tooltip" data-href="<?= $this->u('board', 'attachments', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>"><i class="fa fa-paperclip"></i> <?= $task['nb_files'] ?></span> <?php endif ?> <?php if (! empty($task['nb_comments'])): ?> - <span title="<?= p($task['nb_comments'], t('%d comment', $task['nb_comments']), t('%d comments', $task['nb_comments'])) ?>" class="task-board-tooltip" data-href="<?= $this->u('board', 'comments', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>"><?= $task['nb_comments'] ?> <i class="fa fa-comment-o"></i></span> + <span title="<?= p($task['nb_comments'], t('%d comment', $task['nb_comments']), t('%d comments', $task['nb_comments'])) ?>" class="task-board-tooltip" data-href="<?= $this->u('board', 'comments', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>"><i class="fa fa-comment-o"></i> <?= $task['nb_comments'] ?></span> <?php endif ?> <?php if (! empty($task['description'])): ?> @@ -42,4 +42,4 @@ <i class="fa fa-file-text-o"></i> </span> <?php endif ?> -</div>
\ No newline at end of file +</div> diff --git a/app/Template/board/task_menu.php b/app/Template/board/task_menu.php index e7e0f419..bbf12291 100644 --- a/app/Template/board/task_menu.php +++ b/app/Template/board/task_menu.php @@ -1,5 +1,5 @@ -<ul class="dropdown"> - <li> +<span class="dropdown"> + <span> <a href="#" class="dropdown-menu"><?= '#'.$task['id'] ?></a> <ul> <li><i class="fa fa-user"></i> <?= $this->a(t('Change assignee'), 'board', 'changeAssignee', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'task-board-popover') ?></li> @@ -9,5 +9,5 @@ <li><i class="fa fa-pencil-square-o"></i> <?= $this->a(t('Edit this task'), 'task', 'edit', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'task-board-popover') ?></li> <li><i class="fa fa-close"></i> <?= $this->a(t('Close this task'), 'task', 'close', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'redirect' => 'board'), false, 'task-board-popover') ?></li> </ul> - </li> -</ul>
\ No newline at end of file + </span> +</span>
\ No newline at end of file diff --git a/app/Template/config/about.php b/app/Template/config/about.php index f6474e21..b6ed43e5 100644 --- a/app/Template/config/about.php +++ b/app/Template/config/about.php @@ -46,6 +46,7 @@ <ul> <li><?= t('New task') ?> = <strong>n</strong></li> <li><?= t('Expand/collapse tasks') ?> = <strong>s</strong></li> + <li><?= t('Compact/wide view') ?> = <strong>c</strong></li> </ul> <h3><?= t('Application') ?></h3> <ul> diff --git a/app/Template/layout.php b/app/Template/layout.php index ad4c4084..9290a21e 100644 --- a/app/Template/layout.php +++ b/app/Template/layout.php @@ -35,11 +35,17 @@ <?php else: ?> <header> <nav> - <h1><?= $this->a('K<span>B</span>', 'app', 'index', array(), false, 'logo', t('Dashboard')).' '.$this->summary($this->e($title)) ?></h1> + <h1><?= $this->a('K<span>B</span>', 'app', 'index', array(), false, 'logo', t('Dashboard')).' '.$this->summary($this->e($title)) ?> + <?php if (! empty($description)): ?> + <span class="column-tooltip" title='<?= $this->e($this->markdown($description)) ?>'> + <i class="fa fa-info-circle"></i> + </span> + <?php endif ?> + </h1> <ul> <?php if (isset($board_selector) && ! empty($board_selector)): ?> <li> - <select id="board-selector" data-placeholder="<?= t('Display another project') ?>" data-board-url="<?= $this->u('board', 'show', array('project_id' => 'PROJECT_ID')) ?>"> + <select id="board-selector" data-notfound="<?= t('No results match:') ?>" data-placeholder="<?= t('Display another project') ?>" data-board-url="<?= $this->u('board', 'show', array('project_id' => 'PROJECT_ID')) ?>"> <option value=""></option> <?php foreach($board_selector as $board_id => $board_name): ?> <option value="<?= $board_id ?>"><?= $this->e($board_name) ?></option> diff --git a/app/Template/project/edit.php b/app/Template/project/edit.php index a1b945cd..37b03fe1 100644 --- a/app/Template/project/edit.php +++ b/app/Template/project/edit.php @@ -9,7 +9,28 @@ <?= $this->formLabel(t('Name'), 'name') ?> <?= $this->formText('name', $values, $errors, array('required', 'maxlength="50"')) ?> + <?= $this->formLabel(t('Description'), 'description') ?> + + <div class="form-tabs"> + + <div class="write-area"> + <?= $this->formTextarea('description', $values, $errors) ?> + </div> + <div class="preview-area"> + <div class="markdown"></div> + </div> + <ul class="form-tabs-nav"> + <li class="form-tab form-tab-selected"> + <i class="fa fa-pencil-square-o fa-fw"></i><a id="markdown-write" href="#"><?= t('Write') ?></a> + </li> + <li class="form-tab"> + <a id="markdown-preview" href="#"><i class="fa fa-eye fa-fw"></i><?= t('Preview') ?></a> + </li> + </ul> + </div> + <div class="form-help"><a href="http://kanboard.net/documentation/syntax-guide" target="_blank" rel="noreferrer"><?= t('Write your text in Markdown') ?></a></div> + <div class="form-actions"> <input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/> </div> -</form>
\ No newline at end of file +</form> diff --git a/app/Template/project/index.php b/app/Template/project/index.php index a36a9ce1..05a7d955 100644 --- a/app/Template/project/index.php +++ b/app/Template/project/index.php @@ -39,7 +39,13 @@ <?php if ($project['is_private']): ?> <i class="fa fa-lock fa-fw"></i> <?php endif ?> + <?= $this->a($this->e($project['name']), 'project', 'show', array('project_id' => $project['id'])) ?> + <?php if (! empty($project['description'])): ?> + <span class="column-tooltip" title='<?= $this->e($this->markdown($project['description'])) ?>'> + <i class="fa fa-info-circle"></i> + </span> + <?php endif ?> </td> <td class="dashboard-project-stats"> <?php foreach ($project['columns'] as $column): ?> @@ -54,4 +60,4 @@ <?= $paginator ?> <?php endif ?> </section> -</section>
\ No newline at end of file +</section> diff --git a/app/Template/project/show.php b/app/Template/project/show.php index b8bfd510..9c6cd1a8 100644 --- a/app/Template/project/show.php +++ b/app/Template/project/show.php @@ -50,7 +50,7 @@ <td> <?= $this->e($column['title']) ?> <?php if (! empty($column['description'])): ?> - <span class="column-tooltip" title="<?= $this->markdown($column['description']) ?>"> + <span class="column-tooltip" title='<?= $this->e($this->markdown($column['description'])) ?>'> <i class="fa fa-info-circle"></i> </span> <?php endif ?> @@ -60,3 +60,13 @@ </tr> <?php endforeach ?> </table> + +<?php if (! empty($project['description'])): ?> + <div class="page-header"> + <h2><?= t('Description') ?></h2> + </div> + + <article class="markdown"> + <?= $this->markdown($project['description']) ?> + </article> +<?php endif ?> diff --git a/app/Template/subtask/show.php b/app/Template/subtask/show.php index 1d55d1ee..c7ac652a 100644 --- a/app/Template/subtask/show.php +++ b/app/Template/subtask/show.php @@ -20,7 +20,7 @@ <?php if (! isset($not_editable)): ?> <?= $this->toggleSubtaskStatus($subtask, 'task') ?> <?php else: ?> - <?= $this->render('subtask/icons', array('subtask' => $subtask)) . $this->e($subtask['status_name']) ?> + <?= $this->render('subtask/icons', array('subtask' => $subtask)) . $this->e($subtask['title']) ?> <?php endif ?> </td> <td> @@ -40,6 +40,16 @@ <?php if (! isset($not_editable)): ?> <td> <ul> + <?php if ($subtask['position'] > 1): ?> + <li> + <?= $this->a(t('Move Up'), 'subtask', 'movePosition', array('project_id' => $project['id'], 'task_id' => $subtask['task_id'], 'subtask_id' => $subtask['id'], 'direction' => 'up'), true) ?> + </li> + <?php endif ?> + <?php if ($subtask['position'] != 0 && $subtask['position'] != count($subtasks)): ?> + <li> + <?= $this->a(t('Move Down'), 'subtask', 'movePosition', array('project_id' => $project['id'], 'task_id' => $subtask['task_id'], 'subtask_id' => $subtask['id'], 'direction' => 'down'), true) ?> + </li> + <?php endif ?> <li> <?= $this->a(t('Edit'), 'subtask', 'edit', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'subtask_id' => $subtask['id'])) ?> </li> diff --git a/app/Template/task/show.php b/app/Template/task/show.php index 1ff2ef43..d51b5542 100644 --- a/app/Template/task/show.php +++ b/app/Template/task/show.php @@ -2,7 +2,7 @@ <?= $this->render('task/time', array('task' => $task, 'values' => $values, 'date_format' => $date_format, 'date_formats' => $date_formats)) ?> <?= $this->render('task/show_description', array('task' => $task)) ?> <?= $this->render('tasklink/show', array('task' => $task, 'links' => $links)) ?> -<?= $this->render('subtask/show', array('task' => $task, 'subtasks' => $subtasks)) ?> +<?= $this->render('subtask/show', array('task' => $task, 'subtasks' => $subtasks, 'project' => $project)) ?> <?= $this->render('task/timesheet', array('task' => $task)) ?> <?= $this->render('file/show', array('task' => $task, 'files' => $files)) ?> <?= $this->render('task/comments', array('task' => $task, 'comments' => $comments, 'project' => $project)) ?> diff --git a/assets/css/app.css b/assets/css/app.css index 7969bca5..f0446f30 100644 --- a/assets/css/app.css +++ b/assets/css/app.css @@ -57,6 +57,11 @@ hr { border-top: 1px solid rgba(0, 0, 0, 0.1); border-bottom: 1px solid rgba(255, 255, 255, 0.3); } + +#board-selector, +.chosen-select { + min-height: 27px; /* Reserve some space to avoid re-layout due to chosen */ +} /* links */ a { color: #3366CC; @@ -735,6 +740,10 @@ nav .active a { font-size: 0.95em; } +#more-filters { + display: none; /* Hide this filter initially, to avoid re-layout */ +} + /* public board */ .public-board { margin-top: 5px; @@ -748,16 +757,29 @@ nav .active a { /* board table */ #board-container { - overflow-x: scroll; padding-bottom: 180px; /* Space to avoid dropdown menu truncated */ } -#board td, -#board th { +/* Board container classes for wide/compact view */ +.board-container-wide { + overflow-x: scroll; +} + +.board-container-compact { + overflow-x: hidden; +} + +/* Board table column for wide/compact view */ +.board-column-wide { min-width: 240px; max-width: 240px; } +.board-column-compact { + min-width: 0px; + max-width: 0px; +} + #board th a { text-decoration: none; color: #3366CC; diff --git a/assets/css/src/base.css b/assets/css/src/base.css index a8c7d73e..d92df612 100644 --- a/assets/css/src/base.css +++ b/assets/css/src/base.css @@ -41,3 +41,8 @@ hr { border-top: 1px solid rgba(0, 0, 0, 0.1); border-bottom: 1px solid rgba(255, 255, 255, 0.3); } + +#board-selector, +.chosen-select { + min-height: 27px; /* Reserve some space to avoid re-layout due to chosen */ +} diff --git a/assets/css/src/board.css b/assets/css/src/board.css index 6d7d8dd4..f4aefa95 100644 --- a/assets/css/src/board.css +++ b/assets/css/src/board.css @@ -3,6 +3,10 @@ font-size: 0.95em; } +#more-filters { + display: none; /* Hide this filter initially, to avoid re-layout */ +} + /* public board */ .public-board { margin-top: 5px; @@ -16,16 +20,29 @@ /* board table */ #board-container { - overflow-x: scroll; padding-bottom: 180px; /* Space to avoid dropdown menu truncated */ } -#board td, -#board th { +/* Board container classes for wide/compact view */ +.board-container-wide { + overflow-x: scroll; +} + +.board-container-compact { + overflow-x: hidden; +} + +/* Board table column for wide/compact view */ +.board-column-wide { min-width: 240px; max-width: 240px; } +.board-column-compact { + min-width: 0px; + max-width: 0px; +} + #board th a { text-decoration: none; color: #3366CC; diff --git a/assets/js/app.js b/assets/js/app.js index 64ea371d..6e6f7f34 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -140,19 +140,21 @@ var Kanboard=function(){jQuery(document).ready(function(){Kanboard.Init()});retu $("#popover-content").click(function(a){a.stopPropagation()});$(".close-popover").click(function(a){a.preventDefault();$("#popover-container").remove()});Mousetrap.bind("esc",function(){$("#popover-container").remove()});c&&c()})},IsVisible:function(){var a="";"undefined"!==typeof document.hidden?a="visibilityState":"undefined"!==typeof document.mozHidden?a="mozVisibilityState":"undefined"!==typeof document.msHidden?a="msVisibilityState":"undefined"!==typeof document.webkitHidden&&(a="webkitVisibilityState"); return""!=a?"visible"==document[a]:!0},SetStorageItem:function(a,c){"undefined"!==typeof Storage&&localStorage.setItem(a,c)},GetStorageItem:function(a){return"undefined"!==typeof Storage?localStorage.getItem(a):""},MarkdownPreview:function(a){a.preventDefault();var c=$(this),b=$(this).closest("ul"),d=$(".write-area"),e=$(".preview-area"),f=$("textarea");$.ajax({url:"?controller=app&action=preview",contentType:"application/json",type:"POST",processData:!1,dataType:"html",data:JSON.stringify({text:f.val()})}).done(function(a){b.find("li").removeClass("form-tab-selected"); c.parent().addClass("form-tab-selected");e.find(".markdown").html(a);e.css("height",f.css("height"));e.css("width",f.css("width"));d.hide();e.show()})},MarkdownWriter:function(a){a.preventDefault();$(this).closest("ul").find("li").removeClass("form-tab-selected");$(this).parent().addClass("form-tab-selected");$(".write-area").show();$(".preview-area").hide()},CheckSession:function(){$(".form-login").length||$.ajax({cache:!1,url:$("body").data("status-url"),statusCode:{401:function(){window.location= -$("body").data("login-url")}}})},Init:function(){$("#board-selector").chosen({width:180});$("#board-selector").change(function(){window.location=$(this).attr("data-board-url").replace(/PROJECT_ID/g,$(this).val())});window.setInterval(Kanboard.CheckSession,6E4);Mousetrap.bindGlobal("mod+enter",function(){$("form").submit()});Mousetrap.bind("b",function(a){a.preventDefault();$("#board-selector").trigger("chosen:open")});$(".column-tooltip").tooltip({content:function(){return'<div class="markdown">'+ -$(this).attr("title")+"</div>"}});$.datepicker.setDefaults($.datepicker.regional[$("body").data("js-lang")]);Kanboard.InitAfterAjax()},InitAfterAjax:function(){$(document).on("click",".popover",Kanboard.Popover);$(".form-date").datepicker({showOtherMonths:!0,selectOtherMonths:!0,dateFormat:"yy-mm-dd",constrainInput:!1});$("#markdown-preview").click(Kanboard.MarkdownPreview);$("#markdown-write").click(Kanboard.MarkdownWriter);$(".auto-select").focus(function(){$(this).select()});$(".dropit-submenu").hide(); -$(".dropdown").not(".dropit").dropit()}}}(); -Kanboard.Board=function(){function a(a){a.preventDefault();a.stopPropagation();Kanboard.Popover(a,Kanboard.InitAfterAjax)}function c(){Mousetrap.bind("n",function(){Kanboard.OpenPopover($("#board").data("task-creation-url"),Kanboard.InitAfterAjax)});Mousetrap.bind("s",function(){"expanded"===(Kanboard.GetStorageItem(d())||"expanded")?(e(),Kanboard.SetStorageItem(d(),"collapsed")):(f(),Kanboard.SetStorageItem(d(),"expanded"))})}function b(){$(".filter-expand-link").click(function(a){a.preventDefault();f(); -Kanboard.SetStorageItem(d(),"expanded")});$(".filter-collapse-link").click(function(a){a.preventDefault();e();Kanboard.SetStorageItem(d(),"collapsed")});g()}function d(){return"board_stacking_"+$("#board").data("project-id")}function e(){$(".filter-collapse").hide();$(".task-board-collapsed").show();$(".filter-expand").show();$(".task-board-expanded").hide()}function f(){$(".filter-collapse").show();$(".task-board-collapsed").hide();$(".filter-expand").hide();$(".task-board-expanded").show()}function g(){"expanded"=== -(Kanboard.GetStorageItem(d())||"expanded")?f():e()}function k(){$(".column").sortable({delay:300,distance:5,connectWith:".column",placeholder:"draggable-placeholder",stop:function(a,b){n(b.item.attr("data-task-id"),b.item.parent().attr("data-column-id"),b.item.index()+1,b.item.parent().attr("data-swimlane-id"))}});$("#board").on("click",".task-board-popover",a);$("#board").on("click",".task-board",function(){window.location=$(this).data("task-url")});$(".task-board-tooltip").tooltip({track:!1,position:{my:"left-20 top", -at:"center bottom+9",using:function(a,b){$(this).css(a);var c=b.target.left+b.target.width/2-b.element.left-20;$("<div>").addClass("tooltip-arrow").addClass(b.vertical).addClass(0==c?"align-left":"align-right").appendTo(this)}},content:function(a){if(a=$(this).attr("data-href")){var b=this;$.get(a,function p(a){$(".ui-tooltip-content:visible").html(a);a=$(".ui-tooltip:visible");a.css({top:"",left:""});a.children(".tooltip-arrow").remove();var c=$(b).tooltip("option","position");c.of=$(b);a.position(c); -$("#tooltip-subtasks a").not(".popover").click(function(a){a.preventDefault();a.stopPropagation();$(this).hasClass("popover-subtask-restriction")?(Kanboard.OpenPopover($(this).attr("href")),$(b).tooltip("close")):$.get($(this).attr("href"),p)})});return'<i class="fa fa-refresh fa-spin fa-2x"></i>'}}}).on("mouseenter",function(){var a=this;$(this).tooltip("open");$(".ui-tooltip").on("mouseleave",function(){$(a).tooltip("close")})}).on("mouseleave focusout",function(a){a.stopImmediatePropagation(); -var b=this;setTimeout(function(){$(".ui-tooltip:hover").length||$(b).tooltip("close")},100)});var b=parseInt($("#board").attr("data-check-interval"));0<b&&(l=window.setInterval(m,1E3*b))}function n(a,b,c,d){clearInterval(l);$.ajax({cache:!1,url:$("#board").attr("data-save-url"),contentType:"application/json",type:"POST",processData:!1,data:JSON.stringify({task_id:a,column_id:b,swimlane_id:d,position:c}),success:function(a){$("#board-container").remove();$("#main").append(a);Kanboard.InitAfterAjax(); -k();h();g()}})}function m(){Kanboard.IsVisible()&&$.ajax({cache:!1,url:$("#board").attr("data-check-url"),statusCode:{200:function(a){$("#board-container").remove();$("#main").append(a);Kanboard.InitAfterAjax();clearInterval(l);k();h();g()}}})}function h(){var a=$("#form-user_id").val(),b=$("#form-category_id").val(),c=$("#more-filters option[value=filter-due-date]").is(":selected"),d=$("#more-filters option[value=filter-recent]").is(":selected"),e=$("#board").data("project-id");$("[data-task-id]").each(function(e, -g){var k=g.getAttribute("data-owner-id"),f=g.getAttribute("data-due-date"),m=g.getAttribute("data-category-id"),h=$(g).hasClass("task-board-recent");g.style.display=k!=a&&-1!=a?"none":"block";!c||""!=f&&"0"!=f||(g.style.display="none");m!=b&&-1!=b&&(g.style.display="none");d&&!h&&(g.style.display="none")});Kanboard.SetStorageItem("board_filter_"+e+"_form-user_id",a);Kanboard.SetStorageItem("board_filter_"+e+"_form-category_id",b);Kanboard.SetStorageItem("board_filter_"+e+"_filter-due-date",~~c);Kanboard.SetStorageItem("board_filter_"+ -e+"_filter-recent",~~d)}function q(){var a=$("#board").data("project-id");$("#form-user_id").chosen({width:"180px"});$("#form-category_id").chosen({width:"200px"});$("#more-filters").chosen({width:"30%"});$(".apply-filters").change(function(a){h()});$("#form-user_id").val(Kanboard.GetStorageItem("board_filter_"+a+"_form-user_id")||-1);$("#form-user_id").trigger("chosen:updated");$("#form-category_id").val(Kanboard.GetStorageItem("board_filter_"+a+"_form-category_id")||-1);$("#form-category_id").trigger("chosen:updated"); -+Kanboard.GetStorageItem("board_filter_"+a+"_filter-due-date")&&$("#more-filters option[value=filter-due-date]").attr("selected",!0);+Kanboard.GetStorageItem("board_filter_"+a+"_filter-recent")&&$("#more-filters option[value=filter-recent]").attr("selected",!0);$("#more-filters").trigger("chosen:updated");h()}var l=null;jQuery(document).ready(function(){Kanboard.Exists("board")&&(k(),q(),b(),c())})}(); +$("body").data("login-url")}}})},Init:function(){$("#board-selector").chosen({width:180,no_results_text:$("#board-selector").data("notfound")});$("#board-selector").change(function(){window.location=$(this).attr("data-board-url").replace(/PROJECT_ID/g,$(this).val())});window.setInterval(Kanboard.CheckSession,6E4);Mousetrap.bindGlobal("mod+enter",function(){$("form").submit()});Mousetrap.bind("b",function(a){a.preventDefault();$("#board-selector").trigger("chosen:open")});$(".column-tooltip").tooltip({content:function(){return'<div class="markdown">'+ +$(this).attr("title")+"</div>"},position:{my:"left-20 top",at:"center bottom+9",using:function(a,c){$(this).css(a);var b=c.target.left+c.target.width/2-c.element.left-20;$("<div>").addClass("tooltip-arrow").addClass(c.vertical).addClass(0==b?"align-left":"align-right").appendTo(this)}}});$.datepicker.setDefaults($.datepicker.regional[$("body").data("js-lang")]);Kanboard.InitAfterAjax()},InitAfterAjax:function(){$(document).on("click",".popover",Kanboard.Popover);$(".form-date").datepicker({showOtherMonths:!0, +selectOtherMonths:!0,dateFormat:"yy-mm-dd",constrainInput:!1});$("#markdown-preview").click(Kanboard.MarkdownPreview);$("#markdown-write").click(Kanboard.MarkdownWriter);$(".auto-select").focus(function(){$(this).select()});$(".dropit-submenu").hide();$(".dropdown").not(".dropit").dropit({triggerParentEl:"span"})}}}(); +Kanboard.Board=function(){function a(a){a.preventDefault();a.stopPropagation();Kanboard.Popover(a,Kanboard.InitAfterAjax)}function c(){Mousetrap.bind("n",function(){Kanboard.OpenPopover($("#board").data("task-creation-url"),Kanboard.InitAfterAjax)});Mousetrap.bind("s",function(){"expanded"===(Kanboard.GetStorageItem(d())||"expanded")?(e(),Kanboard.SetStorageItem(d(),"collapsed")):(f(),Kanboard.SetStorageItem(d(),"expanded"))});Mousetrap.bind("c",function(){p()})}function b(){$(".filter-expand-link").click(function(a){a.preventDefault(); +f();Kanboard.SetStorageItem(d(),"expanded")});$(".filter-collapse-link").click(function(a){a.preventDefault();e();Kanboard.SetStorageItem(d(),"collapsed")});g()}function d(){return"board_stacking_"+$("#board").data("project-id")}function e(){$(".filter-collapse").hide();$(".task-board-collapsed").show();$(".filter-expand").show();$(".task-board-expanded").hide()}function f(){$(".filter-collapse").show();$(".task-board-collapsed").hide();$(".filter-expand").hide();$(".task-board-expanded").show()} +function g(){"expanded"===(Kanboard.GetStorageItem(d())||"expanded")?f():e()}function k(){$(".column").sortable({delay:300,distance:5,connectWith:".column",placeholder:"draggable-placeholder",stop:function(a,b){q(b.item.attr("data-task-id"),b.item.parent().attr("data-column-id"),b.item.index()+1,b.item.parent().attr("data-swimlane-id"))}});$("#board").on("click",".task-board-popover",a);$("#board").on("click",".task-board",function(){window.location=$(this).data("task-url")});$(".task-board-tooltip").tooltip({track:!1, +position:{my:"left-20 top",at:"center bottom+9",using:function(a,b){$(this).css(a);var c=b.target.left+b.target.width/2-b.element.left-20;$("<div>").addClass("tooltip-arrow").addClass(b.vertical).addClass(0==c?"align-left":"align-right").appendTo(this)}},content:function(a){if(a=$(this).attr("data-href")){var b=this;$.get(a,function r(a){$(".ui-tooltip-content:visible").html(a);a=$(".ui-tooltip:visible");a.css({top:"",left:""});a.children(".tooltip-arrow").remove();var c=$(b).tooltip("option","position"); +c.of=$(b);a.position(c);$("#tooltip-subtasks a").not(".popover").click(function(a){a.preventDefault();a.stopPropagation();$(this).hasClass("popover-subtask-restriction")?(Kanboard.OpenPopover($(this).attr("href")),$(b).tooltip("close")):$.get($(this).attr("href"),r)})});return'<i class="fa fa-refresh fa-spin fa-2x"></i>'}}}).on("mouseenter",function(){var a=this;$(this).tooltip("open");$(".ui-tooltip").on("mouseleave",function(){$(a).tooltip("close")})}).on("mouseleave focusout",function(a){a.stopImmediatePropagation(); +var b=this;setTimeout(function(){$(".ui-tooltip:hover").length||$(b).tooltip("close")},100)});var b=parseInt($("#board").attr("data-check-interval"));0<b&&(m=window.setInterval(n,1E3*b))}function q(a,b,c,d){clearInterval(m);$.ajax({cache:!1,url:$("#board").attr("data-save-url"),contentType:"application/json",type:"POST",processData:!1,data:JSON.stringify({task_id:a,column_id:b,swimlane_id:d,position:c}),success:function(a){$("#board-container").remove();$("#main").append(a);Kanboard.InitAfterAjax(); +k();h();g();l()}})}function n(){Kanboard.IsVisible()&&$.ajax({cache:!1,url:$("#board").attr("data-check-url"),statusCode:{200:function(a){$("#board-container").remove();$("#main").append(a);Kanboard.InitAfterAjax();clearInterval(m);k();h();g();l()}}})}function h(){var a=$("#form-user_id").val(),b=$("#form-category_id").val(),c=$("#more-filters option[value=filter-due-date]").is(":selected"),d=$("#more-filters option[value=filter-recent]").is(":selected"),e=$("#board").data("project-id");$("[data-task-id]").each(function(e, +g){var k=g.getAttribute("data-owner-id"),f=g.getAttribute("data-due-date"),n=g.getAttribute("data-category-id"),h=$(g).hasClass("task-board-recent");g.style.display=k!=a&&-1!=a?"none":"block";!c||""!=f&&"0"!=f||(g.style.display="none");n!=b&&-1!=b&&(g.style.display="none");d&&!h&&(g.style.display="none")});Kanboard.SetStorageItem("board_filter_"+e+"_form-user_id",a);Kanboard.SetStorageItem("board_filter_"+e+"_form-category_id",b);Kanboard.SetStorageItem("board_filter_"+e+"_filter-due-date",~~c);Kanboard.SetStorageItem("board_filter_"+ +e+"_filter-recent",~~d)}function t(){var a=$("#board").data("project-id");$("#form-user_id").chosen({width:"180px",no_results_text:$("#form-user_id").data("notfound")});$("#form-category_id").chosen({width:"200px",no_results_text:$("#form-category_id").data("notfound")});$("#more-filters").chosen({width:"30%",no_results_text:$("#more-filters").data("notfound")});$(".apply-filters").change(function(a){h()});$("#form-user_id").val(Kanboard.GetStorageItem("board_filter_"+a+"_form-user_id")||-1);$("#form-user_id").trigger("chosen:updated"); +$("#form-category_id").val(Kanboard.GetStorageItem("board_filter_"+a+"_form-category_id")||-1);$("#form-category_id").trigger("chosen:updated");+Kanboard.GetStorageItem("board_filter_"+a+"_filter-due-date")&&$("#more-filters option[value=filter-due-date]").attr("selected",!0);+Kanboard.GetStorageItem("board_filter_"+a+"_filter-recent")&&$("#more-filters option[value=filter-recent]").attr("selected",!0);$("#more-filters").trigger("chosen:updated");h()}function u(){jQuery(document).on("click",".filter-toggle-scrolling", +function(a){a.preventDefault();p()});l()}function p(){var a=Kanboard.GetStorageItem("horizontal_scroll")||1;Kanboard.SetStorageItem("horizontal_scroll",0==a?1:0);l()}function l(){0==Kanboard.GetStorageItem("horizontal_scroll")?($(".filter-wide").show(),$(".filter-compact").hide(),$("#board-container").removeClass("board-container-wide").addClass("board-container-compact"),$("#board th,#board td").removeClass("board-column-wide").addClass("board-column-compact")):($(".filter-wide").hide(),$(".filter-compact").show(), +$("#board-container").removeClass("board-container-compact").addClass("board-container-wide"),$("#board th,#board td").removeClass("board-column-compact").addClass("board-column-wide"))}var m=null;jQuery(document).ready(function(){Kanboard.Exists("board")&&(k(),t(),b(),u(),c())})}(); Kanboard.Calendar=function(){function a(a){var b=$("#calendar").data("save-url")||$("#user-calendar").data("save-url");$.ajax({cache:!1,url:b,contentType:"application/json",type:"POST",processData:!1,data:JSON.stringify({task_id:a.id,date_due:a.start.format()})})}function c(){var a=$("#user-calendar"),b=a.data("check-url"),c={start:a.fullCalendar("getView").start.format(),end:a.fullCalendar("getView").end.format(),user_id:a.data("user-id")},d;for(d in c)b+="&"+d+"="+c[d];$.getJSON(b,function(b){a.fullCalendar("removeEvents"); a.fullCalendar("addEventSource",b);a.fullCalendar("rerenderEvents")})}function b(a){var b=$("#calendar"),c=b.data("check-url"),d={start:b.fullCalendar("getView").start.format(),end:b.fullCalendar("getView").end.format()};jQuery.extend(d,a);for(var e in d)c+="&"+e+"="+d[e];$.getJSON(c,function(a){b.fullCalendar("removeEvents");b.fullCalendar("addEventSource",a);b.fullCalendar("rerenderEvents")})}function d(){var a=Kanboard.GetStorageItem(f);if(""!==a){var a=JSON.parse(a),c;for(c in a)$("select[name="+ c+"]").val(a[c])}b(a||{});$(".calendar-filter").change(e)}function e(){var a={};$(".calendar-filter").each(function(){a[$(this).attr("name")]=$(this).val()});Kanboard.SetStorageItem(f,JSON.stringify(a));b(a)}var f="";jQuery(document).ready(function(){Kanboard.Exists("calendar")?(f="calendar_filters_"+$("#calendar").data("project-id"),$("#calendar").fullCalendar({lang:$("body").data("js-lang"),editable:!0,eventLimit:!0,defaultView:"month",header:{left:"prev,next today",center:"title",right:"month,agendaWeek,agendaDay"}, @@ -167,4 +169,4 @@ b=$(this).data("swimlane-id");if(-1<c().indexOf(b)){var d="hidden_swimlanes_"+$( JSON.stringify(e)),a(b)})}(); Kanboard.Dashboard=function(){function a(){0<$(".dashboard-right-column > div:visible").size()?$(".dashboard-left-column").removeClass("dashboard-single-column"):$(".dashboard-left-column").addClass("dashboard-single-column");0<$(".dashboard-left-column > div:visible").size()?$(".dashboard-right-column").removeClass("dashboard-single-column"):$(".dashboard-right-column").addClass("dashboard-single-column")}jQuery(document).ready(function(){var c=Kanboard.GetStorageItem("dashboard_view");if(c){var c= JSON.parse(c),b;for(b in c)$("#dashboard-"+b).toggle(c[b]);a()}});jQuery(document).on("click",".dashboard-toggle",function(c){c.preventDefault();$("#dashboard-"+$(this).data("toggle")).toggle();a();c=["projects","tasks","subtasks","activities","calendar"];for(var b={},d=0;d<c.length;d++)b[c[d]]=$("#dashboard-"+c[d]).is(":visible");Kanboard.SetStorageItem("dashboard_view",JSON.stringify(b))})}(); -(function(t){"function"==typeof define&&define.amd?define(["jquery","moment"],t):t(jQuery,moment)})(function(t,e){(e.defineLocale||e.lang).call(e,"da",{months:"januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december".split("_"),monthsShort:"jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec".split("_"),weekdays:"søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag".split("_"),weekdaysShort:"søn_man_tir_ons_tor_fre_lør".split("_"),weekdaysMin:"sø_ma_ti_on_to_fr_lø".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD/MM/YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY LT",LLLL:"dddd [d.] D. MMMM YYYY LT"},calendar:{sameDay:"[I dag kl.] LT",nextDay:"[I morgen kl.] LT",nextWeek:"dddd [kl.] LT",lastDay:"[I går kl.] LT",lastWeek:"[sidste] dddd [kl] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"%s siden",s:"få sekunder",m:"et minut",mm:"%d minutter",h:"en time",hh:"%d timer",d:"en dag",dd:"%d dage",M:"en måned",MM:"%d måneder",y:"et år",yy:"%d år"},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}}),t.fullCalendar.datepickerLang("da","da",{closeText:"Luk",prevText:"<Forrige",nextText:"Næste>",currentText:"Idag",monthNames:["Januar","Februar","Marts","April","Maj","Juni","Juli","August","September","Oktober","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","Maj","Jun","Jul","Aug","Sep","Okt","Nov","Dec"],dayNames:["Søndag","Mandag","Tirsdag","Onsdag","Torsdag","Fredag","Lørdag"],dayNamesShort:["Søn","Man","Tir","Ons","Tor","Fre","Lør"],dayNamesMin:["Sø","Ma","Ti","On","To","Fr","Lø"],weekHeader:"Uge",dateFormat:"dd-mm-yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),t.fullCalendar.lang("da",{defaultButtonText:{month:"Måned",week:"Uge",day:"Dag",list:"Agenda"},allDayText:"Hele dagen",eventLimitText:"flere"})});(function(t){"function"==typeof define&&define.amd?define(["jquery","moment"],t):t(jQuery,moment)})(function(t,e){function n(t,e,n){var i={m:["eine Minute","einer Minute"],h:["eine Stunde","einer Stunde"],d:["ein Tag","einem Tag"],dd:[t+" Tage",t+" Tagen"],M:["ein Monat","einem Monat"],MM:[t+" Monate",t+" Monaten"],y:["ein Jahr","einem Jahr"],yy:[t+" Jahre",t+" Jahren"]};return e?i[n][0]:i[n][1]}(e.defineLocale||e.lang).call(e,"de",{months:"Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jan._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"),weekdays:"Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),weekdaysShort:"So._Mo._Di._Mi._Do._Fr._Sa.".split("_"),weekdaysMin:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY LT",LLLL:"dddd, D. MMMM YYYY LT"},calendar:{sameDay:"[Heute um] LT [Uhr]",sameElse:"L",nextDay:"[Morgen um] LT [Uhr]",nextWeek:"dddd [um] LT [Uhr]",lastDay:"[Gestern um] LT [Uhr]",lastWeek:"[letzten] dddd [um] LT [Uhr]"},relativeTime:{future:"in %s",past:"vor %s",s:"ein paar Sekunden",m:n,mm:"%d Minuten",h:n,hh:"%d Stunden",d:n,dd:n,M:n,MM:n,y:n,yy:n},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}}),t.fullCalendar.datepickerLang("de","de",{closeText:"Schließen",prevText:"<Zurück",nextText:"Vor>",currentText:"Heute",monthNames:["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember"],monthNamesShort:["Jan","Feb","Mär","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez"],dayNames:["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"],dayNamesShort:["So","Mo","Di","Mi","Do","Fr","Sa"],dayNamesMin:["So","Mo","Di","Mi","Do","Fr","Sa"],weekHeader:"KW",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),t.fullCalendar.lang("de",{defaultButtonText:{month:"Monat",week:"Woche",day:"Tag",list:"Terminübersicht"},allDayText:"Ganztägig",eventLimitText:function(t){return"+ weitere "+t}})});(function(e){"function"==typeof define&&define.amd?define(["jquery","moment"],e):e(jQuery,moment)})(function(e,t){var n="ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.".split("_"),i="ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic".split("_");(t.defineLocale||t.lang).call(t,"es",{months:"enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre".split("_"),monthsShort:function(e,t){return/-MMM-/.test(t)?i[e.month()]:n[e.month()]},weekdays:"domingo_lunes_martes_miércoles_jueves_viernes_sábado".split("_"),weekdaysShort:"dom._lun._mar._mié._jue._vie._sáb.".split("_"),weekdaysMin:"Do_Lu_Ma_Mi_Ju_Vi_Sá".split("_"),longDateFormat:{LT:"H:mm",LTS:"LT:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY LT",LLLL:"dddd, D [de] MMMM [de] YYYY LT"},calendar:{sameDay:function(){return"[hoy a la"+(1!==this.hours()?"s":"")+"] LT"},nextDay:function(){return"[mañana a la"+(1!==this.hours()?"s":"")+"] LT"},nextWeek:function(){return"dddd [a la"+(1!==this.hours()?"s":"")+"] LT"},lastDay:function(){return"[ayer a la"+(1!==this.hours()?"s":"")+"] LT"},lastWeek:function(){return"[el] dddd [pasado a la"+(1!==this.hours()?"s":"")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"hace %s",s:"unos segundos",m:"un minuto",mm:"%d minutos",h:"una hora",hh:"%d horas",d:"un día",dd:"%d días",M:"un mes",MM:"%d meses",y:"un año",yy:"%d años"},ordinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:1,doy:4}}),e.fullCalendar.datepickerLang("es","es",{closeText:"Cerrar",prevText:"<Ant",nextText:"Sig>",currentText:"Hoy",monthNames:["enero","febrero","marzo","abril","mayo","junio","julio","agosto","septiembre","octubre","noviembre","diciembre"],monthNamesShort:["ene","feb","mar","abr","may","jun","jul","ago","sep","oct","nov","dic"],dayNames:["domingo","lunes","martes","miércoles","jueves","viernes","sábado"],dayNamesShort:["dom","lun","mar","mié","jue","vie","sáb"],dayNamesMin:["D","L","M","X","J","V","S"],weekHeader:"Sm",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),e.fullCalendar.lang("es",{defaultButtonText:{month:"Mes",week:"Semana",day:"Día",list:"Agenda"},allDayHtml:"Todo<br/>el día",eventLimitText:"más"})});(function(e){"function"==typeof define&&define.amd?define(["jquery","moment"],e):e(jQuery,moment)})(function(e,t){function n(e,t,n,r){var s="";switch(n){case"s":return r?"muutaman sekunnin":"muutama sekunti";case"m":return r?"minuutin":"minuutti";case"mm":s=r?"minuutin":"minuuttia";break;case"h":return r?"tunnin":"tunti";case"hh":s=r?"tunnin":"tuntia";break;case"d":return r?"päivän":"päivä";case"dd":s=r?"päivän":"päivää";break;case"M":return r?"kuukauden":"kuukausi";case"MM":s=r?"kuukauden":"kuukautta";break;case"y":return r?"vuoden":"vuosi";case"yy":s=r?"vuoden":"vuotta"}return s=i(e,r)+" "+s}function i(e,t){return 10>e?t?s[e]:r[e]:e}var r="nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän".split(" "),s=["nolla","yhden","kahden","kolmen","neljän","viiden","kuuden",r[7],r[8],r[9]];(t.defineLocale||t.lang).call(t,"fi",{months:"tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu".split("_"),monthsShort:"tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu".split("_"),weekdays:"sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai".split("_"),weekdaysShort:"su_ma_ti_ke_to_pe_la".split("_"),weekdaysMin:"su_ma_ti_ke_to_pe_la".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD.MM.YYYY",LL:"Do MMMM[ta] YYYY",LLL:"Do MMMM[ta] YYYY, [klo] LT",LLLL:"dddd, Do MMMM[ta] YYYY, [klo] LT",l:"D.M.YYYY",ll:"Do MMM YYYY",lll:"Do MMM YYYY, [klo] LT",llll:"ddd, Do MMM YYYY, [klo] LT"},calendar:{sameDay:"[tänään] [klo] LT",nextDay:"[huomenna] [klo] LT",nextWeek:"dddd [klo] LT",lastDay:"[eilen] [klo] LT",lastWeek:"[viime] dddd[na] [klo] LT",sameElse:"L"},relativeTime:{future:"%s päästä",past:"%s sitten",s:n,m:n,mm:n,h:n,hh:n,d:n,dd:n,M:n,MM:n,y:n,yy:n},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}}),e.fullCalendar.datepickerLang("fi","fi",{closeText:"Sulje",prevText:"«Edellinen",nextText:"Seuraava»",currentText:"Tänään",monthNames:["Tammikuu","Helmikuu","Maaliskuu","Huhtikuu","Toukokuu","Kesäkuu","Heinäkuu","Elokuu","Syyskuu","Lokakuu","Marraskuu","Joulukuu"],monthNamesShort:["Tammi","Helmi","Maalis","Huhti","Touko","Kesä","Heinä","Elo","Syys","Loka","Marras","Joulu"],dayNamesShort:["Su","Ma","Ti","Ke","To","Pe","La"],dayNames:["Sunnuntai","Maanantai","Tiistai","Keskiviikko","Torstai","Perjantai","Lauantai"],dayNamesMin:["Su","Ma","Ti","Ke","To","Pe","La"],weekHeader:"Vk",dateFormat:"d.m.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),e.fullCalendar.lang("fi",{defaultButtonText:{month:"Kuukausi",week:"Viikko",day:"Päivä",list:"Tapahtumat"},allDayText:"Koko päivä",eventLimitText:"lisää"})});(function(e){"function"==typeof define&&define.amd?define(["jquery","moment"],e):e(jQuery,moment)})(function(e,t){(t.defineLocale||t.lang).call(t,"fr",{months:"janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"),monthsShort:"janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"),weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"Di_Lu_Ma_Me_Je_Ve_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd D MMMM YYYY LT"},calendar:{sameDay:"[Aujourd'hui à] LT",nextDay:"[Demain à] LT",nextWeek:"dddd [à] LT",lastDay:"[Hier à] LT",lastWeek:"dddd [dernier à] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"un an",yy:"%d ans"},ordinalParse:/\d{1,2}(er|)/,ordinal:function(e){return e+(1===e?"er":"")},week:{dow:1,doy:4}}),e.fullCalendar.datepickerLang("fr","fr",{closeText:"Fermer",prevText:"Précédent",nextText:"Suivant",currentText:"Aujourd'hui",monthNames:["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre"],monthNamesShort:["janv.","févr.","mars","avr.","mai","juin","juil.","août","sept.","oct.","nov.","déc."],dayNames:["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"],dayNamesShort:["dim.","lun.","mar.","mer.","jeu.","ven.","sam."],dayNamesMin:["D","L","M","M","J","V","S"],weekHeader:"Sem.",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),e.fullCalendar.lang("fr",{defaultButtonText:{month:"Mois",week:"Semaine",day:"Jour",list:"Mon planning"},allDayHtml:"Toute la<br/>journée",eventLimitText:"en plus"})});(function(e){"function"==typeof define&&define.amd?define(["jquery","moment"],e):e(jQuery,moment)})(function(e,t){function n(e,t,n,r){var i=e;switch(n){case"s":return r||t?"néhány másodperc":"néhány másodperce";case"m":return"egy"+(r||t?" perc":" perce");case"mm":return i+(r||t?" perc":" perce");case"h":return"egy"+(r||t?" óra":" órája");case"hh":return i+(r||t?" óra":" órája");case"d":return"egy"+(r||t?" nap":" napja");case"dd":return i+(r||t?" nap":" napja");case"M":return"egy"+(r||t?" hónap":" hónapja");case"MM":return i+(r||t?" hónap":" hónapja");case"y":return"egy"+(r||t?" év":" éve");case"yy":return i+(r||t?" év":" éve")}return""}function r(e){return(e?"":"[múlt] ")+"["+i[this.day()]+"] LT[-kor]"}var i="vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton".split(" ");(t.defineLocale||t.lang).call(t,"hu",{months:"január_február_március_április_május_június_július_augusztus_szeptember_október_november_december".split("_"),monthsShort:"jan_feb_márc_ápr_máj_jún_júl_aug_szept_okt_nov_dec".split("_"),weekdays:"vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat".split("_"),weekdaysShort:"vas_hét_kedd_sze_csüt_pén_szo".split("_"),weekdaysMin:"v_h_k_sze_cs_p_szo".split("_"),longDateFormat:{LT:"H:mm",LTS:"LT:ss",L:"YYYY.MM.DD.",LL:"YYYY. MMMM D.",LLL:"YYYY. MMMM D., LT",LLLL:"YYYY. MMMM D., dddd LT"},meridiemParse:/de|du/i,isPM:function(e){return"u"===e.charAt(1).toLowerCase()},meridiem:function(e,t,n){return 12>e?n===!0?"de":"DE":n===!0?"du":"DU"},calendar:{sameDay:"[ma] LT[-kor]",nextDay:"[holnap] LT[-kor]",nextWeek:function(){return r.call(this,!0)},lastDay:"[tegnap] LT[-kor]",lastWeek:function(){return r.call(this,!1)},sameElse:"L"},relativeTime:{future:"%s múlva",past:"%s",s:n,m:n,mm:n,h:n,hh:n,d:n,dd:n,M:n,MM:n,y:n,yy:n},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}}),e.fullCalendar.datepickerLang("hu","hu",{closeText:"bezár",prevText:"vissza",nextText:"előre",currentText:"ma",monthNames:["Január","Február","Március","Április","Május","Június","Július","Augusztus","Szeptember","Október","November","December"],monthNamesShort:["Jan","Feb","Már","Ápr","Máj","Jún","Júl","Aug","Szep","Okt","Nov","Dec"],dayNames:["Vasárnap","Hétfő","Kedd","Szerda","Csütörtök","Péntek","Szombat"],dayNamesShort:["Vas","Hét","Ked","Sze","Csü","Pén","Szo"],dayNamesMin:["V","H","K","Sze","Cs","P","Szo"],weekHeader:"Hét",dateFormat:"yy.mm.dd.",firstDay:1,isRTL:!1,showMonthAfterYear:!0,yearSuffix:""}),e.fullCalendar.lang("hu",{defaultButtonText:{month:"Hónap",week:"Hét",day:"Nap",list:"Napló"},allDayText:"Egész nap",eventLimitText:"további"})});(function(e){"function"==typeof define&&define.amd?define(["jquery","moment"],e):e(jQuery,moment)})(function(e,t){(t.defineLocale||t.lang).call(t,"it",{months:"gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre".split("_"),monthsShort:"gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic".split("_"),weekdays:"Domenica_Lunedì_Martedì_Mercoledì_Giovedì_Venerdì_Sabato".split("_"),weekdaysShort:"Dom_Lun_Mar_Mer_Gio_Ven_Sab".split("_"),weekdaysMin:"D_L_Ma_Me_G_V_S".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd, D MMMM YYYY LT"},calendar:{sameDay:"[Oggi alle] LT",nextDay:"[Domani alle] LT",nextWeek:"dddd [alle] LT",lastDay:"[Ieri alle] LT",lastWeek:function(){switch(this.day()){case 0:return"[la scorsa] dddd [alle] LT";default:return"[lo scorso] dddd [alle] LT"}},sameElse:"L"},relativeTime:{future:function(e){return(/^[0-9].+$/.test(e)?"tra":"in")+" "+e},past:"%s fa",s:"alcuni secondi",m:"un minuto",mm:"%d minuti",h:"un'ora",hh:"%d ore",d:"un giorno",dd:"%d giorni",M:"un mese",MM:"%d mesi",y:"un anno",yy:"%d anni"},ordinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:1,doy:4}}),e.fullCalendar.datepickerLang("it","it",{closeText:"Chiudi",prevText:"<Prec",nextText:"Succ>",currentText:"Oggi",monthNames:["Gennaio","Febbraio","Marzo","Aprile","Maggio","Giugno","Luglio","Agosto","Settembre","Ottobre","Novembre","Dicembre"],monthNamesShort:["Gen","Feb","Mar","Apr","Mag","Giu","Lug","Ago","Set","Ott","Nov","Dic"],dayNames:["Domenica","Lunedì","Martedì","Mercoledì","Giovedì","Venerdì","Sabato"],dayNamesShort:["Dom","Lun","Mar","Mer","Gio","Ven","Sab"],dayNamesMin:["Do","Lu","Ma","Me","Gi","Ve","Sa"],weekHeader:"Sm",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),e.fullCalendar.lang("it",{defaultButtonText:{month:"Mese",week:"Settimana",day:"Giorno",list:"Agenda"},allDayHtml:"Tutto il<br/>giorno",eventLimitText:function(e){return"+altri "+e}})});(function(e){"function"==typeof define&&define.amd?define(["jquery","moment"],e):e(jQuery,moment)})(function(e,t){(t.defineLocale||t.lang).call(t,"ja",{months:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),monthsShort:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),weekdays:"日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日".split("_"),weekdaysShort:"日_月_火_水_木_金_土".split("_"),weekdaysMin:"日_月_火_水_木_金_土".split("_"),longDateFormat:{LT:"Ah時m分",LTS:"LTs秒",L:"YYYY/MM/DD",LL:"YYYY年M月D日",LLL:"YYYY年M月D日LT",LLLL:"YYYY年M月D日LT dddd"},meridiemParse:/午前|午後/i,isPM:function(e){return"午後"===e},meridiem:function(e){return 12>e?"午前":"午後"},calendar:{sameDay:"[今日] LT",nextDay:"[明日] LT",nextWeek:"[来週]dddd LT",lastDay:"[昨日] LT",lastWeek:"[前週]dddd LT",sameElse:"L"},relativeTime:{future:"%s後",past:"%s前",s:"数秒",m:"1分",mm:"%d分",h:"1時間",hh:"%d時間",d:"1日",dd:"%d日",M:"1ヶ月",MM:"%dヶ月",y:"1年",yy:"%d年"}}),e.fullCalendar.datepickerLang("ja","ja",{closeText:"閉じる",prevText:"<前",nextText:"次>",currentText:"今日",monthNames:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],monthNamesShort:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],dayNames:["日曜日","月曜日","火曜日","水曜日","木曜日","金曜日","土曜日"],dayNamesShort:["日","月","火","水","木","金","土"],dayNamesMin:["日","月","火","水","木","金","土"],weekHeader:"週",dateFormat:"yy/mm/dd",firstDay:0,isRTL:!1,showMonthAfterYear:!0,yearSuffix:"年"}),e.fullCalendar.lang("ja",{defaultButtonText:{month:"月",week:"週",day:"日",list:"予定リスト"},allDayText:"終日",eventLimitText:function(e){return"他 "+e+" 件"}})});(function(e){"function"==typeof define&&define.amd?define(["jquery","moment"],e):e(jQuery,moment)})(function(e,t){function n(e){return 5>e%10&&e%10>1&&1!==~~(e/10)%10}function i(e,t,i){var r=e+" ";switch(i){case"m":return t?"minuta":"minutę";case"mm":return r+(n(e)?"minuty":"minut");case"h":return t?"godzina":"godzinę";case"hh":return r+(n(e)?"godziny":"godzin");case"MM":return r+(n(e)?"miesiące":"miesięcy");case"yy":return r+(n(e)?"lata":"lat")}}var r="styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień".split("_"),a="stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia".split("_");(t.defineLocale||t.lang).call(t,"pl",{months:function(e,t){return/D MMMM/.test(t)?a[e.month()]:r[e.month()]},monthsShort:"sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru".split("_"),weekdays:"niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota".split("_"),weekdaysShort:"nie_pon_wt_śr_czw_pt_sb".split("_"),weekdaysMin:"N_Pn_Wt_Śr_Cz_Pt_So".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd, D MMMM YYYY LT"},calendar:{sameDay:"[Dziś o] LT",nextDay:"[Jutro o] LT",nextWeek:"[W] dddd [o] LT",lastDay:"[Wczoraj o] LT",lastWeek:function(){switch(this.day()){case 0:return"[W zeszłą niedzielę o] LT";case 3:return"[W zeszłą środę o] LT";case 6:return"[W zeszłą sobotę o] LT";default:return"[W zeszły] dddd [o] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"%s temu",s:"kilka sekund",m:i,mm:i,h:i,hh:i,d:"1 dzień",dd:"%d dni",M:"miesiąc",MM:i,y:"rok",yy:i},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}}),e.fullCalendar.datepickerLang("pl","pl",{closeText:"Zamknij",prevText:"<Poprzedni",nextText:"Następny>",currentText:"Dziś",monthNames:["Styczeń","Luty","Marzec","Kwiecień","Maj","Czerwiec","Lipiec","Sierpień","Wrzesień","Październik","Listopad","Grudzień"],monthNamesShort:["Sty","Lu","Mar","Kw","Maj","Cze","Lip","Sie","Wrz","Pa","Lis","Gru"],dayNames:["Niedziela","Poniedziałek","Wtorek","Środa","Czwartek","Piątek","Sobota"],dayNamesShort:["Nie","Pn","Wt","Śr","Czw","Pt","So"],dayNamesMin:["N","Pn","Wt","Śr","Cz","Pt","So"],weekHeader:"Tydz",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),e.fullCalendar.lang("pl",{defaultButtonText:{month:"Miesiąc",week:"Tydzień",day:"Dzień",list:"Plan dnia"},allDayText:"Cały dzień",eventLimitText:"więcej"})});(function(e){"function"==typeof define&&define.amd?define(["jquery","moment"],e):e(jQuery,moment)})(function(e,t){(t.defineLocale||t.lang).call(t,"pt-br",{months:"janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro".split("_"),monthsShort:"jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez".split("_"),weekdays:"domingo_segunda-feira_terça-feira_quarta-feira_quinta-feira_sexta-feira_sábado".split("_"),weekdaysShort:"dom_seg_ter_qua_qui_sex_sáb".split("_"),weekdaysMin:"dom_2ª_3ª_4ª_5ª_6ª_sáb".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY [às] LT",LLLL:"dddd, D [de] MMMM [de] YYYY [às] LT"},calendar:{sameDay:"[Hoje às] LT",nextDay:"[Amanhã às] LT",nextWeek:"dddd [às] LT",lastDay:"[Ontem às] LT",lastWeek:function(){return 0===this.day()||6===this.day()?"[Último] dddd [às] LT":"[Última] dddd [às] LT"},sameElse:"L"},relativeTime:{future:"em %s",past:"%s atrás",s:"segundos",m:"um minuto",mm:"%d minutos",h:"uma hora",hh:"%d horas",d:"um dia",dd:"%d dias",M:"um mês",MM:"%d meses",y:"um ano",yy:"%d anos"},ordinalParse:/\d{1,2}º/,ordinal:"%dº"}),e.fullCalendar.datepickerLang("pt-br","pt-BR",{closeText:"Fechar",prevText:"<Anterior",nextText:"Próximo>",currentText:"Hoje",monthNames:["Janeiro","Fevereiro","Março","Abril","Maio","Junho","Julho","Agosto","Setembro","Outubro","Novembro","Dezembro"],monthNamesShort:["Jan","Fev","Mar","Abr","Mai","Jun","Jul","Ago","Set","Out","Nov","Dez"],dayNames:["Domingo","Segunda-feira","Terça-feira","Quarta-feira","Quinta-feira","Sexta-feira","Sábado"],dayNamesShort:["Dom","Seg","Ter","Qua","Qui","Sex","Sáb"],dayNamesMin:["Dom","Seg","Ter","Qua","Qui","Sex","Sáb"],weekHeader:"Sm",dateFormat:"dd/mm/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),e.fullCalendar.lang("pt-br",{defaultButtonText:{month:"Mês",week:"Semana",day:"Dia",list:"Compromissos"},allDayText:"dia inteiro",eventLimitText:function(e){return"mais +"+e}})});(function(e){"function"==typeof define&&define.amd?define(["jquery","moment"],e):e(jQuery,moment)})(function(e,t){function n(e,t){var n=e.split("_");return 1===t%10&&11!==t%100?n[0]:t%10>=2&&4>=t%10&&(10>t%100||t%100>=20)?n[1]:n[2]}function i(e,t,i){var a={mm:t?"минута_минуты_минут":"минуту_минуты_минут",hh:"час_часа_часов",dd:"день_дня_дней",MM:"месяц_месяца_месяцев",yy:"год_года_лет"};return"m"===i?t?"минута":"минуту":e+" "+n(a[i],+e)}function a(e,t){var n={nominative:"январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь".split("_"),accusative:"января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря".split("_")},i=/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/.test(t)?"accusative":"nominative";return n[i][e.month()]}function r(e,t){var n={nominative:"янв_фев_март_апр_май_июнь_июль_авг_сен_окт_ноя_дек".split("_"),accusative:"янв_фев_мар_апр_мая_июня_июля_авг_сен_окт_ноя_дек".split("_")},i=/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/.test(t)?"accusative":"nominative";return n[i][e.month()]}function s(e,t){var n={nominative:"воскресенье_понедельник_вторник_среда_четверг_пятница_суббота".split("_"),accusative:"воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу".split("_")},i=/\[ ?[Вв] ?(?:прошлую|следующую|эту)? ?\] ?dddd/.test(t)?"accusative":"nominative";return n[i][e.day()]}(t.defineLocale||t.lang).call(t,"ru",{months:a,monthsShort:r,weekdays:s,weekdaysShort:"вс_пн_вт_ср_чт_пт_сб".split("_"),weekdaysMin:"вс_пн_вт_ср_чт_пт_сб".split("_"),monthsParse:[/^янв/i,/^фев/i,/^мар/i,/^апр/i,/^ма[й|я]/i,/^июн/i,/^июл/i,/^авг/i,/^сен/i,/^окт/i,/^ноя/i,/^дек/i],longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY г.",LLL:"D MMMM YYYY г., LT",LLLL:"dddd, D MMMM YYYY г., LT"},calendar:{sameDay:"[Сегодня в] LT",nextDay:"[Завтра в] LT",lastDay:"[Вчера в] LT",nextWeek:function(){return 2===this.day()?"[Во] dddd [в] LT":"[В] dddd [в] LT"},lastWeek:function(e){if(e.week()===this.week())return 2===this.day()?"[Во] dddd [в] LT":"[В] dddd [в] LT";switch(this.day()){case 0:return"[В прошлое] dddd [в] LT";case 1:case 2:case 4:return"[В прошлый] dddd [в] LT";case 3:case 5:case 6:return"[В прошлую] dddd [в] LT"}},sameElse:"L"},relativeTime:{future:"через %s",past:"%s назад",s:"несколько секунд",m:i,mm:i,h:"час",hh:i,d:"день",dd:i,M:"месяц",MM:i,y:"год",yy:i},meridiemParse:/ночи|утра|дня|вечера/i,isPM:function(e){return/^(дня|вечера)$/.test(e)},meridiem:function(e){return 4>e?"ночи":12>e?"утра":17>e?"дня":"вечера"},ordinalParse:/\d{1,2}-(й|го|я)/,ordinal:function(e,t){switch(t){case"M":case"d":case"DDD":return e+"-й";case"D":return e+"-го";case"w":case"W":return e+"-я";default:return e}},week:{dow:1,doy:7}}),e.fullCalendar.datepickerLang("ru","ru",{closeText:"Закрыть",prevText:"<Пред",nextText:"След>",currentText:"Сегодня",monthNames:["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь"],monthNamesShort:["Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек"],dayNames:["воскресенье","понедельник","вторник","среда","четверг","пятница","суббота"],dayNamesShort:["вск","пнд","втр","срд","чтв","птн","сбт"],dayNamesMin:["Вс","Пн","Вт","Ср","Чт","Пт","Сб"],weekHeader:"Нед",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),e.fullCalendar.lang("ru",{defaultButtonText:{month:"Месяц",week:"Неделя",day:"День",list:"Повестка дня"},allDayText:"Весь день",eventLimitText:function(e){return"+ ещё "+e}})});(function(e){"function"==typeof define&&define.amd?define(["jquery","moment"],e):e(jQuery,moment)})(function(e,t){(t.defineLocale||t.lang).call(t,"sv",{months:"januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december".split("_"),monthsShort:"jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec".split("_"),weekdays:"söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag".split("_"),weekdaysShort:"sön_mån_tis_ons_tor_fre_lör".split("_"),weekdaysMin:"sö_må_ti_on_to_fr_lö".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"YYYY-MM-DD",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd D MMMM YYYY LT"},calendar:{sameDay:"[Idag] LT",nextDay:"[Imorgon] LT",lastDay:"[Igår] LT",nextWeek:"dddd LT",lastWeek:"[Förra] dddd[en] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"för %s sedan",s:"några sekunder",m:"en minut",mm:"%d minuter",h:"en timme",hh:"%d timmar",d:"en dag",dd:"%d dagar",M:"en månad",MM:"%d månader",y:"ett år",yy:"%d år"},ordinalParse:/\d{1,2}(e|a)/,ordinal:function(e){var t=e%10,n=1===~~(e%100/10)?"e":1===t?"a":2===t?"a":3===t?"e":"e";return e+n},week:{dow:1,doy:4}}),e.fullCalendar.datepickerLang("sv","sv",{closeText:"Stäng",prevText:"«Förra",nextText:"Nästa»",currentText:"Idag",monthNames:["Januari","Februari","Mars","April","Maj","Juni","Juli","Augusti","September","Oktober","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","Maj","Jun","Jul","Aug","Sep","Okt","Nov","Dec"],dayNamesShort:["Sön","Mån","Tis","Ons","Tor","Fre","Lör"],dayNames:["Söndag","Måndag","Tisdag","Onsdag","Torsdag","Fredag","Lördag"],dayNamesMin:["Sö","Må","Ti","On","To","Fr","Lö"],weekHeader:"Ve",dateFormat:"yy-mm-dd",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),e.fullCalendar.lang("sv",{defaultButtonText:{month:"Månad",week:"Vecka",day:"Dag",list:"Program"},allDayText:"Heldag",eventLimitText:"till"})});(function(e){"function"==typeof define&&define.amd?define(["jquery","moment"],e):e(jQuery,moment)})(function(e,t){(t.defineLocale||t.lang).call(t,"th",{months:"มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม".split("_"),monthsShort:"มกรา_กุมภา_มีนา_เมษา_พฤษภา_มิถุนา_กรกฎา_สิงหา_กันยา_ตุลา_พฤศจิกา_ธันวา".split("_"),weekdays:"อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์".split("_"),weekdaysShort:"อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์".split("_"),weekdaysMin:"อา._จ._อ._พ._พฤ._ศ._ส.".split("_"),longDateFormat:{LT:"H นาฬิกา m นาที",LTS:"LT s วินาที",L:"YYYY/MM/DD",LL:"D MMMM YYYY",LLL:"D MMMM YYYY เวลา LT",LLLL:"วันddddที่ D MMMM YYYY เวลา LT"},meridiemParse:/ก่อนเที่ยง|หลังเที่ยง/,isPM:function(e){return"หลังเที่ยง"===e},meridiem:function(e){return 12>e?"ก่อนเที่ยง":"หลังเที่ยง"},calendar:{sameDay:"[วันนี้ เวลา] LT",nextDay:"[พรุ่งนี้ เวลา] LT",nextWeek:"dddd[หน้า เวลา] LT",lastDay:"[เมื่อวานนี้ เวลา] LT",lastWeek:"[วัน]dddd[ที่แล้ว เวลา] LT",sameElse:"L"},relativeTime:{future:"อีก %s",past:"%sที่แล้ว",s:"ไม่กี่วินาที",m:"1 นาที",mm:"%d นาที",h:"1 ชั่วโมง",hh:"%d ชั่วโมง",d:"1 วัน",dd:"%d วัน",M:"1 เดือน",MM:"%d เดือน",y:"1 ปี",yy:"%d ปี"}}),e.fullCalendar.datepickerLang("th","th",{closeText:"ปิด",prevText:"« ย้อน",nextText:"ถัดไป »",currentText:"วันนี้",monthNames:["มกราคม","กุมภาพันธ์","มีนาคม","เมษายน","พฤษภาคม","มิถุนายน","กรกฎาคม","สิงหาคม","กันยายน","ตุลาคม","พฤศจิกายน","ธันวาคม"],monthNamesShort:["ม.ค.","ก.พ.","มี.ค.","เม.ย.","พ.ค.","มิ.ย.","ก.ค.","ส.ค.","ก.ย.","ต.ค.","พ.ย.","ธ.ค."],dayNames:["อาทิตย์","จันทร์","อังคาร","พุธ","พฤหัสบดี","ศุกร์","เสาร์"],dayNamesShort:["อา.","จ.","อ.","พ.","พฤ.","ศ.","ส."],dayNamesMin:["อา.","จ.","อ.","พ.","พฤ.","ศ.","ส."],weekHeader:"Wk",dateFormat:"dd/mm/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),e.fullCalendar.lang("th",{defaultButtonText:{month:"เดือน",week:"สัปดาห์",day:"วัน",list:"แผนงาน"},allDayText:"ตลอดวัน",eventLimitText:"เพิ่มเติม"})});(function(e){"function"==typeof define&&define.amd?define(["jquery","moment"],e):e(jQuery,moment)})(function(e,t){(t.defineLocale||t.lang).call(t,"zh-cn",{months:"一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split("_"),monthsShort:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),weekdays:"星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"),weekdaysShort:"周日_周一_周二_周三_周四_周五_周六".split("_"),weekdaysMin:"日_一_二_三_四_五_六".split("_"),longDateFormat:{LT:"Ah点mm",LTS:"Ah点m分s秒",L:"YYYY-MM-DD",LL:"YYYY年MMMD日",LLL:"YYYY年MMMD日LT",LLLL:"YYYY年MMMD日ddddLT",l:"YYYY-MM-DD",ll:"YYYY年MMMD日",lll:"YYYY年MMMD日LT",llll:"YYYY年MMMD日ddddLT"},meridiemParse:/凌晨|早上|上午|中午|下午|晚上/,meridiemHour:function(e,t){return 12===e&&(e=0),"凌晨"===t||"早上"===t||"上午"===t?e:"下午"===t||"晚上"===t?e+12:e>=11?e:e+12},meridiem:function(e,t){var n=100*e+t;return 600>n?"凌晨":900>n?"早上":1130>n?"上午":1230>n?"中午":1800>n?"下午":"晚上"},calendar:{sameDay:function(){return 0===this.minutes()?"[今天]Ah[点整]":"[今天]LT"},nextDay:function(){return 0===this.minutes()?"[明天]Ah[点整]":"[明天]LT"},lastDay:function(){return 0===this.minutes()?"[昨天]Ah[点整]":"[昨天]LT"},nextWeek:function(){var e,n;return e=t().startOf("week"),n=this.unix()-e.unix()>=604800?"[下]":"[本]",0===this.minutes()?n+"dddAh点整":n+"dddAh点mm"},lastWeek:function(){var e,n;return e=t().startOf("week"),n=this.unix()<e.unix()?"[上]":"[本]",0===this.minutes()?n+"dddAh点整":n+"dddAh点mm"},sameElse:"LL"},ordinalParse:/\d{1,2}(日|月|周)/,ordinal:function(e,t){switch(t){case"d":case"D":case"DDD":return e+"日";case"M":return e+"月";case"w":case"W":return e+"周";default:return e}},relativeTime:{future:"%s内",past:"%s前",s:"几秒",m:"1分钟",mm:"%d分钟",h:"1小时",hh:"%d小时",d:"1天",dd:"%d天",M:"1个月",MM:"%d个月",y:"1年",yy:"%d年"},week:{dow:1,doy:4}}),e.fullCalendar.datepickerLang("zh-cn","zh-CN",{closeText:"关闭",prevText:"<上月",nextText:"下月>",currentText:"今天",monthNames:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],monthNamesShort:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],dayNames:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],dayNamesShort:["周日","周一","周二","周三","周四","周五","周六"],dayNamesMin:["日","一","二","三","四","五","六"],weekHeader:"周",dateFormat:"yy-mm-dd",firstDay:1,isRTL:!1,showMonthAfterYear:!0,yearSuffix:"年"}),e.fullCalendar.lang("zh-cn",{defaultButtonText:{month:"月",week:"周",day:"日",list:"日程"},allDayText:"全天",eventLimitText:function(e){return"另外 "+e+" 个"}})});
\ No newline at end of file +(function(t){"function"==typeof define&&define.amd?define(["jquery","moment"],t):t(jQuery,moment)})(function(t,e){(e.defineLocale||e.lang).call(e,"da",{months:"januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december".split("_"),monthsShort:"jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec".split("_"),weekdays:"søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag".split("_"),weekdaysShort:"søn_man_tir_ons_tor_fre_lør".split("_"),weekdaysMin:"sø_ma_ti_on_to_fr_lø".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD/MM/YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY LT",LLLL:"dddd [d.] D. MMMM YYYY LT"},calendar:{sameDay:"[I dag kl.] LT",nextDay:"[I morgen kl.] LT",nextWeek:"dddd [kl.] LT",lastDay:"[I går kl.] LT",lastWeek:"[sidste] dddd [kl] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"%s siden",s:"få sekunder",m:"et minut",mm:"%d minutter",h:"en time",hh:"%d timer",d:"en dag",dd:"%d dage",M:"en måned",MM:"%d måneder",y:"et år",yy:"%d år"},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}}),t.fullCalendar.datepickerLang("da","da",{closeText:"Luk",prevText:"<Forrige",nextText:"Næste>",currentText:"Idag",monthNames:["Januar","Februar","Marts","April","Maj","Juni","Juli","August","September","Oktober","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","Maj","Jun","Jul","Aug","Sep","Okt","Nov","Dec"],dayNames:["Søndag","Mandag","Tirsdag","Onsdag","Torsdag","Fredag","Lørdag"],dayNamesShort:["Søn","Man","Tir","Ons","Tor","Fre","Lør"],dayNamesMin:["Sø","Ma","Ti","On","To","Fr","Lø"],weekHeader:"Uge",dateFormat:"dd-mm-yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),t.fullCalendar.lang("da",{defaultButtonText:{month:"Måned",week:"Uge",day:"Dag",list:"Agenda"},allDayText:"Hele dagen",eventLimitText:"flere"})});(function(t){"function"==typeof define&&define.amd?define(["jquery","moment"],t):t(jQuery,moment)})(function(t,e){function n(t,e,n){var i={m:["eine Minute","einer Minute"],h:["eine Stunde","einer Stunde"],d:["ein Tag","einem Tag"],dd:[t+" Tage",t+" Tagen"],M:["ein Monat","einem Monat"],MM:[t+" Monate",t+" Monaten"],y:["ein Jahr","einem Jahr"],yy:[t+" Jahre",t+" Jahren"]};return e?i[n][0]:i[n][1]}(e.defineLocale||e.lang).call(e,"de",{months:"Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jan._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"),weekdays:"Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),weekdaysShort:"So._Mo._Di._Mi._Do._Fr._Sa.".split("_"),weekdaysMin:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY LT",LLLL:"dddd, D. MMMM YYYY LT"},calendar:{sameDay:"[Heute um] LT [Uhr]",sameElse:"L",nextDay:"[Morgen um] LT [Uhr]",nextWeek:"dddd [um] LT [Uhr]",lastDay:"[Gestern um] LT [Uhr]",lastWeek:"[letzten] dddd [um] LT [Uhr]"},relativeTime:{future:"in %s",past:"vor %s",s:"ein paar Sekunden",m:n,mm:"%d Minuten",h:n,hh:"%d Stunden",d:n,dd:n,M:n,MM:n,y:n,yy:n},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}}),t.fullCalendar.datepickerLang("de","de",{closeText:"Schließen",prevText:"<Zurück",nextText:"Vor>",currentText:"Heute",monthNames:["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember"],monthNamesShort:["Jan","Feb","Mär","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez"],dayNames:["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"],dayNamesShort:["So","Mo","Di","Mi","Do","Fr","Sa"],dayNamesMin:["So","Mo","Di","Mi","Do","Fr","Sa"],weekHeader:"KW",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),t.fullCalendar.lang("de",{defaultButtonText:{month:"Monat",week:"Woche",day:"Tag",list:"Terminübersicht"},allDayText:"Ganztägig",eventLimitText:function(t){return"+ weitere "+t}})});(function(e){"function"==typeof define&&define.amd?define(["jquery","moment"],e):e(jQuery,moment)})(function(e,t){var n="ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.".split("_"),i="ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic".split("_");(t.defineLocale||t.lang).call(t,"es",{months:"enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre".split("_"),monthsShort:function(e,t){return/-MMM-/.test(t)?i[e.month()]:n[e.month()]},weekdays:"domingo_lunes_martes_miércoles_jueves_viernes_sábado".split("_"),weekdaysShort:"dom._lun._mar._mié._jue._vie._sáb.".split("_"),weekdaysMin:"Do_Lu_Ma_Mi_Ju_Vi_Sá".split("_"),longDateFormat:{LT:"H:mm",LTS:"LT:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY LT",LLLL:"dddd, D [de] MMMM [de] YYYY LT"},calendar:{sameDay:function(){return"[hoy a la"+(1!==this.hours()?"s":"")+"] LT"},nextDay:function(){return"[mañana a la"+(1!==this.hours()?"s":"")+"] LT"},nextWeek:function(){return"dddd [a la"+(1!==this.hours()?"s":"")+"] LT"},lastDay:function(){return"[ayer a la"+(1!==this.hours()?"s":"")+"] LT"},lastWeek:function(){return"[el] dddd [pasado a la"+(1!==this.hours()?"s":"")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"hace %s",s:"unos segundos",m:"un minuto",mm:"%d minutos",h:"una hora",hh:"%d horas",d:"un día",dd:"%d días",M:"un mes",MM:"%d meses",y:"un año",yy:"%d años"},ordinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:1,doy:4}}),e.fullCalendar.datepickerLang("es","es",{closeText:"Cerrar",prevText:"<Ant",nextText:"Sig>",currentText:"Hoy",monthNames:["enero","febrero","marzo","abril","mayo","junio","julio","agosto","septiembre","octubre","noviembre","diciembre"],monthNamesShort:["ene","feb","mar","abr","may","jun","jul","ago","sep","oct","nov","dic"],dayNames:["domingo","lunes","martes","miércoles","jueves","viernes","sábado"],dayNamesShort:["dom","lun","mar","mié","jue","vie","sáb"],dayNamesMin:["D","L","M","X","J","V","S"],weekHeader:"Sm",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),e.fullCalendar.lang("es",{defaultButtonText:{month:"Mes",week:"Semana",day:"Día",list:"Agenda"},allDayHtml:"Todo<br/>el día",eventLimitText:"más"})});(function(e){"function"==typeof define&&define.amd?define(["jquery","moment"],e):e(jQuery,moment)})(function(e,t){function n(e,t,n,r){var s="";switch(n){case"s":return r?"muutaman sekunnin":"muutama sekunti";case"m":return r?"minuutin":"minuutti";case"mm":s=r?"minuutin":"minuuttia";break;case"h":return r?"tunnin":"tunti";case"hh":s=r?"tunnin":"tuntia";break;case"d":return r?"päivän":"päivä";case"dd":s=r?"päivän":"päivää";break;case"M":return r?"kuukauden":"kuukausi";case"MM":s=r?"kuukauden":"kuukautta";break;case"y":return r?"vuoden":"vuosi";case"yy":s=r?"vuoden":"vuotta"}return s=i(e,r)+" "+s}function i(e,t){return 10>e?t?s[e]:r[e]:e}var r="nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän".split(" "),s=["nolla","yhden","kahden","kolmen","neljän","viiden","kuuden",r[7],r[8],r[9]];(t.defineLocale||t.lang).call(t,"fi",{months:"tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu".split("_"),monthsShort:"tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu".split("_"),weekdays:"sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai".split("_"),weekdaysShort:"su_ma_ti_ke_to_pe_la".split("_"),weekdaysMin:"su_ma_ti_ke_to_pe_la".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD.MM.YYYY",LL:"Do MMMM[ta] YYYY",LLL:"Do MMMM[ta] YYYY, [klo] LT",LLLL:"dddd, Do MMMM[ta] YYYY, [klo] LT",l:"D.M.YYYY",ll:"Do MMM YYYY",lll:"Do MMM YYYY, [klo] LT",llll:"ddd, Do MMM YYYY, [klo] LT"},calendar:{sameDay:"[tänään] [klo] LT",nextDay:"[huomenna] [klo] LT",nextWeek:"dddd [klo] LT",lastDay:"[eilen] [klo] LT",lastWeek:"[viime] dddd[na] [klo] LT",sameElse:"L"},relativeTime:{future:"%s päästä",past:"%s sitten",s:n,m:n,mm:n,h:n,hh:n,d:n,dd:n,M:n,MM:n,y:n,yy:n},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}}),e.fullCalendar.datepickerLang("fi","fi",{closeText:"Sulje",prevText:"«Edellinen",nextText:"Seuraava»",currentText:"Tänään",monthNames:["Tammikuu","Helmikuu","Maaliskuu","Huhtikuu","Toukokuu","Kesäkuu","Heinäkuu","Elokuu","Syyskuu","Lokakuu","Marraskuu","Joulukuu"],monthNamesShort:["Tammi","Helmi","Maalis","Huhti","Touko","Kesä","Heinä","Elo","Syys","Loka","Marras","Joulu"],dayNamesShort:["Su","Ma","Ti","Ke","To","Pe","La"],dayNames:["Sunnuntai","Maanantai","Tiistai","Keskiviikko","Torstai","Perjantai","Lauantai"],dayNamesMin:["Su","Ma","Ti","Ke","To","Pe","La"],weekHeader:"Vk",dateFormat:"d.m.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),e.fullCalendar.lang("fi",{defaultButtonText:{month:"Kuukausi",week:"Viikko",day:"Päivä",list:"Tapahtumat"},allDayText:"Koko päivä",eventLimitText:"lisää"})});(function(e){"function"==typeof define&&define.amd?define(["jquery","moment"],e):e(jQuery,moment)})(function(e,t){(t.defineLocale||t.lang).call(t,"fr",{months:"janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"),monthsShort:"janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"),weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"Di_Lu_Ma_Me_Je_Ve_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd D MMMM YYYY LT"},calendar:{sameDay:"[Aujourd'hui à] LT",nextDay:"[Demain à] LT",nextWeek:"dddd [à] LT",lastDay:"[Hier à] LT",lastWeek:"dddd [dernier à] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"un an",yy:"%d ans"},ordinalParse:/\d{1,2}(er|)/,ordinal:function(e){return e+(1===e?"er":"")},week:{dow:1,doy:4}}),e.fullCalendar.datepickerLang("fr","fr",{closeText:"Fermer",prevText:"Précédent",nextText:"Suivant",currentText:"Aujourd'hui",monthNames:["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre"],monthNamesShort:["janv.","févr.","mars","avr.","mai","juin","juil.","août","sept.","oct.","nov.","déc."],dayNames:["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"],dayNamesShort:["dim.","lun.","mar.","mer.","jeu.","ven.","sam."],dayNamesMin:["D","L","M","M","J","V","S"],weekHeader:"Sem.",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),e.fullCalendar.lang("fr",{defaultButtonText:{month:"Mois",week:"Semaine",day:"Jour",list:"Mon planning"},allDayHtml:"Toute la<br/>journée",eventLimitText:"en plus"})});(function(e){"function"==typeof define&&define.amd?define(["jquery","moment"],e):e(jQuery,moment)})(function(e,t){function n(e,t,n,r){var i=e;switch(n){case"s":return r||t?"néhány másodperc":"néhány másodperce";case"m":return"egy"+(r||t?" perc":" perce");case"mm":return i+(r||t?" perc":" perce");case"h":return"egy"+(r||t?" óra":" órája");case"hh":return i+(r||t?" óra":" órája");case"d":return"egy"+(r||t?" nap":" napja");case"dd":return i+(r||t?" nap":" napja");case"M":return"egy"+(r||t?" hónap":" hónapja");case"MM":return i+(r||t?" hónap":" hónapja");case"y":return"egy"+(r||t?" év":" éve");case"yy":return i+(r||t?" év":" éve")}return""}function r(e){return(e?"":"[múlt] ")+"["+i[this.day()]+"] LT[-kor]"}var i="vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton".split(" ");(t.defineLocale||t.lang).call(t,"hu",{months:"január_február_március_április_május_június_július_augusztus_szeptember_október_november_december".split("_"),monthsShort:"jan_feb_márc_ápr_máj_jún_júl_aug_szept_okt_nov_dec".split("_"),weekdays:"vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat".split("_"),weekdaysShort:"vas_hét_kedd_sze_csüt_pén_szo".split("_"),weekdaysMin:"v_h_k_sze_cs_p_szo".split("_"),longDateFormat:{LT:"H:mm",LTS:"LT:ss",L:"YYYY.MM.DD.",LL:"YYYY. MMMM D.",LLL:"YYYY. MMMM D., LT",LLLL:"YYYY. MMMM D., dddd LT"},meridiemParse:/de|du/i,isPM:function(e){return"u"===e.charAt(1).toLowerCase()},meridiem:function(e,t,n){return 12>e?n===!0?"de":"DE":n===!0?"du":"DU"},calendar:{sameDay:"[ma] LT[-kor]",nextDay:"[holnap] LT[-kor]",nextWeek:function(){return r.call(this,!0)},lastDay:"[tegnap] LT[-kor]",lastWeek:function(){return r.call(this,!1)},sameElse:"L"},relativeTime:{future:"%s múlva",past:"%s",s:n,m:n,mm:n,h:n,hh:n,d:n,dd:n,M:n,MM:n,y:n,yy:n},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}}),e.fullCalendar.datepickerLang("hu","hu",{closeText:"bezár",prevText:"vissza",nextText:"előre",currentText:"ma",monthNames:["Január","Február","Március","Április","Május","Június","Július","Augusztus","Szeptember","Október","November","December"],monthNamesShort:["Jan","Feb","Már","Ápr","Máj","Jún","Júl","Aug","Szep","Okt","Nov","Dec"],dayNames:["Vasárnap","Hétfő","Kedd","Szerda","Csütörtök","Péntek","Szombat"],dayNamesShort:["Vas","Hét","Ked","Sze","Csü","Pén","Szo"],dayNamesMin:["V","H","K","Sze","Cs","P","Szo"],weekHeader:"Hét",dateFormat:"yy.mm.dd.",firstDay:1,isRTL:!1,showMonthAfterYear:!0,yearSuffix:""}),e.fullCalendar.lang("hu",{defaultButtonText:{month:"Hónap",week:"Hét",day:"Nap",list:"Napló"},allDayText:"Egész nap",eventLimitText:"további"})});(function(e){"function"==typeof define&&define.amd?define(["jquery","moment"],e):e(jQuery,moment)})(function(e,t){(t.defineLocale||t.lang).call(t,"it",{months:"gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre".split("_"),monthsShort:"gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic".split("_"),weekdays:"Domenica_Lunedì_Martedì_Mercoledì_Giovedì_Venerdì_Sabato".split("_"),weekdaysShort:"Dom_Lun_Mar_Mer_Gio_Ven_Sab".split("_"),weekdaysMin:"D_L_Ma_Me_G_V_S".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd, D MMMM YYYY LT"},calendar:{sameDay:"[Oggi alle] LT",nextDay:"[Domani alle] LT",nextWeek:"dddd [alle] LT",lastDay:"[Ieri alle] LT",lastWeek:function(){switch(this.day()){case 0:return"[la scorsa] dddd [alle] LT";default:return"[lo scorso] dddd [alle] LT"}},sameElse:"L"},relativeTime:{future:function(e){return(/^[0-9].+$/.test(e)?"tra":"in")+" "+e},past:"%s fa",s:"alcuni secondi",m:"un minuto",mm:"%d minuti",h:"un'ora",hh:"%d ore",d:"un giorno",dd:"%d giorni",M:"un mese",MM:"%d mesi",y:"un anno",yy:"%d anni"},ordinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:1,doy:4}}),e.fullCalendar.datepickerLang("it","it",{closeText:"Chiudi",prevText:"<Prec",nextText:"Succ>",currentText:"Oggi",monthNames:["Gennaio","Febbraio","Marzo","Aprile","Maggio","Giugno","Luglio","Agosto","Settembre","Ottobre","Novembre","Dicembre"],monthNamesShort:["Gen","Feb","Mar","Apr","Mag","Giu","Lug","Ago","Set","Ott","Nov","Dic"],dayNames:["Domenica","Lunedì","Martedì","Mercoledì","Giovedì","Venerdì","Sabato"],dayNamesShort:["Dom","Lun","Mar","Mer","Gio","Ven","Sab"],dayNamesMin:["Do","Lu","Ma","Me","Gi","Ve","Sa"],weekHeader:"Sm",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),e.fullCalendar.lang("it",{defaultButtonText:{month:"Mese",week:"Settimana",day:"Giorno",list:"Agenda"},allDayHtml:"Tutto il<br/>giorno",eventLimitText:function(e){return"+altri "+e}})});(function(e){"function"==typeof define&&define.amd?define(["jquery","moment"],e):e(jQuery,moment)})(function(e,t){(t.defineLocale||t.lang).call(t,"ja",{months:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),monthsShort:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),weekdays:"日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日".split("_"),weekdaysShort:"日_月_火_水_木_金_土".split("_"),weekdaysMin:"日_月_火_水_木_金_土".split("_"),longDateFormat:{LT:"Ah時m分",LTS:"LTs秒",L:"YYYY/MM/DD",LL:"YYYY年M月D日",LLL:"YYYY年M月D日LT",LLLL:"YYYY年M月D日LT dddd"},meridiemParse:/午前|午後/i,isPM:function(e){return"午後"===e},meridiem:function(e){return 12>e?"午前":"午後"},calendar:{sameDay:"[今日] LT",nextDay:"[明日] LT",nextWeek:"[来週]dddd LT",lastDay:"[昨日] LT",lastWeek:"[前週]dddd LT",sameElse:"L"},relativeTime:{future:"%s後",past:"%s前",s:"数秒",m:"1分",mm:"%d分",h:"1時間",hh:"%d時間",d:"1日",dd:"%d日",M:"1ヶ月",MM:"%dヶ月",y:"1年",yy:"%d年"}}),e.fullCalendar.datepickerLang("ja","ja",{closeText:"閉じる",prevText:"<前",nextText:"次>",currentText:"今日",monthNames:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],monthNamesShort:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],dayNames:["日曜日","月曜日","火曜日","水曜日","木曜日","金曜日","土曜日"],dayNamesShort:["日","月","火","水","木","金","土"],dayNamesMin:["日","月","火","水","木","金","土"],weekHeader:"週",dateFormat:"yy/mm/dd",firstDay:0,isRTL:!1,showMonthAfterYear:!0,yearSuffix:"年"}),e.fullCalendar.lang("ja",{defaultButtonText:{month:"月",week:"週",day:"日",list:"予定リスト"},allDayText:"終日",eventLimitText:function(e){return"他 "+e+" 件"}})});(function(e){"function"==typeof define&&define.amd?define(["jquery","moment"],e):e(jQuery,moment)})(function(e,t){function n(e){return 5>e%10&&e%10>1&&1!==~~(e/10)%10}function i(e,t,i){var r=e+" ";switch(i){case"m":return t?"minuta":"minutę";case"mm":return r+(n(e)?"minuty":"minut");case"h":return t?"godzina":"godzinę";case"hh":return r+(n(e)?"godziny":"godzin");case"MM":return r+(n(e)?"miesiące":"miesięcy");case"yy":return r+(n(e)?"lata":"lat")}}var r="styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień".split("_"),a="stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia".split("_");(t.defineLocale||t.lang).call(t,"pl",{months:function(e,t){return/D MMMM/.test(t)?a[e.month()]:r[e.month()]},monthsShort:"sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru".split("_"),weekdays:"niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota".split("_"),weekdaysShort:"nie_pon_wt_śr_czw_pt_sb".split("_"),weekdaysMin:"N_Pn_Wt_Śr_Cz_Pt_So".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd, D MMMM YYYY LT"},calendar:{sameDay:"[Dziś o] LT",nextDay:"[Jutro o] LT",nextWeek:"[W] dddd [o] LT",lastDay:"[Wczoraj o] LT",lastWeek:function(){switch(this.day()){case 0:return"[W zeszłą niedzielę o] LT";case 3:return"[W zeszłą środę o] LT";case 6:return"[W zeszłą sobotę o] LT";default:return"[W zeszły] dddd [o] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"%s temu",s:"kilka sekund",m:i,mm:i,h:i,hh:i,d:"1 dzień",dd:"%d dni",M:"miesiąc",MM:i,y:"rok",yy:i},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}}),e.fullCalendar.datepickerLang("pl","pl",{closeText:"Zamknij",prevText:"<Poprzedni",nextText:"Następny>",currentText:"Dziś",monthNames:["Styczeń","Luty","Marzec","Kwiecień","Maj","Czerwiec","Lipiec","Sierpień","Wrzesień","Październik","Listopad","Grudzień"],monthNamesShort:["Sty","Lu","Mar","Kw","Maj","Cze","Lip","Sie","Wrz","Pa","Lis","Gru"],dayNames:["Niedziela","Poniedziałek","Wtorek","Środa","Czwartek","Piątek","Sobota"],dayNamesShort:["Nie","Pn","Wt","Śr","Czw","Pt","So"],dayNamesMin:["N","Pn","Wt","Śr","Cz","Pt","So"],weekHeader:"Tydz",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),e.fullCalendar.lang("pl",{defaultButtonText:{month:"Miesiąc",week:"Tydzień",day:"Dzień",list:"Plan dnia"},allDayText:"Cały dzień",eventLimitText:"więcej"})});(function(e){"function"==typeof define&&define.amd?define(["jquery","moment"],e):e(jQuery,moment)})(function(e,t){(t.defineLocale||t.lang).call(t,"pt-br",{months:"janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro".split("_"),monthsShort:"jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez".split("_"),weekdays:"domingo_segunda-feira_terça-feira_quarta-feira_quinta-feira_sexta-feira_sábado".split("_"),weekdaysShort:"dom_seg_ter_qua_qui_sex_sáb".split("_"),weekdaysMin:"dom_2ª_3ª_4ª_5ª_6ª_sáb".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY [às] LT",LLLL:"dddd, D [de] MMMM [de] YYYY [às] LT"},calendar:{sameDay:"[Hoje às] LT",nextDay:"[Amanhã às] LT",nextWeek:"dddd [às] LT",lastDay:"[Ontem às] LT",lastWeek:function(){return 0===this.day()||6===this.day()?"[Último] dddd [às] LT":"[Última] dddd [às] LT"},sameElse:"L"},relativeTime:{future:"em %s",past:"%s atrás",s:"segundos",m:"um minuto",mm:"%d minutos",h:"uma hora",hh:"%d horas",d:"um dia",dd:"%d dias",M:"um mês",MM:"%d meses",y:"um ano",yy:"%d anos"},ordinalParse:/\d{1,2}º/,ordinal:"%dº"}),e.fullCalendar.datepickerLang("pt-br","pt-BR",{closeText:"Fechar",prevText:"<Anterior",nextText:"Próximo>",currentText:"Hoje",monthNames:["Janeiro","Fevereiro","Março","Abril","Maio","Junho","Julho","Agosto","Setembro","Outubro","Novembro","Dezembro"],monthNamesShort:["Jan","Fev","Mar","Abr","Mai","Jun","Jul","Ago","Set","Out","Nov","Dez"],dayNames:["Domingo","Segunda-feira","Terça-feira","Quarta-feira","Quinta-feira","Sexta-feira","Sábado"],dayNamesShort:["Dom","Seg","Ter","Qua","Qui","Sex","Sáb"],dayNamesMin:["Dom","Seg","Ter","Qua","Qui","Sex","Sáb"],weekHeader:"Sm",dateFormat:"dd/mm/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),e.fullCalendar.lang("pt-br",{defaultButtonText:{month:"Mês",week:"Semana",day:"Dia",list:"Compromissos"},allDayText:"dia inteiro",eventLimitText:function(e){return"mais +"+e}})});(function(e){"function"==typeof define&&define.amd?define(["jquery","moment"],e):e(jQuery,moment)})(function(e,t){function n(e,t){var n=e.split("_");return 1===t%10&&11!==t%100?n[0]:t%10>=2&&4>=t%10&&(10>t%100||t%100>=20)?n[1]:n[2]}function i(e,t,i){var a={mm:t?"минута_минуты_минут":"минуту_минуты_минут",hh:"час_часа_часов",dd:"день_дня_дней",MM:"месяц_месяца_месяцев",yy:"год_года_лет"};return"m"===i?t?"минута":"минуту":e+" "+n(a[i],+e)}function a(e,t){var n={nominative:"январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь".split("_"),accusative:"января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря".split("_")},i=/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/.test(t)?"accusative":"nominative";return n[i][e.month()]}function r(e,t){var n={nominative:"янв_фев_март_апр_май_июнь_июль_авг_сен_окт_ноя_дек".split("_"),accusative:"янв_фев_мар_апр_мая_июня_июля_авг_сен_окт_ноя_дек".split("_")},i=/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/.test(t)?"accusative":"nominative";return n[i][e.month()]}function s(e,t){var n={nominative:"воскресенье_понедельник_вторник_среда_четверг_пятница_суббота".split("_"),accusative:"воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу".split("_")},i=/\[ ?[Вв] ?(?:прошлую|следующую|эту)? ?\] ?dddd/.test(t)?"accusative":"nominative";return n[i][e.day()]}(t.defineLocale||t.lang).call(t,"ru",{months:a,monthsShort:r,weekdays:s,weekdaysShort:"вс_пн_вт_ср_чт_пт_сб".split("_"),weekdaysMin:"вс_пн_вт_ср_чт_пт_сб".split("_"),monthsParse:[/^янв/i,/^фев/i,/^мар/i,/^апр/i,/^ма[й|я]/i,/^июн/i,/^июл/i,/^авг/i,/^сен/i,/^окт/i,/^ноя/i,/^дек/i],longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY г.",LLL:"D MMMM YYYY г., LT",LLLL:"dddd, D MMMM YYYY г., LT"},calendar:{sameDay:"[Сегодня в] LT",nextDay:"[Завтра в] LT",lastDay:"[Вчера в] LT",nextWeek:function(){return 2===this.day()?"[Во] dddd [в] LT":"[В] dddd [в] LT"},lastWeek:function(e){if(e.week()===this.week())return 2===this.day()?"[Во] dddd [в] LT":"[В] dddd [в] LT";switch(this.day()){case 0:return"[В прошлое] dddd [в] LT";case 1:case 2:case 4:return"[В прошлый] dddd [в] LT";case 3:case 5:case 6:return"[В прошлую] dddd [в] LT"}},sameElse:"L"},relativeTime:{future:"через %s",past:"%s назад",s:"несколько секунд",m:i,mm:i,h:"час",hh:i,d:"день",dd:i,M:"месяц",MM:i,y:"год",yy:i},meridiemParse:/ночи|утра|дня|вечера/i,isPM:function(e){return/^(дня|вечера)$/.test(e)},meridiem:function(e){return 4>e?"ночи":12>e?"утра":17>e?"дня":"вечера"},ordinalParse:/\d{1,2}-(й|го|я)/,ordinal:function(e,t){switch(t){case"M":case"d":case"DDD":return e+"-й";case"D":return e+"-го";case"w":case"W":return e+"-я";default:return e}},week:{dow:1,doy:7}}),e.fullCalendar.datepickerLang("ru","ru",{closeText:"Закрыть",prevText:"<Пред",nextText:"След>",currentText:"Сегодня",monthNames:["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь"],monthNamesShort:["Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек"],dayNames:["воскресенье","понедельник","вторник","среда","четверг","пятница","суббота"],dayNamesShort:["вск","пнд","втр","срд","чтв","птн","сбт"],dayNamesMin:["Вс","Пн","Вт","Ср","Чт","Пт","Сб"],weekHeader:"Нед",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),e.fullCalendar.lang("ru",{defaultButtonText:{month:"Месяц",week:"Неделя",day:"День",list:"Повестка дня"},allDayText:"Весь день",eventLimitText:function(e){return"+ ещё "+e}})});(function(e){"function"==typeof define&&define.amd?define(["jquery","moment"],e):e(jQuery,moment)})(function(e,t){(t.defineLocale||t.lang).call(t,"sv",{months:"januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december".split("_"),monthsShort:"jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec".split("_"),weekdays:"söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag".split("_"),weekdaysShort:"sön_mån_tis_ons_tor_fre_lör".split("_"),weekdaysMin:"sö_må_ti_on_to_fr_lö".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"YYYY-MM-DD",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd D MMMM YYYY LT"},calendar:{sameDay:"[Idag] LT",nextDay:"[Imorgon] LT",lastDay:"[Igår] LT",nextWeek:"dddd LT",lastWeek:"[Förra] dddd[en] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"för %s sedan",s:"några sekunder",m:"en minut",mm:"%d minuter",h:"en timme",hh:"%d timmar",d:"en dag",dd:"%d dagar",M:"en månad",MM:"%d månader",y:"ett år",yy:"%d år"},ordinalParse:/\d{1,2}(e|a)/,ordinal:function(e){var t=e%10,n=1===~~(e%100/10)?"e":1===t?"a":2===t?"a":3===t?"e":"e";return e+n},week:{dow:1,doy:4}}),e.fullCalendar.datepickerLang("sv","sv",{closeText:"Stäng",prevText:"«Förra",nextText:"Nästa»",currentText:"Idag",monthNames:["Januari","Februari","Mars","April","Maj","Juni","Juli","Augusti","September","Oktober","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","Maj","Jun","Jul","Aug","Sep","Okt","Nov","Dec"],dayNamesShort:["Sön","Mån","Tis","Ons","Tor","Fre","Lör"],dayNames:["Söndag","Måndag","Tisdag","Onsdag","Torsdag","Fredag","Lördag"],dayNamesMin:["Sö","Må","Ti","On","To","Fr","Lö"],weekHeader:"Ve",dateFormat:"yy-mm-dd",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),e.fullCalendar.lang("sv",{defaultButtonText:{month:"Månad",week:"Vecka",day:"Dag",list:"Program"},allDayText:"Heldag",eventLimitText:"till"})});(function(e){"function"==typeof define&&define.amd?define(["jquery","moment"],e):e(jQuery,moment)})(function(e,t){(t.defineLocale||t.lang).call(t,"th",{months:"มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม".split("_"),monthsShort:"มกรา_กุมภา_มีนา_เมษา_พฤษภา_มิถุนา_กรกฎา_สิงหา_กันยา_ตุลา_พฤศจิกา_ธันวา".split("_"),weekdays:"อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์".split("_"),weekdaysShort:"อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์".split("_"),weekdaysMin:"อา._จ._อ._พ._พฤ._ศ._ส.".split("_"),longDateFormat:{LT:"H นาฬิกา m นาที",LTS:"LT s วินาที",L:"YYYY/MM/DD",LL:"D MMMM YYYY",LLL:"D MMMM YYYY เวลา LT",LLLL:"วันddddที่ D MMMM YYYY เวลา LT"},meridiemParse:/ก่อนเที่ยง|หลังเที่ยง/,isPM:function(e){return"หลังเที่ยง"===e},meridiem:function(e){return 12>e?"ก่อนเที่ยง":"หลังเที่ยง"},calendar:{sameDay:"[วันนี้ เวลา] LT",nextDay:"[พรุ่งนี้ เวลา] LT",nextWeek:"dddd[หน้า เวลา] LT",lastDay:"[เมื่อวานนี้ เวลา] LT",lastWeek:"[วัน]dddd[ที่แล้ว เวลา] LT",sameElse:"L"},relativeTime:{future:"อีก %s",past:"%sที่แล้ว",s:"ไม่กี่วินาที",m:"1 นาที",mm:"%d นาที",h:"1 ชั่วโมง",hh:"%d ชั่วโมง",d:"1 วัน",dd:"%d วัน",M:"1 เดือน",MM:"%d เดือน",y:"1 ปี",yy:"%d ปี"}}),e.fullCalendar.datepickerLang("th","th",{closeText:"ปิด",prevText:"« ย้อน",nextText:"ถัดไป »",currentText:"วันนี้",monthNames:["มกราคม","กุมภาพันธ์","มีนาคม","เมษายน","พฤษภาคม","มิถุนายน","กรกฎาคม","สิงหาคม","กันยายน","ตุลาคม","พฤศจิกายน","ธันวาคม"],monthNamesShort:["ม.ค.","ก.พ.","มี.ค.","เม.ย.","พ.ค.","มิ.ย.","ก.ค.","ส.ค.","ก.ย.","ต.ค.","พ.ย.","ธ.ค."],dayNames:["อาทิตย์","จันทร์","อังคาร","พุธ","พฤหัสบดี","ศุกร์","เสาร์"],dayNamesShort:["อา.","จ.","อ.","พ.","พฤ.","ศ.","ส."],dayNamesMin:["อา.","จ.","อ.","พ.","พฤ.","ศ.","ส."],weekHeader:"Wk",dateFormat:"dd/mm/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),e.fullCalendar.lang("th",{defaultButtonText:{month:"เดือน",week:"สัปดาห์",day:"วัน",list:"แผนงาน"},allDayText:"ตลอดวัน",eventLimitText:"เพิ่มเติม"})});(function(e){"function"==typeof define&&define.amd?define(["jquery","moment"],e):e(jQuery,moment)})(function(e,t){(t.defineLocale||t.lang).call(t,"zh-cn",{months:"一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split("_"),monthsShort:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),weekdays:"星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"),weekdaysShort:"周日_周一_周二_周三_周四_周五_周六".split("_"),weekdaysMin:"日_一_二_三_四_五_六".split("_"),longDateFormat:{LT:"Ah点mm",LTS:"Ah点m分s秒",L:"YYYY-MM-DD",LL:"YYYY年MMMD日",LLL:"YYYY年MMMD日LT",LLLL:"YYYY年MMMD日ddddLT",l:"YYYY-MM-DD",ll:"YYYY年MMMD日",lll:"YYYY年MMMD日LT",llll:"YYYY年MMMD日ddddLT"},meridiemParse:/凌晨|早上|上午|中午|下午|晚上/,meridiemHour:function(e,t){return 12===e&&(e=0),"凌晨"===t||"早上"===t||"上午"===t?e:"下午"===t||"晚上"===t?e+12:e>=11?e:e+12},meridiem:function(e,t){var n=100*e+t;return 600>n?"凌晨":900>n?"早上":1130>n?"上午":1230>n?"中午":1800>n?"下午":"晚上"},calendar:{sameDay:function(){return 0===this.minutes()?"[今天]Ah[点整]":"[今天]LT"},nextDay:function(){return 0===this.minutes()?"[明天]Ah[点整]":"[明天]LT"},lastDay:function(){return 0===this.minutes()?"[昨天]Ah[点整]":"[昨天]LT"},nextWeek:function(){var e,n;return e=t().startOf("week"),n=this.unix()-e.unix()>=604800?"[下]":"[本]",0===this.minutes()?n+"dddAh点整":n+"dddAh点mm"},lastWeek:function(){var e,n;return e=t().startOf("week"),n=this.unix()<e.unix()?"[上]":"[本]",0===this.minutes()?n+"dddAh点整":n+"dddAh点mm"},sameElse:"LL"},ordinalParse:/\d{1,2}(日|月|周)/,ordinal:function(e,t){switch(t){case"d":case"D":case"DDD":return e+"日";case"M":return e+"月";case"w":case"W":return e+"周";default:return e}},relativeTime:{future:"%s内",past:"%s前",s:"几秒",m:"1分钟",mm:"%d分钟",h:"1小时",hh:"%d小时",d:"1天",dd:"%d天",M:"1个月",MM:"%d个月",y:"1年",yy:"%d年"},week:{dow:1,doy:4}}),e.fullCalendar.datepickerLang("zh-cn","zh-CN",{closeText:"关闭",prevText:"<上月",nextText:"下月>",currentText:"今天",monthNames:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],monthNamesShort:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],dayNames:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],dayNamesShort:["周日","周一","周二","周三","周四","周五","周六"],dayNamesMin:["日","一","二","三","四","五","六"],weekHeader:"周",dateFormat:"yy-mm-dd",firstDay:1,isRTL:!1,showMonthAfterYear:!0,yearSuffix:"年"}),e.fullCalendar.lang("zh-cn",{defaultButtonText:{month:"月",week:"周",day:"日",list:"日程"},allDayText:"全天",eventLimitText:function(e){return"另外 "+e+" 个"}})});(function(e){"function"==typeof define&&define.amd?define(["jquery","moment"],e):e(jQuery,moment)})(function(e,t){var n={1:"'inci",5:"'inci",8:"'inci",70:"'inci",80:"'inci",2:"'nci",7:"'nci",20:"'nci",50:"'nci",3:"'üncü",4:"'üncü",100:"'üncü",6:"'ncı",9:"'uncu",10:"'uncu",30:"'uncu",60:"'ıncı",90:"'ıncı"};(t.defineLocale||t.lang).call(t,"tr",{months:"Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık".split("_"),monthsShort:"Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara".split("_"),weekdays:"Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi".split("_"),weekdaysShort:"Paz_Pts_Sal_Çar_Per_Cum_Cts".split("_"),weekdaysMin:"Pz_Pt_Sa_Ça_Pe_Cu_Ct".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd, D MMMM YYYY LT"},calendar:{sameDay:"[bugün saat] LT",nextDay:"[yarın saat] LT",nextWeek:"[haftaya] dddd [saat] LT",lastDay:"[dün] LT",lastWeek:"[geçen hafta] dddd [saat] LT",sameElse:"L"},relativeTime:{future:"%s sonra",past:"%s önce",s:"birkaç saniye",m:"bir dakika",mm:"%d dakika",h:"bir saat",hh:"%d saat",d:"bir gün",dd:"%d gün",M:"bir ay",MM:"%d ay",y:"bir yıl",yy:"%d yıl"},ordinalParse:/\d{1,2}'(inci|nci|üncü|ncı|uncu|ıncı)/,ordinal:function(e){if(0===e)return e+"'ıncı";var t=e%10,a=e%100-t,r=e>=100?100:null;return e+(n[t]||n[a]||n[r])},week:{dow:1,doy:7}}),e.fullCalendar.datepickerLang("tr","tr",{closeText:"kapat",prevText:"<geri",nextText:"ileri>",currentText:"bugün",monthNames:["Ocak","Şubat","Mart","Nisan","Mayıs","Haziran","Temmuz","Ağustos","Eylül","Ekim","Kasım","Aralık"],monthNamesShort:["Oca","Şub","Mar","Nis","May","Haz","Tem","Ağu","Eyl","Eki","Kas","Ara"],dayNames:["Pazar","Pazartesi","Salı","Çarşamba","Perşembe","Cuma","Cumartesi"],dayNamesShort:["Pz","Pt","Sa","Ça","Pe","Cu","Ct"],dayNamesMin:["Pz","Pt","Sa","Ça","Pe","Cu","Ct"],weekHeader:"Hf",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),e.fullCalendar.lang("tr",{defaultButtonText:{next:"ileri",month:"Ay",week:"Hafta",day:"Gün",list:"Ajanda"},allDayText:"Tüm gün",eventLimitText:"daha fazla"})});
\ No newline at end of file diff --git a/assets/js/src/base.js b/assets/js/src/base.js index 75e04b3a..6e92eb31 100644 --- a/assets/js/src/base.js +++ b/assets/js/src/base.js @@ -168,7 +168,8 @@ var Kanboard = (function() { // Project select box $("#board-selector").chosen({ - width: 180 + width: 180, + no_results_text: $("#board-selector").data("notfound") }); $("#board-selector").change(function() { @@ -192,6 +193,22 @@ var Kanboard = (function() { $(".column-tooltip").tooltip({ content: function() { return '<div class="markdown">' + $(this).attr("title") + '</div>'; + }, + position: { + my: 'left-20 top', + at: 'center bottom+9', + using: function(position, feedback) { + + $(this).css(position); + + var arrow_pos = feedback.target.left + feedback.target.width / 2 - feedback.element.left - 20; + + $("<div>") + .addClass("tooltip-arrow") + .addClass(feedback.vertical) + .addClass(arrow_pos == 0 ? "align-left" : "align-right") + .appendTo(this); + } } }); @@ -224,7 +241,7 @@ var Kanboard = (function() { // Dropdown $(".dropit-submenu").hide(); - $('.dropdown').not(".dropit").dropit(); + $('.dropdown').not(".dropit").dropit({ triggerParentEl : "span" }); } }; diff --git a/assets/js/src/board.js b/assets/js/src/board.js index 75c44f2e..878cb98e 100644 --- a/assets/js/src/board.js +++ b/assets/js/src/board.js @@ -23,6 +23,10 @@ Kanboard.Board = (function() { Mousetrap.bind("s", function() { stack_toggle(); }); + + Mousetrap.bind("c", function() { + compactview_toggle(); + }); } // Collapse/Expand tasks @@ -241,11 +245,12 @@ Kanboard.Board = (function() { board_load_events(); filter_apply(); stack_show(); + compactview_reload(); } }); } - // Check if a board have been changed by someone else + // Check if the board have been changed by someone else function board_check() { if (Kanboard.IsVisible()) { @@ -261,6 +266,7 @@ Kanboard.Board = (function() { board_load_events(); filter_apply(); stack_show(); + compactview_reload(); } } }); @@ -274,7 +280,7 @@ Kanboard.Board = (function() { var selectedCategoryId = $("#form-category_id").val(); var filterDueDate = $("#more-filters option[value=filter-due-date]").is(":selected") var filterRecent = $("#more-filters option[value=filter-recent]").is(":selected") - var projectId = $('#board').data('project-id'); + var projectId = $('#board').data('project-id'); $("[data-task-id]").each(function(index, item) { @@ -313,18 +319,21 @@ Kanboard.Board = (function() { // Load filter events function filter_load_events() { - var projectId = $('#board').data('project-id'); + var projectId = $('#board').data('project-id'); $("#form-user_id").chosen({ - width: "180px" + width: "180px", + no_results_text: $("#form-user_id").data("notfound") }); $("#form-category_id").chosen({ - width: "200px" + width: "200px", + no_results_text: $("#form-category_id").data("notfound") }); $("#more-filters").chosen({ - width: "30%" + width: "30%", + no_results_text: $("#more-filters").data("notfound") }); $(".apply-filters").change(function(e) { @@ -348,7 +357,44 @@ Kanboard.Board = (function() { $("#more-filters").trigger("chosen:updated"); - filter_apply(); + filter_apply(); + } + + function compactview_load_events() + { + jQuery(document).on('click', ".filter-toggle-scrolling", function(e) { + e.preventDefault(); + compactview_toggle(); + }); + + compactview_reload(); + } + + function compactview_toggle() + { + var scrolling = Kanboard.GetStorageItem("horizontal_scroll") || 1; + Kanboard.SetStorageItem("horizontal_scroll", scrolling == 0 ? 1 : 0); + compactview_reload(); + } + + function compactview_reload() + { + if (Kanboard.GetStorageItem("horizontal_scroll") == 0) { + + $(".filter-wide").show(); + $(".filter-compact").hide(); + + $("#board-container").removeClass("board-container-wide").addClass("board-container-compact"); + $("#board th,#board td").removeClass("board-column-wide").addClass("board-column-compact"); + } + else { + + $(".filter-wide").hide(); + $(".filter-compact").show(); + + $("#board-container").removeClass("board-container-compact").addClass("board-container-wide"); + $("#board th,#board td").removeClass("board-column-compact").addClass("board-column-wide"); + } } jQuery(document).ready(function() { @@ -357,6 +403,7 @@ Kanboard.Board = (function() { board_load_events(); filter_load_events(); stack_load_events(); + compactview_load_events(); keyboard_shortcuts(); } }); diff --git a/docs/api-json-rpc.markdown b/docs/api-json-rpc.markdown index 346b1dec..dcf92ea8 100644 --- a/docs/api-json-rpc.markdown +++ b/docs/api-json-rpc.markdown @@ -144,6 +144,32 @@ Array Procedures ---------- +### getVersion + +- Purpose: **Get the application version** +- Parameters: none +- Result: **version** (Example: 1.0.12, master) + +Request example: + +```json +{ + "jsonrpc": "2.0", + "method": "getVersion", + "id": 1661138292 +} +``` + +Response example: + +```json +{ + "jsonrpc": "2.0", + "id": 1661138292, + "result": "1.0.13" +} +``` + ### getTimezone - Purpose: **Get the application timezone** @@ -176,6 +202,7 @@ Response example: - Purpose: **Create a new project** - Parameters: - **name** (string, required) + - **description** (string, optional) - Result on success: **project_id** - Result on failure: **false** @@ -235,7 +262,8 @@ Response example: "is_active": "1", "token": "", "last_modified": "1410263246", - "is_public": "0" + "is_public": "0", + "description": "A sample project" } } ``` @@ -273,7 +301,8 @@ Response example: "is_active": "1", "token": "", "last_modified": "0", - "is_public": "0" + "is_public": "0", + "description": "A sample project" } } ``` @@ -309,7 +338,8 @@ Response example: "is_active": "1", "token": "", "last_modified": "0", - "is_public": "0" + "is_public": "0", + "description": "PHP client project" }, { "id": "1", @@ -317,7 +347,8 @@ Response example: "is_active": "1", "token": "", "last_modified": "0", - "is_public": "0" + "is_public": "0", + "description": "Test project" } ] } @@ -332,6 +363,7 @@ Response example: - **is_active** (integer, optional) - **token** (string, optional) - **is_public** (integer, optional) + - **description** (string, optional) - Result on success: **true** - Result on failure: **false** @@ -973,6 +1005,600 @@ Response example: } ``` +### getSwimlanes + +- Purpose: **Get the list of enabled swimlanes of a project** +- Parameters: + - **project_id** (integer, required) +- Result on success: **swimlane properties** +- Result on failure: **null** + +Request example: + +```json +{ + "jsonrpc": "2.0", + "method": "getSwimlanes", + "id": 1242049935, + "params": [ + 2 + ] +} +``` + +Response example: + +```json +{ + "jsonrpc": "2.0", + "id": 1242049935, + "result": [ + { + "id": "0", + "name": "Default" + }, + { + "id": "2", + "name": "Version 7.0" + }, + ] +} +``` + +### getAllSwimlanes + +- Purpose: **Get the list of all swimlanes of a project** +- Parameters: + - **project_id** (integer, required) +- Result on success: **swimlane properties** +- Result on failure: **null** + +Request example: + +```json +{ + "jsonrpc": "2.0", + "method": "getAllSwimlanes", + "id": 1242049935, + "params": [ + 2 + ] +} +``` + +Response example: + +```json +{ + "jsonrpc": "2.0", + "id": 1242049935, + "result": [ + { + "id": "0", + "name": "Default" + }, + { + "id": "3", + "name": "Version 1.0", + "is_active": "0", + "position": 1, + "project_id": 2 + }, + { + "id": "2", + "name": "Version 7.0", + "is_active": "1", + "position": 2, + "project_id": 2 + } + ] +} +``` + +### getSwimlane + +- Purpose: **Get the a swimlane** +- Parameters: + - **project_id** (integer, required) + - **name** (string, required) +- Result on success: **swimlane properties** +- Result on failure: **null** + +Request example: + +```json +{ + "jsonrpc": "2.0", + "method": "getSwimlane", + "id": 1242049935, + "params": [ + 2, + "Version 1.0" + ] +} +``` + +Response example: + +```json +{ + "jsonrpc": "2.0", + "id": 1242049935, + "result": { + "id": "3", + "name": "Version 1.0", + "is_active": "0", + "position": 2, + "project_id": 2 + } +} +``` + +### moveSwimlaneUp + +- Purpose: **Move up the swimlane position** +- Parameters: + - **project_id** (integer, required) + - **swimlane_id** (integer, required) +- Result on success: **true** +- Result on failure: **false** + +Request example: + +```json +{ + "jsonrpc": "2.0", + "method": "moveSwimlaneUp", + "id": 99275573, + "params": [ + 1, + 2 + ] +} +``` + +Response example: + +```json +{ + "jsonrpc": "2.0", + "id": 99275573, + "result": true +} +``` + +### moveSwimlaneDown + +- Purpose: **Move down the swimlane position** +- Parameters: + - **project_id** (integer, required) + - **swimlane_id** (integer, required) +- Result on success: **true** +- Result on failure: **false** + +Request example: + +```json +{ + "jsonrpc": "2.0", + "method": "moveSwimlaneDown", + "id": 957090649, + "params": { + "project_id": 1, + "swimlane_id": 2 + } +} +``` + +Response example: + +```json +{ + "jsonrpc": "2.0", + "id": 957090649, + "result": true +} +``` + +### updateSwimlane + +- Purpose: **Update swimlane properties** +- Parameters: + - **swimlane_id** (integer, required) + - **name** (string, required) +- Result on success: **true** +- Result on failure: **false** + +Request example: + +```json +{ + "jsonrpc": "2.0", + "method": "updateSwimlane", + "id": 480740641, + "params": [ + 2, + "Version 4.1" + ] +} +``` + +Response example: + +```json +{ + "jsonrpc": "2.0", + "id": 480740641, + "result": true +} +``` + +### addSwimlane + +- Purpose: **Add a new swimlane** +- Parameters: + - **project_id** (integer, required) + - **name** (string, required) +- Result on success: **swimlane_id** +- Result on failure: **false** + +Request example: + +```json +{ + "jsonrpc": "2.0", + "method": "addSwimlane", + "id": 638544704, + "params": [ + 1, + "Version 1.0" + ] +} +``` + +Response example: + +```json +{ + "jsonrpc": "2.0", + "id": 638544704, + "result": 5 +} +``` + +### removeSwimlane + +- Purpose: **Remove a swimlane** +- Parameters: + - **project_id** (integer, required) + - **swimlane_id** (integer, required) +- Result on success: **true** +- Result on failure: **false** + +Request example: + +```json +{ + "jsonrpc": "2.0", + "method": "removeSwimlane", + "id": 1433237746, + "params": [ + 2, + 1 + ] +} +``` + +Response example: + +```json +{ + "jsonrpc": "2.0", + "id": 1433237746, + "result": true +} +``` + +### disableSwimlane + +- Purpose: **Enable a swimlane** +- Parameters: + - **project_id** (integer, required) + - **swimlane_id** (integer, required) +- Result on success: **true** +- Result on failure: **false** + +Request example: + +```json +{ + "jsonrpc": "2.0", + "method": "disableSwimlane", + "id": 1433237746, + "params": [ + 2, + 1 + ] +} +``` + +Response example: + +```json +{ + "jsonrpc": "2.0", + "id": 1433237746, + "result": true +} +``` + +### enableSwimlane + +- Purpose: **Enable a swimlane** +- Parameters: + - **project_id** (integer, required) + - **swimlane_id** (integer, required) +- Result on success: **true** +- Result on failure: **false** + +Request example: + +```json +{ + "jsonrpc": "2.0", + "method": "enableSwimlane", + "id": 1433237746, + "params": [ + 2, + 1 + ] +} +``` + +Response example: + +```json +{ + "jsonrpc": "2.0", + "id": 1433237746, + "result": true +} +``` + +### getAvailableActions + +- Purpose: **Get list of available actions** +- Parameters: none +- Result on success: **list of actions** +- Result on failure: **false** + +Request example: + +```json +{ + "jsonrpc": "2.0", + "method": "getAvailableActions", + "id": 1433237746, +} +``` + +Response example: + +```json +{ + "jsonrpc": "2.0", + "id": 1433237746, + "result": { + "TaskLogMoveAnotherColumn" : "Add a comment logging moving the task between columns", + "TaskAssignColorUser" : "Assign a color to a specific user", + "TaskAssignCategoryColor" : "Assign automatically a category based on a color", + "TaskAssignColorCategory" : "Assign automatically a color based on a category", + "TaskAssignSpecificUser" : "Assign the task to a specific user", + "TaskAssignCurrentUser" : "Assign the task to the person who does the action", + "TaskAssignUser" : "Change the assignee based on an external username", + "TaskAssignCategoryLabel" : "Change the category based on an external label", + "TaskClose" : "Close a task", + "CommentCreation" : "Create a comment from an external provider", + "TaskCreation" : "Create a task from an external provider", + "TaskDuplicateAnotherProject" : "Duplicate the task to another project", + "TaskMoveAnotherProject" : "Move the task to another project", + "TaskOpen" : "Open a task" + } +} +``` + +### getAvailableEvents + +- Purpose: **Get list of available events** +- Parameters: none +- Result on success: **list of events** +- Result on failure: **false** + +Request example: + +```json +{ + "jsonrpc": "2.0", + "method": "getAvailableEvents", + "id": 1433237746, +} +``` + +Response example: + +```json +{ + "jsonrpc": "2.0", + "id": 1433237746, + "result": { + "bitbucket.webhook.commit" : "Bitbucket commit received", + "task.close" : "Closing a task", + "github.webhook.commit" : "Github commit received", + "github.webhook.issue.assignee" : "Github issue assignee change", + "github.webhook.issue.closed" : "Github issue closed", + "github.webhook.issue.commented" : "Github issue comment created", + "github.webhook.issue.label" : "Github issue label change", + "github.webhook.issue.opened" : "Github issue opened", + "github.webhook.issue.reopened" : "Github issue reopened", + "gitlab.webhook.commit" : "Gitlab commit received", + "gitlab.webhook.issue.closed" : "Gitlab issue closed", + "gitlab.webhook.issue.opened" : "Gitlab issue opened", + "task.move.column" : "Move a task to another column", + "task.open" : "Open a closed task", + "task.assignee_change" : "Task assignee change", + "task.create" : "Task creation", + "task.create_update" : "Task creation or modification", + "task.update" : "Task modification" + } +} +``` + +### getCompatibleEvents + +- Purpose: **Get list of events compatible with an action** +- Parameters: + - **action_name** (string, required) +- Result on success: **list of events** +- Result on failure: **false** + +Request example: + +```json +{ + "jsonrpc": "2.0", + "method": "getCompatibleEvents", + "id": 1433237746, + "params": [ + "TaskAssignSpecificUser" + ] +} +``` + +Response example: + +```json +{ + "jsonrpc": "2.0", + "id": 1433237746, + "result": { + "task.move.column" : "Move a task to another column", + "task.create_update" : "Task creation or modification", + } +} +``` + +### getActions + +- Purpose: **Get list of actions for a project** +- Parameters: + - **project_id** (integer, required) +- Result on success: **list of actions info** +- Result on failure: **false** + +Request example: + +```json +{ + "jsonrpc": "2.0", + "method": "getActions", + "id": 1433237746, + "params": [ + "1" + ] +} +``` + +Response example: + +```json +{ + "jsonrpc": "2.0", + "id": 1433237746, + "result": [ + { + "id" : "13", + "project_id" : "2", + "event_name" : "task.move.column", + "action_name" : "TaskAssignSpecificUser", + "params" : { + "column_id" : "5", + "user_id" : "1" + } + } + ] +} +``` + +### createAction + +- Purpose: **Create an action** +- Parameters: + - **project_id** (integer, required) + - **event_name** (string, required) + - **action_name** (string, required) + - **params** (list of string pairs, required) +- Result on success: **action_id** +- Result on failure: **false** + +Request example: + +```json +{ + "jsonrpc": "2.0", + "method": "createAction", + "id": 1433237746, + "params": { + "project_id" : "2", + "event_name" : "task.move.column", + "action_name" : "TaskAssignSpecificUser", + "params" : { + "column_id" : "3", + "user_id" : "2" + } + } +} +``` + +Response example: + +```json +{ + "jsonrpc": "2.0", + "id": 1433237746, + "result": 14 +} +``` + +### removeAction + +- Purpose: **Remove an action** +- Parameters: + - **action_id** (integer, required) +- Result on success: **true** +- Result on failure: **false** + +Request example: + +```json +{ + "jsonrpc": "2.0", + "method": "getAvailableEvents", + "id": 1433237746, + "params": [ + "2", + ] +} +``` + +Response example: + +```json +{ + "jsonrpc": "2.0", + "id": 1433237746, + "result": true +} +``` ### createTask diff --git a/jsonrpc.php b/jsonrpc.php index 566976cd..afc1ed18 100644 --- a/jsonrpc.php +++ b/jsonrpc.php @@ -22,13 +22,16 @@ $server->bind('enableProjectPublicAccess', $container['project'], 'enablePublicA $server->bind('disableProjectPublicAccess', $container['project'], 'disablePublicAccess'); $server->bind('getProjectActivity', $container['projectActivity'], 'getProjects'); -$server->register('createProject', function($name) use ($container) { - $values = array('name' => $name); +$server->register('createProject', function($name, $description = null) use ($container) { + $values = array( + 'name' => $name, + 'description' => $description + ); list($valid,) = $container['project']->validateCreation($values); return $valid ? $container['project']->create($values) : false; }); -$server->register('updateProject', function($id, $name, $is_active = null, $is_public = null, $token = null) use ($container) { +$server->register('updateProject', function($id, $name, $is_active = null, $is_public = null, $token = null, $description = null) use ($container) { $values = array( 'id' => $id, @@ -36,6 +39,7 @@ $server->register('updateProject', function($id, $name, $is_active = null, $is_p 'is_active' => $is_active, 'is_public' => $is_public, 'token' => $token, + 'description' => $description ); foreach ($values as $key => $value) { @@ -61,6 +65,91 @@ $server->bind('addColumn', $container['board'], 'addColumn'); $server->bind('removeColumn', $container['board'], 'removeColumn'); /** + * Swimlane procedures + */ +$server->bind('getSwimlanes', $container['swimlane'], 'getSwimlanes'); +$server->bind('getAllSwimlanes', $container['swimlane'], 'getAll'); +$server->bind('getSwimlane', $container['swimlane'], 'getByName'); +$server->bind('addSwimlane', $container['swimlane'], 'create'); +$server->bind('updateSwimlane', $container['swimlane'], 'rename'); +$server->bind('removeSwimlane', $container['swimlane'], 'remove'); +$server->bind('disableSwimlane', $container['swimlane'], 'disable'); +$server->bind('enableSwimlane', $container['swimlane'], 'enable'); +$server->bind('moveSwimlaneUp', $container['swimlane'], 'moveUp'); +$server->bind('moveSwimlaneDown', $container['swimlane'], 'moveDown'); + +/** + * Actions procedures + */ +$server->bind('getAvailableActions', $container['action'], 'getAvailableActions'); +$server->bind('getAvailableEvents', $container['action'], 'getAvailableEvents'); +$server->bind('getCompatibleEvents', $container['action'], 'getCompatibleEvents'); +$server->bind('removeAction', $container['action'], 'remove'); + +$server->register('getActions', function($project_id) use ($container) { + $actions = $container['action']->getAllByProject($project_id); + + foreach ($actions as $index => $action) { + $params = array(); + + foreach($action['params'] as $param) { + $params[$param['name']] = $param['value']; + } + + $actions[$index]['params'] = $params; + } + + return $actions; +}); + +$server->register('createAction', function($project_id, $event_name, $action_name, $params) use ($container) { + + $values = array( + 'project_id' => $project_id, + 'event_name' => $event_name, + 'action_name' => $action_name, + 'params' => $params, + ); + + list($valid,) = $container['action']->validateCreation($values); + + if (! $valid) { + return false; + } + + // Check the action exists + if (! isset($container['action']->getAvailableActions()[$action_name])) { + return false; + } + + // Check the event + $action = $container['action']->load($action_name, $project_id, $event_name); + + if (! in_array($event_name, $action->getCompatibleEvents())) { + return false; + } + + $required_params = $action->getActionRequiredParameters(); + + // Check missing parameters + foreach($required_params as $param => $value) { + if (! isset($params[$param])) { + return false; + } + } + + // Check extra parameters + foreach($params as $param => $value) { + if (! isset($required_params[$param])) { + return false; + } + } + + return $container['action']->create($values); +}); + + +/** * Project permissions procedures */ $server->bind('getMembers', $container['projectPermission'], 'getMembers'); @@ -331,6 +420,10 @@ $server->register('getTimezone', function() use ($container) { return $container['config']->get('application_timezone'); }); +$server->register('getVersion', function() use ($container) { + return APP_VERSION; +}); + /** * Parse incoming requests */ diff --git a/scripts/make-assets.sh b/scripts/make-assets.sh index d9562ee0..6fe867bb 100755 --- a/scripts/make-assets.sh +++ b/scripts/make-assets.sh @@ -5,7 +5,7 @@ vendor_css="jquery-ui.min chosen.min fullcalendar.min font-awesome.min" app_js="base board calendar analytic task swimlane dashboard" vendor_js="jquery-1.11.1.min jquery-ui.min jquery.ui.touch-punch.min chosen.jquery.min dropit.min moment.min fullcalendar.min mousetrap.min mousetrap-global-bind.min app.min" -lang_js="da de es fi fr hu it ja pl pt-br ru sv th zh-cn" +lang_js="da de es fi fr hu it ja pl pt-br ru sv th zh-cn tr" function merge_css { diff --git a/tests/functionals/ApiTest.php b/tests/functionals/ApiTest.php index f778d1ca..9fdfd1ba 100644 --- a/tests/functionals/ApiTest.php +++ b/tests/functionals/ApiTest.php @@ -39,7 +39,7 @@ class Api extends PHPUnit_Framework_TestCase { $this->client = new JsonRPC\Client(API_URL); $this->client->authentication('jsonrpc', API_KEY); - //$this->client->debug = true; + // $this->client->debug = true; } private function getTaskId() @@ -53,8 +53,12 @@ class Api extends PHPUnit_Framework_TestCase public function testGetTimezone() { - $timezone = $this->client->getTimezone(); - $this->assertEquals('Europe/Paris', $timezone); + $this->assertEquals('Europe/Paris', $this->client->getTimezone()); + } + + public function testGetVersion() + { + $this->assertEquals('master', $this->client->getVersion()); } public function testRemoveAll() diff --git a/tests/units/ActionTest.php b/tests/units/ActionTest.php index 429a181a..67957a26 100644 --- a/tests/units/ActionTest.php +++ b/tests/units/ActionTest.php @@ -27,7 +27,7 @@ class ActionTest extends Base $this->assertEquals(1, $project->create(array('name' => 'unit_test'))); // We create a new action - $this->assertTrue($action->create(array( + $this->assertEquals(1, $action->create(array( 'project_id' => 1, 'event_name' => Task::EVENT_MOVE_COLUMN, 'action_name' => 'TaskClose', @@ -78,14 +78,14 @@ class ActionTest extends Base $this->assertEquals(1, $c->create(array('name' => 'unit_test'))); // We create a new action - $this->assertTrue($a->create(array( + $this->assertEquals(1, $a->create(array( 'project_id' => 1, 'event_name' => GithubWebhook::EVENT_ISSUE_OPENED, 'action_name' => 'TaskCreation', 'params' => array() ))); - $this->assertTrue($a->create(array( + $this->assertEquals(2, $a->create(array( 'project_id' => 1, 'event_name' => GithubWebhook::EVENT_ISSUE_LABEL_CHANGE, 'action_name' => 'TaskAssignCategoryLabel', @@ -95,7 +95,7 @@ class ActionTest extends Base ) ))); - $this->assertTrue($a->create(array( + $this->assertEquals(3, $a->create(array( 'project_id' => 1, 'event_name' => Task::EVENT_CREATE_UPDATE, 'action_name' => 'TaskAssignColorCategory', diff --git a/tests/units/ProjectDuplicationTest.php b/tests/units/ProjectDuplicationTest.php index b35575aa..311ecc4a 100644 --- a/tests/units/ProjectDuplicationTest.php +++ b/tests/units/ProjectDuplicationTest.php @@ -156,7 +156,7 @@ class ProjectDuplicationTest extends Base $this->assertEquals(1, $p->create(array('name' => 'P1'))); - $this->assertTrue($a->create(array( + $this->assertEquals(1, $a->create(array( 'project_id' => 1, 'event_name' => Task::EVENT_MOVE_COLUMN, 'action_name' => 'TaskAssignCurrentUser', @@ -186,7 +186,7 @@ class ProjectDuplicationTest extends Base $this->assertEquals(2, $c->create(array('name' => 'C2', 'project_id' => 1))); $this->assertEquals(3, $c->create(array('name' => 'C3', 'project_id' => 1))); - $this->assertTrue($a->create(array( + $this->assertEquals(1, $a->create(array( 'project_id' => 1, 'event_name' => Task::EVENT_CREATE_UPDATE, 'action_name' => 'TaskAssignColorCategory', diff --git a/tests/units/SubtaskTest.php b/tests/units/SubtaskTest.php index 62475186..eb1a3fd3 100644 --- a/tests/units/SubtaskTest.php +++ b/tests/units/SubtaskTest.php @@ -11,6 +11,78 @@ use Model\User; class SubTaskTest extends Base { + public function testMoveUp() + { + $tc = new TaskCreation($this->container); + $s = new Subtask($this->container); + $p = new Project($this->container); + + $this->assertEquals(1, $p->create(array('name' => 'test1'))); + $this->assertEquals(1, $tc->create(array('title' => 'test 1', 'project_id' => 1))); + + $this->assertEquals(1, $s->create(array('title' => 'subtask #1', 'task_id' => 1))); + $this->assertEquals(2, $s->create(array('title' => 'subtask #2', 'task_id' => 1))); + $this->assertEquals(3, $s->create(array('title' => 'subtask #3', 'task_id' => 1))); + + $subtask = $s->getById(1); + $this->assertNotEmpty($subtask); + $this->assertEquals(1, $subtask['position']); + + $subtask = $s->getById(2); + $this->assertNotEmpty($subtask); + $this->assertEquals(2, $subtask['position']); + + $subtask = $s->getById(3); + $this->assertNotEmpty($subtask); + $this->assertEquals(3, $subtask['position']); + + $this->assertTrue($s->moveUp(1, 2)); + + $subtask = $s->getById(1); + $this->assertNotEmpty($subtask); + $this->assertEquals(2, $subtask['position']); + + $subtask = $s->getById(2); + $this->assertNotEmpty($subtask); + $this->assertEquals(1, $subtask['position']); + + $subtask = $s->getById(3); + $this->assertNotEmpty($subtask); + $this->assertEquals(3, $subtask['position']); + + $this->assertFalse($s->moveUp(1, 2)); + } + + public function testMoveDown() + { + $tc = new TaskCreation($this->container); + $s = new Subtask($this->container); + $p = new Project($this->container); + + $this->assertEquals(1, $p->create(array('name' => 'test1'))); + $this->assertEquals(1, $tc->create(array('title' => 'test 1', 'project_id' => 1))); + + $this->assertEquals(1, $s->create(array('title' => 'subtask #1', 'task_id' => 1))); + $this->assertEquals(2, $s->create(array('title' => 'subtask #2', 'task_id' => 1))); + $this->assertEquals(3, $s->create(array('title' => 'subtask #3', 'task_id' => 1))); + + $this->assertTrue($s->moveDown(1, 1)); + + $subtask = $s->getById(1); + $this->assertNotEmpty($subtask); + $this->assertEquals(2, $subtask['position']); + + $subtask = $s->getById(2); + $this->assertNotEmpty($subtask); + $this->assertEquals(1, $subtask['position']); + + $subtask = $s->getById(3); + $this->assertNotEmpty($subtask); + $this->assertEquals(3, $subtask['position']); + + $this->assertFalse($s->moveDown(1, 3)); + } + public function testDuplicate() { $tc = new TaskCreation($this->container); @@ -53,5 +125,8 @@ class SubTaskTest extends Base $this->assertEquals(0, $subtasks[0]['user_id']); $this->assertEquals(0, $subtasks[1]['user_id']); + + $this->assertEquals(1, $subtasks[0]['position']); + $this->assertEquals(2, $subtasks[1]['position']); } } |