From fff59a2e8461427fd62f760aaf8715772b2aa714 Mon Sep 17 00:00:00 2001 From: mbugeia Date: Wed, 27 Apr 2016 20:50:42 +0200 Subject: [PATCH] Update to kanboard v1.0.27 --- sources/ChangeLog | 49 +- sources/app/Action/Base.php | 10 +- .../Analytic/AverageLeadCycleTimeAnalytic.php | 14 +- .../AverageTimeSpentColumnAnalytic.php | 1 + sources/app/Api/Auth.php | 1 + sources/app/Api/User.php | 19 +- sources/app/Auth/LdapAuth.php | 6 +- sources/app/Console/Base.php | 10 +- .../app/Console/TaskOverdueNotification.php | 68 +- sources/app/Console/TransitionExport.php | 2 +- sources/app/Controller/Action.php | 94 +- sources/app/Controller/ActionCreation.php | 121 ++ sources/app/Controller/ActionProject.php | 38 + sources/app/Controller/Activity.php | 1 + sources/app/Controller/Analytic.php | 3 +- sources/app/Controller/App.php | 6 +- sources/app/Controller/Auth.php | 2 + sources/app/Controller/AvatarFile.php | 92 ++ sources/app/Controller/Base.php | 56 - sources/app/Controller/Board.php | 13 +- sources/app/Controller/BoardTooltip.php | 1 + sources/app/Controller/Calendar.php | 7 +- sources/app/Controller/Column.php | 2 + sources/app/Controller/Comment.php | 7 +- sources/app/Controller/Config.php | 2 + sources/app/Controller/Doc.php | 89 +- sources/app/Controller/Export.php | 2 +- sources/app/Controller/FileViewer.php | 26 +- sources/app/Controller/Gantt.php | 11 +- sources/app/Controller/Listing.php | 15 +- sources/app/Controller/Oauth.php | 152 +- sources/app/Controller/ProjectEdit.php | 2 +- sources/app/Controller/ProjectOverview.php | 21 +- sources/app/Controller/Subtask.php | 22 +- sources/app/Controller/Task.php | 32 +- sources/app/Controller/TaskExternalLink.php | 30 +- sources/app/Controller/TaskHelper.php | 16 - .../{Tasklink.php => TaskInternalLink.php} | 37 +- sources/app/Controller/TaskRecurrence.php | 2 +- sources/app/Controller/Taskduplication.php | 4 +- sources/app/Controller/Taskmodification.php | 10 +- sources/app/Controller/Taskstatus.php | 2 +- sources/app/Core/Base.php | 18 +- sources/app/Core/Csv.php | 3 +- sources/app/Core/DateParser.php | 5 +- sources/app/Core/Helper.php | 77 +- sources/app/Core/Http/OAuth2.php | 45 +- sources/app/Core/Http/Request.php | 13 +- sources/app/Core/Http/Response.php | 18 + sources/app/Core/Ldap/Client.php | 49 +- sources/app/Core/Ldap/Query.php | 8 +- sources/app/Core/Ldap/User.php | 10 +- sources/app/Core/Mail/Client.php | 6 +- .../app/Core/ObjectStorage/FileStorage.php | 5 + sources/app/Core/Plugin/Base.php | 11 + sources/app/Core/Plugin/Loader.php | 3 + sources/app/Core/Security/AccessMap.php | 10 +- .../OAuthAuthenticationProviderInterface.php | 4 +- ...asswordAuthenticationProviderInterface.php | 2 +- .../PreAuthenticationProviderInterface.php | 2 +- sources/app/Core/Session/SessionStorage.php | 1 + sources/app/Core/Template.php | 120 +- sources/app/Core/Thumbnail.php | 172 +++ sources/app/Core/Tool.php | 73 +- .../app/Core/User/Avatar/AvatarManager.php | 93 ++ .../User/Avatar/AvatarProviderInterface.php | 30 + sources/app/Core/User/UserSession.php | 24 + .../app/{Model => Export}/SubtaskExport.php | 9 +- sources/app/{Model => Export}/TaskExport.php | 11 +- sources/app/Export/TransitionExport.php | 77 + .../ExternalLink/AttachmentLinkProvider.php | 2 +- sources/app/ExternalLink/FileLink.php | 26 + sources/app/ExternalLink/FileLinkProvider.php | 74 + sources/app/ExternalLink/WebLinkProvider.php | 2 +- sources/app/Helper/{App.php => AppHelper.php} | 8 +- .../app/Helper/{Asset.php => AssetHelper.php} | 9 +- sources/app/Helper/AvatarHelper.php | 68 + .../app/Helper/{Board.php => BoardHelper.php} | 4 +- sources/app/Helper/{Dt.php => DateHelper.php} | 3 +- .../app/Helper/{File.php => FileHelper.php} | 4 +- .../app/Helper/{Form.php => FormHelper.php} | 31 +- .../app/Helper/{Hook.php => HookHelper.php} | 6 +- .../Helper/{Layout.php => LayoutHelper.php} | 27 +- sources/app/Helper/ModelHelper.php | 94 ++ sources/app/Helper/ProjectHeaderHelper.php | 80 ++ .../Helper/{Subtask.php => SubtaskHelper.php} | 6 +- .../app/Helper/{Task.php => TaskHelper.php} | 2 +- .../app/Helper/{Text.php => TextHelper.php} | 15 +- sources/app/Helper/{Url.php => UrlHelper.php} | 42 +- .../app/Helper/{User.php => UserHelper.php} | 25 +- sources/app/{Model => Import}/TaskImport.php | 7 +- sources/app/{Model => Import}/UserImport.php | 8 +- sources/app/Locale/bs_BA/translations.php | 485 +++---- sources/app/Locale/cs_CZ/translations.php | 51 +- sources/app/Locale/da_DK/translations.php | 51 +- sources/app/Locale/de_DE/translations.php | 57 +- sources/app/Locale/el_GR/translations.php | 437 +++--- sources/app/Locale/es_ES/translations.php | 87 +- sources/app/Locale/fi_FI/translations.php | 51 +- sources/app/Locale/fr_FR/translations.php | 56 +- sources/app/Locale/hu_HU/translations.php | 51 +- sources/app/Locale/id_ID/translations.php | 51 +- sources/app/Locale/it_IT/translations.php | 319 ++--- sources/app/Locale/ja_JP/translations.php | 51 +- sources/app/Locale/ko_KR/translations.php | 1156 +++++++++++++++ sources/app/Locale/my_MY/translations.php | 51 +- sources/app/Locale/nb_NO/translations.php | 51 +- sources/app/Locale/nl_NL/translations.php | 181 +-- sources/app/Locale/pl_PL/translations.php | 53 +- sources/app/Locale/pt_BR/translations.php | 51 +- sources/app/Locale/pt_PT/translations.php | 81 +- sources/app/Locale/ru_RU/translations.php | 81 +- .../app/Locale/sr_Latn_RS/translations.php | 51 +- sources/app/Locale/sv_SE/translations.php | 51 +- sources/app/Locale/th_TH/translations.php | 972 ++++++------- sources/app/Locale/tr_TR/translations.php | 51 +- sources/app/Locale/zh_CN/translations.php | 81 +- sources/app/Model/Action.php | 2 +- sources/app/Model/AvatarFile.php | 111 ++ sources/app/Model/Base.php | 99 -- sources/app/Model/Board.php | 2 +- sources/app/Model/Category.php | 17 +- sources/app/Model/Color.php | 3 +- sources/app/Model/Comment.php | 3 +- sources/app/Model/Config.php | 3 + sources/app/Model/File.php | 20 +- sources/app/Model/Link.php | 2 +- sources/app/Model/Metadata.php | 20 +- sources/app/Model/NotificationType.php | 2 +- sources/app/Model/OverdueNotification.php | 58 - sources/app/Model/PasswordReset.php | 2 +- sources/app/Model/Project.php | 4 +- sources/app/Model/ProjectActivity.php | 6 +- sources/app/Model/ProjectDailyColumnStats.php | 2 +- sources/app/Model/ProjectDailyStats.php | 9 +- sources/app/Model/ProjectGroupRole.php | 2 +- sources/app/Model/Setting.php | 16 +- sources/app/Model/Subtask.php | 4 +- sources/app/Model/TaskCreation.php | 4 +- sources/app/Model/TaskDuplication.php | 1 + sources/app/Model/TaskFinder.php | 2 + sources/app/Model/TaskLink.php | 1 + sources/app/Model/TaskModification.php | 6 +- sources/app/Model/TaskPermission.php | 3 +- sources/app/Model/Transition.php | 86 +- sources/app/Model/User.php | 17 +- sources/app/Model/UserNotification.php | 19 +- sources/app/Model/UserNotificationFilter.php | 9 +- sources/app/Schema/Mysql.php | 33 +- sources/app/Schema/Postgres.php | 22 +- sources/app/Schema/Sqlite.php | 23 +- .../AuthenticationProvider.php | 7 +- .../app/ServiceProvider/AvatarProvider.php | 35 + sources/app/ServiceProvider/ClassProvider.php | 17 +- .../app/ServiceProvider/DatabaseProvider.php | 4 +- .../ServiceProvider/ExternalLinkProvider.php | 2 + .../app/ServiceProvider/HelperProvider.php | 36 + sources/app/ServiceProvider/RouteProvider.php | 2 - sources/app/Subscriber/AuthSubscriber.php | 1 + sources/app/Template/action/index.php | 136 +- .../app/Template/action_creation/create.php | 16 + .../{action => action_creation}/event.php | 12 +- .../{action => action_creation}/params.php | 17 +- .../app/Template/action_project/project.php | 20 + sources/app/Template/activity/project.php | 40 +- sources/app/Template/activity/task.php | 4 + .../Template/analytic/avg_time_columns.php | 2 +- sources/app/Template/analytic/burndown.php | 2 +- sources/app/Template/analytic/cfd.php | 2 +- .../app/Template/analytic/compare_hours.php | 12 +- sources/app/Template/analytic/layout.php | 33 +- .../app/Template/analytic/lead_cycle_time.php | 2 +- sources/app/Template/analytic/tasks.php | 2 +- sources/app/Template/analytic/users.php | 2 +- sources/app/Template/app/layout.php | 2 +- sources/app/Template/app/projects.php | 8 +- sources/app/Template/app/sidebar.php | 2 +- sources/app/Template/app/subtasks.php | 8 +- sources/app/Template/app/tasks.php | 8 +- sources/app/Template/auth/index.php | 4 +- sources/app/Template/avatar_file/show.php | 20 + .../app/Template/board/popover_assignee.php | 4 +- .../app/Template/board/popover_category.php | 4 +- .../board/popover_close_all_tasks_column.php | 2 +- sources/app/Template/board/table_column.php | 8 +- sources/app/Template/board/table_swimlane.php | 2 +- sources/app/Template/board/table_tasks.php | 2 +- sources/app/Template/board/task_avatar.php | 20 + sources/app/Template/board/task_footer.php | 30 +- sources/app/Template/board/task_menu.php | 4 +- sources/app/Template/board/task_private.php | 43 +- sources/app/Template/board/task_public.php | 14 +- .../app/Template/board/tooltip_comments.php | 21 +- .../Template/board/tooltip_external_links.php | 38 +- sources/app/Template/board/tooltip_files.php | 38 +- .../app/Template/board/tooltip_subtasks.php | 36 +- .../app/Template/board/tooltip_tasklinks.php | 48 +- sources/app/Template/board/view_private.php | 17 +- sources/app/Template/calendar/show.php | 6 +- sources/app/Template/category/edit.php | 21 +- sources/app/Template/category/index.php | 4 +- sources/app/Template/column/create.php | 21 +- sources/app/Template/column/edit.php | 22 +- sources/app/Template/column/index.php | 6 +- sources/app/Template/comment/create.php | 51 +- sources/app/Template/comment/edit.php | 27 +- sources/app/Template/comment/remove.php | 6 +- sources/app/Template/comment/show.php | 50 +- sources/app/Template/comments/create.php | 24 + sources/app/Template/comments/show.php | 33 + sources/app/Template/config/about.php | 78 +- sources/app/Template/config/api.php | 2 +- sources/app/Template/config/application.php | 4 +- sources/app/Template/config/board.php | 2 +- sources/app/Template/config/calendar.php | 2 +- sources/app/Template/config/integrations.php | 2 +- .../Template/config/keyboard_shortcuts.php | 36 + sources/app/Template/config/plugins.php | 10 +- sources/app/Template/config/project.php | 2 +- sources/app/Template/config/webhook.php | 4 +- sources/app/Template/currency/index.php | 6 +- sources/app/Template/custom_filter/add.php | 2 +- sources/app/Template/custom_filter/edit.php | 2 +- sources/app/Template/custom_filter/index.php | 6 +- sources/app/Template/event/comment_create.php | 9 +- sources/app/Template/event/comment_update.php | 9 +- sources/app/Template/event/events.php | 27 +- sources/app/Template/event/subtask_create.php | 9 +- sources/app/Template/event/subtask_update.php | 9 +- .../Template/event/task_assignee_change.php | 15 +- sources/app/Template/event/task_close.php | 11 +- sources/app/Template/event/task_create.php | 11 +- .../app/Template/event/task_file_create.php | 11 +- .../app/Template/event/task_move_column.php | 13 +- .../app/Template/event/task_move_position.php | 13 +- .../app/Template/event/task_move_swimlane.php | 15 +- sources/app/Template/event/task_open.php | 11 +- sources/app/Template/event/task_update.php | 11 +- sources/app/Template/export/subtasks.php | 2 +- sources/app/Template/export/summary.php | 2 +- sources/app/Template/export/tasks.php | 2 +- sources/app/Template/export/transitions.php | 2 +- sources/app/Template/feed/project.php | 2 +- sources/app/Template/feed/user.php | 2 +- sources/app/Template/file_viewer/show.php | 4 +- sources/app/Template/gantt/project.php | 7 +- sources/app/Template/gantt/task_creation.php | 19 +- sources/app/Template/group/associate.php | 2 +- sources/app/Template/group/create.php | 2 +- sources/app/Template/group/edit.php | 2 +- sources/app/Template/group/index.php | 4 +- sources/app/Template/group/users.php | 6 +- sources/app/Template/header.php | 10 +- sources/app/Template/layout.php | 4 +- sources/app/Template/link/create.php | 2 +- sources/app/Template/link/edit.php | 2 +- sources/app/Template/listing/show.php | 24 +- .../Template/notification/comment_create.php | 2 +- .../Template/notification/comment_update.php | 2 +- .../notification/comment_user_mention.php | 2 +- .../Template/notification/subtask_create.php | 10 +- .../Template/notification/subtask_update.php | 12 +- .../notification/task_assignee_change.php | 2 +- .../app/Template/notification/task_close.php | 2 +- .../app/Template/notification/task_create.php | 8 +- .../notification/task_file_create.php | 2 +- .../notification/task_move_column.php | 6 +- .../notification/task_move_position.php | 6 +- .../notification/task_move_swimlane.php | 8 +- .../app/Template/notification/task_open.php | 2 +- .../Template/notification/task_overdue.php | 4 +- .../app/Template/notification/task_update.php | 2 +- .../notification/task_user_mention.php | 2 +- .../app/Template/password_reset/change.php | 2 +- .../app/Template/password_reset/create.php | 2 +- sources/app/Template/project/duplicate.php | 2 +- sources/app/Template/project/index.php | 8 +- sources/app/Template/project/layout.php | 27 +- .../app/Template/project/notifications.php | 2 +- sources/app/Template/project/show.php | 6 +- .../app/Template/project_creation/create.php | 2 +- sources/app/Template/project_edit/dates.php | 12 +- .../app/Template/project_edit/description.php | 32 +- sources/app/Template/project_edit/general.php | 12 +- .../Template/project_edit/task_priority.php | 12 +- sources/app/Template/project_file/remove.php | 2 +- .../app/Template/project_header/dropdown.php | 4 +- .../app/Template/project_header/header.php | 2 +- .../app/Template/project_header/search.php | 6 +- sources/app/Template/project_header/views.php | 2 +- .../Template/project_overview/activity.php | 8 + .../Template/project_overview/attachments.php | 15 + .../app/Template/project_overview/columns.php | 2 +- .../Template/project_overview/description.php | 21 +- .../app/Template/project_overview/files.php | 137 +- .../app/Template/project_overview/images.php | 35 + .../Template/project_overview/information.php | 66 +- .../app/Template/project_overview/show.php | 14 +- .../app/Template/project_permission/index.php | 10 +- sources/app/Template/project_user/layout.php | 2 +- sources/app/Template/project_user/roles.php | 6 +- sources/app/Template/project_user/tasks.php | 10 +- .../Template/project_user/tooltip_users.php | 2 +- sources/app/Template/search/results.php | 14 +- sources/app/Template/subtask/create.php | 2 +- sources/app/Template/subtask/edit.php | 2 +- sources/app/Template/subtask/remove.php | 2 +- sources/app/Template/subtask/show.php | 32 +- sources/app/Template/subtask/table.php | 8 +- .../Template/subtask_restriction/popover.php | 2 +- sources/app/Template/swimlane/create.php | 21 +- sources/app/Template/swimlane/edit.php | 22 +- .../app/Template/swimlane/edit_default.php | 2 +- sources/app/Template/swimlane/table.php | 6 +- sources/app/Template/task/analytics.php | 5 +- sources/app/Template/task/changes.php | 2 +- sources/app/Template/task/color_picker.php | 2 +- sources/app/Template/task/comments.php | 35 - sources/app/Template/task/description.php | 15 +- sources/app/Template/task/details.php | 30 +- sources/app/Template/task/dropdown.php | 2 +- sources/app/Template/task/layout.php | 30 +- sources/app/Template/task/menu.php | 78 -- sources/app/Template/task/public.php | 24 +- sources/app/Template/task/remove.php | 2 +- sources/app/Template/task/show.php | 24 +- sources/app/Template/task/sidebar.php | 89 +- .../Template/task/time_tracking_details.php | 6 +- .../Template/task/time_tracking_summary.php | 6 +- sources/app/Template/task/transitions.php | 10 +- sources/app/Template/task_creation/form.php | 43 +- .../app/Template/task_duplication/copy.php | 2 +- .../app/Template/task_duplication/move.php | 2 +- .../Template/task_external_link/create.php | 2 +- .../app/Template/task_external_link/edit.php | 2 +- .../app/Template/task_external_link/find.php | 2 +- .../app/Template/task_external_link/show.php | 62 +- .../app/Template/task_external_link/table.php | 44 + sources/app/Template/task_file/files.php | 47 + sources/app/Template/task_file/images.php | 34 + sources/app/Template/task_file/remove.php | 2 +- sources/app/Template/task_file/screenshot.php | 2 +- sources/app/Template/task_file/show.php | 97 +- sources/app/Template/task_import/step1.php | 2 +- .../create.php | 4 +- .../{tasklink => task_internal_link}/edit.php | 6 +- .../remove.php | 4 +- .../app/Template/task_internal_link/show.php | 14 + .../app/Template/task_internal_link/table.php | 85 ++ .../task_modification/edit_description.php | 41 +- .../Template/task_modification/edit_task.php | 2 +- sources/app/Template/task_recurrence/edit.php | 2 +- sources/app/Template/task_recurrence/info.php | 8 +- sources/app/Template/tasklink/show.php | 111 -- sources/app/Template/twofactor/check.php | 2 +- sources/app/Template/twofactor/index.php | 6 +- sources/app/Template/twofactor/show.php | 6 +- sources/app/Template/user/authentication.php | 2 +- sources/app/Template/user/create_local.php | 2 +- sources/app/Template/user/create_remote.php | 2 +- sources/app/Template/user/edit.php | 2 +- sources/app/Template/user/index.php | 6 +- sources/app/Template/user/last.php | 6 +- sources/app/Template/user/notifications.php | 5 +- sources/app/Template/user/password.php | 2 +- sources/app/Template/user/password_reset.php | 4 +- sources/app/Template/user/profile.php | 7 +- sources/app/Template/user/sessions.php | 4 +- sources/app/Template/user/show.php | 6 +- sources/app/Template/user/sidebar.php | 3 + sources/app/Template/user/timesheet.php | 4 +- sources/app/Template/user_import/step1.php | 2 +- .../app/User/Avatar/AvatarFileProvider.php | 42 + sources/app/User/Avatar/GravatarProvider.php | 42 + .../app/User/Avatar/LetterAvatarProvider.php | 170 +++ sources/app/User/LdapUserProvider.php | 2 +- sources/app/Validator/AuthValidator.php | 2 +- sources/app/Validator/UserValidator.php | 4 +- sources/app/check_setup.php | 5 - sources/app/common.php | 2 + sources/app/constants.php | 2 +- sources/app/functions.php | 27 + sources/assets/css/app.css | 8 +- sources/assets/css/print.css | 8 +- sources/assets/css/src/accordion.css | 40 + sources/assets/css/src/activity.css | 42 +- sources/assets/css/src/alert.css | 24 +- sources/assets/css/src/avatar.css | 40 + sources/assets/css/src/base.css | 5 - sources/assets/css/src/button.css | 35 +- sources/assets/css/src/comment.css | 135 +- sources/assets/css/src/filters.css | 17 +- sources/assets/css/src/form.css | 52 +- sources/assets/css/src/header.css | 7 - sources/assets/css/src/markdown.css | 18 +- sources/assets/css/src/popover.css | 5 +- sources/assets/css/src/print.css | 2 +- sources/assets/css/src/project.css | 3 + sources/assets/css/src/sidebar.css | 25 + sources/assets/css/src/table.css | 4 + sources/assets/css/src/task.css | 145 +- sources/assets/css/src/tasklink.css | 12 + sources/assets/css/src/tooltip.css | 25 +- sources/assets/css/src/views.css | 18 +- sources/assets/css/vendor/simplemde.min.css | 7 + sources/assets/js/app.js | 1240 +---------------- sources/assets/js/src/Accordion.js | 18 + sources/assets/js/src/App.js | 214 ++- sources/assets/js/src/AvgTimeColumnChart.js | 17 +- sources/assets/js/src/Board.js | 331 ----- sources/assets/js/src/BoardCollapsedMode.js | 27 + sources/assets/js/src/BoardColumnScrolling.js | 85 ++ sources/assets/js/src/BoardColumnView.js | 79 ++ sources/assets/js/src/BoardDragAndDrop.js | 103 ++ .../assets/js/src/BoardHorizontalScrolling.js | 55 + sources/assets/js/src/BoardPolling.js | 33 + sources/assets/js/src/BoardTask.js | 29 + sources/assets/js/src/BurndownChart.js | 20 +- sources/assets/js/src/Calendar.js | 14 +- sources/assets/js/src/Column.js | 10 +- .../assets/js/src/CompareHoursColumnChart.js | 23 +- .../assets/js/src/CumulativeFlowDiagram.js | 17 +- sources/assets/js/src/Dropdown.js | 28 +- sources/assets/js/src/FileUpload.js | 27 +- sources/assets/js/src/Gantt.js | 56 +- sources/assets/js/src/LeadCycleTimeChart.js | 27 +- sources/assets/js/src/Markdown.js | 91 +- sources/assets/js/src/Namespace.js | 3 + sources/assets/js/src/Notification.js | 9 + sources/assets/js/src/Popover.js | 133 +- sources/assets/js/src/Project.js | 28 - sources/assets/js/src/ProjectCreation.js | 15 + sources/assets/js/src/ProjectPermission.js | 19 + sources/assets/js/src/Router.js | 37 - sources/assets/js/src/Screenshot.js | 23 +- sources/assets/js/src/Search.js | 93 +- sources/assets/js/src/Session.js | 21 + sources/assets/js/src/Subtask.js | 15 +- sources/assets/js/src/Swimlane.js | 109 +- sources/assets/js/src/Task.js | 40 +- sources/assets/js/src/TaskRepartitionChart.js | 13 +- sources/assets/js/src/TaskTimeColumnChart.js | 17 +- sources/assets/js/src/Tooltip.js | 12 +- sources/assets/js/src/UserRepartitionChart.js | 13 +- sources/assets/js/src/bootstrap.js | 4 + .../assets/js/vendor/jquery.textcomplete.js | 1227 ---------------- sources/assets/js/vendor/simplemde.min.js | 14 + sources/doc/.htaccess | 7 - sources/doc/automatic-actions.markdown | 14 +- sources/doc/board-collapsed-expanded.markdown | 5 +- ...zontal-scrolling-and-compact-view.markdown | 4 +- sources/doc/board-show-hide-columns.markdown | 9 +- sources/doc/cloudron.markdown | 28 + sources/doc/creating-projects.markdown | 13 +- sources/doc/editing-projects.markdown | 2 +- sources/doc/fr/automatic-actions.markdown | 24 +- .../doc/fr/board-collapsed-expanded.markdown | 21 +- ...zontal-scrolling-and-compact-view.markdown | 8 +- .../doc/fr/board-show-hide-columns.markdown | 10 +- .../doc/fr/captures/kanboard-acces-prive.png | Bin 14432 -> 0 bytes .../doc/fr/captures/kanboard-acces-public.png | Bin 26672 -> 0 bytes sources/doc/fr/captures/kanboard-board.png | Bin 65587 -> 0 bytes .../captures/kanboard-creer-utilisateur.png | Bin 35907 -> 0 bytes .../captures/kanboard-nouveauprojet-prive.png | Bin 17942 -> 0 bytes .../fr/captures/kanboard-nouveauprojet.png | Bin 21282 -> 0 bytes .../doc/fr/captures/kanboard-swimlanes.png | Bin 43399 -> 0 bytes .../fr/captures/kanboard-vue-calendrier.png | Bin 31640 -> 0 bytes .../doc/fr/captures/kanboard-vue-gantt.png | Bin 42360 -> 0 bytes .../doc/fr/captures/kanboard-vue-liste.png | Bin 38316 -> 0 bytes sources/doc/fr/creating-projects.markdown | 23 +- sources/doc/fr/editing-projects.markdown | 5 +- sources/doc/fr/index.markdown | 2 + sources/doc/fr/keyboard-shortcuts.markdown | 9 + sources/doc/fr/project-permissions.markdown | 55 +- sources/doc/fr/project-types.markdown | 14 + sources/doc/fr/project-views.markdown | 53 +- sources/doc/fr/roles.markdown | 24 + .../screenshots/automatic-action-creation.png | Bin 0 -> 19900 bytes .../fr/screenshots/board-collapsed-mode.png | Bin 0 -> 7074 bytes .../doc/fr/screenshots/board-compact-mode.png | Bin 0 -> 12765 bytes .../fr/screenshots/board-expanded-mode.png | Bin 0 -> 11783 bytes .../doc/fr/screenshots/board-task-limit.png | Bin 0 -> 16848 bytes sources/doc/fr/screenshots/board-view.png | Bin 0 -> 24371 bytes sources/doc/fr/screenshots/calendar-view.png | Bin 0 -> 21691 bytes sources/doc/fr/screenshots/gantt-view.png | Bin 0 -> 29367 bytes sources/doc/fr/screenshots/hide-column.png | Bin 0 -> 9642 bytes sources/doc/fr/screenshots/list-view.png | Bin 0 -> 23457 bytes sources/doc/fr/screenshots/new-project.png | Bin 0 -> 20818 bytes sources/doc/fr/screenshots/new-user.png | Bin 0 -> 26286 bytes .../screenshots/project-disable-sharing.png | Bin 0 -> 17706 bytes .../doc/fr/screenshots/project-edition.png | Bin 0 -> 40230 bytes .../fr/screenshots/project-enable-sharing.png | Bin 0 -> 14297 bytes .../fr/screenshots/project-permissions.png | Bin 0 -> 32926 bytes sources/doc/fr/screenshots/project-view.png | Bin 0 -> 40868 bytes sources/doc/fr/screenshots/show-column.png | Bin 0 -> 17940 bytes .../fr/screenshots/swimlane-configuration.png | Bin 0 -> 14226 bytes sources/doc/fr/screenshots/swimlanes.png | Bin 0 -> 25290 bytes sources/doc/fr/sharing-projects.markdown | 10 +- sources/doc/fr/swimlanes.markdown | 7 +- sources/doc/fr/user-management.markdown | 60 +- sources/doc/index.markdown | 1 + sources/doc/keyboard-shortcuts.markdown | 9 + sources/doc/plugin-avatar-provider.markdown | 32 + sources/doc/plugin-helpers.markdown | 40 + sources/doc/plugin-hooks.markdown | 75 +- sources/doc/plugin-metadata.markdown | 3 +- sources/doc/plugin-overrides.markdown | 6 + sources/doc/plugins.markdown | 8 +- sources/doc/project-views.markdown | 18 +- sources/doc/roles.markdown | 1 - .../screenshots/automatic-action-creation.png | Bin 0 -> 16241 bytes .../doc/screenshots/board-collapsed-mode.png | Bin 0 -> 6296 bytes .../doc/screenshots/board-compact-mode.png | Bin 0 -> 13501 bytes .../doc/screenshots/board-expanded-mode.png | Bin 0 -> 10680 bytes sources/doc/screenshots/board-task-limit.png | Bin 0 -> 22642 bytes sources/doc/screenshots/board-view.png | Bin 0 -> 24460 bytes sources/doc/screenshots/calendar-view.png | Bin 0 -> 20973 bytes sources/doc/screenshots/gantt-view.png | Bin 0 -> 27793 bytes sources/doc/screenshots/hide-column.png | Bin 0 -> 8553 bytes sources/doc/screenshots/list-view.png | Bin 0 -> 22769 bytes sources/doc/screenshots/new-project.png | Bin 0 -> 20808 bytes sources/doc/screenshots/new-user.png | Bin 0 -> 22387 bytes .../screenshots/project-disable-sharing.png | Bin 0 -> 15375 bytes sources/doc/screenshots/project-edition.png | Bin 0 -> 36345 bytes .../screenshots/project-enable-sharing.png | Bin 0 -> 12251 bytes .../doc/screenshots/project-permissions.png | Bin 64960 -> 41833 bytes sources/doc/screenshots/project-view.png | Bin 0 -> 37215 bytes sources/doc/screenshots/show-column.png | Bin 0 -> 13581 bytes .../screenshots/swimlane-configuration.png | Bin 0 -> 13069 bytes sources/doc/screenshots/swimlanes.png | Bin 0 -> 25733 bytes sources/doc/sharing-projects.markdown | 6 +- sources/doc/swimlanes.markdown | 13 +- sources/doc/ubuntu-installation.markdown | 51 +- sources/doc/user-management.markdown | 10 +- sources/doc/vagrant.markdown | 64 +- sources/vendor/autoload.php | 2 +- sources/vendor/composer/autoload_classmap.php | 55 +- sources/vendor/composer/autoload_real.php | 10 +- sources/vendor/composer/installed.json | 52 +- .../picodb/lib/PicoDb/Driver/Base.php | 11 + .../picodb/lib/PicoDb/Driver/Postgres.php | 11 + .../picodb/lib/PicoDb/Driver/Sqlite.php | 12 + .../fguillot/picodb/lib/PicoDb/Schema.php | 20 +- .../fguillot/picodb/lib/PicoDb/Table.php | 24 + .../paragonie/random_compat/CHANGELOG.md | 49 +- .../vendor/paragonie/random_compat/ERRATA.md | 12 +- .../paragonie/random_compat/build-phar.sh | 5 + .../paragonie/random_compat/lib/random.php | 50 +- .../lib/random_bytes_openssl.php | 83 -- .../vendor/symfony/console/Application.php | 2 +- sources/vendor/symfony/console/CHANGELOG.md | 5 + .../symfony/console/Command/Command.php | 2 +- .../console/Formatter/OutputFormatter.php | 16 +- .../symfony/console/Helper/DialogHelper.php | 17 + .../symfony/console/Helper/ProgressHelper.php | 5 + .../symfony/console/Helper/QuestionHelper.php | 30 +- .../symfony/console/Input/InputOption.php | 2 +- .../symfony/console/Question/Question.php | 6 +- .../symfony/console/Style/SymfonyStyle.php | 4 +- .../Descriptor/AbstractDescriptorTest.php | 1 + .../Tests/Formatter/OutputFormatterTest.php | 4 +- .../Tests/Helper/LegacyDialogHelperTest.php | 69 +- .../Tests/Helper/ProgressIndicatorTest.php | 3 + .../Tests/Helper/QuestionHelperTest.php | 23 + .../vendor/symfony/console/phpunit.xml.dist | 10 + .../Debug/TraceableEventDispatcher.php | 7 +- .../RegisterListenersPass.php | 3 +- .../ContainerAwareEventDispatcherTest.php | 26 +- .../Debug/TraceableEventDispatcherTest.php | 23 +- sources/web.config | 17 + 570 files changed, 9329 insertions(+), 8452 deletions(-) create mode 100644 sources/app/Controller/ActionCreation.php create mode 100644 sources/app/Controller/ActionProject.php create mode 100644 sources/app/Controller/AvatarFile.php rename sources/app/Controller/{Tasklink.php => TaskInternalLink.php} (79%) create mode 100644 sources/app/Core/Thumbnail.php create mode 100644 sources/app/Core/User/Avatar/AvatarManager.php create mode 100644 sources/app/Core/User/Avatar/AvatarProviderInterface.php rename sources/app/{Model => Export}/SubtaskExport.php (95%) rename sources/app/{Model => Export}/TaskExport.php (96%) create mode 100644 sources/app/Export/TransitionExport.php create mode 100644 sources/app/ExternalLink/FileLink.php create mode 100644 sources/app/ExternalLink/FileLinkProvider.php rename sources/app/Helper/{App.php => AppHelper.php} (94%) rename sources/app/Helper/{Asset.php => AssetHelper.php} (90%) create mode 100644 sources/app/Helper/AvatarHelper.php rename sources/app/Helper/{Board.php => BoardHelper.php} (87%) rename sources/app/Helper/{Dt.php => DateHelper.php} (98%) rename sources/app/Helper/{File.php => FileHelper.php} (97%) rename sources/app/Helper/{Form.php => FormHelper.php} (90%) rename sources/app/Helper/{Hook.php => HookHelper.php} (92%) rename sources/app/Helper/{Layout.php => LayoutHelper.php} (85%) create mode 100644 sources/app/Helper/ModelHelper.php create mode 100644 sources/app/Helper/ProjectHeaderHelper.php rename sources/app/Helper/{Subtask.php => SubtaskHelper.php} (96%) rename sources/app/Helper/{Task.php => TaskHelper.php} (99%) rename sources/app/Helper/{Text.php => TextHelper.php} (87%) rename sources/app/Helper/{Url.php => UrlHelper.php} (80%) rename sources/app/Helper/{User.php => UserHelper.php} (83%) rename sources/app/{Model => Import}/TaskImport.php (97%) rename sources/app/{Model => Import}/UserImport.php (94%) create mode 100644 sources/app/Locale/ko_KR/translations.php create mode 100644 sources/app/Model/AvatarFile.php delete mode 100644 sources/app/Model/OverdueNotification.php create mode 100644 sources/app/ServiceProvider/AvatarProvider.php create mode 100644 sources/app/ServiceProvider/HelperProvider.php create mode 100644 sources/app/Template/action_creation/create.php rename sources/app/Template/{action => action_creation}/event.php (52%) rename sources/app/Template/{action => action_creation}/params.php (76%) create mode 100644 sources/app/Template/action_project/project.php create mode 100644 sources/app/Template/avatar_file/show.php create mode 100644 sources/app/Template/board/task_avatar.php create mode 100644 sources/app/Template/comments/create.php create mode 100644 sources/app/Template/comments/show.php create mode 100644 sources/app/Template/config/keyboard_shortcuts.php create mode 100644 sources/app/Template/project_overview/activity.php create mode 100644 sources/app/Template/project_overview/attachments.php create mode 100644 sources/app/Template/project_overview/images.php delete mode 100644 sources/app/Template/task/comments.php delete mode 100644 sources/app/Template/task/menu.php create mode 100644 sources/app/Template/task_external_link/table.php create mode 100644 sources/app/Template/task_file/files.php create mode 100644 sources/app/Template/task_file/images.php rename sources/app/Template/{tasklink => task_internal_link}/create.php (79%) rename sources/app/Template/{tasklink => task_internal_link}/edit.php (72%) rename sources/app/Template/{tasklink => task_internal_link}/remove.php (56%) create mode 100644 sources/app/Template/task_internal_link/show.php create mode 100644 sources/app/Template/task_internal_link/table.php delete mode 100644 sources/app/Template/tasklink/show.php create mode 100644 sources/app/User/Avatar/AvatarFileProvider.php create mode 100644 sources/app/User/Avatar/GravatarProvider.php create mode 100644 sources/app/User/Avatar/LetterAvatarProvider.php create mode 100644 sources/assets/css/src/accordion.css create mode 100644 sources/assets/css/src/avatar.css create mode 100644 sources/assets/css/src/tasklink.css create mode 100644 sources/assets/css/vendor/simplemde.min.css create mode 100644 sources/assets/js/src/Accordion.js delete mode 100644 sources/assets/js/src/Board.js create mode 100644 sources/assets/js/src/BoardCollapsedMode.js create mode 100644 sources/assets/js/src/BoardColumnScrolling.js create mode 100644 sources/assets/js/src/BoardColumnView.js create mode 100644 sources/assets/js/src/BoardDragAndDrop.js create mode 100644 sources/assets/js/src/BoardHorizontalScrolling.js create mode 100644 sources/assets/js/src/BoardPolling.js create mode 100644 sources/assets/js/src/BoardTask.js create mode 100644 sources/assets/js/src/Namespace.js create mode 100644 sources/assets/js/src/Notification.js delete mode 100644 sources/assets/js/src/Project.js create mode 100644 sources/assets/js/src/ProjectCreation.js create mode 100644 sources/assets/js/src/ProjectPermission.js delete mode 100644 sources/assets/js/src/Router.js create mode 100644 sources/assets/js/src/Session.js create mode 100644 sources/assets/js/src/bootstrap.js delete mode 100644 sources/assets/js/vendor/jquery.textcomplete.js create mode 100644 sources/assets/js/vendor/simplemde.min.js delete mode 100644 sources/doc/.htaccess create mode 100644 sources/doc/cloudron.markdown delete mode 100644 sources/doc/fr/captures/kanboard-acces-prive.png delete mode 100644 sources/doc/fr/captures/kanboard-acces-public.png delete mode 100644 sources/doc/fr/captures/kanboard-board.png delete mode 100644 sources/doc/fr/captures/kanboard-creer-utilisateur.png delete mode 100644 sources/doc/fr/captures/kanboard-nouveauprojet-prive.png delete mode 100644 sources/doc/fr/captures/kanboard-nouveauprojet.png delete mode 100644 sources/doc/fr/captures/kanboard-swimlanes.png delete mode 100644 sources/doc/fr/captures/kanboard-vue-calendrier.png delete mode 100644 sources/doc/fr/captures/kanboard-vue-gantt.png delete mode 100644 sources/doc/fr/captures/kanboard-vue-liste.png create mode 100644 sources/doc/fr/project-types.markdown create mode 100644 sources/doc/fr/roles.markdown create mode 100644 sources/doc/fr/screenshots/automatic-action-creation.png create mode 100644 sources/doc/fr/screenshots/board-collapsed-mode.png create mode 100644 sources/doc/fr/screenshots/board-compact-mode.png create mode 100644 sources/doc/fr/screenshots/board-expanded-mode.png create mode 100644 sources/doc/fr/screenshots/board-task-limit.png create mode 100644 sources/doc/fr/screenshots/board-view.png create mode 100644 sources/doc/fr/screenshots/calendar-view.png create mode 100644 sources/doc/fr/screenshots/gantt-view.png create mode 100644 sources/doc/fr/screenshots/hide-column.png create mode 100644 sources/doc/fr/screenshots/list-view.png create mode 100644 sources/doc/fr/screenshots/new-project.png create mode 100644 sources/doc/fr/screenshots/new-user.png create mode 100644 sources/doc/fr/screenshots/project-disable-sharing.png create mode 100644 sources/doc/fr/screenshots/project-edition.png create mode 100644 sources/doc/fr/screenshots/project-enable-sharing.png create mode 100644 sources/doc/fr/screenshots/project-permissions.png create mode 100644 sources/doc/fr/screenshots/project-view.png create mode 100644 sources/doc/fr/screenshots/show-column.png create mode 100644 sources/doc/fr/screenshots/swimlane-configuration.png create mode 100644 sources/doc/fr/screenshots/swimlanes.png create mode 100644 sources/doc/plugin-avatar-provider.markdown create mode 100644 sources/doc/plugin-helpers.markdown create mode 100644 sources/doc/screenshots/automatic-action-creation.png create mode 100644 sources/doc/screenshots/board-collapsed-mode.png create mode 100644 sources/doc/screenshots/board-compact-mode.png create mode 100644 sources/doc/screenshots/board-expanded-mode.png create mode 100644 sources/doc/screenshots/board-task-limit.png create mode 100644 sources/doc/screenshots/board-view.png create mode 100644 sources/doc/screenshots/calendar-view.png create mode 100644 sources/doc/screenshots/gantt-view.png create mode 100644 sources/doc/screenshots/hide-column.png create mode 100644 sources/doc/screenshots/list-view.png create mode 100644 sources/doc/screenshots/new-project.png create mode 100644 sources/doc/screenshots/new-user.png create mode 100644 sources/doc/screenshots/project-disable-sharing.png create mode 100644 sources/doc/screenshots/project-edition.png create mode 100644 sources/doc/screenshots/project-enable-sharing.png create mode 100644 sources/doc/screenshots/project-view.png create mode 100644 sources/doc/screenshots/show-column.png create mode 100644 sources/doc/screenshots/swimlane-configuration.png create mode 100644 sources/doc/screenshots/swimlanes.png create mode 100755 sources/vendor/paragonie/random_compat/build-phar.sh delete mode 100644 sources/vendor/paragonie/random_compat/lib/random_bytes_openssl.php create mode 100644 sources/web.config diff --git a/sources/ChangeLog b/sources/ChangeLog index a869925..f07ba9e 100644 --- a/sources/ChangeLog +++ b/sources/ChangeLog @@ -1,11 +1,56 @@ +Version 1.0.27 +-------------- + +New features: + +* Added Markdown editor +* Added user avatars with pluggable system + - Default is a letter based avatar + - Gravatar + - Avatar Image upload +* Added Korean translation + +Improvements: + +* Added more logging for LDAP client +* Improve schema migration process +* Improve notification configuration form +* Handle state in OAuth2 client +* Allow to use the original template in overridden templates +* Unification of the project header +* Refactoring of Javascript code +* Improve comments design +* Improve task summary sections +* Put back the action sidebar in task view +* Added support for multiple placeholders for LDAP_USER_FILTER +* Added local file link provider +* Show configuration in settings page +* Added "?" to display list of keyboard shortcuts +* Added new keyboard shortcuts for task view +* Always display project name and task title in task views +* Improve automatic action creation +* Move notifications to the bottom of the screen +* Added the possibility to import automatic actions from another project +* Added Ajax loading icon for submit buttons +* Added support for HTTP header "X-Forwarded-Proto: https" + +Bug fixes: + +* Fix bad unique constraints in Mysql table user_has_notifications +* Force integer type for aggregated metrics (Burndown chart concat values instead of summing) +* Fixes cycle time calculation when the start date is defined in the future +* Access allowed to any tasks from the shared public board by changing the URL parameters +* Fix invalid user filter for API procedure createLdapUser() +* Ambiguous column name with very old version of Sqlite + Version 1.0.26 -------------- Breaking changes: * API procedures: - - "moveColumnUp" and "moveColumnDown" are replace by "changeColumnPosition" - - "moveSwimlaneUp" and "moveSwimlaneDown" are replace by "changeSwimlanePosition" + - "moveColumnUp" and "moveColumnDown" are replaced by "changeColumnPosition" + - "moveSwimlaneUp" and "moveSwimlaneDown" are replaced by "changeSwimlanePosition" New features: diff --git a/sources/app/Action/Base.php b/sources/app/Action/Base.php index e8449d0..e5c65a1 100644 --- a/sources/app/Action/Base.php +++ b/sources/app/Action/Base.php @@ -132,6 +132,7 @@ abstract class Base extends \Kanboard\Core\Base * Set project id * * @access public + * @param integer $project_id * @return Base */ public function setProjectId($project_id) @@ -154,10 +155,10 @@ abstract class Base extends \Kanboard\Core\Base /** * Set an user defined parameter * - * @access public - * @param string $name Parameter name - * @param mixed $value Value - * @param Base + * @access public + * @param string $name Parameter name + * @param mixed $value Value + * @return Base */ public function setParam($name, $value) { @@ -271,6 +272,7 @@ abstract class Base extends \Kanboard\Core\Base * @access public * @param string $event * @param string $description + * @return Base */ public function addEvent($event, $description = '') { diff --git a/sources/app/Analytic/AverageLeadCycleTimeAnalytic.php b/sources/app/Analytic/AverageLeadCycleTimeAnalytic.php index fd85f86..62c8355 100644 --- a/sources/app/Analytic/AverageLeadCycleTimeAnalytic.php +++ b/sources/app/Analytic/AverageLeadCycleTimeAnalytic.php @@ -85,20 +85,22 @@ class AverageLeadCycleTimeAnalytic extends Base */ private function calculateCycleTime(array &$task) { - if (empty($task['date_started'])) { - return 0; + $end = (int) $task['date_completed'] ?: time(); + $start = (int) $task['date_started']; + + // Start date can be in the future when defined with the Gantt chart + if ($start > 0 && $end > $start) { + return $end - $start; } - $end = $task['date_completed'] ?: time(); - $start = $task['date_started']; - - return $end - $start; + return 0; } /** * Get the 1000 last created tasks * * @access private + * @param integer $project_id * @return array */ private function getTasks($project_id) diff --git a/sources/app/Analytic/AverageTimeSpentColumnAnalytic.php b/sources/app/Analytic/AverageTimeSpentColumnAnalytic.php index bef5541..1107832 100644 --- a/sources/app/Analytic/AverageTimeSpentColumnAnalytic.php +++ b/sources/app/Analytic/AverageTimeSpentColumnAnalytic.php @@ -126,6 +126,7 @@ class AverageTimeSpentColumnAnalytic extends Base * * @access private * @param array $task + * @return integer */ private function getTaskTimeSpentInCurrentColumn(array &$task) { diff --git a/sources/app/Api/Auth.php b/sources/app/Api/Auth.php index c7c5298..6c6e1eb 100644 --- a/sources/app/Api/Auth.php +++ b/sources/app/Api/Auth.php @@ -31,6 +31,7 @@ class Auth extends Base } elseif ($this->isAppAuthenticated($username, $password)) { $this->checkProcedurePermission(false, $method); } else { + $this->logger->error('API authentication failure for '.$username); throw new AuthenticationFailure('Wrong credentials'); } } diff --git a/sources/app/Api/User.php b/sources/app/Api/User.php index 48337ac..6ee935a 100644 --- a/sources/app/Api/User.php +++ b/sources/app/Api/User.php @@ -66,12 +66,29 @@ class User extends \Kanboard\Core\Base return $valid ? $this->user->create($values) : false; } + /** + * Create LDAP user in the database + * + * Only "anonymous" and "proxy" LDAP authentication are supported by this method + * + * User information will be fetched from the LDAP server + * + * @access public + * @param string $username + * @return bool|int + */ public function createLdapUser($username) { + if (LDAP_BIND_TYPE === 'user') { + $this->logger->error('LDAP authentication "user" is not supported by this API call'); + return false; + } + try { $ldap = LdapClient::connect(); - $user = LdapUser::getUser($ldap, sprintf(LDAP_USER_FILTER, $username)); + $ldap->setLogger($this->logger); + $user = LdapUser::getUser($ldap, $username); if ($user === null) { $this->logger->info('User not found in LDAP server'); diff --git a/sources/app/Auth/LdapAuth.php b/sources/app/Auth/LdapAuth.php index b4efbb5..c942358 100644 --- a/sources/app/Auth/LdapAuth.php +++ b/sources/app/Auth/LdapAuth.php @@ -63,10 +63,12 @@ class LdapAuth extends Base implements PasswordAuthenticationProviderInterface try { $client = LdapClient::connect($this->getLdapUsername(), $this->getLdapPassword()); + $client->setLogger($this->logger); + $user = LdapUser::getUser($client, $this->username); if ($user === null) { - $this->logger->info('User not found in LDAP server'); + $this->logger->info('User ('.$this->username.') not found in LDAP server'); return false; } @@ -74,6 +76,8 @@ class LdapAuth extends Base implements PasswordAuthenticationProviderInterface throw new LogicException('Username not found in LDAP profile, check the parameter LDAP_USER_ATTRIBUTE_USERNAME'); } + $this->logger->info('Authenticate user: '.$user->getDn()); + if ($client->authenticate($user->getDn(), $this->password)) { $this->userInfo = $user; return true; diff --git a/sources/app/Console/Base.php b/sources/app/Console/Base.php index ac89207..25d48e4 100644 --- a/sources/app/Console/Base.php +++ b/sources/app/Console/Base.php @@ -11,18 +11,18 @@ use Symfony\Component\Console\Command\Command; * @package console * @author Frederic Guillot * + * @property \Kanboard\Export\SubtaskExport $subtaskExport + * @property \Kanboard\Export\TaskExport $taskExport + * @property \Kanboard\Export\TransitionExport $transitionExport * @property \Kanboard\Model\Notification $notification * @property \Kanboard\Model\Project $project * @property \Kanboard\Model\ProjectPermission $projectPermission - * @property \Kanboard\Model\ProjectAnalytic $projectAnalytic * @property \Kanboard\Model\ProjectDailyColumnStats $projectDailyColumnStats * @property \Kanboard\Model\ProjectDailyStats $projectDailyStats - * @property \Kanboard\Model\SubtaskExport $subtaskExport - * @property \Kanboard\Model\OverdueNotification $overdueNotification * @property \Kanboard\Model\Task $task - * @property \Kanboard\Model\TaskExport $taskExport * @property \Kanboard\Model\TaskFinder $taskFinder - * @property \Kanboard\Model\Transition $transition + * @property \Kanboard\Model\UserNotification $userNotification + * @property \Kanboard\Model\UserNotificationFilter $userNotificationFilter * @property \Symfony\Component\EventDispatcher\EventDispatcher $dispatcher */ abstract class Base extends Command diff --git a/sources/app/Console/TaskOverdueNotification.php b/sources/app/Console/TaskOverdueNotification.php index ffb9fab..43be4df 100644 --- a/sources/app/Console/TaskOverdueNotification.php +++ b/sources/app/Console/TaskOverdueNotification.php @@ -2,6 +2,7 @@ namespace Kanboard\Console; +use Kanboard\Model\Task; use Symfony\Component\Console\Helper\Table; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -19,7 +20,7 @@ class TaskOverdueNotification extends Base protected function execute(InputInterface $input, OutputInterface $output) { - $tasks = $this->overdueNotification->sendOverdueTaskNotifications(); + $tasks = $this->sendOverdueTaskNotifications(); if ($input->getOption('show')) { $this->showTable($output, $tasks); @@ -47,4 +48,69 @@ class TaskOverdueNotification extends Base ->setRows($rows) ->render(); } + + /** + * Send overdue tasks + * + * @access public + */ + public function sendOverdueTaskNotifications() + { + $tasks = $this->taskFinder->getOverdueTasks(); + + foreach ($this->groupByColumn($tasks, 'project_id') as $project_id => $project_tasks) { + $users = $this->userNotification->getUsersWithNotificationEnabled($project_id); + + foreach ($users as $user) { + $this->sendUserOverdueTaskNotifications($user, $project_tasks); + } + } + + return $tasks; + } + + /** + * Send overdue tasks for a given user + * + * @access public + * @param array $user + * @param array $tasks + */ + public function sendUserOverdueTaskNotifications(array $user, array $tasks) + { + $user_tasks = array(); + + foreach ($tasks as $task) { + if ($this->userNotificationFilter->shouldReceiveNotification($user, array('task' => $task))) { + $user_tasks[] = $task; + } + } + + if (! empty($user_tasks)) { + $this->userNotification->sendUserNotification( + $user, + Task::EVENT_OVERDUE, + array('tasks' => $user_tasks, 'project_name' => $tasks[0]['project_name']) + ); + } + } + + /** + * Group a collection of records by a column + * + * @access public + * @param array $collection + * @param string $column + * @return array + */ + public function groupByColumn(array $collection, $column) + { + $result = array(); + + foreach ($collection as $item) { + $result[$item[$column]][] = $item; + } + + return $result; + } } diff --git a/sources/app/Console/TransitionExport.php b/sources/app/Console/TransitionExport.php index 9ae4141..d9f805a 100644 --- a/sources/app/Console/TransitionExport.php +++ b/sources/app/Console/TransitionExport.php @@ -21,7 +21,7 @@ class TransitionExport extends Base protected function execute(InputInterface $input, OutputInterface $output) { - $data = $this->transition->export( + $data = $this->transitionExport->export( $input->getArgument('project_id'), $input->getArgument('start_date'), $input->getArgument('end_date') diff --git a/sources/app/Controller/Action.php b/sources/app/Controller/Action.php index 6c32432..8881e8e 100644 --- a/sources/app/Controller/Action.php +++ b/sources/app/Controller/Action.php @@ -3,7 +3,7 @@ namespace Kanboard\Controller; /** - * Automatic actions management + * Automatic Actions * * @package controller * @author Frederic Guillot @@ -37,98 +37,6 @@ class Action extends Base ))); } - /** - * Choose the event according to the action (step 2) - * - * @access public - */ - public function event() - { - $project = $this->getProject(); - $values = $this->request->getValues(); - - if (empty($values['action_name']) || empty($values['project_id'])) { - $this->response->redirect($this->helper->url->to('action', 'index', array('project_id' => $project['id']))); - } - - $this->response->html($this->helper->layout->project('action/event', array( - 'values' => $values, - 'project' => $project, - 'events' => $this->actionManager->getCompatibleEvents($values['action_name']), - 'title' => t('Automatic actions') - ))); - } - - /** - * Define action parameters (step 3) - * - * @access public - */ - public function params() - { - $project = $this->getProject(); - $values = $this->request->getValues(); - - if (empty($values['action_name']) || empty($values['project_id']) || empty($values['event_name'])) { - $this->response->redirect($this->helper->url->to('action', 'index', array('project_id' => $project['id']))); - } - - $action = $this->actionManager->getAction($values['action_name']); - $action_params = $action->getActionRequiredParameters(); - - if (empty($action_params)) { - $this->doCreation($project, $values + array('params' => array())); - } - - $projects_list = $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId()); - unset($projects_list[$project['id']]); - - $this->response->html($this->helper->layout->project('action/params', array( - 'values' => $values, - 'action_params' => $action_params, - 'columns_list' => $this->column->getList($project['id']), - 'users_list' => $this->projectUserRole->getAssignableUsersList($project['id']), - 'projects_list' => $projects_list, - 'colors_list' => $this->color->getList(), - 'categories_list' => $this->category->getList($project['id']), - 'links_list' => $this->link->getList(0, false), - 'project' => $project, - 'title' => t('Automatic actions') - ))); - } - - /** - * Create a new action (last step) - * - * @access public - */ - public function create() - { - $this->doCreation($this->getProject(), $this->request->getValues()); - } - - /** - * Save the action - * - * @access private - * @param array $project Project properties - * @param array $values Form values - */ - private function doCreation(array $project, array $values) - { - list($valid, ) = $this->actionValidator->validateCreation($values); - - if ($valid) { - if ($this->action->create($values) !== false) { - $this->flash->success(t('Your automatic action have been created successfully.')); - } else { - $this->flash->failure(t('Unable to create your automatic action.')); - } - } - - $this->response->redirect($this->helper->url->to('action', 'index', array('project_id' => $project['id']))); - } - /** * Confirmation dialog before removing an action * diff --git a/sources/app/Controller/ActionCreation.php b/sources/app/Controller/ActionCreation.php new file mode 100644 index 0000000..24a12d9 --- /dev/null +++ b/sources/app/Controller/ActionCreation.php @@ -0,0 +1,121 @@ +getProject(); + + $this->response->html($this->template->render('action_creation/create', array( + 'project' => $project, + 'values' => array('project_id' => $project['id']), + 'available_actions' => $this->actionManager->getAvailableActions(), + ))); + } + + /** + * Choose the event according to the action (step 2) + * + * @access public + */ + public function event() + { + $project = $this->getProject(); + $values = $this->request->getValues(); + + if (empty($values['action_name']) || empty($values['project_id'])) { + return $this->create(); + } + + $this->response->html($this->template->render('action_creation/event', array( + 'values' => $values, + 'project' => $project, + 'available_actions' => $this->actionManager->getAvailableActions(), + 'events' => $this->actionManager->getCompatibleEvents($values['action_name']), + ))); + } + + /** + * Define action parameters (step 3) + * + * @access public + */ + public function params() + { + $project = $this->getProject(); + $values = $this->request->getValues(); + + if (empty($values['action_name']) || empty($values['project_id']) || empty($values['event_name'])) { + return $this->create(); + } + + $action = $this->actionManager->getAction($values['action_name']); + $action_params = $action->getActionRequiredParameters(); + + if (empty($action_params)) { + $this->doCreation($project, $values + array('params' => array())); + } + + $projects_list = $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId()); + unset($projects_list[$project['id']]); + + $this->response->html($this->template->render('action_creation/params', array( + 'values' => $values, + 'action_params' => $action_params, + 'columns_list' => $this->column->getList($project['id']), + 'users_list' => $this->projectUserRole->getAssignableUsersList($project['id']), + 'projects_list' => $projects_list, + 'colors_list' => $this->color->getList(), + 'categories_list' => $this->category->getList($project['id']), + 'links_list' => $this->link->getList(0, false), + 'project' => $project, + 'available_actions' => $this->actionManager->getAvailableActions(), + 'events' => $this->actionManager->getCompatibleEvents($values['action_name']), + ))); + } + + /** + * Save the action (last step) + * + * @access public + */ + public function save() + { + $this->doCreation($this->getProject(), $this->request->getValues()); + } + + /** + * Common method to save the action + * + * @access private + * @param array $project Project properties + * @param array $values Form values + */ + private function doCreation(array $project, array $values) + { + list($valid, ) = $this->actionValidator->validateCreation($values); + + if ($valid) { + if ($this->action->create($values) !== false) { + $this->flash->success(t('Your automatic action have been created successfully.')); + } else { + $this->flash->failure(t('Unable to create your automatic action.')); + } + } + + $this->response->redirect($this->helper->url->to('action', 'index', array('project_id' => $project['id']))); + } +} diff --git a/sources/app/Controller/ActionProject.php b/sources/app/Controller/ActionProject.php new file mode 100644 index 0000000..e5063f7 --- /dev/null +++ b/sources/app/Controller/ActionProject.php @@ -0,0 +1,38 @@ +getProject(); + $projects = $this->projectUserRole->getProjectsByUser($this->userSession->getId()); + unset($projects[$project['id']]); + + $this->response->html($this->template->render('action_project/project', array( + 'project' => $project, + 'projects_list' => $projects, + ))); + } + + public function save() + { + $project = $this->getProject(); + $src_project_id = $this->request->getValue('src_project_id'); + + if ($this->action->duplicate($src_project_id, $project['id'])) { + $this->flash->success(t('Actions duplicated successfully.')); + } else { + $this->flash->failure(t('Unable to duplicate actions.')); + } + + $this->response->redirect($this->helper->url->to('action', 'index', array('project_id' => $project['id']))); + } +} diff --git a/sources/app/Controller/Activity.php b/sources/app/Controller/Activity.php index db520eb..e455b1d 100644 --- a/sources/app/Controller/Activity.php +++ b/sources/app/Controller/Activity.php @@ -38,6 +38,7 @@ class Activity extends Base $this->response->html($this->helper->layout->task('activity/task', array( 'title' => $task['title'], 'task' => $task, + 'project' => $this->project->getById($task['project_id']), 'events' => $this->projectActivity->getTask($task['id']), ))); } diff --git a/sources/app/Controller/Analytic.php b/sources/app/Controller/Analytic.php index 6ce062c..6b0730b 100644 --- a/sources/app/Controller/Analytic.php +++ b/sources/app/Controller/Analytic.php @@ -44,8 +44,7 @@ class Analytic extends Base public function compareHours() { $project = $this->getProject(); - $params = $this->getProjectFilters('analytic', 'compareHours'); - $query = $this->taskFilter->create()->filterByProject($params['project']['id'])->getQuery(); + $query = $this->taskFilter->create()->filterByProject($project['id'])->getQuery(); $paginator = $this->paginator ->setUrl('analytic', 'compareHours', array('project_id' => $project['id'])) diff --git a/sources/app/Controller/App.php b/sources/app/Controller/App.php index 1ce7450..df1d3c9 100644 --- a/sources/app/Controller/App.php +++ b/sources/app/Controller/App.php @@ -2,6 +2,7 @@ namespace Kanboard\Controller; +use Kanboard\Model\Project as ProjectModel; use Kanboard\Model\Subtask as SubtaskModel; /** @@ -19,13 +20,14 @@ class App extends Base * @param integer $user_id * @param string $action * @param integer $max + * @return \Kanboard\Core\Paginator */ private function getProjectPaginator($user_id, $action, $max) { return $this->paginator ->setUrl('app', $action, array('pagination' => 'projects', 'user_id' => $user_id)) ->setMax($max) - ->setOrder('name') + ->setOrder(ProjectModel::TABLE.'.name') ->setQuery($this->project->getQueryColumnStats($this->projectPermission->getActiveProjectIds($user_id))) ->calculateOnlyIf($this->request->getStringParam('pagination') === 'projects'); } @@ -37,6 +39,7 @@ class App extends Base * @param integer $user_id * @param string $action * @param integer $max + * @return \Kanboard\Core\Paginator */ private function getTaskPaginator($user_id, $action, $max) { @@ -55,6 +58,7 @@ class App extends Base * @param integer $user_id * @param string $action * @param integer $max + * @return \Kanboard\Core\Paginator */ private function getSubtaskPaginator($user_id, $action, $max) { diff --git a/sources/app/Controller/Auth.php b/sources/app/Controller/Auth.php index 46b5a54..b882a72 100644 --- a/sources/app/Controller/Auth.php +++ b/sources/app/Controller/Auth.php @@ -14,6 +14,8 @@ class Auth extends Base * Display the form login * * @access public + * @param array $values + * @param array $errors */ public function login(array $values = array(), array $errors = array()) { diff --git a/sources/app/Controller/AvatarFile.php b/sources/app/Controller/AvatarFile.php new file mode 100644 index 0000000..a47cca6 --- /dev/null +++ b/sources/app/Controller/AvatarFile.php @@ -0,0 +1,92 @@ +getUser(); + + $this->response->html($this->helper->layout->user('avatar_file/show', array( + 'user' => $user, + ))); + } + + /** + * Upload Avatar + */ + public function upload() + { + $user = $this->getUser(); + + if (! $this->avatarFile->uploadFile($user['id'], $this->request->getFileInfo('avatar'))) { + $this->flash->failure(t('Unable to upload the file.')); + } + + $this->response->redirect($this->helper->url->to('AvatarFile', 'show', array('user_id' => $user['id']))); + } + + /** + * Remove Avatar image + */ + public function remove() + { + $this->checkCSRFParam(); + $user = $this->getUser(); + $this->avatarFile->remove($user['id']); + $this->response->redirect($this->helper->url->to('AvatarFile', 'show', array('user_id' => $user['id']))); + } + + /** + * Show Avatar image (public) + */ + public function image() + { + $user_id = $this->request->getIntegerParam('user_id'); + $size = $this->request->getStringParam('size', 48); + $filename = $this->avatarFile->getFilename($user_id); + $etag = md5($filename.$size); + + $this->response->cache(365 * 86400, $etag); + $this->response->contentType('image/jpeg'); + + if ($this->request->getHeader('If-None-Match') !== '"'.$etag.'"') { + $this->render($filename, $size); + } else { + $this->response->status(304); + } + } + + /** + * Render thumbnail from object storage + * + * @access private + * @param string $filename + * @param integer $size + */ + private function render($filename, $size) + { + try { + $blob = $this->objectStorage->get($filename); + + Thumbnail::createFromString($blob) + ->resize($size, $size) + ->toOutput(); + } catch (ObjectStorageException $e) { + $this->logger->error($e->getMessage()); + } + } +} diff --git a/sources/app/Controller/Base.php b/sources/app/Controller/Base.php index 884c439..beb5690 100644 --- a/sources/app/Controller/Base.php +++ b/sources/app/Controller/Base.php @@ -287,60 +287,4 @@ abstract class Base extends \Kanboard\Core\Base return $subtask; } - - /** - * Common method to get project filters - * - * @access protected - * @param string $controller - * @param string $action - * @return array - */ - protected function getProjectFilters($controller, $action) - { - $project = $this->getProject(); - $search = $this->request->getStringParam('search', $this->userSession->getFilters($project['id'])); - $board_selector = $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId()); - unset($board_selector[$project['id']]); - - $filters = array( - 'controller' => $controller, - 'action' => $action, - 'project_id' => $project['id'], - 'search' => urldecode($search), - ); - - $this->userSession->setFilters($project['id'], $filters['search']); - - return array( - 'project' => $project, - 'board_selector' => $board_selector, - 'filters' => $filters, - 'title' => $project['name'], - 'description' => $this->getProjectDescription($project), - ); - } - - /** - * Get project description - * - * @access protected - * @param array &$project - * @return string - */ - protected function getProjectDescription(array &$project) - { - if ($project['owner_id'] > 0) { - $description = t('Project owner: ').'**'.$this->template->e($project['owner_name'] ?: $project['owner_username']).'**'.PHP_EOL.PHP_EOL; - - if (! empty($project['description'])) { - $description .= '***'.PHP_EOL.PHP_EOL; - $description .= $project['description']; - } - } else { - $description = $project['description']; - } - - return $description; - } } diff --git a/sources/app/Controller/Board.php b/sources/app/Controller/Board.php index 199f170..51344bd 100644 --- a/sources/app/Controller/Board.php +++ b/sources/app/Controller/Board.php @@ -47,16 +47,17 @@ class Board extends Base */ public function show() { - $params = $this->getProjectFilters('board', 'show'); + $project = $this->getProject(); + $search = $this->helper->projectHeader->getSearchQuery($project); $this->response->html($this->helper->layout->app('board/view_private', array( - 'categories_list' => $this->category->getList($params['project']['id'], false), - 'users_list' => $this->projectUserRole->getAssignableUsersList($params['project']['id'], false), - 'custom_filters_list' => $this->customFilter->getAll($params['project']['id'], $this->userSession->getId()), - 'swimlanes' => $this->taskFilter->search($params['filters']['search'])->getBoard($params['project']['id']), + 'swimlanes' => $this->taskFilter->search($search)->getBoard($project['id']), + 'project' => $project, + 'title' => $project['name'], + 'description' => $this->helper->projectHeader->getDescription($project), 'board_private_refresh_interval' => $this->config->get('board_private_refresh_interval'), 'board_highlight_period' => $this->config->get('board_highlight_period'), - ) + $params)); + ))); } /** diff --git a/sources/app/Controller/BoardTooltip.php b/sources/app/Controller/BoardTooltip.php index bc07ce0..c7819bc 100644 --- a/sources/app/Controller/BoardTooltip.php +++ b/sources/app/Controller/BoardTooltip.php @@ -77,6 +77,7 @@ class BoardTooltip extends Base $task = $this->getTask(); $this->response->html($this->template->render('board/tooltip_comments', array( + 'task' => $task, 'comments' => $this->comment->getAll($task['id'], $this->userSession->getCommentSorting()) ))); } diff --git a/sources/app/Controller/Calendar.php b/sources/app/Controller/Calendar.php index a0a25e4..af31ae4 100644 --- a/sources/app/Controller/Calendar.php +++ b/sources/app/Controller/Calendar.php @@ -20,9 +20,14 @@ class Calendar extends Base */ public function show() { + $project = $this->getProject(); + $this->response->html($this->helper->layout->app('calendar/show', array( + 'project' => $project, + 'title' => $project['name'], + 'description' => $this->helper->projectHeader->getDescription($project), 'check_interval' => $this->config->get('board_private_refresh_interval'), - ) + $this->getProjectFilters('calendar', 'show'))); + ))); } /** diff --git a/sources/app/Controller/Column.php b/sources/app/Controller/Column.php index 66073b5..bbe12fe 100644 --- a/sources/app/Controller/Column.php +++ b/sources/app/Controller/Column.php @@ -76,6 +76,8 @@ class Column extends Base * Display a form to edit a column * * @access public + * @param array $values + * @param array $errors */ public function edit(array $values = array(), array $errors = array()) { diff --git a/sources/app/Controller/Comment.php b/sources/app/Controller/Comment.php index da3213e..ff7ec30 100644 --- a/sources/app/Controller/Comment.php +++ b/sources/app/Controller/Comment.php @@ -47,11 +47,10 @@ class Comment extends Base ); } - $this->response->html($this->helper->layout->task('comment/create', array( + $this->response->html($this->template->render('comment/create', array( 'values' => $values, 'errors' => $errors, 'task' => $task, - 'title' => t('Add a comment'), ))); } @@ -90,7 +89,7 @@ class Comment extends Base $task = $this->getTask(); $comment = $this->getComment(); - $this->response->html($this->helper->layout->task('comment/edit', array( + $this->response->html($this->template->render('comment/edit', array( 'values' => empty($values) ? $comment : $values, 'errors' => $errors, 'comment' => $comment, @@ -135,7 +134,7 @@ class Comment extends Base $task = $this->getTask(); $comment = $this->getComment(); - $this->response->html($this->helper->layout->task('comment/remove', array( + $this->response->html($this->template->render('comment/remove', array( 'comment' => $comment, 'task' => $task, 'title' => t('Remove a comment') diff --git a/sources/app/Controller/Config.php b/sources/app/Controller/Config.php index e811f87..a1b8c2a 100644 --- a/sources/app/Controller/Config.php +++ b/sources/app/Controller/Config.php @@ -61,6 +61,8 @@ class Config extends Base { $this->response->html($this->helper->layout->config('config/about', array( 'db_size' => $this->config->getDatabaseSize(), + 'db_version' => $this->db->getDriver()->getDatabaseVersion(), + 'user_agent' => $this->request->getServerVariable('HTTP_USER_AGENT'), 'title' => t('Settings').' > '.t('About'), ))); } diff --git a/sources/app/Controller/Doc.php b/sources/app/Controller/Doc.php index 6f309d4..00b9e58 100644 --- a/sources/app/Controller/Doc.php +++ b/sources/app/Controller/Doc.php @@ -5,53 +5,88 @@ namespace Kanboard\Controller; use Parsedown; /** - * Documentation controller + * Documentation Viewer * * @package controller * @author Frederic Guillot */ class Doc extends Base { - private function readFile($filename) + public function show() + { + $page = $this->request->getStringParam('file', 'index'); + + if (!preg_match('/^[a-z0-9\-]+/', $page)) { + $page = 'index'; + } + + if ($this->config->getCurrentLanguage() === 'fr_FR') { + $filename = __DIR__.'/../../doc/fr/' . $page . '.markdown'; + } else { + $filename = __DIR__ . '/../../doc/' . $page . '.markdown'; + } + + if (!file_exists($filename)) { + $filename = __DIR__.'/../../doc/index.markdown'; + } + + $this->response->html($this->helper->layout->app('doc/show', $this->render($filename))); + } + + /** + * Display keyboard shortcut + */ + public function shortcuts() + { + $this->response->html($this->template->render('config/keyboard_shortcuts')); + } + + /** + * Prepare Markdown file + * + * @access private + * @param string $filename + * @return array + */ + private function render($filename) { - $url = $this->helper->url; $data = file_get_contents($filename); + $content = preg_replace_callback('/\((.*.markdown)\)/', array($this, 'replaceMarkdownUrl'), $data); + $content = preg_replace_callback('/\((screenshots.*\.png)\)/', array($this, 'replaceImageUrl'), $content); + list($title, ) = explode("\n", $data, 2); - $replaceUrl = function (array $matches) use ($url) { - return '('.$url->to('doc', 'show', array('file' => str_replace('.markdown', '', $matches[1]))).')'; - }; - - $content = preg_replace_callback('/\((.*.markdown)\)/', $replaceUrl, $data); - return array( 'content' => Parsedown::instance()->text($content), 'title' => $title !== 'Documentation' ? t('Documentation: %s', $title) : $title, ); } - public function show() + /** + * Regex callback to replace Markdown links + * + * @access public + * @param array $matches + * @return string + */ + public function replaceMarkdownUrl(array $matches) { - $page = $this->request->getStringParam('file', 'index'); - - if (! preg_match('/^[a-z0-9\-]+/', $page)) { - $page = 'index'; - } - - $filenames = array(__DIR__.'/../../doc/'.$page.'.markdown'); - $filename = __DIR__.'/../../doc/index.markdown'; + return '('.$this->helper->url->to('doc', 'show', array('file' => str_replace('.markdown', '', $matches[1]))).')'; + } + /** + * Regex callback to replace image links + * + * @access public + * @param array $matches + * @return string + */ + public function replaceImageUrl(array $matches) + { if ($this->config->getCurrentLanguage() === 'fr_FR') { - array_unshift($filenames, __DIR__.'/../../doc/fr/'.$page.'.markdown'); + return '('.$this->helper->url->base().'doc/fr/'.$matches[1].')'; } - foreach ($filenames as $file) { - if (file_exists($file)) { - $filename = $file; - break; - } - } - - $this->response->html($this->helper->layout->app('doc/show', $this->readFile($filename))); + return '('.$this->helper->url->base().'doc/'.$matches[1].')'; } } diff --git a/sources/app/Controller/Export.php b/sources/app/Controller/Export.php index 726edd4..c2ff652 100644 --- a/sources/app/Controller/Export.php +++ b/sources/app/Controller/Export.php @@ -80,6 +80,6 @@ class Export extends Base */ public function transitions() { - $this->common('transition', 'export', t('Transitions'), 'transitions', t('Task transitions export')); + $this->common('transitionExport', 'export', t('Transitions'), 'transitions', t('Task transitions export')); } } diff --git a/sources/app/Controller/FileViewer.php b/sources/app/Controller/FileViewer.php index bc91c3d..3be4ea1 100644 --- a/sources/app/Controller/FileViewer.php +++ b/sources/app/Controller/FileViewer.php @@ -66,9 +66,16 @@ class FileViewer extends Base */ public function image() { + $file = $this->getFile(); + $etag = md5($file['path']); + $this->response->contentType($this->helper->file->getImageMimeType($file['name'])); + $this->response->cache(5 * 86400, $etag); + + if ($this->request->getHeader('If-None-Match') === '"'.$etag.'"') { + return $this->response->status(304); + } + try { - $file = $this->getFile(); - $this->response->contentType($this->helper->file->getImageMimeType($file['name'])); $this->objectStorage->output($file['path']); } catch (ObjectStorageException $e) { $this->logger->error($e->getMessage()); @@ -82,12 +89,21 @@ class FileViewer extends Base */ public function thumbnail() { + $file = $this->getFile(); + $model = $file['model']; + $filename = $this->$model->getThumbnailPath($file['path']); + $etag = md5($filename); + + $this->response->cache(5 * 86400, $etag); $this->response->contentType('image/jpeg'); + if ($this->request->getHeader('If-None-Match') === '"'.$etag.'"') { + return $this->response->status(304); + } + try { - $file = $this->getFile(); - $model = $file['model']; - $this->objectStorage->output($this->$model->getThumbnailPath($file['path'])); + + $this->objectStorage->output($filename); } catch (ObjectStorageException $e) { $this->logger->error($e->getMessage()); diff --git a/sources/app/Controller/Gantt.php b/sources/app/Controller/Gantt.php index 9ffa277..02ee946 100644 --- a/sources/app/Controller/Gantt.php +++ b/sources/app/Controller/Gantt.php @@ -54,8 +54,9 @@ class Gantt extends Base */ public function project() { - $params = $this->getProjectFilters('gantt', 'project'); - $filter = $this->taskFilterGanttFormatter->search($params['filters']['search'])->filterByProject($params['project']['id']); + $project = $this->getProject(); + $search = $this->helper->projectHeader->getSearchQuery($project); + $filter = $this->taskFilterGanttFormatter->search($search)->filterByProject($project['id']); $sorting = $this->request->getStringParam('sorting', 'board'); if ($sorting === 'date') { @@ -64,8 +65,10 @@ class Gantt extends Base $filter->getQuery()->asc('column_position')->asc(TaskModel::TABLE.'.position'); } - $this->response->html($this->helper->layout->app('gantt/project', $params + array( - 'users_list' => $this->projectUserRole->getAssignableUsersList($params['project']['id'], false), + $this->response->html($this->helper->layout->app('gantt/project', array( + 'project' => $project, + 'title' => $project['name'], + 'description' => $this->helper->projectHeader->getDescription($project), 'sorting' => $sorting, 'tasks' => $filter->format(), ))); diff --git a/sources/app/Controller/Listing.php b/sources/app/Controller/Listing.php index c784dd5..9931c34 100644 --- a/sources/app/Controller/Listing.php +++ b/sources/app/Controller/Listing.php @@ -19,22 +19,23 @@ class Listing extends Base */ public function show() { - $params = $this->getProjectFilters('listing', 'show'); - $query = $this->taskFilter->search($params['filters']['search'])->filterByProject($params['project']['id'])->getQuery(); + $project = $this->getProject(); + $search = $this->helper->projectHeader->getSearchQuery($project); + $query = $this->taskFilter->search($search)->filterByProject($project['id'])->getQuery(); $paginator = $this->paginator - ->setUrl('listing', 'show', array('project_id' => $params['project']['id'])) + ->setUrl('listing', 'show', array('project_id' => $project['id'])) ->setMax(30) ->setOrder(TaskModel::TABLE.'.id') ->setDirection('DESC') ->setQuery($query) ->calculate(); - $this->response->html($this->helper->layout->app('listing/show', $params + array( + $this->response->html($this->helper->layout->app('listing/show', array( + 'project' => $project, + 'title' => $project['name'], + 'description' => $this->helper->projectHeader->getDescription($project), 'paginator' => $paginator, - 'categories_list' => $this->category->getList($params['project']['id'], false), - 'users_list' => $this->projectUserRole->getAssignableUsersList($params['project']['id'], false), - 'custom_filters_list' => $this->customFilter->getAll($params['project']['id'], $this->userSession->getId()), ))); } } diff --git a/sources/app/Controller/Oauth.php b/sources/app/Controller/Oauth.php index 452faec..12b9114 100644 --- a/sources/app/Controller/Oauth.php +++ b/sources/app/Controller/Oauth.php @@ -2,6 +2,8 @@ namespace Kanboard\Controller; +use Kanboard\Core\Security\OAuthAuthenticationProviderInterface; + /** * OAuth controller * @@ -10,6 +12,72 @@ namespace Kanboard\Controller; */ class Oauth extends Base { + /** + * Redirect to the provider if no code received + * + * @access private + * @param string $provider + */ + protected function step1($provider) + { + $code = $this->request->getStringParam('code'); + $state = $this->request->getStringParam('state'); + + if (! empty($code)) { + $this->step2($provider, $code, $state); + } else { + $this->response->redirect($this->authenticationManager->getProvider($provider)->getService()->getAuthorizationUrl()); + } + } + + /** + * Link or authenticate the user + * + * @access protected + * @param string $providerName + * @param string $code + * @param string $state + */ + protected function step2($providerName, $code, $state) + { + $provider = $this->authenticationManager->getProvider($providerName); + $provider->setCode($code); + $hasValidState = $provider->getService()->isValidateState($state); + + if ($this->userSession->isLogged()) { + if ($hasValidState) { + $this->link($provider); + } else { + $this->flash->failure(t('The OAuth2 state parameter is invalid')); + $this->response->redirect($this->helper->url->to('user', 'external', array('user_id' => $this->userSession->getId()))); + } + } else { + if ($hasValidState) { + $this->authenticate($providerName); + } else { + $this->authenticationFailure(t('The OAuth2 state parameter is invalid')); + } + } + } + + /** + * Link the account + * + * @access protected + * @param OAuthAuthenticationProviderInterface $provider + */ + protected function link(OAuthAuthenticationProviderInterface $provider) + { + if (! $provider->authenticate()) { + $this->flash->failure(t('External authentication failed')); + } else { + $this->userProfile->assign($this->userSession->getId(), $provider->getUser()); + $this->flash->success(t('Your external account is linked to your profile successfully.')); + } + + $this->response->redirect($this->helper->url->to('user', 'external', array('user_id' => $this->userSession->getId()))); + } + /** * Unlink external account * @@ -29,78 +97,34 @@ class Oauth extends Base $this->response->redirect($this->helper->url->to('user', 'external', array('user_id' => $this->userSession->getId()))); } - /** - * Redirect to the provider if no code received - * - * @access private - * @param string $provider - */ - protected function step1($provider) - { - $code = $this->request->getStringParam('code'); - - if (! empty($code)) { - $this->step2($provider, $code); - } else { - $this->response->redirect($this->authenticationManager->getProvider($provider)->getService()->getAuthorizationUrl()); - } - } - - /** - * Link or authenticate the user - * - * @access protected - * @param string $provider - * @param string $code - */ - protected function step2($provider, $code) - { - $this->authenticationManager->getProvider($provider)->setCode($code); - - if ($this->userSession->isLogged()) { - $this->link($provider); - } - - $this->authenticate($provider); - } - - /** - * Link the account - * - * @access protected - * @param string $provider - */ - protected function link($provider) - { - $authProvider = $this->authenticationManager->getProvider($provider); - - if (! $authProvider->authenticate()) { - $this->flash->failure(t('External authentication failed')); - } else { - $this->userProfile->assign($this->userSession->getId(), $authProvider->getUser()); - $this->flash->success(t('Your external account is linked to your profile successfully.')); - } - - $this->response->redirect($this->helper->url->to('user', 'external', array('user_id' => $this->userSession->getId()))); - } - /** * Authenticate the account * * @access protected - * @param string $provider + * @param string $providerName */ - protected function authenticate($provider) + protected function authenticate($providerName) { - if ($this->authenticationManager->oauthAuthentication($provider)) { + if ($this->authenticationManager->oauthAuthentication($providerName)) { $this->response->redirect($this->helper->url->to('app', 'index')); } else { - $this->response->html($this->helper->layout->app('auth/index', array( - 'errors' => array('login' => t('External authentication failed')), - 'values' => array(), - 'no_layout' => true, - 'title' => t('Login') - ))); + $this->authenticationFailure(t('External authentication failed')); } } + + /** + * Show login failure page + * + * @access protected + * @param string $message + */ + protected function authenticationFailure($message) + { + $this->response->html($this->helper->layout->app('auth/index', array( + 'errors' => array('login' => $message), + 'values' => array(), + 'no_layout' => true, + 'title' => t('Login') + ))); + } } diff --git a/sources/app/Controller/ProjectEdit.php b/sources/app/Controller/ProjectEdit.php index f4a3a7c..94be020 100644 --- a/sources/app/Controller/ProjectEdit.php +++ b/sources/app/Controller/ProjectEdit.php @@ -67,7 +67,7 @@ class ProjectEdit extends Base if ($valid) { if ($this->project->update($values)) { $this->flash->success(t('Project updated successfully.')); - $this->response->redirect($this->helper->url->to('ProjectEdit', $redirect, array('project_id' => $project['id']))); + $this->response->redirect($this->helper->url->to('ProjectEdit', $redirect, array('project_id' => $project['id'])), true); } else { $this->flash->failure(t('Unable to update this project.')); } diff --git a/sources/app/Controller/ProjectOverview.php b/sources/app/Controller/ProjectOverview.php index b0687ed..0464580 100644 --- a/sources/app/Controller/ProjectOverview.php +++ b/sources/app/Controller/ProjectOverview.php @@ -15,15 +15,18 @@ class ProjectOverview extends Base */ public function show() { - $params = $this->getProjectFilters('ProjectOverview', 'show'); - $params['users'] = $this->projectUserRole->getAllUsersGroupedByRole($params['project']['id']); - $params['roles'] = $this->role->getProjectRoles(); - $params['events'] = $this->projectActivity->getProject($params['project']['id'], 10); - $params['images'] = $this->projectFile->getAllImages($params['project']['id']); - $params['files'] = $this->projectFile->getAllDocuments($params['project']['id']); + $project = $this->getProject(); + $this->project->getColumnStats($project); - $this->project->getColumnStats($params['project']); - - $this->response->html($this->helper->layout->app('project_overview/show', $params)); + $this->response->html($this->helper->layout->app('project_overview/show', array( + 'project' => $project, + 'title' => $project['name'], + 'description' => $this->helper->projectHeader->getDescription($project), + 'users' => $this->projectUserRole->getAllUsersGroupedByRole($project['id']), + 'roles' => $this->role->getProjectRoles(), + 'events' => $this->projectActivity->getProject($project['id'], 10), + 'images' => $this->projectFile->getAllImages($project['id']), + 'files' => $this->projectFile->getAllDocuments($project['id']), + ))); } } diff --git a/sources/app/Controller/Subtask.php b/sources/app/Controller/Subtask.php index 8ca0ce9..dea2b08 100644 --- a/sources/app/Controller/Subtask.php +++ b/sources/app/Controller/Subtask.php @@ -10,22 +10,6 @@ namespace Kanboard\Controller; */ class Subtask extends Base { - /** - * Show list of subtasks - */ - public function show() - { - $task = $this->getTask(); - - $this->response->html($this->helper->layout->task('subtask/show', array( - 'users_list' => $this->projectUserRole->getAssignableUsersList($task['project_id']), - 'task' => $task, - 'project' => $this->getProject(), - 'subtasks' => $this->subtask->getAll($task['id']), - 'editable' => true, - ))); - } - /** * Creation form * @@ -42,7 +26,7 @@ class Subtask extends Base ); } - $this->response->html($this->helper->layout->task('subtask/create', array( + $this->response->html($this->template->render('subtask/create', array( 'values' => $values, 'errors' => $errors, 'users_list' => $this->projectUserRole->getAssignableUsersList($task['project_id']), @@ -89,7 +73,7 @@ class Subtask extends Base $task = $this->getTask(); $subtask = $this->getSubTask(); - $this->response->html($this->helper->layout->task('subtask/edit', array( + $this->response->html($this->template->render('subtask/edit', array( 'values' => empty($values) ? $subtask : $values, 'errors' => $errors, 'users_list' => $this->projectUserRole->getAssignableUsersList($task['project_id']), @@ -135,7 +119,7 @@ class Subtask extends Base $task = $this->getTask(); $subtask = $this->getSubtask(); - $this->response->html($this->helper->layout->task('subtask/remove', array( + $this->response->html($this->template->render('subtask/remove', array( 'subtask' => $subtask, 'task' => $task, ))); diff --git a/sources/app/Controller/Task.php b/sources/app/Controller/Task.php index 539d377..902a32d 100644 --- a/sources/app/Controller/Task.php +++ b/sources/app/Controller/Task.php @@ -2,6 +2,8 @@ namespace Kanboard\Controller; +use Kanboard\Core\DateParser; + /** * Task controller * @@ -21,13 +23,17 @@ class Task extends Base // Token verification if (empty($project)) { - $this->forbidden(true); + return $this->forbidden(true); } $task = $this->taskFinder->getDetails($this->request->getIntegerParam('task_id')); if (empty($task)) { - $this->notfound(true); + return $this->notfound(true); + } + + if ($task['project_id'] != $project['id']) { + return $this->forbidden(true); } $this->response->html($this->helper->layout->app('task/public', array( @@ -62,25 +68,19 @@ class Task extends Base 'time_spent' => $task['time_spent'] ?: '', ); - $values = $this->dateParser->format($values, array('date_started'), $this->config->get('application_datetime_format', 'm/d/Y H:i')); + $values = $this->dateParser->format($values, array('date_started'), $this->config->get('application_datetime_format', DateParser::DATE_TIME_FORMAT)); $this->response->html($this->helper->layout->task('task/show', array( + 'task' => $task, 'project' => $this->project->getById($task['project_id']), + 'values' => $values, 'files' => $this->taskFile->getAllDocuments($task['id']), 'images' => $this->taskFile->getAllImages($task['id']), 'comments' => $this->comment->getAll($task['id'], $this->userSession->getCommentSorting()), 'subtasks' => $subtasks, - 'links' => $this->taskLink->getAllGroupedByLabel($task['id']), - 'task' => $task, - 'values' => $values, + 'internal_links' => $this->taskLink->getAllGroupedByLabel($task['id']), + 'external_links' => $this->taskExternalLink->getAll($task['id']), 'link_label_list' => $this->link->getList(0, false), - 'columns_list' => $this->column->getList($task['project_id']), - 'colors_list' => $this->color->getList(), - 'users_list' => $this->projectUserRole->getAssignableUsersList($task['project_id'], true, false, false), - 'title' => $task['project_name'].' > '.$task['title'], - 'recurrence_trigger_list' => $this->task->getRecurrenceTriggerList(), - 'recurrence_timeframe_list' => $this->task->getRecurrenceTimeframeList(), - 'recurrence_basedate_list' => $this->task->getRecurrenceBasedateList(), ))); } @@ -94,8 +94,8 @@ class Task extends Base $task = $this->getTask(); $this->response->html($this->helper->layout->task('task/analytics', array( - 'title' => $task['title'], 'task' => $task, + 'project' => $this->project->getById($task['project_id']), 'lead_time' => $this->taskAnalytic->getLeadTime($task), 'cycle_time' => $this->taskAnalytic->getCycleTime($task), 'time_spent_columns' => $this->taskAnalytic->getTimeSpentByColumn($task), @@ -121,6 +121,7 @@ class Task extends Base $this->response->html($this->helper->layout->task('task/time_tracking_details', array( 'task' => $task, + 'project' => $this->project->getById($task['project_id']), 'subtask_paginator' => $subtask_paginator, ))); } @@ -136,6 +137,7 @@ class Task extends Base $this->response->html($this->helper->layout->task('task/transitions', array( 'task' => $task, + 'project' => $this->project->getById($task['project_id']), 'transitions' => $this->transition->getAllByTask($task['id']), ))); } @@ -165,7 +167,7 @@ class Task extends Base $this->response->redirect($this->helper->url->to('board', 'show', array('project_id' => $task['project_id']))); } - $this->response->html($this->helper->layout->task('task/remove', array( + $this->response->html($this->template->render('task/remove', array( 'task' => $task, ))); } diff --git a/sources/app/Controller/TaskExternalLink.php b/sources/app/Controller/TaskExternalLink.php index f26922d..0db8ec3 100644 --- a/sources/app/Controller/TaskExternalLink.php +++ b/sources/app/Controller/TaskExternalLink.php @@ -12,22 +12,6 @@ use Kanboard\Core\ExternalLink\ExternalLinkProviderNotFound; */ class TaskExternalLink extends Base { - /** - * Creation form - * - * @access public - */ - public function show() - { - $task = $this->getTask(); - - $this->response->html($this->helper->layout->task('task_external_link/show', array( - 'links' => $this->taskExternalLink->getAll($task['id']), - 'task' => $task, - 'title' => t('List of external links'), - ))); - } - /** * First creation form * @@ -37,7 +21,7 @@ class TaskExternalLink extends Base { $task = $this->getTask(); - $this->response->html($this->helper->layout->task('task_external_link/find', array( + $this->response->html($this->template->render('task_external_link/find', array( 'values' => $values, 'errors' => $errors, 'task' => $task, @@ -60,7 +44,7 @@ class TaskExternalLink extends Base $provider = $this->externalLinkManager->setUserInput($values)->find(); $link = $provider->getLink(); - $this->response->html($this->helper->layout->task('task_external_link/create', array( + $this->response->html($this->template->render('task_external_link/create', array( 'values' => array( 'title' => $link->getTitle(), 'url' => $link->getUrl(), @@ -90,7 +74,7 @@ class TaskExternalLink extends Base if ($valid && $this->taskExternalLink->create($values)) { $this->flash->success(t('Link added successfully.')); - return $this->response->redirect($this->helper->url->to('TaskExternalLink', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), true); + return $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), true); } $this->edit($values, $errors); @@ -116,7 +100,7 @@ class TaskExternalLink extends Base $provider = $this->externalLinkManager->getProvider($values['link_type']); - $this->response->html($this->helper->layout->task('task_external_link/edit', array( + $this->response->html($this->template->render('task_external_link/edit', array( 'values' => $values, 'errors' => $errors, 'task' => $task, @@ -137,7 +121,7 @@ class TaskExternalLink extends Base if ($valid && $this->taskExternalLink->update($values)) { $this->flash->success(t('Link updated successfully.')); - return $this->response->redirect($this->helper->url->to('TaskExternalLink', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), true); + return $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), true); } $this->edit($values, $errors); @@ -158,7 +142,7 @@ class TaskExternalLink extends Base return $this->notfound(); } - $this->response->html($this->helper->layout->task('task_external_link/remove', array( + $this->response->html($this->template->render('task_external_link/remove', array( 'link' => $link, 'task' => $task, ))); @@ -180,6 +164,6 @@ class TaskExternalLink extends Base $this->flash->failure(t('Unable to remove this link.')); } - $this->response->redirect($this->helper->url->to('TaskExternalLink', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']))); + $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']))); } } diff --git a/sources/app/Controller/TaskHelper.php b/sources/app/Controller/TaskHelper.php index 236af33..7e340a6 100644 --- a/sources/app/Controller/TaskHelper.php +++ b/sources/app/Controller/TaskHelper.php @@ -10,22 +10,6 @@ namespace Kanboard\Controller; */ class TaskHelper extends Base { - /** - * Render Markdown text and reply with the HTML Code - * - * @access public - */ - public function preview() - { - $payload = $this->request->getJson(); - - if (empty($payload['text'])) { - $this->response->html('

'.t('Nothing to preview...').'

'); - } - - $this->response->html($this->helper->text->markdown($payload['text'])); - } - /** * Task autocompletion (Ajax) * diff --git a/sources/app/Controller/Tasklink.php b/sources/app/Controller/TaskInternalLink.php similarity index 79% rename from sources/app/Controller/Tasklink.php rename to sources/app/Controller/TaskInternalLink.php index fdb4fad..ac5e04b 100644 --- a/sources/app/Controller/Tasklink.php +++ b/sources/app/Controller/TaskInternalLink.php @@ -3,13 +3,13 @@ namespace Kanboard\Controller; /** - * TaskLink controller + * TaskInternalLink Controller * * @package controller * @author Olivier Maridat * @author Frederic Guillot */ -class Tasklink extends Base +class TaskInternalLink extends Base { /** * Get the current link @@ -28,25 +28,6 @@ class Tasklink extends Base return $link; } - /** - * Show links - * - * @access public - */ - public function show() - { - $task = $this->getTask(); - $project = $this->project->getById($task['project_id']); - - $this->response->html($this->helper->layout->task('tasklink/show', array( - 'links' => $this->taskLink->getAllGroupedByLabel($task['id']), - 'task' => $task, - 'project' => $project, - 'editable' => true, - 'is_public' => false, - ))); - } - /** * Creation form * @@ -56,12 +37,11 @@ class Tasklink extends Base { $task = $this->getTask(); - $this->response->html($this->helper->layout->task('tasklink/create', array( + $this->response->html($this->template->render('task_internal_link/create', array( 'values' => $values, 'errors' => $errors, 'task' => $task, 'labels' => $this->link->getList(0, false), - 'title' => t('Add a new link') ))); } @@ -80,7 +60,7 @@ class Tasklink extends Base if ($valid) { if ($this->taskLink->create($values['task_id'], $values['opposite_task_id'], $values['link_id'])) { $this->flash->success(t('Link added successfully.')); - return $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])).'#links', true); + return $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), true); } $errors = array('title' => array(t('The exact same link already exists'))); @@ -106,13 +86,12 @@ class Tasklink extends Base $values['title'] = '#'.$opposite_task['id'].' - '.$opposite_task['title']; } - $this->response->html($this->helper->layout->task('tasklink/edit', array( + $this->response->html($this->template->render('task_internal_link/edit', array( 'values' => $values, 'errors' => $errors, 'task_link' => $task_link, 'task' => $task, - 'labels' => $this->link->getList(0, false), - 'title' => t('Edit link') + 'labels' => $this->link->getList(0, false) ))); } @@ -150,7 +129,7 @@ class Tasklink extends Base $task = $this->getTask(); $link = $this->getTaskLink(); - $this->response->html($this->helper->layout->task('tasklink/remove', array( + $this->response->html($this->template->render('task_internal_link/remove', array( 'link' => $link, 'task' => $task, ))); @@ -172,6 +151,6 @@ class Tasklink extends Base $this->flash->failure(t('Unable to remove this link.')); } - $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])).'#links'); + $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']))); } } diff --git a/sources/app/Controller/TaskRecurrence.php b/sources/app/Controller/TaskRecurrence.php index f02f3cd..569ef8d 100644 --- a/sources/app/Controller/TaskRecurrence.php +++ b/sources/app/Controller/TaskRecurrence.php @@ -23,7 +23,7 @@ class TaskRecurrence extends Base $values = $task; } - $this->response->html($this->helper->layout->task('task_recurrence/edit', array( + $this->response->html($this->template->render('task_recurrence/edit', array( 'values' => $values, 'errors' => $errors, 'task' => $task, diff --git a/sources/app/Controller/Taskduplication.php b/sources/app/Controller/Taskduplication.php index 7641a48..8fca930 100644 --- a/sources/app/Controller/Taskduplication.php +++ b/sources/app/Controller/Taskduplication.php @@ -32,7 +32,7 @@ class Taskduplication extends Base } } - $this->response->html($this->helper->layout->task('task_duplication/duplicate', array( + $this->response->html($this->template->render('task_duplication/duplicate', array( 'task' => $task, ))); } @@ -128,7 +128,7 @@ class Taskduplication extends Base $users_list = array(); } - $this->response->html($this->helper->layout->task($template, array( + $this->response->html($this->template->render($template, array( 'values' => $values, 'task' => $task, 'projects_list' => $projects_list, diff --git a/sources/app/Controller/Taskmodification.php b/sources/app/Controller/Taskmodification.php index 306d34c..6b945f3 100644 --- a/sources/app/Controller/Taskmodification.php +++ b/sources/app/Controller/Taskmodification.php @@ -2,6 +2,8 @@ namespace Kanboard\Controller; +use Kanboard\Core\DateParser; + /** * Task Modification controller * @@ -35,7 +37,7 @@ class Taskmodification extends Base $values = array('id' => $task['id'], 'description' => $task['description']); } - $this->response->html($this->helper->layout->task('task_modification/edit_description', array( + $this->response->html($this->template->render('task_modification/edit_description', array( 'values' => $values, 'errors' => $errors, 'task' => $task, @@ -83,10 +85,10 @@ class Taskmodification extends Base $values = $this->hook->merge('controller:task-modification:form:default', $values, array('default_values' => $values)); } - $values = $this->dateParser->format($values, array('date_due'), $this->config->get('application_date_format', 'm/d/Y')); - $values = $this->dateParser->format($values, array('date_started'), $this->config->get('application_datetime_format', 'm/d/Y H:i')); + $values = $this->dateParser->format($values, array('date_due'), $this->config->get('application_date_format', DateParser::DATE_FORMAT)); + $values = $this->dateParser->format($values, array('date_started'), $this->config->get('application_datetime_format', DateParser::DATE_TIME_FORMAT)); - $this->response->html($this->helper->layout->task('task_modification/edit_task', array( + $this->response->html($this->template->render('task_modification/edit_task', array( 'project' => $project, 'values' => $values, 'errors' => $errors, diff --git a/sources/app/Controller/Taskstatus.php b/sources/app/Controller/Taskstatus.php index c07f2cc..a67459c 100644 --- a/sources/app/Controller/Taskstatus.php +++ b/sources/app/Controller/Taskstatus.php @@ -55,7 +55,7 @@ class Taskstatus extends Base return $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), true); } - $this->response->html($this->helper->layout->task($template, array( + $this->response->html($this->template->render($template, array( 'task' => $task, ))); } diff --git a/sources/app/Core/Base.php b/sources/app/Core/Base.php index f105311..74573e9 100644 --- a/sources/app/Core/Base.php +++ b/sources/app/Core/Base.php @@ -31,7 +31,6 @@ use Pimple\Container; * @property \Kanboard\Core\ObjectStorage\ObjectStorageInterface $objectStorage * @property \Kanboard\Core\Plugin\Hook $hook * @property \Kanboard\Core\Plugin\Loader $pluginLoader - * @property \Kanboard\Core\Security\AccessMap $projectAccessMap * @property \Kanboard\Core\Security\AuthenticationManager $authenticationManager * @property \Kanboard\Core\Security\AccessMap $applicationAccessMap * @property \Kanboard\Core\Security\AccessMap $projectAccessMap @@ -42,6 +41,7 @@ use Pimple\Container; * @property \Kanboard\Core\Session\FlashMessage $flash * @property \Kanboard\Core\Session\SessionManager $sessionManager * @property \Kanboard\Core\Session\SessionStorage $sessionStorage + * @property \Kanboard\Core\User\Avatar\AvatarManager $avatarManager * @property \Kanboard\Core\User\GroupSync $groupSync * @property \Kanboard\Core\User\UserProfile $userProfile * @property \Kanboard\Core\User\UserSync $userSync @@ -60,6 +60,7 @@ use Pimple\Container; * @property \Kanboard\Formatter\GroupAutoCompleteFormatter $groupAutoCompleteFormatter * @property \Kanboard\Model\Action $action * @property \Kanboard\Model\ActionParameter $actionParameter + * @property \Kanboard\Model\AvatarFile $avatarFile * @property \Kanboard\Model\Board $board * @property \Kanboard\Model\Category $category * @property \Kanboard\Model\Color $color @@ -75,11 +76,9 @@ use Pimple\Container; * @property \Kanboard\Model\LastLogin $lastLogin * @property \Kanboard\Model\Link $link * @property \Kanboard\Model\Notification $notification - * @property \Kanboard\Model\OverdueNotification $overdueNotification * @property \Kanboard\Model\PasswordReset $passwordReset * @property \Kanboard\Model\Project $project * @property \Kanboard\Model\ProjectActivity $projectActivity - * @property \Kanboard\Model\ProjectAnalytic $projectAnalytic * @property \Kanboard\Model\ProjectDuplication $projectDuplication * @property \Kanboard\Model\ProjectDailyColumnStats $projectDailyColumnStats * @property \Kanboard\Model\ProjectDailyStats $projectDailyStats @@ -92,16 +91,13 @@ use Pimple\Container; * @property \Kanboard\Model\ProjectNotificationType $projectNotificationType * @property \Kanboard\Model\RememberMeSession $rememberMeSession * @property \Kanboard\Model\Subtask $subtask - * @property \Kanboard\Model\SubtaskExport $subtaskExport * @property \Kanboard\Model\SubtaskTimeTracking $subtaskTimeTracking * @property \Kanboard\Model\Swimlane $swimlane * @property \Kanboard\Model\Task $task * @property \Kanboard\Model\TaskAnalytic $taskAnalytic * @property \Kanboard\Model\TaskCreation $taskCreation * @property \Kanboard\Model\TaskDuplication $taskDuplication - * @property \Kanboard\Model\TaskExport $taskExport * @property \Kanboard\Model\TaskExternalLink $taskExternalLink - * @property \Kanboard\Model\TaskImport $taskImport * @property \Kanboard\Model\TaskFinder $taskFinder * @property \Kanboard\Model\TaskFilter $taskFilter * @property \Kanboard\Model\TaskLink $taskLink @@ -112,7 +108,6 @@ use Pimple\Container; * @property \Kanboard\Model\TaskMetadata $taskMetadata * @property \Kanboard\Model\Transition $transition * @property \Kanboard\Model\User $user - * @property \Kanboard\Model\UserImport $userImport * @property \Kanboard\Model\UserLocking $userLocking * @property \Kanboard\Model\UserMention $userMention * @property \Kanboard\Model\UserNotification $userNotification @@ -120,12 +115,10 @@ use Pimple\Container; * @property \Kanboard\Model\UserNotificationFilter $userNotificationFilter * @property \Kanboard\Model\UserUnreadNotification $userUnreadNotification * @property \Kanboard\Model\UserMetadata $userMetadata - * @property \Kanboard\Model\Webhook $webhook * @property \Kanboard\Validator\ActionValidator $actionValidator * @property \Kanboard\Validator\AuthValidator $authValidator * @property \Kanboard\Validator\ColumnValidator $columnValidator * @property \Kanboard\Validator\CategoryValidator $categoryValidator - * @property \Kanboard\Validator\ColumnValidator $columnValidator * @property \Kanboard\Validator\CommentValidator $commentValidator * @property \Kanboard\Validator\CurrencyValidator $currencyValidator * @property \Kanboard\Validator\CustomFilterValidator $customFilterValidator @@ -136,9 +129,14 @@ use Pimple\Container; * @property \Kanboard\Validator\SubtaskValidator $subtaskValidator * @property \Kanboard\Validator\SwimlaneValidator $swimlaneValidator * @property \Kanboard\Validator\TaskLinkValidator $taskLinkValidator - * @property \Kanboard\Validator\TaskExternalLinkValidator $taskExternalLinkValidator + * @property \Kanboard\Validator\ExternalLinkValidator $externalLinkValidator * @property \Kanboard\Validator\TaskValidator $taskValidator * @property \Kanboard\Validator\UserValidator $userValidator + * @property \Kanboard\Import\TaskImport $taskImport + * @property \Kanboard\Import\UserImport $userImport + * @property \Kanboard\Export\SubtaskExport $subtaskExport + * @property \Kanboard\Export\TaskExport $taskExport + * @property \Kanboard\Export\TransitionExport $transitionExport * @property \Psr\Log\LoggerInterface $logger * @property \PicoDb\Database $db * @property \Symfony\Component\EventDispatcher\EventDispatcher $dispatcher diff --git a/sources/app/Core/Csv.php b/sources/app/Core/Csv.php index e45af24..8801016 100644 --- a/sources/app/Core/Csv.php +++ b/sources/app/Core/Csv.php @@ -87,7 +87,8 @@ class Csv * * @static * @access public - * @return integer + * @param mixed $value + * @return int */ public static function getBooleanValue($value) { diff --git a/sources/app/Core/DateParser.php b/sources/app/Core/DateParser.php index 20e79ff..835eb3e 100644 --- a/sources/app/Core/DateParser.php +++ b/sources/app/Core/DateParser.php @@ -12,6 +12,9 @@ use DateTime; */ class DateParser extends Base { + const DATE_FORMAT = 'm/d/Y'; + const DATE_TIME_FORMAT = 'm/d/Y H:i'; + /** * List of time formats * @@ -201,7 +204,7 @@ class DateParser extends Base } /** - * Get a timetstamp from an ISO date format + * Get a timestamp from an ISO date format * * @access public * @param string $value diff --git a/sources/app/Core/Helper.php b/sources/app/Core/Helper.php index bf71769..3a66fbd 100644 --- a/sources/app/Core/Helper.php +++ b/sources/app/Core/Helper.php @@ -10,17 +10,20 @@ use Pimple\Container; * @package core * @author Frederic Guillot * - * @property \Helper\App $app - * @property \Helper\Asset $asset - * @property \Helper\Dt $dt - * @property \Helper\File $file - * @property \Helper\Form $form - * @property \Helper\Subtask $subtask - * @property \Helper\Task $task - * @property \Helper\Text $text - * @property \Helper\Url $url - * @property \Helper\User $user - * @property \Helper\Layout $layout + * @property \Kanboard\Helper\AppHelper $app + * @property \Kanboard\Helper\AssetHelper $asset + * @property \Kanboard\Helper\DateHelper $dt + * @property \Kanboard\Helper\FileHelper $file + * @property \Kanboard\Helper\FormHelper $form + * @property \Kanboard\Helper\HookHelper $hook + * @property \Kanboard\Helper\ModelHelper $model + * @property \Kanboard\Helper\SubtaskHelper $subtask + * @property \Kanboard\Helper\TaskHelper $task + * @property \Kanboard\Helper\TextHelper $text + * @property \Kanboard\Helper\UrlHelper $url + * @property \Kanboard\Helper\UserHelper $user + * @property \Kanboard\Helper\LayoutHelper $layout + * @property \Kanboard\Helper\ProjectHeaderHelper $projectHeader */ class Helper { @@ -28,17 +31,17 @@ class Helper * Helper instances * * @access private - * @var array + * @var \Pimple\Container */ - private $helpers = array(); + private $helpers; /** * Container instance * - * @access protected + * @access private * @var \Pimple\Container */ - protected $container; + private $container; /** * Constructor @@ -49,33 +52,49 @@ class Helper public function __construct(Container $container) { $this->container = $container; + $this->helpers = new Container; } /** - * Load automatically helpers + * Expose helpers with magic getter * * @access public - * @param string $name Helper name + * @param string $helper * @return mixed */ - public function __get($name) + public function __get($helper) { - if (! isset($this->helpers[$name])) { - $class = '\Kanboard\Helper\\'.ucfirst($name); - $this->helpers[$name] = new $class($this->container); - } - - return $this->helpers[$name]; + return $this->getHelper($helper); } /** - * HTML escaping + * Expose helpers with method * - * @param string $value Value to escape - * @return string + * @access public + * @param string $helper + * @return mixed */ - public function e($value) + public function getHelper($helper) { - return htmlspecialchars($value, ENT_QUOTES, 'UTF-8', false); + return $this->helpers[$helper]; + } + + /** + * Register a new Helper + * + * @access public + * @param string $property + * @param string $className + * @return Helper + */ + public function register($property, $className) + { + $container = $this->container; + + $this->helpers[$property] = function() use($className, $container) { + return new $className($container); + }; + + return $this; } } diff --git a/sources/app/Core/Http/OAuth2.php b/sources/app/Core/Http/OAuth2.php index 6fa1fb0..211ca5b 100644 --- a/sources/app/Core/Http/OAuth2.php +++ b/sources/app/Core/Http/OAuth2.php @@ -12,14 +12,14 @@ use Kanboard\Core\Base; */ class OAuth2 extends Base { - private $clientId; - private $secret; - private $callbackUrl; - private $authUrl; - private $tokenUrl; - private $scopes; - private $tokenType; - private $accessToken; + protected $clientId; + protected $secret; + protected $callbackUrl; + protected $authUrl; + protected $tokenUrl; + protected $scopes; + protected $tokenType; + protected $accessToken; /** * Create OAuth2 service @@ -45,6 +45,33 @@ class OAuth2 extends Base return $this; } + /** + * Generate OAuth2 state and return the token value + * + * @access public + * @return string + */ + public function getState() + { + if (! isset($this->sessionStorage->oauthState) || empty($this->sessionStorage->oauthState)) { + $this->sessionStorage->oauthState = $this->token->getToken(); + } + + return $this->sessionStorage->oauthState; + } + + /** + * Check the validity of the state (CSRF token) + * + * @access public + * @param string $state + * @return bool + */ + public function isValidateState($state) + { + return $state === $this->getState(); + } + /** * Get authorization url * @@ -58,6 +85,7 @@ class OAuth2 extends Base 'client_id' => $this->clientId, 'redirect_uri' => $this->callbackUrl, 'scope' => implode(' ', $this->scopes), + 'state' => $this->getState(), ); return $this->authUrl.'?'.http_build_query($params); @@ -94,6 +122,7 @@ class OAuth2 extends Base 'client_secret' => $this->secret, 'redirect_uri' => $this->callbackUrl, 'grant_type' => 'authorization_code', + 'state' => $this->getState(), ); $response = json_decode($this->httpClient->postForm($this->tokenUrl, $params, array('Accept: application/json')), true); diff --git a/sources/app/Core/Http/Request.php b/sources/app/Core/Http/Request.php index 1b3036d..e0df2d3 100644 --- a/sources/app/Core/Http/Request.php +++ b/sources/app/Core/Http/Request.php @@ -29,7 +29,12 @@ class Request extends Base * Constructor * * @access public - * @param \Pimple\Container $container + * @param \Pimple\Container $container + * @param array $server + * @param array $get + * @param array $post + * @param array $files + * @param array $cookies */ public function __construct(Container $container, array $server = array(), array $get = array(), array $post = array(), array $files = array(), array $cookies = array()) { @@ -211,7 +216,11 @@ class Request extends Base */ public function isHTTPS() { - return isset($this->server['HTTPS']) && $this->server['HTTPS'] !== '' && $this->server['HTTPS'] !== 'off'; + if ($this->getServerVariable('HTTP_X_FORWARDED_PROTO') === 'https') { + return true; + } + + return $this->getServerVariable('HTTPS') !== '' && $this->server['HTTPS'] !== 'off'; } /** diff --git a/sources/app/Core/Http/Response.php b/sources/app/Core/Http/Response.php index d098f51..37349ca 100644 --- a/sources/app/Core/Http/Response.php +++ b/sources/app/Core/Http/Response.php @@ -13,6 +13,24 @@ use Kanboard\Core\Csv; */ class Response extends Base { + /** + * Send headers to cache a resource + * + * @access public + * @param integer $duration + * @param string $etag + */ + public function cache($duration, $etag = '') + { + header('Pragma: cache'); + header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $duration) . ' GMT'); + header('Cache-Control: public, max-age=' . $duration); + + if ($etag) { + header('ETag: "' . $etag . '"'); + } + } + /** * Send no cache headers * diff --git a/sources/app/Core/Ldap/Client.php b/sources/app/Core/Ldap/Client.php index 63149ae..867d67f 100644 --- a/sources/app/Core/Ldap/Client.php +++ b/sources/app/Core/Ldap/Client.php @@ -3,6 +3,7 @@ namespace Kanboard\Core\Ldap; use LogicException; +use Psr\Log\LoggerInterface; /** * LDAP Client @@ -20,6 +21,14 @@ class Client */ protected $ldap; + /** + * Logger instance + * + * @access private + * @var LoggerInterface + */ + private $logger; + /** * Establish LDAP connection * @@ -31,7 +40,7 @@ class Client */ public static function connect($username = null, $password = null) { - $client = new self; + $client = new static; $client->open($client->getLdapServer()); $username = $username ?: $client->getLdapUsername(); $password = $password ?: $client->getLdapPassword(); @@ -60,6 +69,7 @@ class Client * Establish server connection * * @access public + * @throws ClientException * @param string $server LDAP server hostname or IP * @param integer $port LDAP port * @param boolean $tls Start TLS @@ -98,6 +108,7 @@ class Client * Anonymous authentication * * @access public + * @throws ClientException * @return boolean */ public function useAnonymousAuthentication() @@ -113,6 +124,7 @@ class Client * Authentication with username/password * * @access public + * @throws ClientException * @param string $bind_rdn * @param string $bind_password * @return boolean @@ -162,4 +174,39 @@ class Client { return LDAP_PASSWORD; } + + /** + * Set logger + * + * @access public + * @param LoggerInterface $logger + * @return Client + */ + public function setLogger(LoggerInterface $logger) + { + $this->logger = $logger; + return $this; + } + + /** + * Get logger + * + * @access public + * @return LoggerInterface + */ + public function getLogger() + { + return $this->logger; + } + + /** + * Test if a logger is defined + * + * @access public + * @return boolean + */ + public function hasLogger() + { + return $this->logger !== null; + } } diff --git a/sources/app/Core/Ldap/Query.php b/sources/app/Core/Ldap/Query.php index e03495e..7c1524c 100644 --- a/sources/app/Core/Ldap/Query.php +++ b/sources/app/Core/Ldap/Query.php @@ -48,6 +48,12 @@ class Query */ public function execute($baseDn, $filter, array $attributes) { + if (DEBUG && $this->client->hasLogger()) { + $this->client->getLogger()->debug('BaseDN='.$baseDn); + $this->client->getLogger()->debug('Filter='.$filter); + $this->client->getLogger()->debug('Attributes='.implode(', ', $attributes)); + } + $sr = ldap_search($this->client->getConnection(), $baseDn, $filter, $attributes); if ($sr === false) { return $this; @@ -78,7 +84,7 @@ class Query * Get LDAP Entries * * @access public - * @return Entities + * @return Entries */ public function getEntries() { diff --git a/sources/app/Core/Ldap/User.php b/sources/app/Core/Ldap/User.php index d36d6f3..d23ec07 100644 --- a/sources/app/Core/Ldap/User.php +++ b/sources/app/Core/Ldap/User.php @@ -44,8 +44,7 @@ class User */ public static function getUser(Client $client, $username) { - $className = get_called_class(); - $self = new $className(new Query($client)); + $self = new static(new Query($client)); return $self->find($self->getLdapUserPattern($username)); } @@ -211,14 +210,15 @@ class User * * @access public * @param string $username + * @param string $filter * @return string */ - public function getLdapUserPattern($username) + public function getLdapUserPattern($username, $filter = LDAP_USER_FILTER) { - if (! LDAP_USER_FILTER) { + if (! $filter) { throw new LogicException('LDAP user filter empty, check the parameter LDAP_USER_FILTER'); } - return sprintf(LDAP_USER_FILTER, $username); + return str_replace('%s', $username, $filter); } } diff --git a/sources/app/Core/Mail/Client.php b/sources/app/Core/Mail/Client.php index e1f3169..641b6ab 100644 --- a/sources/app/Core/Mail/Client.php +++ b/sources/app/Core/Mail/Client.php @@ -41,7 +41,7 @@ class Client extends Base * @param string $name * @param string $subject * @param string $html - * @return EmailClient + * @return Client */ public function send($email, $name, $subject, $html) { @@ -70,7 +70,7 @@ class Client extends Base * * @access public * @param string $transport - * @return EmailClientInterface + * @return ClientInterface */ public function getTransport($transport) { @@ -83,7 +83,7 @@ class Client extends Base * @access public * @param string $transport * @param string $class - * @return EmailClient + * @return Client */ public function setTransport($transport, $class) { diff --git a/sources/app/Core/ObjectStorage/FileStorage.php b/sources/app/Core/ObjectStorage/FileStorage.php index dd049ca..1845389 100644 --- a/sources/app/Core/ObjectStorage/FileStorage.php +++ b/sources/app/Core/ObjectStorage/FileStorage.php @@ -33,6 +33,7 @@ class FileStorage implements ObjectStorageInterface * Fetch object contents * * @access public + * @throws ObjectStorageException * @param string $key * @return string */ @@ -51,6 +52,7 @@ class FileStorage implements ObjectStorageInterface * Save object * * @access public + * @throws ObjectStorageException * @param string $key * @param string $blob */ @@ -67,6 +69,7 @@ class FileStorage implements ObjectStorageInterface * Output directly object content * * @access public + * @throws ObjectStorageException * @param string $key */ public function output($key) @@ -84,6 +87,7 @@ class FileStorage implements ObjectStorageInterface * Move local file to object storage * * @access public + * @throws ObjectStorageException * @param string $src_filename * @param string $key * @return boolean @@ -136,6 +140,7 @@ class FileStorage implements ObjectStorageInterface * Create object folder * * @access private + * @throws ObjectStorageException * @param string $key */ private function createFolder($key) diff --git a/sources/app/Core/Plugin/Base.php b/sources/app/Core/Plugin/Base.php index 1526537..381b8bb 100644 --- a/sources/app/Core/Plugin/Base.php +++ b/sources/app/Core/Plugin/Base.php @@ -40,6 +40,17 @@ abstract class Base extends \Kanboard\Core\Base return array(); } + /** + * Returns all helper classes that needs to be stored in the DI container + * + * @access public + * @return array + */ + public function getHelpers() + { + return array(); + } + /** * Listen on internal events * diff --git a/sources/app/Core/Plugin/Loader.php b/sources/app/Core/Plugin/Loader.php index 530d9b4..775673d 100644 --- a/sources/app/Core/Plugin/Loader.php +++ b/sources/app/Core/Plugin/Loader.php @@ -55,6 +55,7 @@ class Loader extends \Kanboard\Core\Base * Load plugin * * @access public + * @throws LogicException * @param string $plugin */ public function load($plugin) @@ -69,6 +70,8 @@ class Loader extends \Kanboard\Core\Base Tool::buildDic($this->container, $instance->getClasses()); + Tool::buildDICHelpers($this->container, $instance->getHelpers()); + $instance->initialize(); $this->plugins[] = $instance; } diff --git a/sources/app/Core/Security/AccessMap.php b/sources/app/Core/Security/AccessMap.php index f34c4b0..2431a92 100644 --- a/sources/app/Core/Security/AccessMap.php +++ b/sources/app/Core/Security/AccessMap.php @@ -39,7 +39,7 @@ class AccessMap * * @access public * @param string $role - * @return Acl + * @return AccessMap */ public function setDefaultRole($role) { @@ -53,7 +53,7 @@ class AccessMap * @access public * @param string $role * @param array $subroles - * @return Acl + * @return AccessMap */ public function setRoleHierarchy($role, array $subroles) { @@ -113,7 +113,7 @@ class AccessMap * @param string $controller Controller class name * @param mixed $methods List of method name or just one method * @param string $role Lowest role required - * @return Acl + * @return AccessMap */ public function add($controller, $methods, $role) { @@ -135,7 +135,7 @@ class AccessMap * @param string $controller * @param string $method * @param string $role - * @return Acl + * @return AccessMap */ private function addRule($controller, $method, $role) { @@ -157,7 +157,7 @@ class AccessMap * @access public * @param string $controller * @param string $method - * @return boolean + * @return array */ public function getRoles($controller, $method) { diff --git a/sources/app/Core/Security/OAuthAuthenticationProviderInterface.php b/sources/app/Core/Security/OAuthAuthenticationProviderInterface.php index c32339e..3092672 100644 --- a/sources/app/Core/Security/OAuthAuthenticationProviderInterface.php +++ b/sources/app/Core/Security/OAuthAuthenticationProviderInterface.php @@ -14,7 +14,7 @@ interface OAuthAuthenticationProviderInterface extends AuthenticationProviderInt * Get user object * * @access public - * @return UserProviderInterface + * @return \Kanboard\Core\User\UserProviderInterface */ public function getUser(); @@ -31,7 +31,7 @@ interface OAuthAuthenticationProviderInterface extends AuthenticationProviderInt * Get configured OAuth2 service * * @access public - * @return Kanboard\Core\Http\OAuth2 + * @return \Kanboard\Core\Http\OAuth2 */ public function getService(); diff --git a/sources/app/Core/Security/PasswordAuthenticationProviderInterface.php b/sources/app/Core/Security/PasswordAuthenticationProviderInterface.php index 918a4ae..c230454 100644 --- a/sources/app/Core/Security/PasswordAuthenticationProviderInterface.php +++ b/sources/app/Core/Security/PasswordAuthenticationProviderInterface.php @@ -14,7 +14,7 @@ interface PasswordAuthenticationProviderInterface extends AuthenticationProvider * Get user object * * @access public - * @return UserProviderInterface + * @return \Kanboard\Core\User\UserProviderInterface */ public function getUser(); diff --git a/sources/app/Core/Security/PreAuthenticationProviderInterface.php b/sources/app/Core/Security/PreAuthenticationProviderInterface.php index 391e8d0..c13b06c 100644 --- a/sources/app/Core/Security/PreAuthenticationProviderInterface.php +++ b/sources/app/Core/Security/PreAuthenticationProviderInterface.php @@ -14,7 +14,7 @@ interface PreAuthenticationProviderInterface extends AuthenticationProviderInter * Get user object * * @access public - * @return UserProviderInterface + * @return \Kanboard\Core\User\UserProviderInterface */ public function getUser(); } diff --git a/sources/app/Core/Session/SessionStorage.php b/sources/app/Core/Session/SessionStorage.php index 667d925..6e2f966 100644 --- a/sources/app/Core/Session/SessionStorage.php +++ b/sources/app/Core/Session/SessionStorage.php @@ -21,6 +21,7 @@ namespace Kanboard\Core\Session; * @property bool $boardCollapsed * @property bool $twoFactorBeforeCodeCalled * @property string $twoFactorSecret + * @property string $oauthState */ class SessionStorage { diff --git a/sources/app/Core/Template.php b/sources/app/Core/Template.php index 8ded6f7..1874d44 100644 --- a/sources/app/Core/Template.php +++ b/sources/app/Core/Template.php @@ -3,13 +3,36 @@ namespace Kanboard\Core; /** - * Template class + * Template * * @package core * @author Frederic Guillot + * + * @property \Kanboard\Helper\AppHelper $app + * @property \Kanboard\Helper\AssetHelper $asset + * @property \Kanboard\Helper\DateHelper $dt + * @property \Kanboard\Helper\FileHelper $file + * @property \Kanboard\Helper\FormHelper $form + * @property \Kanboard\Helper\HookHelper $hook + * @property \Kanboard\Helper\ModelHelper $model + * @property \Kanboard\Helper\SubtaskHelper $subtask + * @property \Kanboard\Helper\TaskHelper $task + * @property \Kanboard\Helper\TextHelper $text + * @property \Kanboard\Helper\UrlHelper $url + * @property \Kanboard\Helper\UserHelper $user + * @property \Kanboard\Helper\LayoutHelper $layout + * @property \Kanboard\Helper\ProjectHeaderHelper $projectHeader */ -class Template extends Helper +class Template { + /** + * Helper object + * + * @access private + * @var Helper + */ + private $helper; + /** * List of template overrides * @@ -19,47 +42,26 @@ class Template extends Helper private $overrides = array(); /** - * Rendering start time + * Template constructor * - * @access private - * @var float + * @access public + * @param Helper $helper */ - private $startTime = 0; - - /** - * Total rendering time - * - * @access private - * @var float - */ - private $renderingTime = 0; - - /** - * Method executed before the rendering - * - * @access protected - * @param string $template - */ - protected function beforeRender($template) + public function __construct(Helper $helper) { - if (DEBUG) { - $this->startTime = microtime(true); - } + $this->helper = $helper; } /** - * Method executed after the rendering + * Expose helpers with magic getter * - * @access protected - * @param string $template + * @access public + * @param string $helper + * @return mixed */ - protected function afterRender($template) + public function __get($helper) { - if (DEBUG) { - $duration = microtime(true) - $this->startTime; - $this->renderingTime += $duration; - $this->container['logger']->debug('Rendering '.$template.' in '.$duration.'s, total='.$this->renderingTime); - } + return $this->helper->getHelper($helper); } /** @@ -76,33 +78,10 @@ class Template extends Helper */ public function render($__template_name, array $__template_args = array()) { - $this->beforeRender($__template_name); - extract($__template_args); ob_start(); include $this->getTemplateFile($__template_name); - $html = ob_get_clean(); - - $this->afterRender($__template_name); - - return $html; - } - - /** - * Render a page layout - * - * @access public - * @param string $template_name Template name - * @param array $template_args Key/value map - * @param string $layout_name Layout name - * @return string - */ - public function layout($template_name, array $template_args = array(), $layout_name = 'layout') - { - return $this->render( - $layout_name, - $template_args + array('content_for_layout' => $this->render($template_name, $template_args)) - ); + return ob_get_clean(); } /** @@ -120,25 +99,26 @@ class Template extends Helper /** * Find template filename * - * Core template name: 'task/show' - * Plugin template name: 'myplugin:task/show' + * Core template: 'task/show' or 'kanboard:task/show' + * Plugin template: 'myplugin:task/show' * * @access public - * @param string $template_name + * @param string $template * @return string */ - public function getTemplateFile($template_name) + public function getTemplateFile($template) { - $template_name = isset($this->overrides[$template_name]) ? $this->overrides[$template_name] : $template_name; + $plugin = ''; + $template = isset($this->overrides[$template]) ? $this->overrides[$template] : $template; - if (strpos($template_name, ':') !== false) { - list($plugin, $template) = explode(':', $template_name); - $path = __DIR__.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'plugins'; - $path .= DIRECTORY_SEPARATOR.ucfirst($plugin).DIRECTORY_SEPARATOR.'Template'.DIRECTORY_SEPARATOR.$template.'.php'; - } else { - $path = __DIR__.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'Template'.DIRECTORY_SEPARATOR.$template_name.'.php'; + if (strpos($template, ':') !== false) { + list($plugin, $template) = explode(':', $template); } - return $path; + if ($plugin !== 'kanboard' && $plugin !== '') { + return implode(DIRECTORY_SEPARATOR, array(__DIR__, '..', '..', 'plugins', ucfirst($plugin), 'Template', $template.'.php')); + } + + return implode(DIRECTORY_SEPARATOR, array(__DIR__, '..', 'Template', $template.'.php')); } } diff --git a/sources/app/Core/Thumbnail.php b/sources/app/Core/Thumbnail.php new file mode 100644 index 0000000..733d3a3 --- /dev/null +++ b/sources/app/Core/Thumbnail.php @@ -0,0 +1,172 @@ +fromFile($filename); + return $self; + } + + /** + * Create a thumbnail from a string + * + * @static + * @access public + * @param string $blob + * @return Thumbnail + */ + public static function createFromString($blob) + { + $self = new static(); + $self->fromString($blob); + return $self; + } + + /** + * Load the local image file in memory with GD + * + * @access public + * @param string $filename + * @return Thumbnail + */ + public function fromFile($filename) + { + $this->metadata = getimagesize($filename); + $this->srcImage = imagecreatefromstring(file_get_contents($filename)); + return $this; + } + + /** + * Load the image blob in memory with GD + * + * @access public + * @param string $blob + * @return Thumbnail + */ + public function fromString($blob) + { + if (!function_exists('getimagesizefromstring')) { + $uri = 'data://application/octet-stream;base64,' . base64_encode($blob); + $this->metadata = getimagesize($uri); + } else { + $this->metadata = getimagesizefromstring($blob); + } + + $this->srcImage = imagecreatefromstring($blob); + return $this; + } + + /** + * Resize the image + * + * @access public + * @param int $width + * @param int $height + * @return Thumbnail + */ + public function resize($width = 250, $height = 100) + { + $srcWidth = $this->metadata[0]; + $srcHeight = $this->metadata[1]; + $dstX = 0; + $dstY = 0; + + if ($width == 0 && $height == 0) { + $width = 100; + $height = 100; + } + + if ($width > 0 && $height == 0) { + $dstWidth = $width; + $dstHeight = floor($srcHeight * ($width / $srcWidth)); + $this->dstImage = imagecreatetruecolor($dstWidth, $dstHeight); + } elseif ($width == 0 && $height > 0) { + $dstWidth = floor($srcWidth * ($height / $srcHeight)); + $dstHeight = $height; + $this->dstImage = imagecreatetruecolor($dstWidth, $dstHeight); + } else { + $srcRatio = $srcWidth / $srcHeight; + $resizeRatio = $width / $height; + + if ($srcRatio <= $resizeRatio) { + $dstWidth = $width; + $dstHeight = floor($srcHeight * ($width / $srcWidth)); + $dstY = ($dstHeight - $height) / 2 * (-1); + } else { + $dstWidth = floor($srcWidth * ($height / $srcHeight)); + $dstHeight = $height; + $dstX = ($dstWidth - $width) / 2 * (-1); + } + + $this->dstImage = imagecreatetruecolor($width, $height); + } + + imagecopyresampled($this->dstImage, $this->srcImage, $dstX, $dstY, 0, 0, $dstWidth, $dstHeight, $srcWidth, $srcHeight); + + return $this; + } + + /** + * Save the thumbnail to a local file + * + * @access public + * @param string $filename + * @return Thumbnail + */ + public function toFile($filename) + { + imagejpeg($this->dstImage, $filename); + imagedestroy($this->dstImage); + imagedestroy($this->srcImage); + return $this; + } + + /** + * Return the thumbnail as a string + * + * @access public + * @return string + */ + public function toString() + { + ob_start(); + imagejpeg($this->dstImage, null); + imagedestroy($this->dstImage); + imagedestroy($this->srcImage); + return ob_get_clean(); + } + + /** + * Output the thumbnail directly to the browser or stdout + * + * @access public + */ + public function toOutput() + { + imagejpeg($this->dstImage, null); + imagedestroy($this->dstImage); + imagedestroy($this->srcImage); + } +} diff --git a/sources/app/Core/Tool.php b/sources/app/Core/Tool.php index edd2e60..3423998 100644 --- a/sources/app/Core/Tool.php +++ b/sources/app/Core/Tool.php @@ -56,76 +56,23 @@ class Tool } /** - * Generate a jpeg thumbnail from an image + * Build dependency injection container for custom helpers from an array * * @static * @access public - * @param string $src_file Source file image - * @param string $dst_file Destination file image - * @param integer $resize_width Desired image width - * @param integer $resize_height Desired image height + * @param Container $container + * @param array $namespaces + * @return Container */ - public static function generateThumbnail($src_file, $dst_file, $resize_width = 250, $resize_height = 100) + public static function buildDICHelpers(Container $container, array $namespaces) { - $metadata = getimagesize($src_file); - $src_width = $metadata[0]; - $src_height = $metadata[1]; - $dst_y = 0; - $dst_x = 0; - - if (empty($metadata['mime'])) { - return; - } - - if ($resize_width == 0 && $resize_height == 0) { - $resize_width = 100; - $resize_height = 100; - } - - if ($resize_width > 0 && $resize_height == 0) { - $dst_width = $resize_width; - $dst_height = floor($src_height * ($resize_width / $src_width)); - $dst_image = imagecreatetruecolor($dst_width, $dst_height); - } elseif ($resize_width == 0 && $resize_height > 0) { - $dst_width = floor($src_width * ($resize_height / $src_height)); - $dst_height = $resize_height; - $dst_image = imagecreatetruecolor($dst_width, $dst_height); - } else { - $src_ratio = $src_width / $src_height; - $resize_ratio = $resize_width / $resize_height; - - if ($src_ratio <= $resize_ratio) { - $dst_width = $resize_width; - $dst_height = floor($src_height * ($resize_width / $src_width)); - - $dst_y = ($dst_height - $resize_height) / 2 * (-1); - } else { - $dst_width = floor($src_width * ($resize_height / $src_height)); - $dst_height = $resize_height; - - $dst_x = ($dst_width - $resize_width) / 2 * (-1); + foreach ($namespaces as $namespace => $classes) { + foreach ($classes as $name) { + $class = '\\Kanboard\\'.$namespace.'\\'.$name; + $container['helper']->register($name, $class); } - - $dst_image = imagecreatetruecolor($resize_width, $resize_height); } - switch ($metadata['mime']) { - case 'image/jpeg': - case 'image/jpg': - $src_image = imagecreatefromjpeg($src_file); - break; - case 'image/png': - $src_image = imagecreatefrompng($src_file); - break; - case 'image/gif': - $src_image = imagecreatefromgif($src_file); - break; - default: - return; - } - - imagecopyresampled($dst_image, $src_image, $dst_x, $dst_y, 0, 0, $dst_width, $dst_height, $src_width, $src_height); - imagejpeg($dst_image, $dst_file); - imagedestroy($dst_image); + return $container; } } diff --git a/sources/app/Core/User/Avatar/AvatarManager.php b/sources/app/Core/User/Avatar/AvatarManager.php new file mode 100644 index 0000000..5b61cbd --- /dev/null +++ b/sources/app/Core/User/Avatar/AvatarManager.php @@ -0,0 +1,93 @@ +providers[] = $provider; + return $this; + } + + /** + * Render avatar HTML element + * + * @access public + * @param string $user_id + * @param string $username + * @param string $name + * @param string $email + * @param string $avatar_path + * @param int $size + * @return string + */ + public function render($user_id, $username, $name, $email, $avatar_path, $size) + { + $user = array( + 'id' => $user_id, + 'username' => $username, + 'name' => $name, + 'email' => $email, + 'avatar_path' => $avatar_path, + ); + + krsort($this->providers); + + foreach ($this->providers as $provider) { + if ($provider->isActive($user)) { + return $provider->render($user, $size); + } + } + + return ''; + } + + /** + * Render default provider for unknown users (first provider registered) + * + * @access public + * @param integer $size + * @return string + */ + public function renderDefault($size) + { + if (count($this->providers) > 0) { + ksort($this->providers); + $provider = current($this->providers); + + $user = array( + 'id' => 0, + 'username' => '', + 'name' => '?', + 'email' => '', + 'avatar_path' => '', + ); + + return $provider->render($user, $size); + } + + return ''; + } +} diff --git a/sources/app/Core/User/Avatar/AvatarProviderInterface.php b/sources/app/Core/User/Avatar/AvatarProviderInterface.php new file mode 100644 index 0000000..e0375d2 --- /dev/null +++ b/sources/app/Core/User/Avatar/AvatarProviderInterface.php @@ -0,0 +1,30 @@ +getId() == $user_id) { + $this->initialize($this->user->getById($user_id)); + } + } + /** * Update user session * @@ -35,6 +48,17 @@ class UserSession extends Base $this->sessionStorage->postAuthenticationValidated = false; } + /** + * Get user properties + * + * @access public + * @return array + */ + public function getAll() + { + return $this->sessionStorage->user; + } + /** * Get user application role * diff --git a/sources/app/Model/SubtaskExport.php b/sources/app/Export/SubtaskExport.php similarity index 95% rename from sources/app/Model/SubtaskExport.php rename to sources/app/Export/SubtaskExport.php index 7c4e941..386c566 100644 --- a/sources/app/Model/SubtaskExport.php +++ b/sources/app/Export/SubtaskExport.php @@ -1,11 +1,16 @@ dateParser->format($task, array('date_due', 'date_modification', 'date_creation', 'date_started', 'date_completed'), 'Y-m-d'); + $task = $this->dateParser->format($task, array('date_due', 'date_modification', 'date_creation', 'date_started', 'date_completed'), DateParser::DATE_FORMAT); return $task; } diff --git a/sources/app/Export/TransitionExport.php b/sources/app/Export/TransitionExport.php new file mode 100644 index 0000000..97dc28a --- /dev/null +++ b/sources/app/Export/TransitionExport.php @@ -0,0 +1,77 @@ +getColumns()); + $transitions = $this->transition->getAllByProjectAndDate($project_id, $from, $to); + + foreach ($transitions as $transition) { + $results[] = $this->format($transition); + } + + return $results; + } + + /** + * Get column titles + * + * @access protected + * @return string[] + */ + protected function getColumns() + { + return array( + e('Id'), + e('Task Title'), + e('Source column'), + e('Destination column'), + e('Executer'), + e('Date'), + e('Time spent'), + ); + } + + /** + * Format the output of a transition array + * + * @access protected + * @param array $transition + * @return array + */ + protected function format(array $transition) + { + $values = array( + (int) $transition['id'], + $transition['title'], + $transition['src_column'], + $transition['dst_column'], + $transition['name'] ?: $transition['username'], + date($this->config->get('application_datetime_format', DateParser::DATE_TIME_FORMAT), $transition['date']), + round($transition['time_spent'] / 3600, 2) + ); + + return $values; + } +} diff --git a/sources/app/ExternalLink/AttachmentLinkProvider.php b/sources/app/ExternalLink/AttachmentLinkProvider.php index df27284..706ac1d 100644 --- a/sources/app/ExternalLink/AttachmentLinkProvider.php +++ b/sources/app/ExternalLink/AttachmentLinkProvider.php @@ -85,7 +85,7 @@ class AttachmentLinkProvider extends BaseLinkProvider implements ExternalLinkPro * Get the link found with the properties * * @access public - * @return ExternalLinkInterface + * @return \Kanboard\Core\ExternalLink\ExternalLinkInterface */ public function getLink() { diff --git a/sources/app/ExternalLink/FileLink.php b/sources/app/ExternalLink/FileLink.php new file mode 100644 index 0000000..ea13ece --- /dev/null +++ b/sources/app/ExternalLink/FileLink.php @@ -0,0 +1,26 @@ +url, PHP_URL_PATH); + return basename(str_replace('\\', '/', $path)); + } +} diff --git a/sources/app/ExternalLink/FileLinkProvider.php b/sources/app/ExternalLink/FileLinkProvider.php new file mode 100644 index 0000000..901f78f --- /dev/null +++ b/sources/app/ExternalLink/FileLinkProvider.php @@ -0,0 +1,74 @@ + t('Related'), + ); + } + + /** + * Return true if the provider can parse correctly the user input + * + * @access public + * @return boolean + */ + public function match() + { + return strpos($this->userInput, 'file://') === 0; + } + + /** + * Get the link found with the properties + * + * @access public + * @return \Kanboard\Core\ExternalLink\ExternalLinkInterface + */ + public function getLink() + { + $link = new FileLink($this->container); + $link->setUrl($this->userInput); + + return $link; + } +} diff --git a/sources/app/ExternalLink/WebLinkProvider.php b/sources/app/ExternalLink/WebLinkProvider.php index ea6dc13..5ec1bbe 100644 --- a/sources/app/ExternalLink/WebLinkProvider.php +++ b/sources/app/ExternalLink/WebLinkProvider.php @@ -65,7 +65,7 @@ class WebLinkProvider extends BaseLinkProvider implements ExternalLinkProviderIn * Get the link found with the properties * * @access public - * @return ExternalLinkInterface + * @return \Kanboard\Core\ExternalLink\ExternalLinkInterface */ public function getLink() { diff --git a/sources/app/Helper/App.php b/sources/app/Helper/AppHelper.php similarity index 94% rename from sources/app/Helper/App.php rename to sources/app/Helper/AppHelper.php index 79afa5b..e6f6412 100644 --- a/sources/app/Helper/App.php +++ b/sources/app/Helper/AppHelper.php @@ -5,12 +5,12 @@ namespace Kanboard\Helper; use Kanboard\Core\Base; /** - * Application helpers + * Application Helper * * @package helper * @author Frederic Guillot */ -class App extends Base +class AppHelper extends Base { /** * Get config variable @@ -116,11 +116,11 @@ class App extends Base $failure_message = $this->flash->getMessage('failure'); if (! empty($success_message)) { - return '
'.$this->helper->e($success_message).'
'; + return '
'.$this->helper->text->e($success_message).'
'; } if (! empty($failure_message)) { - return '
'.$this->helper->e($failure_message).'
'; + return '
'.$this->helper->text->e($failure_message).'
'; } return ''; diff --git a/sources/app/Helper/Asset.php b/sources/app/Helper/AssetHelper.php similarity index 90% rename from sources/app/Helper/Asset.php rename to sources/app/Helper/AssetHelper.php index c4178e8..b3dc711 100644 --- a/sources/app/Helper/Asset.php +++ b/sources/app/Helper/AssetHelper.php @@ -2,18 +2,21 @@ namespace Kanboard\Helper; +use Kanboard\Core\Base; + /** - * Assets helpers + * Asset Helper * * @package helper * @author Frederic Guillot */ -class Asset extends \Kanboard\Core\Base +class AssetHelper extends Base { /** * Add a Javascript asset * - * @param string $filename Filename + * @param string $filename Filename + * @param bool $async * @return string */ public function js($filename, $async = false) diff --git a/sources/app/Helper/AvatarHelper.php b/sources/app/Helper/AvatarHelper.php new file mode 100644 index 0000000..a36d9b4 --- /dev/null +++ b/sources/app/Helper/AvatarHelper.php @@ -0,0 +1,68 @@ +avatarManager->renderDefault($size); + } else { + $html = $this->avatarManager->render($user_id, $username, $name, $email, $avatar_path, $size); + } + + return '
'.$html.'
'; + } + + /** + * Render small user avatar + * + * @access public + * @param string $user_id + * @param string $username + * @param string $name + * @param string $email + * @param string $avatar_path + * @param string $css + * @return string + */ + public function small($user_id, $username, $name, $email, $avatar_path, $css = '') + { + return $this->render($user_id, $username, $name, $email, $avatar_path, $css, 20); + } + + /** + * Get a small avatar for the current user + * + * @access public + * @param string $css + * @return string + */ + public function currentUserSmall($css = '') + { + $user = $this->userSession->getAll(); + return $this->small($user['id'], $user['username'], $user['name'], $user['email'], $user['avatar_path'], $css); + } +} diff --git a/sources/app/Helper/Board.php b/sources/app/Helper/BoardHelper.php similarity index 87% rename from sources/app/Helper/Board.php rename to sources/app/Helper/BoardHelper.php index 430d185..a86a6c1 100644 --- a/sources/app/Helper/Board.php +++ b/sources/app/Helper/BoardHelper.php @@ -2,13 +2,15 @@ namespace Kanboard\Helper; +use Kanboard\Core\Base; + /** * Board Helper * * @package helper * @author Frederic Guillot */ -class Board extends \Kanboard\Core\Base +class BoardHelper extends Base { /** * Return true if tasks are collapsed diff --git a/sources/app/Helper/Dt.php b/sources/app/Helper/DateHelper.php similarity index 98% rename from sources/app/Helper/Dt.php rename to sources/app/Helper/DateHelper.php index eb3f93b..3844ce6 100644 --- a/sources/app/Helper/Dt.php +++ b/sources/app/Helper/DateHelper.php @@ -3,6 +3,7 @@ namespace Kanboard\Helper; use DateTime; +use Kanboard\Core\Base; /** * DateTime helpers @@ -10,7 +11,7 @@ use DateTime; * @package helper * @author Frederic Guillot */ -class Dt extends \Kanboard\Core\Base +class DateHelper extends Base { /** * Get formatted time diff --git a/sources/app/Helper/File.php b/sources/app/Helper/FileHelper.php similarity index 97% rename from sources/app/Helper/File.php rename to sources/app/Helper/FileHelper.php index b493e64..cabf371 100644 --- a/sources/app/Helper/File.php +++ b/sources/app/Helper/FileHelper.php @@ -2,13 +2,15 @@ namespace Kanboard\Helper; +use Kanboard\Core\Base; + /** * File helpers * * @package helper * @author Frederic Guillot */ -class File extends \Kanboard\Core\Base +class FileHelper extends Base { /** * Get file icon diff --git a/sources/app/Helper/Form.php b/sources/app/Helper/FormHelper.php similarity index 90% rename from sources/app/Helper/Form.php rename to sources/app/Helper/FormHelper.php index bfd75ee..c2ea1d7 100644 --- a/sources/app/Helper/Form.php +++ b/sources/app/Helper/FormHelper.php @@ -10,7 +10,7 @@ use Kanboard\Core\Base; * @package helper * @author Frederic Guillot */ -class Form extends Base +class FormHelper extends Base { /** * Hidden CSRF token field @@ -40,11 +40,12 @@ class Form extends Base * Display a select field * * @access public - * @param string $name Field name - * @param array $options Options - * @param array $values Form values - * @param array $errors Form errors - * @param string $class CSS class + * @param string $name Field name + * @param array $options Options + * @param array $values Form values + * @param array $errors Form errors + * @param array $attributes + * @param string $class CSS class * @return string */ public function select($name, array $options, array $values = array(), array $errors = array(), array $attributes = array(), $class = '') @@ -52,7 +53,7 @@ class Form extends Base $html = ''; @@ -103,7 +104,7 @@ class Form extends Base */ public function radio($name, $label, $value, $selected = false, $class = '') { - return ''; + return ''; } /** @@ -139,7 +140,7 @@ class Form extends Base */ public function checkbox($name, $label, $value, $checked = false, $class = '') { - return ''; + return ''; } /** @@ -153,7 +154,7 @@ class Form extends Base */ public function label($label, $name, array $attributes = array()) { - return ''; + return ''; } /** @@ -173,7 +174,7 @@ class Form extends Base $html = ''; $html .= $this->errorList($errors, $name); @@ -334,7 +335,7 @@ class Form extends Base $html .= ''; @@ -354,9 +355,9 @@ class Form extends Base private function formValue($values, $name) { if (isset($values->$name)) { - return 'value="'.$this->helper->e($values->$name).'"'; + return 'value="'.$this->helper->text->e($values->$name).'"'; } - return isset($values[$name]) ? 'value="'.$this->helper->e($values[$name]).'"' : ''; + return isset($values[$name]) ? 'value="'.$this->helper->text->e($values[$name]).'"' : ''; } } diff --git a/sources/app/Helper/Hook.php b/sources/app/Helper/HookHelper.php similarity index 92% rename from sources/app/Helper/Hook.php rename to sources/app/Helper/HookHelper.php index 7b69194..2d13ebc 100644 --- a/sources/app/Helper/Hook.php +++ b/sources/app/Helper/HookHelper.php @@ -2,13 +2,15 @@ namespace Kanboard\Helper; +use Kanboard\Core\Base; + /** * Template Hook helpers * * @package helper * @author Frederic Guillot */ -class Hook extends \Kanboard\Core\Base +class HookHelper extends Base { /** * Add assets JS or CSS @@ -54,7 +56,7 @@ class Hook extends \Kanboard\Core\Base * @access public * @param string $hook * @param string $template - * @return \Helper\Hook + * @return \Kanboard\Helper\Hook */ public function attach($hook, $template) { diff --git a/sources/app/Helper/Layout.php b/sources/app/Helper/LayoutHelper.php similarity index 85% rename from sources/app/Helper/Layout.php rename to sources/app/Helper/LayoutHelper.php index 3db2392..9384da1 100644 --- a/sources/app/Helper/Layout.php +++ b/sources/app/Helper/LayoutHelper.php @@ -5,12 +5,12 @@ namespace Kanboard\Helper; use Kanboard\Core\Base; /** - * Layout helpers + * Layout Helper * * @package helper * @author Frederic Guillot */ -class Layout extends Base +class LayoutHelper extends Base { /** * Render a template without the layout if Ajax request @@ -30,7 +30,7 @@ class Layout extends Base $params['board_selector'] = $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId()); } - return $this->template->layout($template, $params); + return $this->pageLayout($template, $params); } /** @@ -60,7 +60,7 @@ class Layout extends Base */ public function task($template, array $params) { - $params['title'] = $params['task']['title']; + $params['title'] = $params['task']['project_name']; return $this->subLayout('task/layout', 'task/sidebar', $template, $params); } @@ -146,7 +146,24 @@ class Layout extends Base } /** - * Common method to generate a sublayout + * Render page layout + * + * @access public + * @param string $template Template name + * @param array $params Key/value dictionary + * @param string $layout Layout name + * @return string + */ + public function pageLayout($template, array $params = array(), $layout = 'layout') + { + return $this->template->render( + $layout, + $params + array('content_for_layout' => $this->template->render($template, $params)) + ); + } + + /** + * Common method to generate a sub-layout * * @access public * @param string $sublayout diff --git a/sources/app/Helper/ModelHelper.php b/sources/app/Helper/ModelHelper.php new file mode 100644 index 0000000..d49637c --- /dev/null +++ b/sources/app/Helper/ModelHelper.php @@ -0,0 +1,94 @@ +request->getStringParam('search', $this->userSession->getFilters($project['id'])); + $this->userSession->setFilters($project['id'], $search); + return urldecode($search); + } + + /** + * Render project header (views switcher and search box) + * + * @access public + * @param array $project + * @param string $controller + * @param string $action + * @param bool $boardView + * @return string + */ + public function render(array $project, $controller, $action, $boardView = false) + { + $filters = array( + 'controller' => $controller, + 'action' => $action, + 'project_id' => $project['id'], + 'search' => $this->getSearchQuery($project), + ); + + return $this->template->render('project_header/header', array( + 'project' => $project, + 'filters' => $filters, + 'categories_list' => $this->category->getList($project['id'], false), + 'users_list' => $this->projectUserRole->getAssignableUsersList($project['id'], false), + 'custom_filters_list' => $this->customFilter->getAll($project['id'], $this->userSession->getId()), + 'board_view' => $boardView, + )); + } + + /** + * Get project description + * + * @access public + * @param array &$project + * @return string + */ + public function getDescription(array &$project) + { + if ($project['owner_id'] > 0) { + $description = t('Project owner: ').'**'.$this->helper->text->e($project['owner_name'] ?: $project['owner_username']).'**'.PHP_EOL.PHP_EOL; + + if (! empty($project['description'])) { + $description .= '***'.PHP_EOL.PHP_EOL; + $description .= $project['description']; + } + } else { + $description = $project['description']; + } + + return $description; + } +} diff --git a/sources/app/Helper/Subtask.php b/sources/app/Helper/SubtaskHelper.php similarity index 96% rename from sources/app/Helper/Subtask.php rename to sources/app/Helper/SubtaskHelper.php index 1784a2b..afa3c14 100644 --- a/sources/app/Helper/Subtask.php +++ b/sources/app/Helper/SubtaskHelper.php @@ -2,13 +2,15 @@ namespace Kanboard\Helper; +use Kanboard\Core\Base; + /** * Subtask helpers * * @package helper * @author Frederic Guillot */ -class Subtask extends \Kanboard\Core\Base +class SubtaskHelper extends Base { public function getTitle(array $subtask) { @@ -20,7 +22,7 @@ class Subtask extends \Kanboard\Core\Base $html = ''; } - return $html.$this->helper->e($subtask['title']); + return $html.$this->helper->text->e($subtask['title']); } /** diff --git a/sources/app/Helper/Task.php b/sources/app/Helper/TaskHelper.php similarity index 99% rename from sources/app/Helper/Task.php rename to sources/app/Helper/TaskHelper.php index 6058c09..4857d0e 100644 --- a/sources/app/Helper/Task.php +++ b/sources/app/Helper/TaskHelper.php @@ -10,7 +10,7 @@ use Kanboard\Core\Base; * @package helper * @author Frederic Guillot */ -class Task extends Base +class TaskHelper extends Base { /** * Local cache for project columns diff --git a/sources/app/Helper/Text.php b/sources/app/Helper/TextHelper.php similarity index 87% rename from sources/app/Helper/Text.php rename to sources/app/Helper/TextHelper.php index 83f1e3f..e5aefdc 100644 --- a/sources/app/Helper/Text.php +++ b/sources/app/Helper/TextHelper.php @@ -11,8 +11,19 @@ use Kanboard\Core\Base; * @package helper * @author Frederic Guillot */ -class Text extends Base +class TextHelper extends Base { + /** + * HTML escaping + * + * @param string $value Value to escape + * @return string + */ + public function e($value) + { + return htmlspecialchars($value, ENT_QUOTES, 'UTF-8', false); + } + /** * Markdown transformation * @@ -88,7 +99,7 @@ class Text extends Base public function in($id, array $listing, $default_value = '?') { if (isset($listing[$id])) { - return $this->helper->e($listing[$id]); + return $this->helper->text->e($listing[$id]); } return $default_value; diff --git a/sources/app/Helper/Url.php b/sources/app/Helper/UrlHelper.php similarity index 80% rename from sources/app/Helper/Url.php rename to sources/app/Helper/UrlHelper.php index 7de8a57..095c4af 100644 --- a/sources/app/Helper/Url.php +++ b/sources/app/Helper/UrlHelper.php @@ -5,12 +5,12 @@ namespace Kanboard\Helper; use Kanboard\Core\Base; /** - * Url helpers + * Url Helper * * @package helper * @author Frederic Guillot */ -class Url extends Base +class UrlHelper extends Base { private $base = ''; private $directory = ''; @@ -29,17 +29,37 @@ class Url extends Base } /** - * HTML Link tag + * Button Link Element * * @access public - * @param string $label Link label - * @param string $controller Controller name - * @param string $action Action name - * @param array $params Url parameters - * @param boolean $csrf Add a CSRF token - * @param string $class CSS class attribute - * @param boolean $new_tab Open the link in a new tab - * @param string $anchor Link Anchor + * @param string $icon Font-Awesome icon + * @param string $label Link label + * @param string $controller Controller name + * @param string $action Action name + * @param array $params Url parameters + * @param string $class CSS class attribute + * @return string + */ + public function button($icon, $label, $controller, $action, array $params = array(), $class = '') + { + $icon = ' '; + $class = 'btn '.$class; + return $this->link($icon.$label, $controller, $action, $params, false, $class); + } + + /** + * Link element + * + * @access public + * @param string $label Link label + * @param string $controller Controller name + * @param string $action Action name + * @param array $params Url parameters + * @param boolean $csrf Add a CSRF token + * @param string $class CSS class attribute + * @param string $title + * @param boolean $new_tab Open the link in a new tab + * @param string $anchor Link Anchor * @return string */ public function link($label, $controller, $action, array $params = array(), $csrf = false, $class = '', $title = '', $new_tab = false, $anchor = '') diff --git a/sources/app/Helper/User.php b/sources/app/Helper/UserHelper.php similarity index 83% rename from sources/app/Helper/User.php rename to sources/app/Helper/UserHelper.php index 29844df..c3369df 100644 --- a/sources/app/Helper/User.php +++ b/sources/app/Helper/UserHelper.php @@ -2,13 +2,15 @@ namespace Kanboard\Helper; +use Kanboard\Core\Base; + /** * User helpers * * @package helper * @author Frederic Guillot */ -class User extends \Kanboard\Core\Base +class UserHelper extends Base { /** * Return true if the logged user as unread notifications @@ -32,7 +34,7 @@ class User extends \Kanboard\Core\Base { $initials = ''; - foreach (explode(' ', $name) as $string) { + foreach (explode(' ', $name, 2) as $string) { $initials .= mb_substr($string, 0, 1); } @@ -154,23 +156,6 @@ class User extends \Kanboard\Core\Base */ public function getFullname(array $user = array()) { - return $this->user->getFullname(empty($user) ? $this->sessionStorage->user : $user); - } - - /** - * Display gravatar image - * - * @access public - * @param string $email - * @param string $alt - * @return string - */ - public function avatar($email, $alt = '') - { - if (! empty($email) && $this->config->get('integration_gravatar') == 1) { - return ''.$this->helper->e($alt).''; - } - - return ''; + return $this->user->getFullname(empty($user) ? $this->userSession->getAll() : $user); } } diff --git a/sources/app/Model/TaskImport.php b/sources/app/Import/TaskImport.php similarity index 97% rename from sources/app/Model/TaskImport.php rename to sources/app/Import/TaskImport.php index ccab015..2abafe1 100644 --- a/sources/app/Model/TaskImport.php +++ b/sources/app/Import/TaskImport.php @@ -1,7 +1,8 @@ dateParser->getTimestampFromIsoFormat($row['date_due']); } - $this->removeEmptyFields( + $this->helper->model->removeEmptyFields( $values, array('owner_id', 'creator_id', 'color_id', 'column_id', 'category_id', 'swimlane_id', 'date_due') ); diff --git a/sources/app/Model/UserImport.php b/sources/app/Import/UserImport.php similarity index 94% rename from sources/app/Model/UserImport.php rename to sources/app/Import/UserImport.php index 0ec4e80..64300d7 100644 --- a/sources/app/Model/UserImport.php +++ b/sources/app/Import/UserImport.php @@ -1,16 +1,18 @@ removeEmptyFields($row, array('password', 'email', 'name')); + $this->helper->model->removeEmptyFields($row, array('password', 'email', 'name')); return $row; } diff --git a/sources/app/Locale/bs_BA/translations.php b/sources/app/Locale/bs_BA/translations.php index 3abb095..7ca864f 100644 --- a/sources/app/Locale/bs_BA/translations.php +++ b/sources/app/Locale/bs_BA/translations.php @@ -8,7 +8,6 @@ return array( 'Edit' => 'Uredi', 'remove' => 'ukloni', 'Remove' => 'Ukloni', - 'Update' => 'Ažuriraj', 'Yes' => 'Da', 'No' => 'Ne', 'cancel' => 'odustani', @@ -56,25 +55,23 @@ return array( 'Project' => 'Projekat', 'Status' => 'Status', 'Tasks' => 'Zadatak', - 'Board' => 'Tabla', + 'Board' => 'Ploča', 'Actions' => 'Akcije', 'Inactive' => 'Neaktivan', 'Active' => 'Aktivan', - 'Add this column' => 'Dodaj kolonu', '%d tasks on the board' => '%d zadataka na tabli', '%d tasks in total' => '%d zadataka ukupno', - 'Unable to update this board.' => 'Nemogu da ažuriram ovu tablu.', - 'Edit board' => 'Izmijeni tablu', + 'Unable to update this board.' => 'Nemogu da ažuriram ovu ploču.', + 'Edit board' => 'Izmijeni ploču', 'Disable' => 'Onemogući', 'Enable' => 'Omogući', 'New project' => 'Novi projekat', 'Do you really want to remove this project: "%s"?' => 'Da li želiš da ukloniš projekat: "%s"?', 'Remove project' => 'Ukloni projekat', - 'Edit the board for "%s"' => 'Uredi tablu za "%s"', + 'Edit the board for "%s"' => 'Uredi ploču za "%s"', 'All projects' => 'Svi projekti', 'Add a new column' => 'Dodaj novu kolonu', 'Title' => 'Naslov', - 'Nobody assigned' => 'Niko nije dodijeljen', 'Assigned to %s' => 'Dodijeljen korisniku %s', 'Remove a column' => 'Ukloni kolonu', 'Remove a column from a board' => 'Ukloni kolonu sa table', @@ -100,7 +97,7 @@ return array( 'New task' => 'Novi zadatak', 'Open a task' => 'Otvori zadatak', 'Do you really want to open this task: "%s"?' => 'Da li zaista želiš da otvoriš zadatak: "%s"?', - 'Back to the board' => 'Nazad na tablu', + 'Back to the board' => 'Nazad na ploču', 'There is nobody assigned' => 'Niko nije dodijeljen!', 'Column on the board:' => 'Kolona na tabli:', 'Close this task' => 'Zatvori ovaj zadatak', @@ -148,7 +145,7 @@ return array( 'Unable to update your user.' => 'Nije moguće ažuriranje korisnika.', 'User removed successfully.' => 'Korisnik uspješno uklonjen.', 'Unable to remove this user.' => 'Nije moguće uklanjanje korisnika.', - 'Board updated successfully.' => 'Tabla uspješno ažurirana.', + 'Board updated successfully.' => 'Ploča je uspješno ažurirana.', 'Ready' => 'Spreman', 'Backlog' => 'Zaliha', 'Work in progress' => 'U izradi', @@ -168,7 +165,6 @@ return array( 'Task count' => 'Broj zadataka', 'User' => 'Korisnik', 'Comments' => 'Komentari', - 'Write your text in Markdown' => 'Pisanje teksta pomoću Markdown', 'Leave a comment' => 'Ostavi komentar', 'Comment is required' => 'Komentar je obavezan', 'Leave a description' => 'Dodaj opis', @@ -184,7 +180,6 @@ return array( 'Unable to remove this action.' => 'Nije moguće obrisati akciju', 'Action removed successfully.' => 'Akcija obrisana', 'Automatic actions for the project "%s"' => 'Akcije za automatizaciju projekta "%s"', - 'Defined actions' => 'Definisane akcje', 'Add an action' => 'dodaj akcju', 'Event name' => 'Naziv događaja', 'Action name' => 'Naziv akcije', @@ -194,7 +189,6 @@ return array( 'When the selected event occurs execute the corresponding action.' => 'Na izabrani događaj izvrši odgovarajuću akciju', 'Next step' => 'Slijedeći korak', 'Define action parameters' => 'Definiši parametre akcije', - 'Save this action' => 'Snimi akciju', 'Do you really want to remove this action: "%s"?' => 'Da li da obrišem akciju "%s"?', 'Remove an automatic action' => 'Obriši automatsku akciju', 'Assign the task to a specific user' => 'Dodijeli zadatak određenom korisniku', @@ -333,10 +327,10 @@ return array( 'Time tracking:' => 'Praćenje vremena:', 'New sub-task' => 'Novi pod-zadatak', 'New attachment added "%s"' => 'Ubačen novi prilog "%s"', - 'Comment updated' => 'Komentar ažuriran', 'New comment posted by %s' => '%s ostavio novi komentar', 'New attachment' => 'Novi prilog', 'New comment' => 'Novi komentar', + 'Comment updated' => 'Komentar ažuriran', 'New subtask' => 'Novi pod-zadatak', 'Subtask updated' => 'Pod-zadatak ažuriran', 'Task updated' => 'Zadatak ažuriran', @@ -404,7 +398,7 @@ return array( '%s moved the task #%d to the position %d in the column "%s"' => '%s premjestio zadatak #%d na poziciju %d u koloni "%s"', 'Activity' => 'Aktivnosti', 'Default values are "%s"' => 'Podrazumijevane vrijednosti su: "%s"', - 'Default columns for new projects (Comma-separated)' => 'Podrazumijevane kolone za novi projekat (Odvojeni zarezom)', + 'Default columns for new projects (Comma-separated)' => 'Podrazumijevane kolone za novi projekat (Odvojene zarezom)', 'Task assignee change' => 'Promijena izvršioca zadatka', '%s change the assignee of the task #%d to %s' => '%s zamijeni izvršioca za zadatak #%d u %s', '%s changed the assignee of the task %s to %s' => '%s promijenio izvršioca za zadatak %s u %s', @@ -416,7 +410,7 @@ return array( 'Reference' => 'Referenca', 'Label' => 'Etiketa', 'Database' => 'Baza', - 'About' => 'O', + 'About' => 'O Kanboardu', 'Database driver:' => 'Database driver:', 'Board settings' => 'Postavke table', 'URL and token' => 'URL i token', @@ -424,23 +418,22 @@ return array( 'URL for task creation:' => 'URL za kreiranje zadataka', 'Reset token' => 'Resetuj token', 'API endpoint:' => 'API endpoint', - 'Refresh interval for private board' => 'Interval osvježavanja privatnih tabli', - 'Refresh interval for public board' => 'Interval osvježavanja javnih tabli', + 'Refresh interval for private board' => 'Interval osvježavanja privatnih ploča', + 'Refresh interval for public board' => 'Interval osvježavanja javnih ploča', 'Task highlight period' => 'Period naznačavanja zadatka', 'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => 'Period (u sekundama) u kom su se događale promjene na zadatku (0 je onemogućeno, 2 dana je uobičajeno)', 'Frequency in second (60 seconds by default)' => 'Frekvencija u sekundama (60 sekundi je uobičajeno)', 'Frequency in second (0 to disable this feature, 10 seconds by default)' => 'Frekvencija u sekundama (0 je onemogućeno u budućnosti, 10 sekundi je uobičajeno)', - 'Application URL' => 'URL aplikacje', + 'Application URL' => 'URL aplikacije', 'Token regenerated.' => 'Token regenerisan.', 'Date format' => 'Format datuma', - 'ISO format is always accepted, example: "%s" and "%s"' => 'Format ISO je uvek prihvatljiv, primjer: "%s", "%s"', + 'ISO format is always accepted, example: "%s" and "%s"' => 'Format ISO je uvijek prihvatljiv, primjer: "%s", "%s"', 'New private project' => 'Novi privatni projekat', 'This project is private' => 'Ovaj projekat je privatan', - 'Type here to create a new sub-task' => 'Piši ovdje za kreiranje novog pod-zadatka', 'Add' => 'Dodaj', 'Start date' => 'Datum početka', 'Time estimated' => 'Procijenjeno vrijeme', - 'There is nothing assigned to you.' => 'Ništa vam nije dodijeljeno', + 'There is nothing assigned to you.' => 'Ništa ti nije dodijeljeno', 'My tasks' => 'Moji zadaci', 'Activity stream' => 'Spisak aktivnosti', 'Dashboard' => 'Panel', @@ -487,9 +480,6 @@ return array( 'Daily project summary export for "%s"' => 'Izvoz zbirnog pregleda po danima za "%s"', 'Exports' => 'Izvozi', 'This export contains the number of tasks per column grouped per day.' => 'Ovaj izvoz sadržava broj zadataka po koloni grupisanih po danima.', - 'Nothing to preview...' => 'Ništa za pokazati...', - 'Preview' => 'Pregled', - 'Write' => 'Piši', 'Active swimlanes' => 'Aktivne swimline trake', 'Add a new swimlane' => 'Dodaj novu swimline traku', 'Change default swimlane' => 'Preimenuj podrazumijevanu swimline traku', @@ -543,7 +533,6 @@ return array( 'Task age in days' => 'Trajanje zadatka u danima', 'Days in this column' => 'Dani u ovoj koloni', '%dd' => '%dd', - 'Add a link' => 'Dodaj vezu', 'Add a new link' => 'Dodaj novu vezu', 'Do you really want to remove this link: "%s"?' => 'Da li zaista želite ukloniti ovu vezu: "%s"?', 'Do you really want to remove this link with task #%d?' => 'Da li zaista želite ukloniti ovu vezu sa zadatkom #%d?', @@ -598,7 +587,7 @@ return array( 'CHF - Swiss Francs' => 'CHF - Švicarski franak', 'Custom Stylesheet' => 'Prilagođeni stil', 'download' => 'preuzmi', - 'EUR - Euro' => 'EUR - Evro', + 'EUR - Euro' => 'EUR - Euro', 'GBP - British Pound' => 'GBP - Britanska funta', 'INR - Indian Rupee' => 'INR - Indijski rupi', 'JPY - Japanese Yen' => 'JPY - Japanski jen', @@ -619,7 +608,7 @@ return array( 'Rate' => 'Stopa', 'Change reference currency' => 'Promijeni referencu valute', 'Add a new currency rate' => 'Dodaj novu stopu valute', - 'Reference currency' => 'Referenca valute', + 'Reference currency' => 'Referentna valuta', 'The currency rate have been added successfully.' => 'Stopa valute je uspješno dodana.', 'Unable to add this currency rate.' => 'Nemoguće dodati stopu valute.', 'Webhook URL' => 'Webhook URL', @@ -734,7 +723,7 @@ return array( 'Time spent changed: %sh' => 'Utrošeno vrijeme je promijenjeno: %sh', 'Time estimated changed: %sh' => 'Očekivano vrijeme je promijenjeno: %sh', 'The field "%s" have been updated' => 'Polje "%s" je ažurirano', - 'The description have been modified' => 'Promijenjen opis', + 'The description has been modified:' => 'Promijenjen opis:', 'Do you really want to close the task "%s" as well as all subtasks?' => 'Da li zaista želiš zatvoriti zadatak "%s" kao i sve pod-zadatke?', 'I want to receive notifications for:' => 'Želim dobijati obavještenja za:', 'All tasks' => 'Sve zadatke', @@ -753,8 +742,6 @@ return array( 'My activity stream' => 'Tok mojih aktivnosti', 'My calendar' => 'Moj kalendar', 'Search tasks' => 'Pretraga zadataka', - 'Back to the calendar' => 'Vrati na kalendar', - 'Filters' => 'Filteri', 'Reset filters' => 'Vrati filtere na početno', 'My tasks due tomorrow' => 'Moji zadaci koje treba završiti sutra', 'Tasks due today' => 'Zadaci koje treba završiti danas', @@ -765,8 +752,8 @@ return array( 'Not assigned' => 'Bez izvršioca', 'View advanced search syntax' => 'Vidi naprednu sintaksu pretrage', 'Overview' => 'Opšti pregled', - 'Board/Calendar/List view' => 'Pregle Table/Kalendara/Liste', - 'Switch to the board view' => 'Promijeni da vidim tablu', + 'Board/Calendar/List view' => 'Pregled Ploče/Kalendara/Liste', + 'Switch to the board view' => 'Promijeni da vidim ploču', 'Switch to the calendar view' => 'Promijeni da vidim kalendar', 'Switch to the list view' => 'Promijeni da vidim listu', 'Go to the search/filter box' => 'Idi na kutiju s pretragom/filterima', @@ -850,11 +837,10 @@ return array( 'Gantt chart for all projects' => 'Gantogram za sve projekte', 'Projects list' => 'Lista projekata', 'Gantt chart for this project' => 'Gantogram za ovaj projekat', - 'Project board' => 'Tabla projekta', + 'Project board' => 'Ploča projekta', 'End date:' => 'Datum završetka:', 'There is no start date or end date for this project.' => 'Nema početnog ili krajnjeg datuma za ovaj projekat.', 'Projects Gantt chart' => 'Gantogram projekata', - 'Link type' => 'Tip veze', 'Change task color when using a specific task link' => 'Promijeni boju zadatka kada se koristi određena veza na zadatku', 'Task link creation or modification' => 'Veza na zadatku je napravljena ili izmijenjena', 'Milestone' => 'Prekretnica', @@ -895,18 +881,17 @@ return array( 'Assignee changed on task #%d' => 'Promijenjen izvršilac na zadatku #%d', '%d overdue tasks' => '%d zadataka kasni', 'Task #%d is overdue' => 'Zadatak #%d kasni', - 'No new notifications.' => 'Nema novi obavještenja.', + 'No new notifications.' => 'Nema novih obavještenja.', 'Mark all as read' => 'Označi sve kao pročitano', 'Mark as read' => 'Označi kao pročitano', 'Total number of tasks in this column across all swimlanes' => 'Ukupan broj zadataka u ovoj koloni u svim swimline trakama', 'Collapse swimlane' => 'Skupi swimline trake', 'Expand swimlane' => 'Proširi swimline trake', 'Add a new filter' => 'Dodaj novi filter', - 'Share with all project members' => 'Podijeli s svim članovima projekta', + 'Share with all project members' => 'Podijeli sa svim članovima projekta', 'Shared' => 'Podijeljeno', 'Owner' => 'Vlasnik', 'Unread notifications' => 'Nepročitana obavještenja', - 'My filters' => 'Moji filteri', 'Notification methods:' => 'Metode obavještenja:', 'Import tasks from CSV file' => 'Uvezi zadatke putem CSV fajla', 'Unable to read your file' => 'Nemoguće pročitati fajl', @@ -936,216 +921,236 @@ return array( 'Your file must use the predefined CSV format' => 'File mora biti predefinisani CSV format', 'Your file must be encoded in UTF-8' => 'File mora biti u UTF-8 kodu', 'The first row must be the header' => 'Prvi red mora biti zaglavlje', - 'Duplicates are not verified for you' => 'Dipliciranje nisu potvrđena', + 'Duplicates are not verified for you' => 'Dupliciranja neće biti provjeravana (to ćeš morati uraditi ručno)', 'The due date must use the ISO format: YYYY-MM-DD' => 'Datum do kog se treba izvršiti mora biti u ISO formatu: GGGG-MM-DD', 'Download CSV template' => 'Preuzmi CSV šablon', 'No external integration registered.' => 'Nema registrovanih vanjskih integracija.', 'Duplicates are not imported' => 'Duplikati nisu uvezeni', 'Usernames must be lowercase and unique' => 'Korisničko ime mora biti malim slovima i jedinstveno', 'Passwords will be encrypted if present' => 'Šifra će biti kriptovana', - // '%s attached a new file to the task %s' => '', + '%s attached a new file to the task %s' => '%s je dodano novi fajl u zadatak %s', + 'Link type' => 'Tip veze', 'Assign automatically a category based on a link' => 'Automatsko pridruživanje kategorije bazirano na vezi', 'BAM - Konvertible Mark' => 'BAM - Konvertibilna marka', - // 'Assignee Username' => '', - // 'Assignee Name' => '', - // 'Groups' => '', - // 'Members of %s' => '', - // 'New group' => '', - // 'Group created successfully.' => '', - // 'Unable to create your group.' => '', - // 'Edit group' => '', - // 'Group updated successfully.' => '', - // 'Unable to update your group.' => '', - // 'Add group member to "%s"' => '', - // 'Group member added successfully.' => '', - // 'Unable to add group member.' => '', - // 'Remove user from group "%s"' => '', - // 'User removed successfully from this group.' => '', - // 'Unable to remove this user from the group.' => '', - // 'Remove group' => '', - // 'Group removed successfully.' => '', - // 'Unable to remove this group.' => '', - // 'Project Permissions' => '', - // 'Manager' => '', - // 'Project Manager' => '', - // 'Project Member' => '', - // 'Project Viewer' => '', - // 'Your account is locked for %d minutes' => '', - // 'Invalid captcha' => '', - // 'The name must be unique' => '', - // 'View all groups' => '', - // 'View group members' => '', - // 'There is no user available.' => '', - // 'Do you really want to remove the user "%s" from the group "%s"?' => '', - // 'There is no group.' => '', - // 'External Id' => '', - // 'Add group member' => '', - // 'Do you really want to remove this group: "%s"?' => '', - // 'There is no user in this group.' => '', - // 'Remove this user' => '', - // 'Permissions' => '', - // 'Allowed Users' => '', - // 'No user have been allowed specifically.' => '', - // 'Role' => '', - // 'Enter user name...' => '', - // 'Allowed Groups' => '', - // 'No group have been allowed specifically.' => '', - // 'Group' => '', - // 'Group Name' => '', - // 'Enter group name...' => '', - // 'Role:' => '', + 'Assignee Username' => 'Pridruži korisničko ime', + 'Assignee Name' => 'Pridruži ime', + 'Groups' => 'Grupe', + 'Members of %s' => 'Članovi %s', + 'New group' => 'Nova grupa', + 'Group created successfully.' => 'Grupa uspješno kreirana.', + 'Unable to create your group.' => 'Nemoguće kreirati grupu.', + 'Edit group' => 'Uredi grupu', + 'Group updated successfully.' => 'Grupa uspješno ažurirana.', + 'Unable to update your group.' => 'Nemoguće ažurirati grupu', + 'Add group member to "%s"' => 'Dodaj člana grupe u ""%s"', + 'Group member added successfully.' => 'Uspješno dodan član grupe.', + 'Unable to add group member.' => 'Nemoguće dodati člana grupe.', + 'Remove user from group "%s"' => 'Ukloni korisnika iz grupe "%s"', + 'User removed successfully from this group.' => 'Korisnik uspješno uklonjen iz grupe.', + 'Unable to remove this user from the group.' => 'Nemoguće ukloniti korisnika iz grupe.', + 'Remove group' => 'Ukloni grupu', + 'Group removed successfully.' => 'Grupa uspješno uklonjena.', + 'Unable to remove this group.' => 'Nemoguće ukloniti grupu.', + 'Project Permissions' => 'Prava na projektu', + 'Manager' => 'Menadžer', + 'Project Manager' => 'Menadžer projekta', + 'Project Member' => 'Član projekta', + 'Project Viewer' => 'Preglednik projekta', + 'Your account is locked for %d minutes' => 'Tvoj korisnički račun je zaključan za narednih %d minuta', + 'Invalid captcha' => 'Pogrešna captcha', + 'The name must be unique' => 'Ime mora biti jedinstveno', + 'View all groups' => 'Pregledaj sve grupe', + 'View group members' => 'Pregledaj članove grupe', + 'There is no user available.' => 'Trenutno nema dostupnih korisnika.', + 'Do you really want to remove the user "%s" from the group "%s"?' => 'Da li zaista želiš ukloniti korisnika "%s" iz grupe "%s"?', + 'There is no group.' => 'Trenutno nema grupa.', + 'External Id' => 'Vanjski Id', + 'Add group member' => 'Dodaj člana grupe', + 'Do you really want to remove this group: "%s"?' => 'Da li zaista želiš ukloniti ovu grupu: "%s"?', + 'There is no user in this group.' => 'Trenutno nema korisnika u grupi.', + 'Remove this user' => 'Ukloni ovog korisnika', + 'Permissions' => 'Prava', + 'Allowed Users' => 'Dozvoljeni korisnici', + 'No user have been allowed specifically.' => 'Nema korisnika sa specijalnim dozvolama.', + 'Role' => 'Uloge', + 'Enter user name...' => 'Unesi korisničko ime...', + 'Allowed Groups' => 'Dozvoljene grupe', + 'No group have been allowed specifically.' => 'Nema grupa sa specijalnim dozvolama.', + 'Group' => 'Grupa', + 'Group Name' => 'Ime grupe', + 'Enter group name...' => 'Unesi ime grupe...', + 'Role:' => 'Uloga:', 'Project members' => 'Članovi projekta', - // 'Compare hours for "%s"' => '', - // '%s mentioned you in the task #%d' => '', - // '%s mentioned you in a comment on the task #%d' => '', - // 'You were mentioned in the task #%d' => '', - // 'You were mentioned in a comment on the task #%d' => '', - // 'Mentioned' => '', - // 'Compare Estimated Time vs Actual Time' => '', - // 'Estimated hours: ' => '', - // 'Actual hours: ' => '', - // 'Hours Spent' => '', - // 'Hours Estimated' => '', - // 'Estimated Time' => '', - // 'Actual Time' => '', - // 'Estimated vs actual time' => '', - // 'RUB - Russian Ruble' => '', - // 'Assign the task to the person who does the action when the column is changed' => '', - // 'Close a task in a specific column' => '', - // 'Time-based One-time Password Algorithm' => '', - // 'Two-Factor Provider: ' => '', - // 'Disable two-factor authentication' => '', - // 'Enable two-factor authentication' => '', - // 'There is no integration registered at the moment.' => '', - // 'Password Reset for Kanboard' => '', - // 'Forgot password?' => '', - // 'Enable "Forget Password"' => '', - // 'Password Reset' => '', - // 'New password' => '', - // 'Change Password' => '', - // 'To reset your password click on this link:' => '', - // 'Last Password Reset' => '', - // 'The password has never been reinitialized.' => '', - // 'Creation' => '', - // 'Expiration' => '', - // 'Password reset history' => '', - // 'All tasks of the column "%s" and the swimlane "%s" have been closed successfully.' => '', - // 'Do you really want to close all tasks of this column?' => '', - // '%d task(s) in the column "%s" and the swimlane "%s" will be closed.' => '', - // 'Close all tasks of this column' => '', - // 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => '', - // 'My dashboard' => '', - // 'My profile' => '', - // 'Project owner: ' => '', - // 'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => '', - // 'Project owner' => '', - // 'Those dates are useful for the project Gantt chart.' => '', - // 'Private projects do not have users and groups management.' => '', - // 'There is no project member.' => '', - // 'Priority' => '', - // 'Task priority' => '', - // 'General' => '', - // 'Dates' => '', - // 'Default priority' => '', - // 'Lowest priority' => '', - // 'Highest priority' => '', - // 'If you put zero to the low and high priority, this feature will be disabled.' => '', - // 'Close a task when there is no activity' => '', - // 'Duration in days' => '', - // 'Send email when there is no activity on a task' => '', - // 'List of external links' => '', - // 'Unable to fetch link information.' => '', - // 'Daily background job for tasks' => '', - // 'Auto' => '', - // 'Related' => '', - // 'Attachment' => '', - // 'Title not found' => '', - // 'Web Link' => '', - // 'External links' => '', - // 'Add external link' => '', - // 'Type' => '', - // 'Dependency' => '', - // 'Add internal link' => '', - // 'Add a new external link' => '', - // 'Edit external link' => '', - // 'External link' => '', - // 'Copy and paste your link here...' => '', - // 'URL' => '', - // 'There is no external link for the moment.' => '', - // 'Internal links' => '', - // 'There is no internal link for the moment.' => '', - // 'Assign to me' => '', - // 'Me' => '', - // 'Do not duplicate anything' => '', - // 'Projects management' => '', - // 'Users management' => '', - // 'Groups management' => '', - // 'Create from another project' => '', - // 'There is no subtask at the moment.' => '', - // 'open' => '', - // 'closed' => '', - // 'Priority:' => '', - // 'Reference:' => '', - // 'Complexity:' => '', - // 'Swimlane:' => '', - // 'Column:' => '', - // 'Position:' => '', - // 'Creator:' => '', - // 'Time estimated:' => '', - // '%s hours' => '', - // 'Time spent:' => '', - // 'Created:' => '', - // 'Modified:' => '', - // 'Completed:' => '', - // 'Started:' => '', - // 'Moved:' => '', - // 'Task #%d' => '', - // 'Sub-tasks' => '', - // 'Date and time format' => '', - // 'Time format' => '', - // 'Start date: ' => '', - // 'End date: ' => '', - // 'New due date: ' => '', - // 'Start date changed: ' => '', - // 'Disable private projects' => '', - // 'Do you really want to remove this custom filter: "%s"?' => '', - // 'Remove a custom filter' => '', - // 'User activated successfully.' => '', - // 'Unable to enable this user.' => '', - // 'User disabled successfully.' => '', - // 'Unable to disable this user.' => '', - // 'All files have been uploaded successfully.' => '', - // 'View uploaded files' => '', - // 'The maximum allowed file size is %sB.' => '', - // 'Choose files again' => '', - // 'Drag and drop your files here' => '', - // 'choose files' => '', - // 'View profile' => '', - // 'Two Factor' => '', - // 'Disable user' => '', - // 'Do you really want to disable this user: "%s"?' => '', - // 'Enable user' => '', - // 'Do you really want to enable this user: "%s"?' => '', - // 'Download' => '', - // 'Uploaded: %s' => '', - // 'Size: %s' => '', - // 'Uploaded by %s' => '', - // 'Filename' => '', - // 'Size' => '', - // 'Column created successfully.' => '', - // 'Another column with the same name exists in the project' => '', - // 'Default filters' => '', - // 'Your board doesn\'t have any column!' => '', - // 'Change column position' => '', - // 'Switch to the project overview' => '', - // 'User filters' => '', - // 'Category filters' => '', - // 'Upload a file' => '', - // 'There is no attachment at the moment.' => '', - // 'View file' => '', - // 'Last activity' => '', - // 'Change subtask position' => '', - // 'This value must be greater than %d' => '', - // 'Another swimlane with the same name exists in the project' => '', - // 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => '', + 'Compare hours for "%s"' => 'Poredi sate za "%s"', + '%s mentioned you in the task #%d' => '%s te spomenuo u zadatku #%d', + '%s mentioned you in a comment on the task #%d' => '%s te spomenuo u komentaru zadatka #%d', + 'You were mentioned in the task #%d' => 'Spomenut si u zadatku #%d', + 'You were mentioned in a comment on the task #%d' => 'Spomenut si u komentaru zadatka #%d', + 'Mentioned' => 'Spominjanja', + 'Compare Estimated Time vs Actual Time' => 'Poređenje očekivanog i aktuelnog vremena', + 'Estimated hours: ' => 'Očekivani sati:', + 'Actual hours: ' => 'Aktuelni sati:', + 'Hours Spent' => 'Utrošeni sati:', + 'Hours Estimated' => 'Očekivani sati', + 'Estimated Time' => 'Očekivano vrijeme', + 'Actual Time' => 'Aktuelno vrijeme', + 'Estimated vs actual time' => 'Očekivano nasuprot aktuelnog vremena', + 'RUB - Russian Ruble' => 'RUB - Ruski rubij', + 'Assign the task to the person who does the action when the column is changed' => 'Dodijeli zadatak osobi koja izvrši akciju promjene kolone', + 'Close a task in a specific column' => 'Zatvori zadatak u određenoj koloni', + 'Time-based One-time Password Algorithm' => 'Vremenski bazirani One-time Algoritam šifri', + 'Two-Factor Provider: ' => 'Two-Factor provajder', + 'Disable two-factor authentication' => 'Onemogući two-factor autentifikaciju', + 'Enable two-factor authentication' => 'Omogući two-factor autentifikaciju', + 'There is no integration registered at the moment.' => 'Trenutno nema registrovanih integracija.', + 'Password Reset for Kanboard' => 'Promjena šifre za Kanboard', + 'Forgot password?' => 'Ne mogu da se sjetim šifre?', + 'Enable "Forget Password"' => 'Omogući "Ne mogu da se sjetim šifre"', + 'Password Reset' => 'Promijena šifre', + 'New password' => 'Nova šifra', + 'Change Password' => 'Promijeni šifru', + 'To reset your password click on this link:' => 'Da bi promijenio šifru klikni na ovaj link:', + 'Last Password Reset' => 'Posljednja promjena šifre', + 'The password has never been reinitialized.' => 'Šifra nije nikada promijenjena.', + 'Creation' => 'Napravljena', + 'Expiration' => 'Ističe', + 'Password reset history' => 'Hitorija promjena šifri', + 'All tasks of the column "%s" and the swimlane "%s" have been closed successfully.' => 'Svi zadaci kolone "%s" i swimline-a "%s" uspješno su zatvoreni.', + 'Do you really want to close all tasks of this column?' => 'Da li zaista želiš zatvoriti sve zadatke ove kolone?', + '%d task(s) in the column "%s" and the swimlane "%s" will be closed.' => '%d zadatak(ci) u koloni "%s" i swimline-u "%s" će biti zatvoreni.', + 'Close all tasks of this column' => 'Zatvori sve zadatke ove kolone', + 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => 'Nema posebnog plugin-a za obavještenja. Još uvijek možeš koristiti individualne postavke obavještenja na svom profilu.', + 'My dashboard' => 'Moj panel', + 'My profile' => 'Moj profil', + 'Project owner: ' => 'Vlasnik projekta:', + 'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => 'Identifikator projekta je opcionalan i mora biti alfanumerički, na primjer: MOJPROJEKAT.', + 'Project owner' => 'Vlasnik projekta', + 'Those dates are useful for the project Gantt chart.' => 'Ovi datumi su korisni za pravljenje Gantt dijagrama za projekat.', + 'Private projects do not have users and groups management.' => 'Privatni projekti ne mogu imati korisnike ili grupe korisnika.', + 'There is no project member.' => 'Nema članova projekta.', + 'Priority' => 'Prioritet', + 'Task priority' => 'Prioritet zadatka', + 'General' => 'Opšte', + 'Dates' => 'Datumi', + 'Default priority' => 'Podrazumijevani prioritet', + 'Lowest priority' => 'Najmanji prioritet', + 'Highest priority' => 'Najveći prioritet', + 'If you put zero to the low and high priority, this feature will be disabled.' => 'Ako upišeš nulu za najmanji i najveći prioritet, ova opcija će biti onemogućena.', + 'Close a task when there is no activity' => 'Zatvori zadatak kada nema aktivnosti', + 'Duration in days' => 'Dužina trajanja u danima', + 'Send email when there is no activity on a task' => 'Pošalji email kada nema aktivnosti na zadatku', + 'Unable to fetch link information.' => 'Ne mogu da pribavim informacije o vezi.', + 'Daily background job for tasks' => 'Dnevni pozadinski poslovi na zadacima', + 'Auto' => 'Automatski', + 'Related' => 'Povezani', + 'Attachment' => 'Dodijeljeni', + 'Title not found' => 'Bez naslova', + 'Web Link' => 'Web veza', + 'External links' => 'Vanjska veza', + 'Add external link' => 'Dodaj vanjsku vezu', + 'Type' => 'Vrsta', + 'Dependency' => 'Zavisnost', + 'Add internal link' => 'Dodaj unutrašnju vezu', + 'Add a new external link' => 'Dodaj novu vanjsku vezu', + 'Edit external link' => 'Uredi vanjsku vezu', + 'External link' => 'Vanjska veza', + 'Copy and paste your link here...' => 'Kopiraj i zalijepi svoju vezu ovdje...', + 'URL' => 'URL', + 'Internal links' => 'Unutrašnje veze', + 'Assign to me' => 'Dodijeli meni', + 'Me' => 'Za mene', + 'Do not duplicate anything' => 'Ništa ne dupliciraj', + 'Projects management' => 'Menadžment projekata', + 'Users management' => 'Menadžment korisnika', + 'Groups management' => 'Menadžment grupa', + 'Create from another project' => 'Napravi iz drugog projekta', + 'open' => 'otvoreno', + 'closed' => 'zatvoreno', + 'Priority:' => 'Prioritet:', + 'Reference:' => 'Preporuka:', + 'Complexity:' => 'Složenost:', + 'Swimlane:' => 'Swimline:', + 'Column:' => 'Kolona:', + 'Position:' => 'Pozicija:', + 'Creator:' => 'Kreator:', + 'Time estimated:' => 'Očekivano vrijeme:', + '%s hours' => '%s sati', + 'Time spent:' => 'Utrošeno vrijeme:', + 'Created:' => 'Kreirao:', + 'Modified:' => 'Uredio:', + 'Completed:' => 'Završio:', + 'Started:' => 'Početo:', + 'Moved:' => 'Pomjereno:', + 'Task #%d' => 'Zadatak #%d', + 'Date and time format' => 'Format za datum i vrijeme', + 'Time format' => 'Format za vrijeme', + 'Start date: ' => 'Početni datum:', + 'End date: ' => 'Krajnji datum:', + 'New due date: ' => 'Novi datum očekivanja:', + 'Start date changed: ' => 'Početni datum promijenjen:', + 'Disable private projects' => 'Onemogući privatne projekte', + 'Do you really want to remove this custom filter: "%s"?' => 'Da li zaista želiš ukloniti ovaj prilagođeni filter "%s"?', + 'Remove a custom filter' => 'Ukloni prilagođeni filter', + 'User activated successfully.' => 'Korisnik uspješno aktiviran.', + 'Unable to enable this user.' => 'Nemoguće omogućiti ovog korisnika.', + 'User disabled successfully.' => 'Korisnik uspješno onemogućen.', + 'Unable to disable this user.' => 'Nemoguće onemogućiti ovog korisnika.', + 'All files have been uploaded successfully.' => 'Svi fajlovi su uspješno dodani.', + 'View uploaded files' => 'Pregled dodanih fajlova', + 'The maximum allowed file size is %sB.' => 'Maksimalna dozvoljena veličina fajla je %sB.', + 'Choose files again' => 'Izaberi ponovo fajlove', + 'Drag and drop your files here' => 'Povuci i spusti svoje fajlove ovdje', + 'choose files' => 'izaberi fajlove', + 'View profile' => 'Pregledaj profil', + 'Two Factor' => 'Dva faktora', + 'Disable user' => 'Onemogući korisnika', + 'Do you really want to disable this user: "%s"?' => 'Da li zaista želiš onemogućiti ovog korisnika: "%s"?', + 'Enable user' => 'Omogući korisnika', + 'Do you really want to enable this user: "%s"?' => 'Da li zaista želiš omogućiti ovog korisnika: "%s"?', + 'Download' => 'Preuzeto', + 'Uploaded: %s' => 'Dodano: %s', + 'Size: %s' => 'Veličina: %s', + 'Uploaded by %s' => 'Dodao %s', + 'Filename' => 'Ime fajla', + 'Size' => 'Veličina', + 'Column created successfully.' => 'Kolona uspješno napravljena.', + 'Another column with the same name exists in the project' => 'Već postoji kolona s istim imenom u ovom projektu.', + 'Default filters' => 'Podrazumijevani filteri', + 'Your board doesn\'t have any column!' => 'Vaš panel nema ni jednu kolonu!', + 'Change column position' => 'Promijeni poziciju kolone', + 'Switch to the project overview' => 'Promijeni u pregled projekta', + 'User filters' => 'Korisnički filteri', + 'Category filters' => 'Kategorija filtera', + 'Upload a file' => 'Dodaj fajl', + 'View file' => 'Pregled fajla', + 'Last activity' => 'Posljednja aktivnost', + 'Change subtask position' => 'Promijeni poziciju pod-zadatka', + 'This value must be greater than %d' => 'Ova vrijednost mora biti veća od %d', + 'Another swimlane with the same name exists in the project' => 'Već postoji swimline sa istim imenom u ovom projektu', + 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => 'Na primjer: http://example.kanboard.net/ (koristi se za pravljenje apsolutnog URL-a)', + 'Actions duplicated successfully.' => 'Akcije uspješno duplicirane.', + 'Unable to duplicate actions.' => 'Nemoguće duplicirati akcije.', + 'Add a new action' => 'Dodaj novu akciju', + 'Import from another project' => 'Uvezi iz drugog projekta', + 'There is no action at the moment.' => 'Trenutno nema akcija.', + 'Import actions from another project' => 'Uvezi akcije iz drugog projekta', + 'There is no available project.' => 'Trenutno nema dostupnih projekata.', + // 'Local File' => '', + // 'Configuration' => '', + // 'PHP version:' => '', + // 'PHP SAPI:' => '', + // 'OS version:' => '', + // 'Database version:' => '', + // 'Browser:' => '', + // 'Task view' => '', + // 'Edit task' => '', + // 'Edit description' => '', + // 'New internal link' => '', + // 'Display list of keyboard shortcuts' => '', + // 'Menu' => '', + // 'Set start date' => '', + // 'Avatar' => '', + // 'Upload my avatar image' => '', + // 'Remove my image' => '', + // 'The OAuth2 state parameter is invalid' => '', ); diff --git a/sources/app/Locale/cs_CZ/translations.php b/sources/app/Locale/cs_CZ/translations.php index f03d70c..b2921de 100644 --- a/sources/app/Locale/cs_CZ/translations.php +++ b/sources/app/Locale/cs_CZ/translations.php @@ -8,7 +8,6 @@ return array( 'Edit' => 'Editovat', 'remove' => 'odstranit', 'Remove' => 'Odstranit', - 'Update' => 'Akualizovat', 'Yes' => 'Ano', 'No' => 'Ne', 'cancel' => 'Zrušit', @@ -60,7 +59,6 @@ return array( 'Actions' => 'Akce', 'Inactive' => 'Neaktivní', 'Active' => 'Aktivní', - 'Add this column' => 'Přidat sloupec', '%d tasks on the board' => '%d úkolů na nástěnce', '%d tasks in total' => '%d úkolů celkem', 'Unable to update this board.' => 'Nástěnku není možné aktualizovat', @@ -74,7 +72,6 @@ return array( 'All projects' => 'Všechny projekty', 'Add a new column' => 'Přidat nový sloupec', 'Title' => 'Název', - 'Nobody assigned' => 'Nepřiřazena žádná osoba', 'Assigned to %s' => 'Přiřazeno uživateli: %s', 'Remove a column' => 'Vyjmout sloupec', 'Remove a column from a board' => 'Vyjmout sloupec z nástěnky', @@ -168,7 +165,6 @@ return array( 'Task count' => 'Počet úkolů', 'User' => 'Uživatel', 'Comments' => 'Komentáře', - 'Write your text in Markdown' => 'Můžete použít i Markdown-syntaxi', 'Leave a comment' => 'Zanechte komentář', 'Comment is required' => 'Komentář je vyžadován', 'Leave a description' => 'Vložte popis', @@ -184,7 +180,6 @@ return array( 'Unable to remove this action.' => 'Tuto akci nelze odstranit.', 'Action removed successfully.' => 'Akce byla úspěšně odstraněna.', 'Automatic actions for the project "%s"' => 'Automaticky vykonávané akce pro projekt "%s"', - 'Defined actions' => 'Definované akce', 'Add an action' => 'Přidat akci', 'Event name' => 'Název události', 'Action name' => 'Název akce', @@ -194,7 +189,6 @@ return array( 'When the selected event occurs execute the corresponding action.' => 'Kdykoliv se vybraná událost objeví, vykonat odpovídající akci.', 'Next step' => 'Další krok', 'Define action parameters' => 'Definovat parametry akce', - 'Save this action' => 'Uložit akci', 'Do you really want to remove this action: "%s"?' => 'Skutečně chcete odebrat tuto akci: "%s"?', 'Remove an automatic action' => 'Odebrat automaticky prováděnou akci', 'Assign the task to a specific user' => 'Přiřadit tento úkol konkrétnímu uživateli', @@ -333,10 +327,10 @@ return array( 'Time tracking:' => 'Sledování času:', 'New sub-task' => 'Nový dílčí úkol', 'New attachment added "%s"' => 'Byla přidána nová příloha "%s".', - 'Comment updated' => 'Komentář byl aktualizován.', 'New comment posted by %s' => 'Nový komentář publikovaný uživatelem %s', 'New attachment' => 'Nová příloha', 'New comment' => 'Nový komentář', + 'Comment updated' => 'Komentář byl aktualizován.', 'New subtask' => 'Nový dílčí úkol', 'Subtask updated' => 'Dílčí úkol byl aktualizován', 'Task updated' => 'Úkol byl aktualizován', @@ -436,7 +430,6 @@ return array( 'ISO format is always accepted, example: "%s" and "%s"' => 'ISO formát je vždy akceptován, například: "%s" a "%s"', 'New private project' => 'Nový soukromý projekt', 'This project is private' => 'Tento projekt je soukromuý', - 'Type here to create a new sub-task' => 'Uveďte zde pro vytvoření nového dílčího úkolu', 'Add' => 'Přidat', 'Start date' => 'Počáteční datum', 'Time estimated' => 'Odhadovaný čas', @@ -487,9 +480,6 @@ return array( 'Daily project summary export for "%s"' => 'Export denních přehledů pro "%s"', 'Exports' => 'Exporty', 'This export contains the number of tasks per column grouped per day.' => 'Tento export obsahuje počet úkolů pro jednotlivé sloupce seskupených podle dní.', - 'Nothing to preview...' => 'Žádná položka k zobrazení ...', - 'Preview' => 'Náhled', - 'Write' => 'Režim psaní', 'Active swimlanes' => 'Aktive Swimlane', 'Add a new swimlane' => 'Přidat nový řádek', 'Change default swimlane' => 'Standard Swimlane ändern', @@ -543,7 +533,6 @@ return array( 'Task age in days' => 'Doba trvání úkolu ve dnech', 'Days in this column' => 'Dní v tomto sloupci', '%dd' => '%d d', - 'Add a link' => 'Přidat odkaz', 'Add a new link' => 'Přidat nový odkaz', 'Do you really want to remove this link: "%s"?' => 'Die Verbindung "%s" wirklich löschen?', 'Do you really want to remove this link with task #%d?' => 'Die Verbindung mit der Aufgabe #%d wirklich löschen?', @@ -734,7 +723,7 @@ return array( 'Time spent changed: %sh' => 'Verbrauchte Zeit geändert: %sh', 'Time estimated changed: %sh' => 'Geschätzte Zeit geändert: %sh', 'The field "%s" have been updated' => 'Das Feld "%s" wurde verändert', - 'The description have been modified' => 'Die Beschreibung wurde geändert', + 'The description has been modified:' => 'Die Beschreibung wurde geändert:', 'Do you really want to close the task "%s" as well as all subtasks?' => 'Soll die Aufgabe "%s" wirklich geschlossen werden? (einschließlich Teilaufgaben)', 'I want to receive notifications for:' => 'Chci dostávat upozornění na:', 'All tasks' => 'Všechny úkoly', @@ -753,8 +742,6 @@ return array( 'My activity stream' => 'Přehled mých aktivit', 'My calendar' => 'Můj kalendář', 'Search tasks' => 'Hledání úkolů', - 'Back to the calendar' => 'Zpět do kalendáře', - 'Filters' => 'Filtry', 'Reset filters' => 'Resetovat filtry', 'My tasks due tomorrow' => 'Moje zítřejší úkoly', 'Tasks due today' => 'Dnešní úkoly', @@ -854,7 +841,6 @@ return array( // 'End date:' => '', // 'There is no start date or end date for this project.' => '', // 'Projects Gantt chart' => '', - // 'Link type' => '', // 'Change task color when using a specific task link' => '', // 'Task link creation or modification' => '', // 'Milestone' => '', @@ -906,7 +892,6 @@ return array( // 'Shared' => '', // 'Owner' => '', // 'Unread notifications' => '', - // 'My filters' => '', // 'Notification methods:' => '', // 'Import tasks from CSV file' => '', // 'Unable to read your file' => '', @@ -944,6 +929,7 @@ return array( // 'Usernames must be lowercase and unique' => '', // 'Passwords will be encrypted if present' => '', // '%s attached a new file to the task %s' => '', + // 'Link type' => '', // 'Assign automatically a category based on a link' => '', // 'BAM - Konvertible Mark' => '', // 'Assignee Username' => '', @@ -1053,7 +1039,6 @@ return array( // 'Close a task when there is no activity' => '', // 'Duration in days' => '', // 'Send email when there is no activity on a task' => '', - // 'List of external links' => '', // 'Unable to fetch link information.' => '', // 'Daily background job for tasks' => '', // 'Auto' => '', @@ -1071,9 +1056,7 @@ return array( // 'External link' => '', // 'Copy and paste your link here...' => '', // 'URL' => '', - // 'There is no external link for the moment.' => '', // 'Internal links' => '', - // 'There is no internal link for the moment.' => '', // 'Assign to me' => '', // 'Me' => '', // 'Do not duplicate anything' => '', @@ -1081,7 +1064,6 @@ return array( // 'Users management' => '', // 'Groups management' => '', // 'Create from another project' => '', - // 'There is no subtask at the moment.' => '', // 'open' => '', // 'closed' => '', // 'Priority:' => '', @@ -1100,7 +1082,6 @@ return array( // 'Started:' => '', // 'Moved:' => '', // 'Task #%d' => '', - // 'Sub-tasks' => '', // 'Date and time format' => '', // 'Time format' => '', // 'Start date: ' => '', @@ -1141,11 +1122,35 @@ return array( // 'User filters' => '', // 'Category filters' => '', // 'Upload a file' => '', - // 'There is no attachment at the moment.' => '', // 'View file' => '', // 'Last activity' => '', // 'Change subtask position' => '', // 'This value must be greater than %d' => '', // 'Another swimlane with the same name exists in the project' => '', // 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => '', + // 'Actions duplicated successfully.' => '', + // 'Unable to duplicate actions.' => '', + // 'Add a new action' => '', + // 'Import from another project' => '', + // 'There is no action at the moment.' => '', + // 'Import actions from another project' => '', + // 'There is no available project.' => '', + // 'Local File' => '', + // 'Configuration' => '', + // 'PHP version:' => '', + // 'PHP SAPI:' => '', + // 'OS version:' => '', + // 'Database version:' => '', + // 'Browser:' => '', + // 'Task view' => '', + // 'Edit task' => '', + // 'Edit description' => '', + // 'New internal link' => '', + // 'Display list of keyboard shortcuts' => '', + // 'Menu' => '', + // 'Set start date' => '', + // 'Avatar' => '', + // 'Upload my avatar image' => '', + // 'Remove my image' => '', + // 'The OAuth2 state parameter is invalid' => '', ); diff --git a/sources/app/Locale/da_DK/translations.php b/sources/app/Locale/da_DK/translations.php index 03180b5..c474392 100644 --- a/sources/app/Locale/da_DK/translations.php +++ b/sources/app/Locale/da_DK/translations.php @@ -8,7 +8,6 @@ return array( 'Edit' => 'Rediger', 'remove' => 'fjern', 'Remove' => 'Fjern', - 'Update' => 'Opdater', 'Yes' => 'Ja', 'No' => 'Nej', 'cancel' => 'annuller', @@ -60,7 +59,6 @@ return array( 'Actions' => 'Handlinger', 'Inactive' => 'Inaktiv', 'Active' => 'Aktiv', - 'Add this column' => 'Tilføj denne kolonne', '%d tasks on the board' => '%d Opgaver på boardet', '%d tasks in total' => '%d Opgaver i alt', 'Unable to update this board.' => 'Ikke muligt at opdatere dette board', @@ -74,7 +72,6 @@ return array( 'All projects' => 'Alle Projekter', 'Add a new column' => 'Tilføj en ny kolonne', 'Title' => 'Titel', - 'Nobody assigned' => 'Ingen ansvarlig', 'Assigned to %s' => 'Ansvarlig: %s', 'Remove a column' => 'Fjern en kolonne', 'Remove a column from a board' => 'Fjern en kolonne fra et board', @@ -168,7 +165,6 @@ return array( // 'Task count' => '', 'User' => 'Bruger', 'Comments' => 'Kommentarer', - 'Write your text in Markdown' => 'Skriv din tekst i markdown', 'Leave a comment' => 'Efterlad en kommentar', 'Comment is required' => 'Kommentar er krævet', 'Leave a description' => 'Efterlad en beskrivelse...', @@ -184,7 +180,6 @@ return array( 'Unable to remove this action.' => 'Handlingen kunne ikke fjernes.', 'Action removed successfully.' => 'Handlingen er fjernet.', 'Automatic actions for the project "%s"' => 'Automatiske handlinger for projektet "%s"', - 'Defined actions' => 'Defineret handlinger', 'Add an action' => 'Tilføj en handling', 'Event name' => 'Begivenhed', 'Action name' => 'Handling', @@ -194,7 +189,6 @@ return array( 'When the selected event occurs execute the corresponding action.' => 'Når den valgte begivenhed opstår, udfør den tilsvarende handling.', 'Next step' => 'Næste', 'Define action parameters' => 'Definer Handlingsparametre', - 'Save this action' => 'Gem denne handling', 'Do you really want to remove this action: "%s"?' => 'Vil du virkelig slette denne handling: "%s"?', 'Remove an automatic action' => 'Fjern en automatisk handling', 'Assign the task to a specific user' => 'Tildel opgaven til en bestem bruger', @@ -333,10 +327,10 @@ return array( 'Time tracking:' => 'Tidsmåling:', 'New sub-task' => 'Ny under-opgave', 'New attachment added "%s"' => 'Ny vedhæftning tilføjet "%s"', - 'Comment updated' => 'Kommentar opdateret', 'New comment posted by %s' => 'Ny kommentar af %s', // 'New attachment' => '', // 'New comment' => '', + 'Comment updated' => 'Kommentar opdateret', // 'New subtask' => '', // 'Subtask updated' => '', // 'Task updated' => '', @@ -436,7 +430,6 @@ return array( 'ISO format is always accepted, example: "%s" and "%s"' => 'ISO format er altid accepteret, eksempelvis: "%s" og "%s"', 'New private project' => 'Nyt privat projekt', 'This project is private' => 'Dette projekt er privat', - 'Type here to create a new sub-task' => 'Skriv her for at tilføje en ny under-opgave', 'Add' => 'Tilføj', 'Start date' => 'Start dato', 'Time estimated' => 'Tid estimeret', @@ -487,9 +480,6 @@ return array( // 'Daily project summary export for "%s"' => '', // 'Exports' => '', // 'This export contains the number of tasks per column grouped per day.' => '', - // 'Nothing to preview...' => '', - // 'Preview' => '', - // 'Write' => '', // 'Active swimlanes' => '', // 'Add a new swimlane' => '', // 'Change default swimlane' => '', @@ -543,7 +533,6 @@ return array( // '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?' => '', @@ -734,7 +723,7 @@ return array( // 'Time spent changed: %sh' => '', // 'Time estimated changed: %sh' => '', // 'The field "%s" have been updated' => '', - // 'The description have been modified' => '', + // 'The description has been modified:' => '', // 'Do you really want to close the task "%s" as well as all subtasks?' => '', // 'I want to receive notifications for:' => '', // 'All tasks' => '', @@ -753,8 +742,6 @@ return array( // 'My activity stream' => '', // 'My calendar' => '', // 'Search tasks' => '', - // 'Back to the calendar' => '', - // 'Filters' => '', // 'Reset filters' => '', // 'My tasks due tomorrow' => '', // 'Tasks due today' => '', @@ -854,7 +841,6 @@ return array( // 'End date:' => '', // 'There is no start date or end date for this project.' => '', // 'Projects Gantt chart' => '', - // 'Link type' => '', // 'Change task color when using a specific task link' => '', // 'Task link creation or modification' => '', // 'Milestone' => '', @@ -906,7 +892,6 @@ return array( // 'Shared' => '', // 'Owner' => '', // 'Unread notifications' => '', - // 'My filters' => '', // 'Notification methods:' => '', // 'Import tasks from CSV file' => '', // 'Unable to read your file' => '', @@ -944,6 +929,7 @@ return array( // 'Usernames must be lowercase and unique' => '', // 'Passwords will be encrypted if present' => '', // '%s attached a new file to the task %s' => '', + // 'Link type' => '', // 'Assign automatically a category based on a link' => '', // 'BAM - Konvertible Mark' => '', // 'Assignee Username' => '', @@ -1053,7 +1039,6 @@ return array( // 'Close a task when there is no activity' => '', // 'Duration in days' => '', // 'Send email when there is no activity on a task' => '', - // 'List of external links' => '', // 'Unable to fetch link information.' => '', // 'Daily background job for tasks' => '', // 'Auto' => '', @@ -1071,9 +1056,7 @@ return array( // 'External link' => '', // 'Copy and paste your link here...' => '', // 'URL' => '', - // 'There is no external link for the moment.' => '', // 'Internal links' => '', - // 'There is no internal link for the moment.' => '', // 'Assign to me' => '', // 'Me' => '', // 'Do not duplicate anything' => '', @@ -1081,7 +1064,6 @@ return array( // 'Users management' => '', // 'Groups management' => '', // 'Create from another project' => '', - // 'There is no subtask at the moment.' => '', // 'open' => '', // 'closed' => '', // 'Priority:' => '', @@ -1100,7 +1082,6 @@ return array( // 'Started:' => '', // 'Moved:' => '', // 'Task #%d' => '', - // 'Sub-tasks' => '', // 'Date and time format' => '', // 'Time format' => '', // 'Start date: ' => '', @@ -1141,11 +1122,35 @@ return array( // 'User filters' => '', // 'Category filters' => '', // 'Upload a file' => '', - // 'There is no attachment at the moment.' => '', // 'View file' => '', // 'Last activity' => '', // 'Change subtask position' => '', // 'This value must be greater than %d' => '', // 'Another swimlane with the same name exists in the project' => '', // 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => '', + // 'Actions duplicated successfully.' => '', + // 'Unable to duplicate actions.' => '', + // 'Add a new action' => '', + // 'Import from another project' => '', + // 'There is no action at the moment.' => '', + // 'Import actions from another project' => '', + // 'There is no available project.' => '', + // 'Local File' => '', + // 'Configuration' => '', + // 'PHP version:' => '', + // 'PHP SAPI:' => '', + // 'OS version:' => '', + // 'Database version:' => '', + // 'Browser:' => '', + // 'Task view' => '', + // 'Edit task' => '', + // 'Edit description' => '', + // 'New internal link' => '', + // 'Display list of keyboard shortcuts' => '', + // 'Menu' => '', + // 'Set start date' => '', + // 'Avatar' => '', + // 'Upload my avatar image' => '', + // 'Remove my image' => '', + // 'The OAuth2 state parameter is invalid' => '', ); diff --git a/sources/app/Locale/de_DE/translations.php b/sources/app/Locale/de_DE/translations.php index 0a6aada..af88b37 100644 --- a/sources/app/Locale/de_DE/translations.php +++ b/sources/app/Locale/de_DE/translations.php @@ -8,7 +8,6 @@ return array( 'Edit' => 'Bearbeiten', 'remove' => 'Entfernen', 'Remove' => 'Entfernen', - 'Update' => 'Aktualisieren', 'Yes' => 'Ja', 'No' => 'Nein', 'cancel' => 'Abbrechen', @@ -60,7 +59,6 @@ return array( 'Actions' => 'Aktionen', 'Inactive' => 'Inaktiv', 'Active' => 'Aktiv', - 'Add this column' => 'Diese Spalte hinzufügen', '%d tasks on the board' => '%d Aufgaben auf dieser Pinnwand', '%d tasks in total' => '%d Aufgaben insgesamt', 'Unable to update this board.' => 'Ändern dieser Pinnwand nicht möglich.', @@ -74,7 +72,6 @@ return array( 'All projects' => 'Alle Projekte', 'Add a new column' => 'Neue Spalte hinzufügen', 'Title' => 'Titel', - 'Nobody assigned' => 'Nicht zugeordnet', 'Assigned to %s' => 'Zuständig: %s', 'Remove a column' => 'Spalte löschen', 'Remove a column from a board' => 'Spalte einer Pinnwand löschen', @@ -168,7 +165,6 @@ return array( 'Task count' => 'Aufgabenanzahl', 'User' => 'Benutzer', 'Comments' => 'Kommentare', - 'Write your text in Markdown' => 'Schreibe deinen Text in Markdown-Syntax', 'Leave a comment' => 'Kommentar eingeben', 'Comment is required' => 'Ein Kommentar wird benötigt', 'Leave a description' => 'Beschreibung eingeben', @@ -184,7 +180,6 @@ return array( 'Unable to remove this action.' => 'Löschen der Aktion nicht möglich.', 'Action removed successfully.' => 'Aktion erfolgreich gelöscht.', 'Automatic actions for the project "%s"' => 'Automatische Aktionen für das Projekt "%s"', - 'Defined actions' => 'Definierte Aktionen', 'Add an action' => 'Aktion hinzufügen', 'Event name' => 'Ereignisname', 'Action name' => 'Aktionsname', @@ -194,7 +189,6 @@ return array( 'When the selected event occurs execute the corresponding action.' => 'Wenn das gewählte Ereignis eintritt, führe die zugehörige Aktion aus.', 'Next step' => 'Weiter', 'Define action parameters' => 'Aktionsparameter definieren', - 'Save this action' => 'Aktion speichern', 'Do you really want to remove this action: "%s"?' => 'Soll diese Aktion wirklich gelöscht werden: "%s"?', 'Remove an automatic action' => 'Löschen einer automatischen Aktion', 'Assign the task to a specific user' => 'Aufgabe einem Benutzer zuordnen', @@ -333,10 +327,10 @@ return array( 'Time tracking:' => 'Zeittracking', 'New sub-task' => 'Neue Teilaufgabe', 'New attachment added "%s"' => 'Neuer Anhang "%s" wurde hinzugefügt.', - 'Comment updated' => 'Kommentar wurde aktualisiert', 'New comment posted by %s' => 'Neuer Kommentar verfasst durch %s', 'New attachment' => 'Neuer Anhang', 'New comment' => 'Neuer Kommentar', + 'Comment updated' => 'Kommentar wurde aktualisiert', 'New subtask' => 'Neue Teilaufgabe', 'Subtask updated' => 'Teilaufgabe aktualisiert', 'Task updated' => 'Aufgabe aktualisiert', @@ -436,7 +430,6 @@ return array( 'ISO format is always accepted, example: "%s" and "%s"' => 'ISO Format wird immer akzeptiert, z.B.: "%s" und "%s"', 'New private project' => 'Neues privates Projekt', 'This project is private' => 'Dieses Projekt ist privat', - 'Type here to create a new sub-task' => 'Hier tippen, um eine neue Teilaufgabe zu erstellen', 'Add' => 'Hinzufügen', 'Start date' => 'Startdatum', 'Time estimated' => 'Geschätzte Zeit', @@ -487,9 +480,6 @@ return array( 'Daily project summary export for "%s"' => 'Export der täglichen Projektzusammenfassung für "%s"', 'Exports' => 'Exporte', 'This export contains the number of tasks per column grouped per day.' => 'Dieser Export enthält die Anzahl der Aufgaben pro Spalte nach Tagen gruppiert.', - 'Nothing to preview...' => 'Nichts in der Vorschau anzuzeigen ...', - 'Preview' => 'Vorschau', - 'Write' => 'Ändern', 'Active swimlanes' => 'Aktive Swimlane', 'Add a new swimlane' => 'Eine neue Swimlane hinzufügen', 'Change default swimlane' => 'Standard-Swimlane ändern', @@ -543,7 +533,6 @@ return array( 'Task age in days' => 'Aufgabenalter in Tagen', 'Days in this column' => 'Tage in dieser Spalte', '%dd' => '%dT', - 'Add a link' => 'Verbindung hinzufügen', 'Add a new link' => 'Neue Verbindung hinzufügen', 'Do you really want to remove this link: "%s"?' => 'Die Verbindung "%s" wirklich löschen?', 'Do you really want to remove this link with task #%d?' => 'Die Verbindung mit der Aufgabe #%d wirklich löschen?', @@ -641,7 +630,7 @@ return array( 'Burndown chart' => 'Burndown-Diagramm', 'This chart show the task complexity over the time (Work Remaining).' => 'Dieses Diagramm zeigt die Aufgabenkomplexität über den Faktor Zeit (Verbleibende Arbeit).', 'Screenshot taken %s' => 'Screenshot aufgenommen %s ', - 'Add a screenshot' => 'Füge einen Screenshot hinzu', + 'Add a screenshot' => 'Screenshot hinzufügen', 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => 'Nimm einen Screenshot auf und drücke STRG+V oder ⌘+V um ihn hier einzufügen.', 'Screenshot uploaded successfully.' => 'Screenshot erfolgreich hochgeladen.', 'SEK - Swedish Krona' => 'SEK - Schwedische Kronen', @@ -734,7 +723,7 @@ return array( 'Time spent changed: %sh' => 'Verbrauchte Zeit geändert: %sh', 'Time estimated changed: %sh' => 'Geschätzte Zeit geändert: %sh', 'The field "%s" have been updated' => 'Das Feld "%s" wurde verändert', - 'The description have been modified' => 'Die Beschreibung wurde geändert', + 'The description has been modified:' => 'Die Beschreibung wurde geändert:', 'Do you really want to close the task "%s" as well as all subtasks?' => 'Soll die Aufgabe "%s" wirklich geschlossen werden? (einschließlich Teilaufgaben)', 'I want to receive notifications for:' => 'Ich möchte Benachrichtigungen erhalten für:', 'All tasks' => 'Alle Aufgaben', @@ -753,8 +742,6 @@ return array( 'My activity stream' => 'Aktivitätsstream', 'My calendar' => 'Mein Kalender', 'Search tasks' => 'Suche nach Aufgaben', - 'Back to the calendar' => 'Zurück zum Kalender', - 'Filters' => 'Filter', 'Reset filters' => 'Filter zurücksetzen', 'My tasks due tomorrow' => 'Meine morgen fälligen Aufgaben', 'Tasks due today' => 'Heute fällige Aufgaben', @@ -854,7 +841,6 @@ return array( 'End date:' => 'Endedatum:', 'There is no start date or end date for this project.' => 'Es gibt kein Startdatum oder Endedatum für dieses Projekt', 'Projects Gantt chart' => 'Projekt Gantt Diagramm', - 'Link type' => 'Verbindungstyp', 'Change task color when using a specific task link' => 'Aufgabefarbe ändern bei bestimmter Aufgabenverbindung', 'Task link creation or modification' => 'Aufgabenverbindung erstellen oder bearbeiten', 'Milestone' => 'Meilenstein', @@ -906,7 +892,6 @@ return array( 'Shared' => 'Geteilt', 'Owner' => 'Eigentümer', 'Unread notifications' => 'Ungelesene Benachrichtigungen', - 'My filters' => 'Meine Filter', 'Notification methods:' => 'Benachrichtigungs-Methoden:', 'Import tasks from CSV file' => 'Importiere Aufgaben aus CSV Datei', 'Unable to read your file' => 'Die Datei kann nicht gelesen werden', @@ -930,7 +915,7 @@ return array( 'change sorting' => 'Sortierung ändern', 'Tasks Importation' => 'Aufgaben Import', 'Delimiter' => 'Trennzeichen', - 'Enclosure' => 'Anlage', + 'Enclosure' => 'Textbegrenzer', 'CSV File' => 'CSV Datei', 'Instructions' => 'Anweisungen', 'Your file must use the predefined CSV format' => 'Ihre Datei muss das vorgegebene CSV Format haben', @@ -944,6 +929,7 @@ return array( 'Usernames must be lowercase and unique' => 'Benutzernamen müssen in Kleinbuschstaben und eindeutig sein', 'Passwords will be encrypted if present' => 'Passwörter werden verschlüsselt wenn vorhanden', '%s attached a new file to the task %s' => '%s hat eine neue Datei zur Aufgabe %s hinzufgefügt', + 'Link type' => 'Verbindungstyp', 'Assign automatically a category based on a link' => 'Linkbasiert eine Kategorie automatisch zuordnen', 'BAM - Konvertible Mark' => 'BAM - Konvertible Mark', 'Assignee Username' => 'Benutzername des Zuständigen', @@ -1053,7 +1039,6 @@ return array( 'Close a task when there is no activity' => 'Schliesse eine Aufgabe, wenn keine Aktivitäten vorhanden sind', 'Duration in days' => 'Dauer in Tagen', 'Send email when there is no activity on a task' => 'Versende eine Email, wenn keine Aktivitäten an einer Aufgabe vorhanden sind', - 'List of external links' => 'Liste der externen Verbindungen', 'Unable to fetch link information.' => 'Kann keine Informationen über Verbindungen holen', 'Daily background job for tasks' => 'Tägliche Hintergrundarbeit für Aufgaben', 'Auto' => 'Auto', @@ -1065,15 +1050,13 @@ return array( 'Add external link' => 'Externe Verbindung hinzufügen', 'Type' => 'Typ', 'Dependency' => 'Abhängigkeit', - 'Add internal link' => 'Füge interne Verbindung hinzu', + 'Add internal link' => 'Interne Verbindung hinzufügen', 'Add a new external link' => 'Füge eine neue externe Verbindung hinzu', 'Edit external link' => 'Externe Verbindung bearbeiten', 'External link' => 'Externe Verbindung', 'Copy and paste your link here...' => 'Kopieren Sie Ihren Link hier...', 'URL' => 'URL', - 'There is no external link for the moment.' => 'Es gibt im Moment keine externe Verbindung.', 'Internal links' => 'Interne Verbindungen', - 'There is no internal link for the moment.' => 'Es gibt im Moment keine interne Verbindung.', 'Assign to me' => 'Mir zuweisen', 'Me' => 'Mich', 'Do not duplicate anything' => 'Nichts duplizieren', @@ -1081,7 +1064,6 @@ return array( 'Users management' => 'Benutzermanagement', 'Groups management' => 'Gruppenmanagement', 'Create from another project' => 'Von einem anderen Projekt erstellen', - 'There is no subtask at the moment.' => 'Es gibt im Moment keine Teilaufgabe', 'open' => 'offen', 'closed' => 'geschlossen', 'Priority:' => 'Priorität:', @@ -1100,7 +1082,6 @@ return array( 'Started:' => 'Gestarted:', 'Moved:' => 'Verschoben:', 'Task #%d' => 'Aufgabe #%d', - 'Sub-tasks' => 'Teilaufgaben', 'Date and time format' => 'Datums- und Zeitformat', 'Time format' => 'Zeitformat', 'Start date: ' => 'Anfangsdatum:', @@ -1141,11 +1122,35 @@ return array( 'User filters' => 'Benutzer-Filter', 'Category filters' => 'Kategorie-Filter', 'Upload a file' => 'Eine Datei hochladen', - 'There is no attachment at the moment.' => 'Es gibt zur Zeit keine Anhänge', 'View file' => 'Datei ansehen', 'Last activity' => 'Letzte Aktivität', 'Change subtask position' => 'Position der Unteraufgabe ändern', 'This value must be greater than %d' => 'Dieser Wert muss größer als %d sein', 'Another swimlane with the same name exists in the project' => 'Es gibt bereits eine Swimlane mit diesem Namen im Projekt', 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => 'Beispiel: http://example.kanboard.net (wird zum Erstellen absoluter URLs genutzt)', + 'Actions duplicated successfully.' => 'Aktionen erfolgreich dupliziert', + 'Unable to duplicate actions.' => 'Aktionen können nicht dupliziert werden.', + 'Add a new action' => 'Neue Aktion hinzufügen', + 'Import from another project' => 'Von einem anderen Projekt importieren', + 'There is no action at the moment.' => 'Es gibt zur Zeit keine Aktionen.', + 'Import actions from another project' => 'Aktionen von einem anderen Projekt importieren', + 'There is no available project.' => 'Es ist kein Projekt verfügbar.', + // 'Local File' => '', + // 'Configuration' => '', + // 'PHP version:' => '', + // 'PHP SAPI:' => '', + // 'OS version:' => '', + // 'Database version:' => '', + // 'Browser:' => '', + // 'Task view' => '', + // 'Edit task' => '', + // 'Edit description' => '', + // 'New internal link' => '', + // 'Display list of keyboard shortcuts' => '', + // 'Menu' => '', + // 'Set start date' => '', + // 'Avatar' => '', + // 'Upload my avatar image' => '', + // 'Remove my image' => '', + // 'The OAuth2 state parameter is invalid' => '', ); diff --git a/sources/app/Locale/el_GR/translations.php b/sources/app/Locale/el_GR/translations.php index e59949c..9a31e48 100644 --- a/sources/app/Locale/el_GR/translations.php +++ b/sources/app/Locale/el_GR/translations.php @@ -8,7 +8,6 @@ return array( 'Edit' => 'Διόρθωση', 'remove' => 'αφαιρετής', 'Remove' => 'Αφαίρεση', - 'Update' => 'Ενημέρωση', 'Yes' => 'Ναι', 'No' => 'Όχι', 'cancel' => 'ακύρωση', @@ -18,24 +17,24 @@ return array( 'Green' => 'Πράσινο', 'Purple' => 'Βιολετί', 'Red' => 'Κόκκινο', - 'Orange' => 'Ποστοκαλί', + 'Orange' => 'Πορτοκαλί', 'Grey' => 'Γκρίζο', 'Brown' => 'Καφέ', 'Deep Orange' => 'Βαθύ πορτοκαλί', 'Dark Grey' => 'Βαθύ γκρί', 'Pink' => 'Ρόζ', - 'Teal' => 'Τουρκουάζ', + 'Teal' => 'Τυρκουάζ', 'Cyan' => 'Γαλάζιο', 'Lime' => 'Λεμονί', 'Light Green' => 'Ανοιχτό πράσινο', 'Amber' => 'Κεχριμπαρί', 'Save' => 'Αποθήκευση', 'Login' => 'Είσοδος', - 'Official website:' => 'Επίσημο web site :', + 'Official website:' => 'Επίσημο web site:', 'Unassigned' => 'Μη εκχωρημένο', 'View this task' => 'Προβολή της εργασίας', 'Remove user' => 'Αφαίρεση χρήστη', - 'Do you really want to remove this user: "%s"?' => 'Θέλετε σίγουρα να αφαιρέσετε αυτό τον χρήστη : « %s » ?', + 'Do you really want to remove this user: "%s"?' => 'Θέλετε σίγουρα να αφαιρέσετε αυτό τον χρήστη: « %s » ?', 'New user' => 'Νέος Χρήστης', 'All users' => 'Όλοι οι χρήστες', 'Username' => 'Όνομα χρήστη', @@ -60,7 +59,6 @@ return array( 'Actions' => 'Ενέργειες', 'Inactive' => 'Ανενεργός', 'Active' => 'Ενεργός', - 'Add this column' => 'Προσθήκη αυτής της στήλης', '%d tasks on the board' => '%d εργασίες στον κεντρικό πίνακα έργου', '%d tasks in total' => '%d εργασιών στο σύνολο', 'Unable to update this board.' => 'Αδύνατη η ενημέρωση αυτού του πίνακα', @@ -68,24 +66,23 @@ return array( 'Disable' => 'Απενεργοποίηση', 'Enable' => 'Ενεργοποίηση', 'New project' => 'Νέο έργο', - 'Do you really want to remove this project: "%s"?' => 'Αφαίρεση του έργου : « %s » ?', + 'Do you really want to remove this project: "%s"?' => 'Αφαίρεση του έργου: « %s » ?', 'Remove project' => 'Αφαίρεση του έργου', 'Edit the board for "%s"' => 'Διόρθωση πίνακα από « %s »', 'All projects' => 'Όλα τα έργα', 'Add a new column' => 'Πρόσθήκη στήλης', 'Title' => 'Τίτλος', - 'Nobody assigned' => 'Δεν έχει ανατεθεί', 'Assigned to %s' => 'Ανατιθεμένο στον %s', 'Remove a column' => 'Αφαίρεση στήλης', 'Remove a column from a board' => 'Αφαίρεση στήλης από τον πίνακα', 'Unable to remove this column.' => 'Αδύνατη η αφαίρεση της στήλης', - 'Do you really want to remove this column: "%s"?' => 'Θέλετε να αφαιρέσετε τη στήλη : « %s » ?', + 'Do you really want to remove this column: "%s"?' => 'Θέλετε να αφαιρέσετε τη στήλη: « %s » ?', 'This action will REMOVE ALL TASKS associated to this column!' => 'Αυτή η ενέργεια θα ΑΦΑΙΡΕΣΕΙ ΟΛΕΣ ΤΙΣ ΕΡΓΑΣΙΕΣ που είναι σχετικές με τη στήλη!!', 'Settings' => 'Προτιμήσεις', 'Application settings' => 'Παραμετροποίηση εφαρμογής', 'Language' => 'Γλώσσα', - 'Webhook token:' => 'Διακριτικό ασφαλείας (token) webhooks :', - 'API token:' => 'Διακριτικό ασφαλείας (token) API :', + 'Webhook token:' => 'Διακριτικό ασφαλείας (token) webhooks:', + 'API token:' => 'Διακριτικό ασφαλείας (token) API:', 'Database size:' => 'Μέγεθος βάσης δεδομένων :', 'Download the database' => 'Κατεβάστε τη βάση δεδομένων', 'Optimize the database' => 'Βελτιστοποίηση της βάσης δεδομένων', @@ -95,7 +92,7 @@ return array( 'Edit a task' => 'Διόρθωση εργασίας', 'Column' => 'Στήλη', 'Color' => 'Χρώμα', - 'Assignee' => 'Ανατεθιμένα', + 'Assignee' => 'Ανατεθιμένο στον χρήστη', 'Create another task' => 'Δημιουργία και άλλης εργασίας', 'New task' => 'Νέα εργασία', 'Open a task' => 'Άνοιγμα εργασίας', @@ -168,7 +165,6 @@ return array( 'Task count' => 'Αρίθμηση εργασιών', 'User' => 'Χρήστης', 'Comments' => 'Σχόλια', - 'Write your text in Markdown' => 'Δυνατότητα γραφής και σε Markdown', 'Leave a comment' => 'Αφήστε ένα σχόλιο', 'Comment is required' => 'Το σχόλιο απαιτείται', 'Leave a description' => 'Αφήστε μια περιγραφή', @@ -184,7 +180,6 @@ return array( 'Unable to remove this action.' => 'Δεν είναι δυνατή η αφαίρεση αυτής της ενέργειας', 'Action removed successfully.' => 'Η ενέργεια αφαιρέθηκε με επιτυχία.', 'Automatic actions for the project "%s"' => 'Αυτόματες ενέργειες για το έργο « %s »', - 'Defined actions' => 'Ορισμένες ενέργειες', 'Add an action' => 'Προσθήκη ενέργειας', 'Event name' => 'Ονομασία συμβάντος', 'Action name' => 'Ονομασία ενέργειας', @@ -194,7 +189,6 @@ return array( 'When the selected event occurs execute the corresponding action.' => 'Όταν εμφανίζεται το επιλεγμένο συμβάν εκτελέστε την αντίστοιχη ενέργεια.', 'Next step' => 'Επόμενο βήμα', 'Define action parameters' => 'Ορισμός παραμέτρων ενέργειας', - 'Save this action' => 'Αποθήκευση ενέργειας', 'Do you really want to remove this action: "%s"?' => 'Αφαίρεση της ενέργειας: « %s » ?', 'Remove an automatic action' => 'Αφαίρεση της αυτόματης ενέργειας', 'Assign the task to a specific user' => 'Ανάθεση της εργασίας σε συγκεκριμένο χρήστη', @@ -228,7 +222,7 @@ return array( 'Persistent connections' => 'Μόνιμες συνδέσεις', 'No session.' => 'Καμμία συνεδρία', 'Expiration date' => 'Ημερομηνία λήξης', - 'Remember Me' => 'Remember Me', + 'Remember Me' => 'Να με θυμάσαι', 'Creation date' => 'Ημερομηνία δημιουργίας', 'Everybody' => 'Όλα', 'Open' => 'Ανοικτά', @@ -236,7 +230,7 @@ return array( 'Search' => 'Αναζήτηση', 'Nothing found.' => 'Δεν βρέθηκε.', 'Due date' => 'Μέχρι την ημερομηνία', - 'Others formats accepted: %s and %s' => 'Άλλες δεκτές μορφοποιήσεις : %s και %s', + 'Others formats accepted: %s and %s' => 'Άλλες δεκτές μορφοποιήσεις: %s και %s', 'Description' => 'Περιγραφή', '%d comments' => '%d σχόλια', '%d comment' => '%d σχόλιο', @@ -254,7 +248,7 @@ return array( 'Assign automatically a category based on a color' => 'Αυτόματη εκχώρηση μιας κατηγορίας με βάση το χρώμα', 'Task creation or modification' => 'Δημιουργία ή τροποποίηση εργασιών', 'Category' => 'Κατηγορία', - 'Category:' => 'Κατηγορία :', + 'Category:' => 'Κατηγορία:', 'Categories' => 'Κατηγορίες', 'Category not found.' => 'Η κατηγορία δεν βρέθηκε', 'Your category have been created successfully.' => 'Η κατηγορία δημιουργήθηκε.', @@ -283,7 +277,7 @@ return array( 'Edit a comment' => 'Διόρθωση σχολίου', 'Summary' => 'Περίληψη', 'Time tracking' => 'Παρακολούθηση χρόνου', - 'Estimate:' => 'Κατ\' εκτίμηση :', + 'Estimate:' => 'Κατ\' εκτίμηση:', 'Spent:' => 'Ξοδεύτηκε :', 'Do you really want to remove this sub-task?' => 'Διαγραφή της υπο-εργασίας ?', 'Remaining:' => 'Απομένει :', @@ -292,7 +286,7 @@ return array( 'estimated' => 'κατ\' εκτίμηση', 'Sub-Tasks' => 'Υπο-Εργασίες', 'Add a sub-task' => 'Προσθήκη υπο-εργασίας', - 'Original estimate' => 'Original estimate', + 'Original estimate' => 'Αρχική πρόβλεψη χρόνου', 'Create another sub-task' => 'Δημιουργία κι άλλης υπο-εργασίας', 'Time spent' => 'Χρόνος που ξοδεύτηκε', 'Edit a sub-task' => 'Διόρθωση υπο-εργασίας', @@ -323,22 +317,22 @@ return array( 'Project cloned successfully.' => 'Το έργο κλωνοποιήθηκε με επιτυχία.', 'Unable to clone this project.' => 'Αδύνατο να κλωνοποιηθεί το έργο.', 'Enable email notifications' => 'Ενεργοποίηση ειδοποιήσεων ηλεκτρονικού ταχυδρομείου', - 'Task position:' => 'Θέση έργου :', + 'Task position:' => 'Θέση έργου:', 'The task #%d have been opened.' => 'Η εργασία #%d έχει ανοίξει.', 'The task #%d have been closed.' => 'Η εργασία #%d έχει κλείσει.', 'Sub-task updated' => 'Η υπο-εργασία ενημερώθηκε', - 'Title:' => 'Τίτλος :', - 'Status:' => 'Κατάσταση :', - 'Assignee:' => 'Εντολοδόχος :', - 'Time tracking:' => 'Παρακολούθηση του χρόνου :', + 'Title:' => 'Τίτλος:', + 'Status:' => 'Κατάσταση:', + 'Assignee:' => 'Εντολοδόχος:', + 'Time tracking:' => 'Παρακολούθηση του χρόνου:', 'New sub-task' => 'Νέα υπο-εργασία', 'New attachment added "%s"' => 'Νέα επικόλληση προστέθηκε « %s »', - 'Comment updated' => 'Το σχόλιο ενημερώθηκε', 'New comment posted by %s' => 'Νέο σχόλιο από τον χρήστη « %s »', 'New attachment' => 'New attachment', 'New comment' => 'Νέο σχόλιο', + 'Comment updated' => 'Το σχόλιο ενημερώθηκε', 'New subtask' => 'Νέα υπο-εργασία', - 'Subtask updated' => 'Υπο-Εργασία ενημερώθηκε', + 'Subtask updated' => 'Η Υπο-Εργασία ενημερώθηκε', 'Task updated' => 'Η εργασία ενημερώθηκε', 'Task closed' => 'Η εργασία έκλεισε', 'Task opened' => 'Η εργασία άνοιξε', @@ -349,8 +343,8 @@ return array( 'Disable public access' => 'Απενεργοποίηση δημόσιας πρόσβασης', 'Enable public access' => 'Ενεργοποίηση δημόσιας πρόσβασης', 'Public access disabled' => 'Δημόσια πρόσβαση απενεργοποιήθηκε', - 'Do you really want to disable this project: "%s"?' => 'Θέλετε πραγματικά να απενεργοποιήσετε το έργο : « %s » ?', - 'Do you really want to enable this project: "%s"?' => 'Θέλετε πραγματικά να ενεργοποιήσετε το έργο : « %s » ?', + 'Do you really want to disable this project: "%s"?' => 'Θέλετε πραγματικά να απενεργοποιήσετε το έργο: « %s » ?', + 'Do you really want to enable this project: "%s"?' => 'Θέλετε πραγματικά να ενεργοποιήσετε το έργο: « %s » ?', 'Project activation' => 'Ενεργοποίηση έργου', 'Move the task to another project' => 'Μεταφορά της εργασίας σε άλλο έργο', 'Move to another project' => 'Μεταφορά σε άλλο έργο', @@ -362,12 +356,12 @@ return array( 'Remote' => 'Απομακρυσμένη', 'Enabled' => 'Ενεργή', 'Disabled' => 'Απενεργοποιημένη', - 'Username:' => 'Username :', - 'Name:' => 'Όνομα :', - 'Email:' => 'Email :', - 'Notifications:' => 'Ειδοποιήσεις :', + 'Username:' => 'Username:', + 'Name:' => 'Όνομα:', + 'Email:' => 'Email:', + 'Notifications:' => 'Ειδοποιήσεις:', 'Notifications' => 'Ειδοποιήσεις', - 'Account type:' => 'Τύπος λογαριασμού :', + 'Account type:' => 'Τύπος λογαριασμού:', 'Edit profile' => 'Επεξεργασία προφίλ', 'Change password' => 'Αλλαγή password', 'Password modification' => 'Τροποποίηση password ', @@ -394,8 +388,8 @@ return array( 'RSS feed' => 'RSS feed', '%s updated a comment on the task #%d' => '%s ενημέρωσε ένα σχόλιο στην εργασία n°%d', '%s commented on the task #%d' => '%s σχολίασε την εργασία n°%d', - '%s updated a subtask for the task #%d' => '%s ενημέρωσε μια υπο-εργασία στην εργασία n °%d', - '%s created a subtask for the task #%d' => '%s δημιούργησε μια υπο-εργασία στην εργασία n°%d', + '%s updated a subtask for the task #%d' => '%s ενημερώθηκε μια υπο-εργασία στην εργασία n °%d', + '%s created a subtask for the task #%d' => '%s δημιουργήθηκε μια υπο-εργασία στην εργασία n°%d', '%s updated the task #%d' => '%s ενημέρωσε την εργασία n°%d', '%s created the task #%d' => '%s δημιούργησε την εργασία n°%d', '%s closed the task #%d' => '%s έκλεισε την εργασία n°%d', @@ -417,13 +411,13 @@ return array( 'Label' => 'Label', 'Database' => 'Database', 'About' => 'About', - 'Database driver:' => 'Database driver :', + 'Database driver:' => 'Database driver:', 'Board settings' => 'Board settings', 'URL and token' => 'URL / token', 'Webhook settings' => 'Webhook settings', - 'URL for task creation:' => 'URL για δημιουργία εργασίας: :', + 'URL for task creation:' => 'URL για δημιουργία εργασίας:', 'Reset token' => 'Reset token', - 'API endpoint:' => 'URL API :', + 'API endpoint:' => 'URL API:', 'Refresh interval for private board' => 'Ανανέωση interval στο private board', 'Refresh interval for public board' => 'Ανανέωση interval στο public board', 'Task highlight period' => 'Περίοδος εργασίας', @@ -433,10 +427,9 @@ return array( 'Application URL' => 'Application URL', 'Token regenerated.' => 'Token regenerated.', 'Date format' => 'Μορφή ημερομηνίας', - 'ISO format is always accepted, example: "%s" and "%s"' => 'ISO format είναι πάντα αποδεκτό, π.χ. : « %s » και « %s »', + 'ISO format is always accepted, example: "%s" and "%s"' => 'ISO format είναι πάντα αποδεκτό, π.χ.: « %s » και « %s »', 'New private project' => 'Νέο ιδιωτικό έργο', 'This project is private' => 'Αυτό το έργο είναι ιδιωτικό', - 'Type here to create a new sub-task' => 'Πληκτρολογήστε εδώ για να δημιουργήσετε μια νέα υπο-εργασία', 'Add' => 'Προσθήκη', 'Start date' => 'Ημερομηνία έναρξης', 'Time estimated' => 'Εκτιμώμενος χρόνος', @@ -487,21 +480,18 @@ return array( 'Daily project summary export for "%s"' => 'Εξαγωγή της καθημερινής περίληψης του έργου « %s »', 'Exports' => 'Εξαγωγές', 'This export contains the number of tasks per column grouped per day.' => 'Αυτή η κατάσταση περιέχει τον αριθμό των εργασιών ανά στήλη ομαδοποιημένα ανά ημέρα.', - 'Nothing to preview...' => 'Τίποτα για προεπισκόπηση...', - 'Preview' => 'Προεπισκόπηση', - 'Write' => 'Write', - 'Active swimlanes' => 'Ενεργά swimlanes', - 'Add a new swimlane' => 'Πρόσθεσε ένα νέο λωρίδα', - 'Change default swimlane' => 'Αλλαγή του default λωρίδα', - 'Default swimlane' => 'Default λωρίδα', + 'Active swimlanes' => 'Ενεργές λωρίδες', + 'Add a new swimlane' => 'Προσθήκη λωρίδας', + 'Change default swimlane' => 'Αλλαγή της εξ\' ορισμού λωρίδας', + 'Default swimlane' => 'Εξ\' ορισμού λωρίδα', 'Do you really want to remove this swimlane: "%s"?' => 'Σίγουρα θέλετε να αφαιρέσετε τη λωρίδα : « %s » ?', - 'Inactive swimlanes' => 'Λωρίδες ανενεργές', - 'Remove a swimlane' => 'Αφαιρέστε μια λωρίδα', + 'Inactive swimlanes' => 'Ανενεργές Λωρίδες', + 'Remove a swimlane' => 'Αφαίρεση λωρίδας', 'Show default swimlane' => 'Εμφάνιση προεπιλεγμένων λωρίδων', 'Swimlane modification for the project "%s"' => 'Τροποποίηση λωρίδας για το έργο « %s »', 'Swimlane not found.' => 'Η λωρίδα δεν βρέθηκε.', 'Swimlane removed successfully.' => 'Η λωρίδα αφαιρέθηκε με επιτυχία.', - 'Swimlanes' => 'Swimlanes', + 'Swimlanes' => 'Λωρίδες', 'Swimlane updated successfully.' => 'Η λωρίδα ενημερώθηκε με επιτυχία.', 'The default swimlane have been updated successfully.' => 'Η προεπιλεγμένη λωρίδα ενημερώθηκε με επιτυχία.', 'Unable to remove this swimlane.' => 'Αδύνατο να αφαιρεθεί η λωρίδα.', @@ -518,8 +508,8 @@ return array( 'Task Title' => 'Τίτλος εργασίας', 'Untitled' => 'Χωρίς τίτλο', 'Application default' => 'Προεπιλογή από την εφαρμογή', - 'Language:' => 'Γλώσσα :', - 'Timezone:' => 'Timezone :', + 'Language:' => 'Γλώσσα:', + 'Timezone:' => 'Timezone:', 'All columns' => 'Όλες οι στήλες', 'Calendar' => 'Ημερολόγιο', 'Next' => 'Επόμενο', @@ -535,7 +525,7 @@ return array( 'Subtask timesheet' => 'Πρόγραμμα υπο-εργασίας', 'There is nothing to show.' => 'Δεν υπάρχει κάτι.', 'Time Tracking' => 'Παρακολούθηση χρονοδιαγράμματος', - 'You already have one subtask in progress' => 'Έχτε ήδη μια υπο-εργασία σε εξέλιξη', + 'You already have one subtask in progress' => 'Έχετε ήδη μια υπο-εργασία σε εξέλιξη', 'Which parts of the project do you want to duplicate?' => 'Ποιά κομμάτια του έργου θέλετε να αντιγράψετε ?', 'Disallow login form' => 'Απαγόρευση φόρμας σύνδεσης', 'Start' => 'Εκκίνηση', @@ -543,7 +533,6 @@ return array( 'Task age in days' => 'Χρόνος εργασίας σε μέρες', 'Days in this column' => 'Μέρες σε αυτή την στήλη', '%dd' => '%dημ', - 'Add a link' => 'Προσθήκη ενός link', 'Add a new link' => 'Προσθήκη ενός νέου link', 'Do you really want to remove this link: "%s"?' => 'Θέλετε σίγουρα να αφαιρέσετε αυτό το link : « %s » ?', 'Do you really want to remove this link with task #%d?' => 'Θέλετε σίγουρα να αφαιρέσετε αυτό το link του έργου n°%d ?', @@ -587,10 +576,10 @@ return array( 'Keyboard shortcuts' => 'Συντομεύσεις πληκτρολογίου', 'Open board switcher' => 'Άνοιγμα μεταγωγέα κεντρικού πίνακα', 'Application' => 'Εφαρμογή', - 'Compact view' => 'Συμπηκνωμένη προβολή', + 'Compact view' => 'Συμπυκνωμένη προβολή', 'Horizontal scrolling' => 'Οριζόντια ολίσθηση', - 'Compact/wide view' => 'Συμπηκνωμένη/Ευρεία Προβολή', - 'No results match:' => 'Δεν ταιριάζει κανένα αποτέλεσμα :', + 'Compact/wide view' => 'Συμπυκνωμένη/Ευρεία Προβολή', + 'No results match:' => 'Δεν ταιριάζει κανένα αποτέλεσμα:', 'Currency' => 'Νόμισμα', 'Private project' => 'Ιδιωτικό έργο', 'AUD - Australian Dollar' => 'AUD - Australian Dollar', @@ -633,7 +622,7 @@ return array( 'Two factor authentication' => 'Κωδικός ελέγχου ταυτότητας δύο παραγόντων', 'This QR code contains the key URI: ' => 'Αυτό το QR code περιέχει το url : ', 'Check my code' => 'Έλεγχος του κωδικού μου', - 'Secret key: ' => 'Μυστικό κλειδί : ', + 'Secret key: ' => 'Μυστικό κλειδί: ', 'Test your device' => 'Ελέγξτε τη συσκευή σας', 'Assign a color when the task is moved to a specific column' => 'Αντιστοίχιση χρώματος όταν η εργασία κινείται σε μια συγκεκριμένη στήλη', '%s via Kanboard' => '%s via Kanboard', @@ -719,22 +708,22 @@ return array( 'Project activities for %s' => 'Ενέργειες για το έργο « %s »', 'view the board on Kanboard' => 'δείτε τον πίνακα στο Kanboard', 'The task have been moved to the first swimlane' => 'Η εργασία αυτή έχει μετακινηθεί στην πρώτη λωρίδα', - 'The task have been moved to another swimlane:' => 'Η εργασία αυτή έχει μετακινηθεί σε άλλη λωρίδα :', + 'The task have been moved to another swimlane:' => 'Η εργασία αυτή έχει μετακινηθεί σε άλλη λωρίδα:', 'Overdue tasks for the project "%s"' => 'Εκπρόθεσμες εργασίες για το έργο « %s »', - 'New title: %s' => 'Νέος τίτλος : %s', + 'New title: %s' => 'Νέος τίτλος: %s', 'The task is not assigned anymore' => 'Η εργασία δεν έχει ανατεθεί πλέον', - 'New assignee: %s' => 'Καινούργια ανάθεση : %s', + 'New assignee: %s' => 'Καινούργια ανάθεση: %s', 'There is no category now' => 'Δεν υπάρχει κατηγορία τώρα', - 'New category: %s' => 'Νέα κατηγορία : %s', - 'New color: %s' => 'Νέο χρώμα : %s', - 'New complexity: %d' => 'Νέα πολυπλοκότητα : %d', + 'New category: %s' => 'Νέα κατηγορία: %s', + 'New color: %s' => 'Νέο χρώμα: %s', + 'New complexity: %d' => 'Νέα πολυπλοκότητα: %d', 'The due date have been removed' => 'Η ημερομηνία καθηκόντων έχει αφαιρεθεί', 'There is no description anymore' => 'Δεν υπάρχει περιγραφή πλέον', 'Recurrence settings have been modified' => 'Οι ρυθμίσεις επανάληψης έχουν τροποποιηθεί', - 'Time spent changed: %sh' => 'Ο χρόνος που πέρασε έχει αλλάξει : %sh', - 'Time estimated changed: %sh' => 'Ο εκτιμώμενος χρόνος άλλαξε : %sh', + 'Time spent changed: %sh' => 'Ο χρόνος που πέρασε έχει αλλάξει: %sh', + 'Time estimated changed: %sh' => 'Ο εκτιμώμενος χρόνος άλλαξε: %sh', 'The field "%s" have been updated' => 'Το πεδίο « %s » έχει ενημερωθεί', - 'The description have been modified' => 'Η περιγραφή έχει ενημερωθεί', + 'The description has been modified:' => 'Η περιγραφή έχει ενημερωθεί', 'Do you really want to close the task "%s" as well as all subtasks?' => 'Σίγουρα θέλετε να κλείσετε την εργασία « %s » και την υπο-εργασία ?', 'I want to receive notifications for:' => 'Επιθυμώ να λαμβάνω ενημερώσεις για :', 'All tasks' => 'Όλες οι εργασίες', @@ -753,8 +742,6 @@ return array( 'My activity stream' => 'Η ροή δραστηριοτήτων μου', 'My calendar' => 'Το ημερολόγιο μου', 'Search tasks' => 'Αναζήτηση εργασιών', - 'Back to the calendar' => 'Πίσω στο ημερολόγιο', - 'Filters' => 'Φίλτρα', 'Reset filters' => 'Επαναφορά φίλτρων', 'My tasks due tomorrow' => 'Οι εργασίες καθηκόντων μου αύριο', 'Tasks due today' => 'Οι εργασίες καθηκόντων μου αύριο', @@ -772,26 +759,26 @@ return array( 'Go to the search/filter box' => 'Μετάβαση στο πλαίσιο αναζήτησης / φίλτρο', 'There is no activity yet.' => 'Δεν υπάρχει καμία δραστηριότητα ακόμα.', 'No tasks found.' => 'Δεν βρέθηκαν εργασίες.', - 'Keyboard shortcut: "%s"' => 'Συντόμευση πληκτρολογίου : « %s »', + 'Keyboard shortcut: "%s"' => 'Συντόμευση πληκτρολογίου: « %s »', 'List' => 'Λίστα', 'Filter' => 'Φίλτρο', 'Advanced search' => 'Προχωρημένη Αναζήτηση', - 'Example of query: ' => 'Παράδειγμα ερωτήματος : ', - 'Search by project: ' => 'Αναζήτηση με βάση το έργο : ', - 'Search by column: ' => 'Αναζήτηση με βάση την στήλη : ', - 'Search by assignee: ' => 'Αναζήτηση με βάση τον δικαιοδόχο : ', - 'Search by color: ' => 'Αναζήτηση βάση χρώματος : ', - 'Search by category: ' => 'Αναζήτηση βάση κατηγορίας : ', - 'Search by description: ' => 'Αναζήτηση βάση περιγραφής : ', - 'Search by due date: ' => 'Αναζήτηση βάση ημέρας λήξης : ', + 'Example of query: ' => 'Παράδειγμα ερωτήματος: ', + 'Search by project: ' => 'Αναζήτηση με βάση το έργο: ', + 'Search by column: ' => 'Αναζήτηση με βάση την στήλη: ', + 'Search by assignee: ' => 'Αναζήτηση με βάση τον δικαιοδόχο: ', + 'Search by color: ' => 'Αναζήτηση βάση χρώματος: ', + 'Search by category: ' => 'Αναζήτηση βάση κατηγορίας: ', + 'Search by description: ' => 'Αναζήτηση βάση περιγραφής: ', + 'Search by due date: ' => 'Αναζήτηση βάση ημέρας λήξης: ', 'Lead and Cycle time for "%s"' => 'Lead & cycle time για « %s »', 'Average time spent into each column for "%s"' => 'Μέσος χρόνος παραμονής σε κάθε στήλη για « %s »', 'Average time spent into each column' => 'Μέσος χρόνος παραμονής σε κάθε στήλη', 'Average time spent' => 'Μέσος χρόνος που δαπανήθηκε', 'This chart show the average time spent into each column for the last %d tasks.' => 'Αυτό το γράφημα δείχνει ότι ο μέσος χρόνος που δαπανάται σε κάθε στήλη για τις τελευταίες %d εργασίες', 'Average Lead and Cycle time' => 'Average Lead & Cycle time', - 'Average lead time: ' => 'Average lead time : ', - 'Average cycle time: ' => 'Average cycle time : ', + 'Average lead time: ' => 'Average lead time: ', + 'Average cycle time: ' => 'Average cycle time: ', 'Cycle Time' => 'Cycle time', 'Lead Time' => 'Lead time', 'This chart show the average lead and cycle time for the last %d tasks over the time.' => 'Αυτό το γράφημα δείχνει το average lead and cycle time για τις τελευταίες %d εργασίες κατά τη διάρκεια του χρόνου.', @@ -815,23 +802,23 @@ return array( 'There is no destination project available.' => 'Δεν υπάρχει διαθέσιμο κανένα έργο προορισμού.', 'Trigger automatically subtask time tracking' => 'Αυτόματη ενεργοποίηση της παρακολούθησης χρόνου σε υπο-εργασίες', 'Include closed tasks in the cumulative flow diagram' => 'Να συμπεριλαμβάνονται οι κλειστές εργασίες στο συσσωρευτικό διάγραμμα ροής', - 'Current swimlane: %s' => 'Τρέχουσα λωρίδα : %s', - 'Current column: %s' => 'Τρέχουσα στήλη : %s', - 'Current category: %s' => 'Τρέχουσα κατηγορία : %s', + 'Current swimlane: %s' => 'Τρέχουσα λωρίδα: %s', + 'Current column: %s' => 'Τρέχουσα στήλη: %s', + 'Current category: %s' => 'Τρέχουσα κατηγορία: %s', 'no category' => 'Καμμία κατηγορία', - 'Current assignee: %s' => 'Τρέχον εκδοχέας : %s', + 'Current assignee: %s' => 'Τρέχον εκδοχέας: %s', 'not assigned' => 'δεν έχει εκχωρηθεί', - 'Author:' => 'Συγγραφέας :', + 'Author:' => 'Συγγραφέας:', 'contributors' => 'συνεισφέροντες', - 'License:' => 'Άδεια :', + 'License:' => 'Άδεια:', 'License' => 'Άδεια', 'Enter the text below' => 'Πληκτρολογήστε το παρακάτω κείμενο', 'Gantt chart for %s' => 'Gantt διάγραμμα για %s', 'Sort by position' => 'Ταξινόμηση κατά Θέση', 'Sort by date' => 'Ταξινόμηση κατά ημέρα', 'Add task' => 'Προσθήκη εργασίας', - 'Start date:' => 'Ημέρα εκκίνησης :', - 'Due date:' => 'Ημέρα καθηκόντων :', + 'Start date:' => 'Ημερομηνία εκκίνησης :', + 'Due date:' => 'Ημερομηνία λήξης:', 'There is no start date or due date for this task.' => 'Δεν υπάρχει ημερομηνία έναρξης ή ημερομηνία λήξης καθηκόντων για το έργο αυτό.', 'Moving or resizing a task will change the start and due date of the task.' => 'Μετακίνηση ή αλλαγή μεγέθους μιας εργασίας θα αλλάξει την ώρα έναρξης και ημερομηνία λήξης της εργασίας.', 'There is no task in your project.' => 'Δεν υπάρχει καμία εργασία στο έργο σας.', @@ -854,11 +841,10 @@ return array( 'End date:' => 'Ημερομηνία λήξης :', 'There is no start date or end date for this project.' => 'Δεν υπάρχει ημερομηνία έναρξης ή λήξης για το έργο αυτό.', 'Projects Gantt chart' => 'Διάγραμμα Gantt έργων', - 'Link type' => 'Τύπος συνδέσμου', 'Change task color when using a specific task link' => 'Αλλαγή χρώματος εργασίας χρησιμοποιώντας συγκεκριμένο σύνδεσμο εργασίας', 'Task link creation or modification' => 'Σύνδεσμος δημιουργίας ή τροποποίησης εργασίας', 'Milestone' => 'Ορόσημο', - 'Documentation: %s' => 'Τεκμηρίωση : %s', + 'Documentation: %s' => 'Τεκμηρίωση: %s', 'Switch to the Gantt chart view' => 'Μεταφορά σε προβολή διαγράμματος Gantt', 'Reset the search/filter box' => 'Αρχικοποίηση του πεδίου αναζήτησης/φιλτραρίσματος', 'Documentation' => 'Τεκμηρίωση', @@ -880,12 +866,12 @@ return array( 'Your custom filter have been updated successfully.' => 'Το παρεμετροποιημένο από τον χρήστη φίλτρο, διορθώθηκε με επιτυχία.', 'Unable to update custom filter.' => 'Δεν είναι δυνατή η ενημέρωση του παρεμετροποιημένου από τον χρήστη φίλτρου.', 'Web' => 'Web', - 'New attachment on task #%d: %s' => 'Νέο συνημμένο για την εργασία n°%d : %s', + 'New attachment on task #%d: %s' => 'Νέο συνημμένο για την εργασία n°%d: %s', 'New comment on task #%d' => 'Νέο σχόλιο για την εργασία n°%d', 'Comment updated on task #%d' => 'Ενημέρωση σχολίου για την εργασία n°%d', 'New subtask on task #%d' => 'Νέα υπο-εργασία για την εργασία n°%d', 'Subtask updated on task #%d' => 'Ενημέρωση υπό-εργασίας για την εργασία n°%d', - 'New task #%d: %s' => 'Νέα εργασία n°%d : %s', + 'New task #%d: %s' => 'Νέα εργασία n°%d: %s', 'Task updated #%d' => 'Η εργασία n°%d ενημερώθηκε με επιτυχία', 'Task #%d closed' => 'Η εργασία n°%d έκλεισε', 'Task #%d opened' => 'Η εργασία n°%d άνοιξε', @@ -906,8 +892,7 @@ return array( 'Shared' => 'Διαμοιρασμένα', 'Owner' => 'Ιδιοκτήτης', 'Unread notifications' => 'Αδιάβαστες ειδοποιήσεις', - 'My filters' => 'Τα φίλτρα μου', - 'Notification methods:' => 'Μέθοδοι ειδοποίησης :', + 'Notification methods:' => 'Μέθοδοι ειδοποίησης:', 'Import tasks from CSV file' => 'Εισαγωγή εργασιών μέσω αρχείου CSV', 'Unable to read your file' => 'Δεν είναι δυνατή η ανάγνωση του αρχείου', '%d task(s) have been imported successfully.' => '%d η(οι) εργασία(ες) εισήχθησαν με επιτυχία.', @@ -937,13 +922,14 @@ return array( 'Your file must be encoded in UTF-8' => 'Το αρχείο σας πρέπει να έχει κωδικοποίηση χαρακτήρων UTF-8', 'The first row must be the header' => 'Η πρώτη γραμμή πρέπει να είναι η κεφαλίδα', 'Duplicates are not verified for you' => 'Οι Διπλοεγγραφές δεν ελέγχονται', - 'The due date must use the ISO format: YYYY-MM-DD' => 'Η ημερομηνία λήξης πρέπει να χρησιμοποιεί τη μορφοποίηση ISO : EEEE-MM-HH ή στα αγγλικά YYYY-MM-DD', + 'The due date must use the ISO format: YYYY-MM-DD' => 'Η ημερομηνία λήξης πρέπει να χρησιμοποιεί τη μορφοποίηση ISO: EEEE-MM-HH ή στα αγγλικά YYYY-MM-DD', 'Download CSV template' => 'Κατέβασμα πρότυπου αρχείου CSV', 'No external integration registered.' => 'No external integration registered.', 'Duplicates are not imported' => 'Διπλοεγγραφές δεν εισήχθησαν', 'Usernames must be lowercase and unique' => 'Οι ονομασίες χρηστών πρέπει να είναι σε μικρά γράμματα (lowercase) και μοναδικά', 'Passwords will be encrypted if present' => 'Οι κωδικοί πρόσβασης κρυπτογραφούνται, αν υπάρχουν', '%s attached a new file to the task %s' => '%s νέο συνημμένο αρχείο της εργασίας %s', + 'Link type' => 'Τύπος συνδέσμου', 'Assign automatically a category based on a link' => 'Ανατίθεται αυτόματα κατηγορία, βασισμένη στον σύνδεσμο', 'BAM - Konvertible Mark' => 'BAM - Konvertible Mark', 'Assignee Username' => 'Δικαιοδόχο όνομα χρήστη', @@ -980,7 +966,7 @@ return array( 'There is no group.' => 'Δεν υπάρχει ομάδα.', 'External Id' => 'Εξωτερικό αναγνωριστικό', 'Add group member' => 'Προσθήκη μέλους ομάδας', - 'Do you really want to remove this group: "%s"?' => 'Αφαίρεση της ομάδας : « %s » ?', + 'Do you really want to remove this group: "%s"?' => 'Αφαίρεση της ομάδας: « %s » ?', 'There is no user in this group.' => 'Δεν υπάρχει χρήστης σε αυτήν την ομάδα', 'Remove this user' => 'Αφαίρεση χρήστη', 'Permissions' => 'Επιτρέψεις', @@ -993,7 +979,7 @@ return array( 'Group' => 'Ομάδα', 'Group Name' => 'Ονομασία ομάδας', 'Enter group name...' => 'Εισαγωγή ονομασίας ομάδας...', - 'Role:' => 'Ρόλος :', + 'Role:' => 'Ρόλος:', 'Project members' => 'Μέλη έργου', 'Compare hours for "%s"' => 'Σύγκριση ωρών για « %s »', '%s mentioned you in the task #%d' => '%s αναφέρονται σε εσάς, στη εργασία n°%d', @@ -1002,8 +988,8 @@ return array( 'You were mentioned in a comment on the task #%d' => 'Αναφέρεστε σε σχόλιο, στην εργασία n°%d', 'Mentioned' => 'Αναφέρεται', 'Compare Estimated Time vs Actual Time' => 'Σύγκριση προβλεπόμενου χρόνου vs πραγματικού χρόνου', - 'Estimated hours: ' => 'Προβλεπόμενες ώρες : ', - 'Actual hours: ' => 'Πραγματικές ώρες : ', + 'Estimated hours: ' => 'Προβλεπόμενες ώρες: ', + 'Actual hours: ' => 'Πραγματικές ώρες: ', 'Hours Spent' => 'Δαπανόμενες ώρες', 'Hours Estimated' => 'Προβλεπόμενες ώρες', 'Estimated Time' => 'Προβλεπόμενος χρόνος', @@ -1013,9 +999,9 @@ return array( 'Assign the task to the person who does the action when the column is changed' => 'Ανάθεση της εργασίας στο άτομο κάνει την ενέργεια όταν η στήλη αλλάζει', 'Close a task in a specific column' => 'Κλείσιμο εργασίας σε συγκεκριμένη στήλη', 'Time-based One-time Password Algorithm' => 'Time-based One-time Password Algorithm', - 'Two-Factor Provider: ' => 'Two-Factor Provider : ', - 'Disable two-factor authentication' => 'Disable two-factor authentication', - 'Enable two-factor authentication' => 'Enable two-factor authentication', + 'Two-Factor Provider: ' => 'Two-Factor Provider: ', + 'Disable two-factor authentication' => 'Απενεργοποίηση two-factor authentication', + 'Enable two-factor authentication' => 'Ενεργοποίηση two-factor authentication', 'There is no integration registered at the moment.' => 'There is no integration registered at the moment.', 'Password Reset for Kanboard' => 'Αρχικοποίηση κωδικών πρόσβασης για την εφαρμογή Kanboard', 'Forgot password?' => 'Ξεχάσατε τον κωδικό πρόσβασης ?', @@ -1023,7 +1009,7 @@ return array( 'Password Reset' => 'Αρχικοποίηση κωδικού πρόσβασης', 'New password' => 'Νέος κωδικός πρόσβασης', 'Change Password' => 'Αλλαγή κωδικού πρόσβασης', - 'To reset your password click on this link:' => 'Για να αρχικοποιηθεί ο κωδικός πρόσβασης σας πατήστε σε αυτόν τον σύνδεσμο :', + 'To reset your password click on this link:' => 'Για να αρχικοποιηθεί ο κωδικός πρόσβασης σας πατήστε σε αυτόν τον σύνδεσμο:', 'Last Password Reset' => 'Αρχικοποίηση τελευταίου κωδικού πρόσβασης', 'The password has never been reinitialized.' => 'Ο κωδικός πρόσβασης δεν μπορεί να αρχικοποιηθεί για δεύτερη φορά.', 'Creation' => 'Δημιουργία', @@ -1036,116 +1022,135 @@ return array( 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => 'Κανένα plugin δεν έχει καταχωρηθεί με τη μέθοδο της κοινοποίησης του έργου. Μπορείτε ακόμα να διαμορφώσετε τις μεμονωμένες κοινοποιήσεις στο προφίλ χρήστη σας.', 'My dashboard' => 'Το κεντρικό ταμπλό μου', 'My profile' => 'Το προφίλ μου', - // 'Project owner: ' => '', - // 'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => '', - // 'Project owner' => '', - // 'Those dates are useful for the project Gantt chart.' => '', - // 'Private projects do not have users and groups management.' => '', - // 'There is no project member.' => '', - // 'Priority' => '', - // 'Task priority' => '', - // 'General' => '', - // 'Dates' => '', - // 'Default priority' => '', - // 'Lowest priority' => '', - // 'Highest priority' => '', - // 'If you put zero to the low and high priority, this feature will be disabled.' => '', - // 'Close a task when there is no activity' => '', - // 'Duration in days' => '', - // 'Send email when there is no activity on a task' => '', - // 'List of external links' => '', - // 'Unable to fetch link information.' => '', - // 'Daily background job for tasks' => '', - // 'Auto' => '', - // 'Related' => '', - // 'Attachment' => '', - // 'Title not found' => '', - // 'Web Link' => '', - // 'External links' => '', - // 'Add external link' => '', - // 'Type' => '', - // 'Dependency' => '', - // 'Add internal link' => '', - // 'Add a new external link' => '', - // 'Edit external link' => '', - // 'External link' => '', - // 'Copy and paste your link here...' => '', - // 'URL' => '', - // 'There is no external link for the moment.' => '', - // 'Internal links' => '', - // 'There is no internal link for the moment.' => '', - // 'Assign to me' => '', - // 'Me' => '', - // 'Do not duplicate anything' => '', - // 'Projects management' => '', - // 'Users management' => '', - // 'Groups management' => '', - // 'Create from another project' => '', - // 'There is no subtask at the moment.' => '', - // 'open' => '', - // 'closed' => '', - // 'Priority:' => '', - // 'Reference:' => '', - // 'Complexity:' => '', - // 'Swimlane:' => '', - // 'Column:' => '', - // 'Position:' => '', - // 'Creator:' => '', - // 'Time estimated:' => '', - // '%s hours' => '', - // 'Time spent:' => '', - // 'Created:' => '', - // 'Modified:' => '', - // 'Completed:' => '', - // 'Started:' => '', - // 'Moved:' => '', - // 'Task #%d' => '', - // 'Sub-tasks' => '', - // 'Date and time format' => '', - // 'Time format' => '', - // 'Start date: ' => '', - // 'End date: ' => '', - // 'New due date: ' => '', - // 'Start date changed: ' => '', - // 'Disable private projects' => '', - // 'Do you really want to remove this custom filter: "%s"?' => '', - // 'Remove a custom filter' => '', - // 'User activated successfully.' => '', - // 'Unable to enable this user.' => '', - // 'User disabled successfully.' => '', - // 'Unable to disable this user.' => '', - // 'All files have been uploaded successfully.' => '', - // 'View uploaded files' => '', - // 'The maximum allowed file size is %sB.' => '', - // 'Choose files again' => '', - // 'Drag and drop your files here' => '', - // 'choose files' => '', - // 'View profile' => '', - // 'Two Factor' => '', - // 'Disable user' => '', - // 'Do you really want to disable this user: "%s"?' => '', - // 'Enable user' => '', - // 'Do you really want to enable this user: "%s"?' => '', - // 'Download' => '', - // 'Uploaded: %s' => '', - // 'Size: %s' => '', - // 'Uploaded by %s' => '', - // 'Filename' => '', - // 'Size' => '', - // 'Column created successfully.' => '', - // 'Another column with the same name exists in the project' => '', - // 'Default filters' => '', - // 'Your board doesn\'t have any column!' => '', - // 'Change column position' => '', - // 'Switch to the project overview' => '', - // 'User filters' => '', - // 'Category filters' => '', - // 'Upload a file' => '', - // 'There is no attachment at the moment.' => '', - // 'View file' => '', - // 'Last activity' => '', - // 'Change subtask position' => '', - // 'This value must be greater than %d' => '', - // 'Another swimlane with the same name exists in the project' => '', - // 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => '', + 'Project owner: ' => 'Ιδιοκτήτης έργου: ', + 'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => 'Το αναγνωριστικό έργου είναι προαιρετικό και πρέπει να είναι αλφαριθμητικό, για παράδειγμα: MYPROJECT', + 'Project owner' => 'Ιδιοκτήτης έργου', + 'Those dates are useful for the project Gantt chart.' => 'Οι ημερομηνίες αυτές είανι χρήσιμες για το διάγραμμα Gantt του έργου', + 'Private projects do not have users and groups management.' => 'Τα ιδιωτικά έργα δεν έχουν χρήστες και διαχείριση ομάδων', + 'There is no project member.' => 'Δεν υπάρχει μέλος στο έργο', + 'Priority' => 'Προτεραιότητα', + 'Task priority' => 'Προτεραιότητα εργασίας', + 'General' => 'Γενικά', + 'Dates' => 'Ημερομηνίες', + 'Default priority' => 'Εξ ορισμού προτεραιότητα', + 'Lowest priority' => 'η χαμηλότερη προτεραιότητα', + 'Highest priority' => 'η υψηλότερη προτεραιότητα', + 'If you put zero to the low and high priority, this feature will be disabled.' => 'Αν βάλετε μηδέν στη χαμηλή και στην υψηλή προτεραιότητα, το χαρακτηριστικό αυτό απενεργοποιείται.', + 'Close a task when there is no activity' => 'Κλείσιμο εργασίας όταν δεν υπάρχει δραστηριότητα', + 'Duration in days' => 'Διάρκεια σε ημέρες', + 'Send email when there is no activity on a task' => 'Αποστολή email όταν δεν υπάρχει δραστηριότητα σε εργασία', + 'Unable to fetch link information.' => 'Δεν είναι δυνατή η ανάλυση της πληροφορίας συνδεσμου', + 'Daily background job for tasks' => 'Ημερήσια παρασκηνιακή δουλειά για τις εργασίες', + 'Auto' => 'Αυτόματο', + 'Related' => 'Σχετίζεται', + 'Attachment' => 'Συνημμένο', + 'Title not found' => 'Ο τίτλος δεν βρέθηκε', + 'Web Link' => 'Σύνδεσμος web', + 'External links' => 'Εξωτερικοί σύνδεσμοι', + 'Add external link' => 'Προσθήκη εξωτερικού συνδέσμου', + 'Type' => 'Τύπος', + 'Dependency' => 'Εξάρτηση', + 'Add internal link' => 'Προσθήκη εσωτερικού συνδέσμου', + 'Add a new external link' => 'Προσθήκη νέου εξωτερικού συνδέσμου', + 'Edit external link' => 'Διόρθωση εξωτερικού συνδέσμου', + 'External link' => 'Εξωτερικός σύνδεσμος', + 'Copy and paste your link here...' => 'Κάντε αντιγραφή και επικόλληση εδώ', + 'URL' => 'URL', + 'Internal links' => 'Εσωτερικοί σύνδεσμοι', + 'Assign to me' => 'Αναττίθεται σε εμένα', + 'Me' => 'Σε μένα', + 'Do not duplicate anything' => 'Να μην γίνει κλωνοποίηση από άλλο έργο', + 'Projects management' => 'Διαχείριση έργων', + 'Users management' => 'Διαχείριση χρηστών', + 'Groups management' => 'Διαχείριση ομάδων', + 'Create from another project' => 'Δημιουργία από άλλο έργο', + 'open' => 'Ανοικτό', + 'closed' => 'Κλειστό', + 'Priority:' => 'Προτεραιότητα:', + 'Reference:' => 'Αναφορά:', + 'Complexity:' => 'Πολυπλοκότητα:', + 'Swimlane:' => 'Λωρίδα:', + 'Column:' => 'Στήλη:', + 'Position:' => 'Θέση:', + 'Creator:' => 'Δημιουργός:', + 'Time estimated:' => 'Προβλεπόμενη ώρα:', + '%s hours' => '%s ώρες', + 'Time spent:' => 'χρόνος που καταναλώθηκε:', + 'Created:' => 'Δημιουργήθηκε:', + 'Modified:' => 'Διορθώθηκε:', + 'Completed:' => 'Ολοκληρώθηκε:', + 'Started:' => 'Ξεκίνησε:', + 'Moved:' => 'Μετακινήθηκε:', + 'Task #%d' => 'Εργασία #%d', + 'Date and time format' => 'Μορφή ημερομηνίας και ώρας', + 'Time format' => 'Μορφή ώρας', + 'Start date: ' => 'Ημερομηνία έναρξης: ', + 'End date: ' => 'Ημερομηνία λήξης: ', + 'New due date: ' => 'Νέα ημερομηνία λήξης: ', + 'Start date changed: ' => 'Αλλαγμένη ημερομηνία έναρξης: ', + 'Disable private projects' => 'Απενεργοποίηση ιδιωτικών έργων', + 'Do you really want to remove this custom filter: "%s"?' => 'Αφαίρεση αυτού του οριζόμενου από το χρήστη φίλτρου %s ?', + 'Remove a custom filter' => 'Αφαίρεση του οριζόμενου από το χρήστη φίλτρου', + 'User activated successfully.' => 'Ο χρήστης ενεργοποιήθηκε με επιτυχία', + 'Unable to enable this user.' => 'Δεν είναι δυνατή η ενεργοποίηση του χρήστη', + 'User disabled successfully.' => 'Η απενεργοποίηση του χρήστη έγινε με επιτυχία', + 'Unable to disable this user.' => 'Δεν είναι δυνατή η απενεργοποίηση του χρήστη', + 'All files have been uploaded successfully.' => 'Όλα τα αρχεία ανέβηκαν με επιτυχία', + 'View uploaded files' => 'Προβολή ανεβασμένων αρχείων', + 'The maximum allowed file size is %sB.' => 'Το μέγιστο μέγεθος αρχείου που επιτρέπεται είναι %sB.', + 'Choose files again' => 'Επιλογή κι άλλων αρχείων', + 'Drag and drop your files here' => 'Σύρετε τα αρχεία σας εδώ', + 'choose files' => 'Επιλογή αρχείων', + 'View profile' => 'Προβολή προφίλ', + 'Two Factor' => 'Δύο παραγόντων', + 'Disable user' => 'Απενεργοποίηση χρήστη', + 'Do you really want to disable this user: "%s"?' => 'Απενεργοποίηση του χρήστη: "%s";', + 'Enable user' => 'Ενεργοποίηση χρήστη', + 'Do you really want to enable this user: "%s"?' => 'Ενεργοποίηση του χρήστη "%s";', + 'Download' => 'Κατέβασμα', + 'Uploaded: %s' => 'Ανέβηκε το αρχείο: %s', + 'Size: %s' => 'Μέγεθος: %s', + 'Uploaded by %s' => 'Ανέβασμα από τον χρήστη: %s', + 'Filename' => 'Όνομα αρχείου', + 'Size' => 'Μέγεθος', + 'Column created successfully.' => 'Η στήλη δημιουργήθηκε με επιτυχία.', + 'Another column with the same name exists in the project' => 'Μια άλλη στήλη με το ίδιο όνομα υπάρχει στο έργο', + 'Default filters' => 'Εξ\' ορισμού φίλτρα', + 'Your board doesn\'t have any column!' => 'Το ταμπλό δεν έχει καμία στήλη!!=', + 'Change column position' => 'Αλλαγή θέσης στήλης', + 'Switch to the project overview' => 'Αλλαγή προβολής σε επισκόπηση έργου', + 'User filters' => 'Φίλτρα οριζόμενα από τον χρήστη', + 'Category filters' => 'Κατηγορία φίλτρων', + 'Upload a file' => 'Ανέβασμα αρχείου', + 'View file' => 'Προβολή αρχείου', + 'Last activity' => 'Τελευταία δραστηριότητα', + 'Change subtask position' => 'Αλλαγή θέσης υπο-εργασίας', + 'This value must be greater than %d' => 'Η τιμή πρέπει να είναι μεγαλύτερη από %d', + 'Another swimlane with the same name exists in the project' => 'Μια άλλη λωρίδα, με το ίδιο όνομα υπάρχει στο έργο', + 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => 'Παράδειγμα: http://example.kanboard.net/ (χρησιμοποιείται για τη δημιουργία απόλυτων URLs)', + // 'Actions duplicated successfully.' => '', + // 'Unable to duplicate actions.' => '', + // 'Add a new action' => '', + // 'Import from another project' => '', + // 'There is no action at the moment.' => '', + // 'Import actions from another project' => '', + // 'There is no available project.' => '', + // 'Local File' => '', + // 'Configuration' => '', + // 'PHP version:' => '', + // 'PHP SAPI:' => '', + // 'OS version:' => '', + // 'Database version:' => '', + // 'Browser:' => '', + // 'Task view' => '', + // 'Edit task' => '', + // 'Edit description' => '', + // 'New internal link' => '', + // 'Display list of keyboard shortcuts' => '', + // 'Menu' => '', + // 'Set start date' => '', + // 'Avatar' => '', + // 'Upload my avatar image' => '', + // 'Remove my image' => '', + // 'The OAuth2 state parameter is invalid' => '', ); diff --git a/sources/app/Locale/es_ES/translations.php b/sources/app/Locale/es_ES/translations.php index 383a43d..c362336 100644 --- a/sources/app/Locale/es_ES/translations.php +++ b/sources/app/Locale/es_ES/translations.php @@ -8,7 +8,6 @@ return array( 'Edit' => 'Modificar', 'remove' => 'suprimir', 'Remove' => 'Suprimir', - 'Update' => 'Actualizar', 'Yes' => 'Sí', 'No' => 'No', 'cancel' => 'cancelar', @@ -60,7 +59,6 @@ return array( 'Actions' => 'Acciones', 'Inactive' => 'Inactivo', 'Active' => 'Activo', - 'Add this column' => 'Añadir esta columna', '%d tasks on the board' => '%d tareas en el tablero', '%d tasks in total' => '%d tareas en total', 'Unable to update this board.' => 'No se puede actualizar este tablero.', @@ -74,7 +72,6 @@ return array( 'All projects' => 'Todos los proyectos', 'Add a new column' => 'Añadir una nueva columna', 'Title' => 'Título', - 'Nobody assigned' => 'Nadie asignado', 'Assigned to %s' => 'Asignada a %s', 'Remove a column' => 'Suprimir esta columna', 'Remove a column from a board' => 'Suprimir una columna de un tablero', @@ -168,7 +165,6 @@ return array( 'Task count' => 'Contador de tareas', 'User' => 'Usuario', 'Comments' => 'Comentarios', - 'Write your text in Markdown' => 'Redacta el texto en Markdown', 'Leave a comment' => 'Dejar un comentario', 'Comment is required' => 'El comentario es obligatorio', 'Leave a description' => 'Dejar una descripción', @@ -184,7 +180,6 @@ return array( 'Unable to remove this action.' => 'No se puede suprimir esta accción.', 'Action removed successfully.' => 'La acción ha sido borrada correctamente.', 'Automatic actions for the project "%s"' => 'Acciones automatizadas para este proyecto « %s »', - 'Defined actions' => 'Acciones definidas', 'Add an action' => 'Agregar una acción', 'Event name' => 'Nombre del evento', 'Action name' => 'Nombre de la acción', @@ -194,7 +189,6 @@ return array( 'When the selected event occurs execute the corresponding action.' => 'Cuando tiene lugar el evento seleccionado, ejecutar la acción correspondiente.', 'Next step' => 'Etapa siguiente', 'Define action parameters' => 'Definición de los parametros de la acción', - 'Save this action' => 'Guardar esta acción', 'Do you really want to remove this action: "%s"?' => '¿Realmente desea suprimir esta acción « %s » ?', 'Remove an automatic action' => 'Suprimir una acción automatizada', 'Assign the task to a specific user' => 'Asignar una tarea a un usuario especifico', @@ -333,10 +327,10 @@ return array( 'Time tracking:' => 'Control de tiempo:', 'New sub-task' => 'Nueva subtarea', 'New attachment added "%s"' => 'Nuevo adjunto agregado "%s"', - 'Comment updated' => 'Comentario actualizado', 'New comment posted by %s' => 'Nuevo comentario agregado por %s', 'New attachment' => 'Nuevo adjunto', 'New comment' => 'Nuevo comentario', + 'Comment updated' => 'Comentario actualizado', 'New subtask' => 'Nueva subtarea', 'Subtask updated' => 'Subtarea actualizada', 'Task updated' => 'Tarea actualizada', @@ -436,7 +430,6 @@ return array( 'ISO format is always accepted, example: "%s" and "%s"' => 'El formato ISO siempre es aceptado, ejemplo: "%s" y "%s"', 'New private project' => 'Nuevo proyecto privado', 'This project is private' => 'Este proyecto es privado', - 'Type here to create a new sub-task' => 'Escriba aquí para crear una nueva sub-tarea', 'Add' => 'Añadir', 'Start date' => 'Fecha de inicio', 'Time estimated' => 'Tiempo estimado', @@ -487,9 +480,6 @@ return array( 'Daily project summary export for "%s"' => 'Exportar sumario diario del proyecto para "%s"', 'Exports' => 'Exportaciones', 'This export contains the number of tasks per column grouped per day.' => 'Esta exportación contiene el número de tereas por columna agrupada por día.', - 'Nothing to preview...' => 'Nada que previsualizar...', - 'Preview' => 'Previsualizar', - 'Write' => 'Grabar', 'Active swimlanes' => 'Calles activas', 'Add a new swimlane' => 'Añadir nueva calle', 'Change default swimlane' => 'Cambiar la calle por defecto', @@ -543,7 +533,6 @@ return array( 'Task age in days' => 'Edad de la tarea en días', 'Days in this column' => 'Días en esta columna', '%dd' => '%dd', - 'Add a link' => 'Añadir enlace', 'Add a new link' => 'Añadir nuevo enlace', 'Do you really want to remove this link: "%s"?' => '¿Realmente quiere quitar este enlace: "%s"?', 'Do you really want to remove this link with task #%d?' => '¿Realmente quiere quitar este enlace con esta tarea: #%d?', @@ -734,7 +723,7 @@ return array( 'Time spent changed: %sh' => 'Se ha cambiado el tiempo empleado: %sh', 'Time estimated changed: %sh' => 'Se ha cambiado el tiempo estimado: %sh', 'The field "%s" have been updated' => 'Se ha actualizado el campo "%s"', - 'The description have been modified' => 'Se ha modificado la descripción', + 'The description has been modified:' => 'Se ha modificado la descripción', 'Do you really want to close the task "%s" as well as all subtasks?' => '¿De verdad que quiere cerra la tarea "%s" así como todas las subtareas?', 'I want to receive notifications for:' => 'Deseo recibir notificaciones para:', 'All tasks' => 'Todas las tareas', @@ -753,8 +742,6 @@ return array( 'My activity stream' => 'Mi flujo de actividad', 'My calendar' => 'Mi calendario', 'Search tasks' => 'Buscar tareas', - 'Back to the calendar' => 'Volver al calendario', - 'Filters' => 'Filtros', 'Reset filters' => 'Limpiar filtros', 'My tasks due tomorrow' => 'Mis tareas a entregar mañana', 'Tasks due today' => 'Tareas a antregar hoy', @@ -854,7 +841,6 @@ return array( 'End date:' => 'Fecha final', 'There is no start date or end date for this project.' => 'No existe fecha de inicio o de fin para este proyecto.', 'Projects Gantt chart' => 'Diagramas de Gantt de los proyectos', - 'Link type' => 'Tipo de enlace', 'Change task color when using a specific task link' => 'Cambiar colo de la tarea al usar un enlace específico a tarea', 'Task link creation or modification' => 'Creación o modificación de enlace a tarea', 'Milestone' => 'Hito', @@ -906,7 +892,6 @@ return array( 'Shared' => 'Compartido', 'Owner' => 'Dueño', 'Unread notifications' => 'Notificaciones sin leer', - 'My filters' => 'Mis filtros', 'Notification methods:' => 'Métodos de notificación', 'Import tasks from CSV file' => 'Importar tareas desde archivo CSV', 'Unable to read your file' => 'No es posible leer el archivo', @@ -930,7 +915,7 @@ return array( 'change sorting' => 'Cambiar orden', 'Tasks Importation' => 'Importación de tareas', 'Delimiter' => 'Delimitador', - // 'Enclosure' => '', + 'Enclosure' => 'Recinto', 'CSV File' => 'Archivo CSV', 'Instructions' => 'Indicaciones', 'Your file must use the predefined CSV format' => 'Su archivo debe utilizar el formato CSV predeterminado', @@ -944,6 +929,7 @@ return array( 'Usernames must be lowercase and unique' => 'Los nombres de usuario deben ser únicos y contener sólo minúsculas', 'Passwords will be encrypted if present' => 'Las contraseñas serán cifradas si es que existen', '%s attached a new file to the task %s' => '%s adjuntó un nuevo archivo a la tarea %s', + 'Link type' => 'Tipo de enlace', 'Assign automatically a category based on a link' => 'Asignar una categoría automáticamente basado en un enlace', 'BAM - Konvertible Mark' => 'BAM - marco convertible', 'Assignee Username' => 'Nombre de usuario del concesionario', @@ -995,19 +981,19 @@ return array( 'Enter group name...' => 'Ingresa el nombre del grupo...', 'Role:' => 'Rol:', 'Project members' => 'Miembros del proyecto', - // 'Compare hours for "%s"' => '', + 'Compare hours for "%s"' => 'Compara horas con "%s"', '%s mentioned you in the task #%d' => '%s te mencionó en la tarea #%d', '%s mentioned you in a comment on the task #%d' => '%s te mencionó en un comentario en la tarea #%d', 'You were mentioned in the task #%d' => 'Te mencionaron en la tarea #%d', 'You were mentioned in a comment on the task #%d' => 'Te mencionaron en un comentario en la tarea #%d', 'Mentioned' => 'Mencionado', - // 'Compare Estimated Time vs Actual Time' => '', - // 'Estimated hours: ' => '', - // 'Actual hours: ' => '', - // 'Hours Spent' => '', - // 'Hours Estimated' => '', - // 'Estimated Time' => '', - // 'Actual Time' => '', + 'Compare Estimated Time vs Actual Time' => 'Comparar Tiempo Estimado vs Tiempo Actual', + 'Estimated hours: ' => 'Horas estimadas: ', + 'Actual hours: ' => 'Horas actuales: ', + 'Hours Spent' => 'Horas gastadas', + 'Hours Estimated' => 'Hora Estimada', + 'Estimated Time' => 'Tiempo Estimado', + 'Actual Time' => 'Tiempo Actual', 'Estimated vs actual time' => 'Tiempo estimado vs real', 'RUB - Russian Ruble' => 'RUB - rublo ruso', 'Assign the task to the person who does the action when the column is changed' => 'Asignar la tarea a la persona que haga la acción al cambiar de columna', @@ -1025,7 +1011,7 @@ return array( 'Change Password' => 'Cambiar contraseña', 'To reset your password click on this link:' => 'Para cambiar tu contraseña haz clic en el siguiente enlace:', 'Last Password Reset' => 'Último cambio de contraseña', - // 'The password has never been reinitialized.' => '', + 'The password has never been reinitialized.' => 'La contraseña nunca se ha reinicializado.', 'Creation' => 'Creación', 'Expiration' => 'Vencimiento', 'Password reset history' => 'Historial de restablecimiento de contraseña', @@ -1053,7 +1039,6 @@ return array( 'Close a task when there is no activity' => 'Cerrar tarea cuando no haya actividad', 'Duration in days' => 'Duración en días', 'Send email when there is no activity on a task' => 'Enviar correo cuando no haya actividad en una tarea', - 'List of external links' => 'Lista de enlaces externos', 'Unable to fetch link information.' => 'No es posible obtener información sobre el enlace', 'Daily background job for tasks' => 'Tarea de fondo diaria para las tareas', 'Auto' => 'Automático', @@ -1071,9 +1056,7 @@ return array( 'External link' => 'Enlace externo', 'Copy and paste your link here...' => 'Copia y pega tu enlace aquí...', 'URL' => 'URL', - 'There is no external link for the moment.' => 'No existe un enlace externo por el momento', 'Internal links' => 'Enlaces internos', - 'There is no internal link for the moment.' => 'No existe un enlace interno por el momento', 'Assign to me' => 'Asignar a mí', 'Me' => 'Yo', 'Do not duplicate anything' => 'No duplicar nada', @@ -1081,26 +1064,24 @@ return array( 'Users management' => 'Administración de usuarios', 'Groups management' => 'Administración de grupos', 'Create from another project' => 'Crear de otro proyecto', - 'There is no subtask at the moment.' => 'No existe subtarea por el momento', 'open' => 'abierto', 'closed' => 'cerrado', 'Priority:' => 'Prioridad', 'Reference:' => 'Referencia', - // 'Complexity:' => 'Complejidad', - // 'Swimlane:' => 'Swimlane', - // 'Column:' => 'Columna', - // 'Position:' => 'Posición', - // 'Creator:' => 'Creador', - // 'Time estimated:' => '', + 'Complexity:' => 'Complejidad:', + 'Swimlane:' => 'Swimlane:', + 'Column:' => 'Columna:', + 'Position:' => 'Posición:', + 'Creator:' => 'Creador:', + 'Time estimated:' => 'Tiempo estimado:', '%s hours' => '%s horas', - // 'Time spent:' => '', + 'Time spent:' => 'Tiempo gastado:', 'Created:' => 'Creado', 'Modified:' => 'Modificado', 'Completed:' => 'Terminado', 'Started:' => 'Iniciado', 'Moved:' => 'Movido', 'Task #%d' => 'Tarea #%d', - 'Sub-tasks' => 'Subtareas', 'Date and time format' => 'Formato de hora y fecha', 'Time format' => 'Formato de hora', 'Start date: ' => 'Fecha de inicio', @@ -1135,17 +1116,41 @@ return array( 'Column created successfully.' => 'Columna creada exitosamente', 'Another column with the same name exists in the project' => 'Ya existe una columna con el mismo nombre en el proyecto', 'Default filters' => 'Filtros predeterminados', - 'Your board doesn\'t have any column!' => '¡Tu tablero no tiene ninguna columna', + 'Your board doesn\'t have any column!' => '¡Tu tablero no tiene ninguna columna!', 'Change column position' => 'Cambiar posición de la columna', 'Switch to the project overview' => 'Cambiar a vista general del proyecto', 'User filters' => 'Usar filtros', 'Category filters' => 'Categoría y filtros', 'Upload a file' => 'Subir archivo', - 'There is no attachment at the moment.' => 'No existe ningún adjunto por el momento', 'View file' => 'Ver archivo', 'Last activity' => 'Última actividad', 'Change subtask position' => 'Cambiar posición de la subtarea', 'This value must be greater than %d' => 'Este valor debe ser mayor a %d', 'Another swimlane with the same name exists in the project' => 'Ya existe otro swimlane con el mismo nombre en el proyecto', 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => 'Ejemplo: http://ejemplo.kanboard.net/ (Usado para generar URLs absolutas)', + 'Actions duplicated successfully.' => 'Acción duplicada con exito.', + 'Unable to duplicate actions.' => 'No se ha podido duplicar la acción.', + 'Add a new action' => 'Añadir una nueva acción', + 'Import from another project' => 'Importar de otro proyecto', + 'There is no action at the moment.' => 'No hay ninguna acción en este momento.', + 'Import actions from another project' => 'Importar acciones de otro proyecto', + 'There is no available project.' => 'No hay proyectos disponibles.', + // 'Local File' => '', + // 'Configuration' => '', + // 'PHP version:' => '', + // 'PHP SAPI:' => '', + // 'OS version:' => '', + // 'Database version:' => '', + // 'Browser:' => '', + // 'Task view' => '', + // 'Edit task' => '', + // 'Edit description' => '', + // 'New internal link' => '', + // 'Display list of keyboard shortcuts' => '', + // 'Menu' => '', + // 'Set start date' => '', + // 'Avatar' => '', + // 'Upload my avatar image' => '', + // 'Remove my image' => '', + // 'The OAuth2 state parameter is invalid' => '', ); diff --git a/sources/app/Locale/fi_FI/translations.php b/sources/app/Locale/fi_FI/translations.php index 169fa66..8e5dd81 100644 --- a/sources/app/Locale/fi_FI/translations.php +++ b/sources/app/Locale/fi_FI/translations.php @@ -8,7 +8,6 @@ return array( 'Edit' => 'Muokkaa', 'remove' => 'poista', 'Remove' => 'Poista', - 'Update' => 'Päivitä', 'Yes' => 'Kyllä', 'No' => 'Ei', 'cancel' => 'peruuta', @@ -60,7 +59,6 @@ return array( 'Actions' => 'Toiminnot', 'Inactive' => 'Ei aktiivinen', 'Active' => 'Aktiivinen', - 'Add this column' => 'Lisää tämä sarake', '%d tasks on the board' => '%d tehtävää taululla', '%d tasks in total' => '%d tehtävää yhteensä', 'Unable to update this board.' => 'Taulun muuttaminen ei onnistunut.', @@ -74,7 +72,6 @@ return array( 'All projects' => 'Kaikki projektit', 'Add a new column' => 'Lisää uusi sarake', 'Title' => 'Nimi', - 'Nobody assigned' => 'Ei suorittajaa', 'Assigned to %s' => 'Tekijä: %s', 'Remove a column' => 'Poista sarake', 'Remove a column from a board' => 'Poista sarake taulusta', @@ -168,7 +165,6 @@ return array( 'Task count' => 'Tehtävien määrä', 'User' => 'Käyttäjät', 'Comments' => 'Kommentit', - 'Write your text in Markdown' => 'Kirjoita kommenttisi Markdownilla', 'Leave a comment' => 'Lisää kommentti', 'Comment is required' => 'Kommentti vaaditaan', 'Leave a description' => 'Lisää kuvaus', @@ -184,7 +180,6 @@ return array( 'Unable to remove this action.' => 'Toiminnon poistaminen epäonnistui.', 'Action removed successfully.' => 'Toiminto poistettiin onnistuneesti.', 'Automatic actions for the project "%s"' => 'Automaattiset toiminnot projektille "%s"', - 'Defined actions' => 'Määritellyt toiminnot', // 'Add an action' => '', 'Event name' => 'Tapahtuman nimi', 'Action name' => 'Toiminnon nimi', @@ -194,7 +189,6 @@ return array( 'When the selected event occurs execute the corresponding action.' => 'Kun valittu tapahtuma tapahtuu, suorita vastaava toiminto.', 'Next step' => 'Seuraava vaihe', 'Define action parameters' => 'Määrittele toiminnon parametrit', - 'Save this action' => 'Tallenna toiminto', 'Do you really want to remove this action: "%s"?' => 'Oletko varma että haluat poistaa toiminnon "%s"?', 'Remove an automatic action' => 'Poista automaattintn toiminto', 'Assign the task to a specific user' => 'Osoita tehtävä käyttäjälle', @@ -333,10 +327,10 @@ return array( 'Time tracking:' => 'Ajan seuranta:', 'New sub-task' => 'Uusi alitehtävä', 'New attachment added "%s"' => 'Uusi liite lisätty "%s"', - 'Comment updated' => 'Kommentti päivitetty', 'New comment posted by %s' => '%s lisäsi uuden kommentin', // 'New attachment' => '', // 'New comment' => '', + 'Comment updated' => 'Kommentti päivitetty', // 'New subtask' => '', // 'Subtask updated' => '', // 'Task updated' => '', @@ -436,7 +430,6 @@ return array( 'ISO format is always accepted, example: "%s" and "%s"' => 'ISO-muoto on aina hyväksytty, esimerkiksi %s ja %s', 'New private project' => 'Uusi yksityinen projekti', 'This project is private' => 'Tämä projekti on yksityinen', - 'Type here to create a new sub-task' => 'Kirjoita tähän luodaksesi uuden alitehtävän', 'Add' => 'Lisää', 'Start date' => 'Aloituspäivä', 'Time estimated' => 'Arvioitu aika', @@ -487,9 +480,6 @@ return array( 'Daily project summary export for "%s"' => 'Päivittäisen yhteenvedon vienti kohteeseen "%s"', 'Exports' => 'Viennit', 'This export contains the number of tasks per column grouped per day.' => 'Tämä tiedosto sisältää tehtäviä sarakkeisiin päiväkohtaisesti ryhmilteltyinä', - 'Nothing to preview...' => 'Ei esikatselua...', - 'Preview' => 'Ei esikatselua', - 'Write' => 'Kirjoita', 'Active swimlanes' => 'Aktiiviset kaistat', 'Add a new swimlane' => 'Lisää uusi kaista', 'Change default swimlane' => 'Vaihda oletuskaistaa', @@ -543,7 +533,6 @@ return array( // '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?' => '', @@ -734,7 +723,7 @@ return array( // 'Time spent changed: %sh' => '', // 'Time estimated changed: %sh' => '', // 'The field "%s" have been updated' => '', - // 'The description have been modified' => '', + // 'The description has been modified:' => '', // 'Do you really want to close the task "%s" as well as all subtasks?' => '', // 'I want to receive notifications for:' => '', // 'All tasks' => '', @@ -753,8 +742,6 @@ return array( // 'My activity stream' => '', // 'My calendar' => '', // 'Search tasks' => '', - // 'Back to the calendar' => '', - // 'Filters' => '', // 'Reset filters' => '', // 'My tasks due tomorrow' => '', // 'Tasks due today' => '', @@ -854,7 +841,6 @@ return array( // 'End date:' => '', // 'There is no start date or end date for this project.' => '', // 'Projects Gantt chart' => '', - // 'Link type' => '', // 'Change task color when using a specific task link' => '', // 'Task link creation or modification' => '', // 'Milestone' => '', @@ -906,7 +892,6 @@ return array( // 'Shared' => '', // 'Owner' => '', // 'Unread notifications' => '', - // 'My filters' => '', // 'Notification methods:' => '', // 'Import tasks from CSV file' => '', // 'Unable to read your file' => '', @@ -944,6 +929,7 @@ return array( // 'Usernames must be lowercase and unique' => '', // 'Passwords will be encrypted if present' => '', // '%s attached a new file to the task %s' => '', + // 'Link type' => '', // 'Assign automatically a category based on a link' => '', // 'BAM - Konvertible Mark' => '', // 'Assignee Username' => '', @@ -1053,7 +1039,6 @@ return array( // 'Close a task when there is no activity' => '', // 'Duration in days' => '', // 'Send email when there is no activity on a task' => '', - // 'List of external links' => '', // 'Unable to fetch link information.' => '', // 'Daily background job for tasks' => '', // 'Auto' => '', @@ -1071,9 +1056,7 @@ return array( // 'External link' => '', // 'Copy and paste your link here...' => '', // 'URL' => '', - // 'There is no external link for the moment.' => '', // 'Internal links' => '', - // 'There is no internal link for the moment.' => '', // 'Assign to me' => '', // 'Me' => '', // 'Do not duplicate anything' => '', @@ -1081,7 +1064,6 @@ return array( // 'Users management' => '', // 'Groups management' => '', // 'Create from another project' => '', - // 'There is no subtask at the moment.' => '', // 'open' => '', // 'closed' => '', // 'Priority:' => '', @@ -1100,7 +1082,6 @@ return array( // 'Started:' => '', // 'Moved:' => '', // 'Task #%d' => '', - // 'Sub-tasks' => '', // 'Date and time format' => '', // 'Time format' => '', // 'Start date: ' => '', @@ -1141,11 +1122,35 @@ return array( // 'User filters' => '', // 'Category filters' => '', // 'Upload a file' => '', - // 'There is no attachment at the moment.' => '', // 'View file' => '', // 'Last activity' => '', // 'Change subtask position' => '', // 'This value must be greater than %d' => '', // 'Another swimlane with the same name exists in the project' => '', // 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => '', + // 'Actions duplicated successfully.' => '', + // 'Unable to duplicate actions.' => '', + // 'Add a new action' => '', + // 'Import from another project' => '', + // 'There is no action at the moment.' => '', + // 'Import actions from another project' => '', + // 'There is no available project.' => '', + // 'Local File' => '', + // 'Configuration' => '', + // 'PHP version:' => '', + // 'PHP SAPI:' => '', + // 'OS version:' => '', + // 'Database version:' => '', + // 'Browser:' => '', + // 'Task view' => '', + // 'Edit task' => '', + // 'Edit description' => '', + // 'New internal link' => '', + // 'Display list of keyboard shortcuts' => '', + // 'Menu' => '', + // 'Set start date' => '', + // 'Avatar' => '', + // 'Upload my avatar image' => '', + // 'Remove my image' => '', + // 'The OAuth2 state parameter is invalid' => '', ); diff --git a/sources/app/Locale/fr_FR/translations.php b/sources/app/Locale/fr_FR/translations.php index 1982e9b..cedd603 100644 --- a/sources/app/Locale/fr_FR/translations.php +++ b/sources/app/Locale/fr_FR/translations.php @@ -8,7 +8,6 @@ return array( 'Edit' => 'Modifier', 'remove' => 'supprimer', 'Remove' => 'Supprimer', - 'Update' => 'Mettre à jour', 'Yes' => 'Oui', 'No' => 'Non', 'cancel' => 'annuler', @@ -60,7 +59,6 @@ return array( 'Actions' => 'Actions', 'Inactive' => 'Inactif', 'Active' => 'Actif', - 'Add this column' => 'Ajouter cette colonne', '%d tasks on the board' => '%d tâches sur le tableau', '%d tasks in total' => '%d tâches au total', 'Unable to update this board.' => 'Impossible de mettre à jour ce tableau.', @@ -74,7 +72,6 @@ return array( 'All projects' => 'Tous les projets', 'Add a new column' => 'Ajouter une nouvelle colonne', 'Title' => 'Titre', - 'Nobody assigned' => 'Personne assignée', 'Assigned to %s' => 'Assigné à %s', 'Remove a column' => 'Supprimer une colonne', 'Remove a column from a board' => 'Supprimer une colonne d\'un tableau', @@ -95,7 +92,7 @@ return array( 'Edit a task' => 'Modifier une tâche', 'Column' => 'Colonne', 'Color' => 'Couleur', - 'Assignee' => 'Personne assigné', + 'Assignee' => 'Personne assignée', 'Create another task' => 'Créer une autre tâche', 'New task' => 'Nouvelle tâche', 'Open a task' => 'Ouvrir une tâche', @@ -168,7 +165,6 @@ return array( 'Task count' => 'Nombre de tâches', 'User' => 'Utilisateur', 'Comments' => 'Commentaires', - 'Write your text in Markdown' => 'Écrivez votre texte en Markdown', 'Leave a comment' => 'Laissez un commentaire', 'Comment is required' => 'Le commentaire est obligatoire', 'Leave a description' => 'Laissez une description', @@ -184,7 +180,6 @@ return array( 'Unable to remove this action.' => 'Impossible de supprimer cette action', 'Action removed successfully.' => 'Action supprimée avec succès.', 'Automatic actions for the project "%s"' => 'Actions automatisées pour le projet « %s »', - 'Defined actions' => 'Actions définies', 'Add an action' => 'Ajouter une action', 'Event name' => 'Nom de l\'événement', 'Action name' => 'Nom de l\'action', @@ -194,7 +189,6 @@ return array( 'When the selected event occurs execute the corresponding action.' => 'Lorsque l\'événement sélectionné se déclenche, exécuter l\'action correspondante.', 'Next step' => 'Étape suivante', 'Define action parameters' => 'Définition des paramètres de l\'action', - 'Save this action' => 'Sauvegarder cette action', 'Do you really want to remove this action: "%s"?' => 'Voulez-vous vraiment supprimer cette action « %s » ?', 'Remove an automatic action' => 'Supprimer une action automatisée', 'Assign the task to a specific user' => 'Assigner la tâche à un utilisateur spécifique', @@ -333,14 +327,12 @@ return array( 'Time tracking:' => 'Gestion du temps :', 'New sub-task' => 'Nouvelle sous-tâche', 'New attachment added "%s"' => 'Nouvelle pièce-jointe ajoutée « %s »', - 'Comment updated' => 'Commentaire ajouté', 'New comment posted by %s' => 'Nouveau commentaire ajouté par « %s »', 'New attachment' => 'Nouveau document', 'New comment' => 'Nouveau commentaire', 'Comment updated' => 'Commentaire mis à jour', 'New subtask' => 'Nouvelle sous-tâche', 'Subtask updated' => 'Sous-tâche mise à jour', - 'New task' => 'Nouvelle tâche', 'Task updated' => 'Tâche mise à jour', 'Task closed' => 'Tâche fermée', 'Task opened' => 'Tâche ouverte', @@ -438,7 +430,6 @@ return array( 'ISO format is always accepted, example: "%s" and "%s"' => 'Le format ISO est toujours accepté, exemple : « %s » et « %s »', 'New private project' => 'Nouveau projet privé', 'This project is private' => 'Ce projet est privé', - 'Type here to create a new sub-task' => 'Créer une sous-tâche en écrivant le titre ici', 'Add' => 'Ajouter', 'Start date' => 'Date de début', 'Time estimated' => 'Temps estimé', @@ -489,9 +480,6 @@ return array( 'Daily project summary export for "%s"' => 'Export du résumé quotidien du projet pour « %s »', 'Exports' => 'Exports', 'This export contains the number of tasks per column grouped per day.' => 'Cet export contient le nombre de tâches par colonne groupé par jour.', - 'Nothing to preview...' => 'Rien à prévisualiser...', - 'Preview' => 'Prévisualiser', - 'Write' => 'Écrire', 'Active swimlanes' => 'Swimlanes actives', 'Add a new swimlane' => 'Ajouter une nouvelle swimlane', 'Change default swimlane' => 'Modifier la swimlane par défaut', @@ -545,7 +533,6 @@ return array( 'Task age in days' => 'Âge de la tâche en jours', 'Days in this column' => 'Jours dans cette colonne', '%dd' => '%dj', - 'Add a link' => 'Ajouter un lien', 'Add a new link' => 'Ajouter un nouveau lien', 'Do you really want to remove this link: "%s"?' => 'Voulez-vous vraiment supprimer ce lien : « %s » ?', 'Do you really want to remove this link with task #%d?' => 'Voulez-vous vraiment supprimer ce lien avec la tâche n°%d ?', @@ -736,7 +723,7 @@ return array( 'Time spent changed: %sh' => 'Le temps passé a été changé : %sh', 'Time estimated changed: %sh' => 'Le temps estimé a été changé : %sh', 'The field "%s" have been updated' => 'Le champ « %s » a été mis à jour', - 'The description have been modified' => 'La description a été modifiée', + 'The description has been modified:' => 'La description a été modifiée', 'Do you really want to close the task "%s" as well as all subtasks?' => 'Voulez-vous vraiment fermer la tâche « %s » ainsi que toutes ses sous-tâches ?', 'I want to receive notifications for:' => 'Je veux reçevoir les notifications pour :', 'All tasks' => 'Toutes les Tâches', @@ -755,8 +742,6 @@ return array( 'My activity stream' => 'Mon flux d\'activité', 'My calendar' => 'Mon agenda', 'Search tasks' => 'Rechercher des tâches', - 'Back to the calendar' => 'Retour au calendrier', - 'Filters' => 'Filtres', 'Reset filters' => 'Réinitialiser les filtres', 'My tasks due tomorrow' => 'Mes tâches qui arrivent à échéance demain', 'Tasks due today' => 'Tâches qui arrivent à échéance aujourd\'hui', @@ -856,7 +841,6 @@ return array( 'End date:' => 'Date de fin :', 'There is no start date or end date for this project.' => 'Il n\'y a pas de date de début ou de date de fin pour ce projet.', 'Projects Gantt chart' => 'Diagramme de Gantt des projets', - 'Link type' => 'Type de lien', 'Change task color when using a specific task link' => 'Changer la couleur de la tâche lorsqu\'un lien spécifique est utilisé', 'Task link creation or modification' => 'Création ou modification d\'un lien sur une tâche', 'Milestone' => 'Étape importante', @@ -908,7 +892,6 @@ return array( 'Shared' => 'Partagé', 'Owner' => 'Propriétaire', 'Unread notifications' => 'Notifications non lus', - 'My filters' => 'Mes filtres', 'Notification methods:' => 'Méthodes de notifications :', 'Import tasks from CSV file' => 'Importer les tâches depuis un fichier CSV', 'Unable to read your file' => 'Impossible de lire votre fichier', @@ -1038,7 +1021,7 @@ return array( 'Close all tasks of this column' => 'Fermer toutes les tâches de cette colonne', 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => 'Aucun plugin n\'a enregistré une méthode de notification de projet. Vous pouvez toujours configurer les notifications individuelles dans votre profil d\'utilisateur.', 'My dashboard' => 'Mon tableau de bord', - 'My profile' => 'Mon profile', + 'My profile' => 'Mon profil', 'Project owner: ' => 'Responsable du projet : ', 'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => 'L\'identifiant du projet est optionnel et doit être alphanumérique, example: MONPROJET.', 'Project owner' => 'Responsable du projet', @@ -1056,7 +1039,6 @@ return array( 'Close a task when there is no activity' => 'Fermer une tâche sans activité', 'Duration in days' => 'Durée en jours', 'Send email when there is no activity on a task' => 'Envoyer un email lorsqu\'il n\'y a pas d\'activité sur une tâche', - 'List of external links' => 'Liste des liens externes', 'Unable to fetch link information.' => 'Impossible de récupérer les informations sur le lien.', 'Daily background job for tasks' => 'Tâche planifiée quotidienne pour les tâches', 'Auto' => 'Auto', @@ -1074,9 +1056,7 @@ return array( 'External link' => 'Lien externe', 'Copy and paste your link here...' => 'Copier-coller vôtre lien ici...', 'URL' => 'URL', - 'There is no external link for the moment.' => 'Il n\'y a pas de lien externe pour le moment.', 'Internal links' => 'Liens internes', - 'There is no internal link for the moment.' => 'Il n\'y a pas de lien interne pour le moment.', 'Assign to me' => 'Assigner à moi', 'Me' => 'Moi', 'Do not duplicate anything' => 'Ne rien dupliquer', @@ -1084,7 +1064,6 @@ return array( 'Users management' => 'Gestion des utilisateurs', 'Groups management' => 'Gestion des groupes', 'Create from another project' => 'Créer depuis un autre projet', - 'There is no subtask at the moment.' => 'Il n\'y a aucune sous-tâche pour le moment.', 'open' => 'ouvert', 'closed' => 'fermé', 'Priority:' => 'Priorité :', @@ -1103,7 +1082,6 @@ return array( 'Started:' => 'Commençé le :', 'Moved:' => 'Déplacé le : ', 'Task #%d' => 'Tâche n°%d', - 'Sub-tasks' => 'Sous-tâches', 'Date and time format' => 'Format de la date et de l\'heure', 'Time format' => 'Format de l\'heure', 'Start date: ' => 'Date de début : ', @@ -1123,7 +1101,7 @@ return array( 'Choose files again' => 'Choisir de nouveau des fichiers', 'Drag and drop your files here' => 'Glissez-déposez vos fichiers ici', 'choose files' => 'choisissez des fichiers', - 'View profile' => 'Voir le profile', + 'View profile' => 'Voir le profil', 'Two Factor' => 'Deux-Facteurs', 'Disable user' => 'Désactiver l\'utilisateur', 'Do you really want to disable this user: "%s"?' => 'Voulez-vous vraiment désactiver cet utilisateur : « %s » ?', @@ -1144,11 +1122,35 @@ return array( 'User filters' => 'Filtres des utilisateurs', 'Category filters' => 'Filtres des catégories', 'Upload a file' => 'Uploader un fichier', - 'There is no attachment at the moment.' => 'Il n\'y a aucune pièce-jointe pour le moment.', 'View file' => 'Voir le fichier', 'Last activity' => 'Dernières activités', 'Change subtask position' => 'Changer la position de la sous-tâche', 'This value must be greater than %d' => 'Cette valeur doit être plus grande que %d', 'Another swimlane with the same name exists in the project' => 'Une autre swimlane existe avec le même nom dans le projet', 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => 'Exemple : http://exemple.kanboard.net/ (utilisé pour générer les URLs absolues)', + 'Actions duplicated successfully.' => 'Actions dupliquées avec succès.', + 'Unable to duplicate actions.' => 'Impossible de dupliquer les actions.', + 'Add a new action' => 'Ajouter une nouvelle action', + 'Import from another project' => 'Importer depuis un autre projet', + 'There is no action at the moment.' => 'Il n\'y a aucune action pour le moment.', + 'Import actions from another project' => 'Importer les actions depuis un autre projet', + 'There is no available project.' => 'Il n\'y a pas de projet disponible.', + 'Local File' => 'Fichier local', + 'Configuration' => 'Configuration', + 'PHP version:' => 'Version de PHP :', + 'PHP SAPI:' => 'PHP SAPI :', + 'OS version:' => 'Version du système d\'exploitation :', + 'Database version:' => 'Version de la base de donnée :', + 'Browser:' => 'Navigateur web :', + 'Task view' => 'Vue détaillée d\'une tâche', + 'Edit task' => 'Modifier la tâche', + 'Edit description' => 'Modifier la description', + 'New internal link' => 'Nouveau lien interne', + 'Display list of keyboard shortcuts' => 'Afficher la liste des raccourcis claviers', + 'Menu' => 'Menu', + 'Set start date' => 'Définir la date de début', + 'Avatar' => 'Avatar', + 'Upload my avatar image' => 'Uploader mon image d\'avatar', + 'Remove my image' => 'Supprimer mon image', + 'The OAuth2 state parameter is invalid' => 'Le paramètre "state" de OAuth2 est invalide', ); diff --git a/sources/app/Locale/hu_HU/translations.php b/sources/app/Locale/hu_HU/translations.php index 71d068e..f642a6c 100644 --- a/sources/app/Locale/hu_HU/translations.php +++ b/sources/app/Locale/hu_HU/translations.php @@ -8,7 +8,6 @@ return array( 'Edit' => 'Szerkesztés', 'remove' => 'törlés', 'Remove' => 'Törlés', - 'Update' => 'Frissítés', 'Yes' => 'Igen', 'No' => 'Nem', 'cancel' => 'Mégsem', @@ -60,7 +59,6 @@ return array( 'Actions' => 'Műveletek', 'Inactive' => 'Inaktív', 'Active' => 'Aktív', - 'Add this column' => 'Oszlop hozzáadása', '%d tasks on the board' => '%d feladat a táblán', '%d tasks in total' => 'Összesen %d feladat', 'Unable to update this board.' => 'Nem lehet frissíteni a táblát.', @@ -74,7 +72,6 @@ return array( 'All projects' => 'Minden projekt', 'Add a new column' => 'Új oszlop', 'Title' => 'Cím', - 'Nobody assigned' => 'Nincs felelős', 'Assigned to %s' => 'Felelős: %s', 'Remove a column' => 'Oszlop törlése', 'Remove a column from a board' => 'Oszlop törlése a tábláról', @@ -168,7 +165,6 @@ return array( 'Task count' => 'Feladatok száma', 'User' => 'Felhasználó', 'Comments' => 'Hozzászólások', - 'Write your text in Markdown' => 'Írja be a szöveget Markdown szintaxissal', 'Leave a comment' => 'Írjon hozzászólást ...', 'Comment is required' => 'A hozzászólás mező kötelező', 'Leave a description' => 'Írjon leírást ...', @@ -184,7 +180,6 @@ return array( 'Unable to remove this action.' => 'Intézkedés törlése nem lehetséges.', 'Action removed successfully.' => 'Intézkedés sikeresen törölve.', 'Automatic actions for the project "%s"' => 'Automatikus intézkedések a projektben: "%s"', - 'Defined actions' => 'Intézkedések', 'Add an action' => 'Intézkedés létrehozása', 'Event name' => 'Esemény neve', 'Action name' => 'Intézkedés neve', @@ -194,7 +189,6 @@ return array( 'When the selected event occurs execute the corresponding action.' => 'Ha a kiválasztott esemény bekövetkezik, hajtsa végre a megfelelő intézkedéseket.', 'Next step' => 'Következő lépés', 'Define action parameters' => 'Határozza meg az intézkedés paramétereit', - 'Save this action' => 'Intézkedés mentése', 'Do you really want to remove this action: "%s"?' => 'Valóban törölni akarja ezt az intézkedést: "%s"?', 'Remove an automatic action' => 'Automatikus intézkedés törlése', 'Assign the task to a specific user' => 'Feladat kiosztása megadott felhasználónak', @@ -333,10 +327,10 @@ return array( 'Time tracking:' => 'Idő követés:', 'New sub-task' => 'Új részfeladat', 'New attachment added "%s"' => 'Új melléklet "%s" hozzáadva.', - 'Comment updated' => 'Megjegyzés frissítve', 'New comment posted by %s' => 'Új megjegyzés %s', 'New attachment' => 'Új melléklet', 'New comment' => 'Új megjegyzés', + 'Comment updated' => 'Megjegyzés frissítve', 'New subtask' => 'Új részfeladat', 'Subtask updated' => 'Részfeladat frissítve', 'Task updated' => 'Feladat frissítve', @@ -436,7 +430,6 @@ return array( 'ISO format is always accepted, example: "%s" and "%s"' => 'ISO formátum mindig elfogadott, pl: "%s" és "%s"', 'New private project' => 'Új privát projekt', 'This project is private' => 'Ez egy privát projekt', - 'Type here to create a new sub-task' => 'Ide írva létrehozhat egy új részfeladatot', 'Add' => 'Hozzáadás', 'Start date' => 'Kezdés dátuma', 'Time estimated' => 'Becsült időtartam', @@ -487,9 +480,6 @@ return array( 'Daily project summary export for "%s"' => 'Napi projektösszefoglaló exportálása: %s', 'Exports' => 'Exportálások', 'This export contains the number of tasks per column grouped per day.' => 'Ez az export tartalmazza a feladatok számát oszloponként összesítve, napokra lebontva.', - 'Nothing to preview...' => 'Nincs semmi az előnézetben ...', - 'Preview' => 'Előnézet', - 'Write' => 'Szerkesztés', 'Active swimlanes' => 'Aktív folyamatok', 'Add a new swimlane' => 'Új folyamat', 'Change default swimlane' => 'Alapértelmezett folyamat változtatás', @@ -543,7 +533,6 @@ return array( 'Task age in days' => 'Feladat életkora napokban', 'Days in this column' => 'Napok ebben az oszlopban', '%dd' => '%dd', - 'Add a link' => 'Hivatkozás hozzáadása', 'Add a new link' => 'Új hivatkozás hozzáadása', 'Do you really want to remove this link: "%s"?' => 'Biztos törölni akarja a hivatkozást: "%s"?', 'Do you really want to remove this link with task #%d?' => 'Biztos törölni akarja a(z) #%d. feladatra mutató hivatkozást?', @@ -734,7 +723,7 @@ return array( // 'Time spent changed: %sh' => '', // 'Time estimated changed: %sh' => '', // 'The field "%s" have been updated' => '', - // 'The description have been modified' => '', + // 'The description has been modified:' => '', // 'Do you really want to close the task "%s" as well as all subtasks?' => '', // 'I want to receive notifications for:' => '', // 'All tasks' => '', @@ -753,8 +742,6 @@ return array( // 'My activity stream' => '', // 'My calendar' => '', // 'Search tasks' => '', - // 'Back to the calendar' => '', - // 'Filters' => '', // 'Reset filters' => '', // 'My tasks due tomorrow' => '', // 'Tasks due today' => '', @@ -854,7 +841,6 @@ return array( // 'End date:' => '', // 'There is no start date or end date for this project.' => '', // 'Projects Gantt chart' => '', - // 'Link type' => '', // 'Change task color when using a specific task link' => '', // 'Task link creation or modification' => '', // 'Milestone' => '', @@ -906,7 +892,6 @@ return array( // 'Shared' => '', // 'Owner' => '', // 'Unread notifications' => '', - // 'My filters' => '', // 'Notification methods:' => '', // 'Import tasks from CSV file' => '', // 'Unable to read your file' => '', @@ -944,6 +929,7 @@ return array( // 'Usernames must be lowercase and unique' => '', // 'Passwords will be encrypted if present' => '', // '%s attached a new file to the task %s' => '', + // 'Link type' => '', // 'Assign automatically a category based on a link' => '', // 'BAM - Konvertible Mark' => '', // 'Assignee Username' => '', @@ -1053,7 +1039,6 @@ return array( // 'Close a task when there is no activity' => '', // 'Duration in days' => '', // 'Send email when there is no activity on a task' => '', - // 'List of external links' => '', // 'Unable to fetch link information.' => '', // 'Daily background job for tasks' => '', // 'Auto' => '', @@ -1071,9 +1056,7 @@ return array( // 'External link' => '', // 'Copy and paste your link here...' => '', // 'URL' => '', - // 'There is no external link for the moment.' => '', // 'Internal links' => '', - // 'There is no internal link for the moment.' => '', // 'Assign to me' => '', // 'Me' => '', // 'Do not duplicate anything' => '', @@ -1081,7 +1064,6 @@ return array( // 'Users management' => '', // 'Groups management' => '', // 'Create from another project' => '', - // 'There is no subtask at the moment.' => '', // 'open' => '', // 'closed' => '', // 'Priority:' => '', @@ -1100,7 +1082,6 @@ return array( // 'Started:' => '', // 'Moved:' => '', // 'Task #%d' => '', - // 'Sub-tasks' => '', // 'Date and time format' => '', // 'Time format' => '', // 'Start date: ' => '', @@ -1141,11 +1122,35 @@ return array( // 'User filters' => '', // 'Category filters' => '', // 'Upload a file' => '', - // 'There is no attachment at the moment.' => '', // 'View file' => '', // 'Last activity' => '', // 'Change subtask position' => '', // 'This value must be greater than %d' => '', // 'Another swimlane with the same name exists in the project' => '', // 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => '', + // 'Actions duplicated successfully.' => '', + // 'Unable to duplicate actions.' => '', + // 'Add a new action' => '', + // 'Import from another project' => '', + // 'There is no action at the moment.' => '', + // 'Import actions from another project' => '', + // 'There is no available project.' => '', + // 'Local File' => '', + // 'Configuration' => '', + // 'PHP version:' => '', + // 'PHP SAPI:' => '', + // 'OS version:' => '', + // 'Database version:' => '', + // 'Browser:' => '', + // 'Task view' => '', + // 'Edit task' => '', + // 'Edit description' => '', + // 'New internal link' => '', + // 'Display list of keyboard shortcuts' => '', + // 'Menu' => '', + // 'Set start date' => '', + // 'Avatar' => '', + // 'Upload my avatar image' => '', + // 'Remove my image' => '', + // 'The OAuth2 state parameter is invalid' => '', ); diff --git a/sources/app/Locale/id_ID/translations.php b/sources/app/Locale/id_ID/translations.php index 936023d..3f10505 100644 --- a/sources/app/Locale/id_ID/translations.php +++ b/sources/app/Locale/id_ID/translations.php @@ -8,7 +8,6 @@ return array( 'Edit' => 'Modifikasi', 'remove' => 'hapus', 'Remove' => 'Hapus', - 'Update' => 'Perbaharui', 'Yes' => 'Ya', 'No' => 'Tidak', 'cancel' => 'batal', @@ -60,7 +59,6 @@ return array( 'Actions' => 'Tindakan', 'Inactive' => 'Non Aktif', 'Active' => 'Aktif', - 'Add this column' => 'Tambahkan kolom ini', '%d tasks on the board' => '%d tugas di papan', '%d tasks in total' => '%d tugas di total', 'Unable to update this board.' => 'Tidak dapat memperbaharui papan ini', @@ -74,7 +72,6 @@ return array( 'All projects' => 'Semua proyek', 'Add a new column' => 'Tambah kolom baru', 'Title' => 'Judul', - 'Nobody assigned' => 'Tidak ada yang ditugaskan', 'Assigned to %s' => 'Ditugaskan ke %s', 'Remove a column' => 'Hapus kolom', 'Remove a column from a board' => 'Hapus kolom dari papan', @@ -168,7 +165,6 @@ return array( 'Task count' => 'Jumlah tugas', 'User' => 'Pengguna', 'Comments' => 'Komentar', - 'Write your text in Markdown' => 'Menulis teks anda didalam Markdown', 'Leave a comment' => 'Tinggalkan komentar', 'Comment is required' => 'Komentar diperlukan', 'Leave a description' => 'Tinggalkan deskripsi', @@ -184,7 +180,6 @@ return array( 'Unable to remove this action.' => 'Tidak dapat menghapus tindakan ini', 'Action removed successfully.' => 'Tindakan berhasil dihapus.', 'Automatic actions for the project "%s"' => 'Tindakan otomatis untuk proyek ini « %s »', - 'Defined actions' => 'Tindakan didefinisikan', 'Add an action' => 'Tambah tindakan', 'Event name' => 'Nama acara', 'Action name' => 'Nama tindakan', @@ -194,7 +189,6 @@ return array( 'When the selected event occurs execute the corresponding action.' => 'Ketika acara yang dipilih terjadi, melakukan tindakan yang sesuai.', 'Next step' => 'Langkah selanjutnya', 'Define action parameters' => 'Definisi parameter tindakan', - 'Save this action' => 'Simpan tindakan ini', 'Do you really want to remove this action: "%s"?' => 'Apakah anda yakin akan menghapus tindakan ini « %s » ?', 'Remove an automatic action' => 'Hapus tindakan otomatis', 'Assign the task to a specific user' => 'Menetapkan tugas untuk pengguna tertentu', @@ -333,10 +327,10 @@ return array( 'Time tracking:' => 'Pelacakan waktu :', 'New sub-task' => 'Sub-tugas baru', 'New attachment added "%s"' => 'Lampiran baru ditambahkan « %s »', - 'Comment updated' => 'Komentar diperbaharui', 'New comment posted by %s' => 'Komentar baru ditambahkan oleh « %s »', 'New attachment' => 'Lampirkan baru', 'New comment' => 'Komentar baru', + 'Comment updated' => 'Komentar diperbaharui', 'New subtask' => 'Sub-tugas baru', 'Subtask updated' => 'Sub-tugas diperbaharui', 'Task updated' => 'Tugas diperbaharui', @@ -436,7 +430,6 @@ return array( 'ISO format is always accepted, example: "%s" and "%s"' => 'Format ISO selalu diterima, contoh : « %s » et « %s »', 'New private project' => 'Proyek pribadi baru', 'This project is private' => 'Proyek ini adalah pribadi', - 'Type here to create a new sub-task' => 'Ketik disini untuk membuat sub-tugas baru', 'Add' => 'Tambah', 'Start date' => 'Tanggal mulai', 'Time estimated' => 'Perkiraan waktu', @@ -487,9 +480,6 @@ return array( 'Daily project summary export for "%s"' => 'Ekspor ringkasan proyek harian untuk « %s »', 'Exports' => 'Ekspor', 'This export contains the number of tasks per column grouped per day.' => 'Ekspor ini berisi jumlah dari tugas per kolom dikelompokan perhari.', - 'Nothing to preview...' => 'Tidak ada yang dapat dilihat...', - 'Preview' => 'Preview', - 'Write' => 'Tulis', 'Active swimlanes' => 'Swimlanes aktif', 'Add a new swimlane' => 'Tambah swimlane baru', 'Change default swimlane' => 'Modifikasi standar swimlane', @@ -543,7 +533,6 @@ return array( 'Task age in days' => 'Usia tugas dalam hari', 'Days in this column' => 'Hari dalam kolom ini', '%dd' => '%dj', - 'Add a link' => 'Menambahkan tautan', 'Add a new link' => 'Tambah tautan baru', 'Do you really want to remove this link: "%s"?' => 'Apakah anda yakin akan menghapus tautan ini : « %s » ?', 'Do you really want to remove this link with task #%d?' => 'Apakah anda yakin akan menghapus tautan ini dengan tugas n°%d ?', @@ -734,7 +723,7 @@ return array( 'Time spent changed: %sh' => 'Waktu yang dihabiskan berubah : %sh', 'Time estimated changed: %sh' => 'Perkiraan waktu berubah : %sh', 'The field "%s" have been updated' => 'Field « %s » telah diperbaharui', - 'The description have been modified' => 'Deskripsi telah dimodifikasi', + 'The description has been modified:' => 'Deskripsi telah dimodifikasi', 'Do you really want to close the task "%s" as well as all subtasks?' => 'Apakah anda yakin akan menutup tugas « %s » beserta semua sub-tugasnya ?', 'I want to receive notifications for:' => 'Saya ingin menerima pemberitahuan untuk :', 'All tasks' => 'Semua tugas', @@ -753,8 +742,6 @@ return array( 'My activity stream' => 'Aliran kegiatan saya', 'My calendar' => 'Kalender saya', 'Search tasks' => 'Cari tugas', - 'Back to the calendar' => 'Kembali ke kalender', - 'Filters' => 'Filter', 'Reset filters' => 'Reset ulang filter', 'My tasks due tomorrow' => 'Tugas saya yang berakhir besok', 'Tasks due today' => 'Tugas yang berakhir hari ini', @@ -854,7 +841,6 @@ return array( 'End date:' => 'Waktu berakhir :', 'There is no start date or end date for this project.' => 'Tidak ada waktu mulai atau waktu berakhir untuk proyek ini', 'Projects Gantt chart' => 'Proyek grafik Gantt', - 'Link type' => 'Tipe tautan', 'Change task color when using a specific task link' => 'Rubah warna tugas ketika menggunakan tautan tugas yang spesifik', 'Task link creation or modification' => 'Tautan pembuatan atau modifikasi tugas ', 'Milestone' => 'Milestone', @@ -906,7 +892,6 @@ return array( // 'Shared' => '', // 'Owner' => '', // 'Unread notifications' => '', - // 'My filters' => '', // 'Notification methods:' => '', // 'Import tasks from CSV file' => '', // 'Unable to read your file' => '', @@ -944,6 +929,7 @@ return array( // 'Usernames must be lowercase and unique' => '', // 'Passwords will be encrypted if present' => '', // '%s attached a new file to the task %s' => '', + 'Link type' => 'Tipe tautan', // 'Assign automatically a category based on a link' => '', // 'BAM - Konvertible Mark' => '', // 'Assignee Username' => '', @@ -1053,7 +1039,6 @@ return array( // 'Close a task when there is no activity' => '', // 'Duration in days' => '', // 'Send email when there is no activity on a task' => '', - // 'List of external links' => '', // 'Unable to fetch link information.' => '', // 'Daily background job for tasks' => '', // 'Auto' => '', @@ -1071,9 +1056,7 @@ return array( // 'External link' => '', // 'Copy and paste your link here...' => '', // 'URL' => '', - // 'There is no external link for the moment.' => '', // 'Internal links' => '', - // 'There is no internal link for the moment.' => '', // 'Assign to me' => '', // 'Me' => '', // 'Do not duplicate anything' => '', @@ -1081,7 +1064,6 @@ return array( // 'Users management' => '', // 'Groups management' => '', // 'Create from another project' => '', - // 'There is no subtask at the moment.' => '', // 'open' => '', // 'closed' => '', // 'Priority:' => '', @@ -1100,7 +1082,6 @@ return array( // 'Started:' => '', // 'Moved:' => '', // 'Task #%d' => '', - // 'Sub-tasks' => '', // 'Date and time format' => '', // 'Time format' => '', // 'Start date: ' => '', @@ -1141,11 +1122,35 @@ return array( // 'User filters' => '', // 'Category filters' => '', // 'Upload a file' => '', - // 'There is no attachment at the moment.' => '', // 'View file' => '', // 'Last activity' => '', // 'Change subtask position' => '', // 'This value must be greater than %d' => '', // 'Another swimlane with the same name exists in the project' => '', // 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => '', + // 'Actions duplicated successfully.' => '', + // 'Unable to duplicate actions.' => '', + // 'Add a new action' => '', + // 'Import from another project' => '', + // 'There is no action at the moment.' => '', + // 'Import actions from another project' => '', + // 'There is no available project.' => '', + // 'Local File' => '', + // 'Configuration' => '', + // 'PHP version:' => '', + // 'PHP SAPI:' => '', + // 'OS version:' => '', + // 'Database version:' => '', + // 'Browser:' => '', + // 'Task view' => '', + // 'Edit task' => '', + // 'Edit description' => '', + // 'New internal link' => '', + // 'Display list of keyboard shortcuts' => '', + // 'Menu' => '', + // 'Set start date' => '', + // 'Avatar' => '', + // 'Upload my avatar image' => '', + // 'Remove my image' => '', + // 'The OAuth2 state parameter is invalid' => '', ); diff --git a/sources/app/Locale/it_IT/translations.php b/sources/app/Locale/it_IT/translations.php index a735128..93ceb03 100644 --- a/sources/app/Locale/it_IT/translations.php +++ b/sources/app/Locale/it_IT/translations.php @@ -8,7 +8,6 @@ return array( 'Edit' => 'Modifica', 'remove' => 'cancella', 'Remove' => 'Cancella', - 'Update' => 'Aggiorna', 'Yes' => 'Si', 'No' => 'No', 'cancel' => 'annulla', @@ -55,12 +54,11 @@ return array( 'No project' => 'Nessun progetto', 'Project' => 'Progetto', 'Status' => 'Stato', - 'Tasks' => 'Tasks', + 'Tasks' => 'Task', 'Board' => 'Bacheca', 'Actions' => 'Azioni', 'Inactive' => 'Inattivo', 'Active' => 'Attivo', - 'Add this column' => 'Aggiungi questa colonna', '%d tasks on the board' => '%d task sulla bacheca', '%d tasks in total' => '%d task in totale', 'Unable to update this board.' => 'Impossibile aggiornare questa bacheca.', @@ -68,18 +66,17 @@ return array( 'Disable' => 'Disattiva', 'Enable' => 'Attiva', 'New project' => 'Nuovo progetto', - 'Do you really want to remove this project: "%s"?' => 'Veramente vuoi eliminare il seguente progetto: "%s" ?', + 'Do you really want to remove this project: "%s"?' => 'Vuoi davvero eliminare il seguente progetto: "%s" ?', 'Remove project' => 'Cancella il progetto', 'Edit the board for "%s"' => 'Modifica la bacheca per "%s"', 'All projects' => 'Tutti i progetti', 'Add a new column' => 'Aggiungi una nuova colonna', 'Title' => 'Titolo', - 'Nobody assigned' => 'Nessuno assegnato', 'Assigned to %s' => 'Assegnato a %s', 'Remove a column' => 'Cancella questa colonna', 'Remove a column from a board' => 'Cancella una colonna da una bacheca', 'Unable to remove this column.' => 'Impossibile cancellare questa colonna.', - 'Do you really want to remove this column: "%s"?' => 'Veramente desideri cancellare questa colonna: "%s" ?', + 'Do you really want to remove this column: "%s"?' => 'Desideri davvero cancellare questa colonna: "%s" ?', 'This action will REMOVE ALL TASKS associated to this column!' => 'Questa azione cancellerà TUTTI I TASK legati a questa colonna!', 'Settings' => 'Impostazioni', 'Application settings' => 'Impostazioni dell\'applicazione', @@ -99,7 +96,7 @@ return array( 'Create another task' => 'Crea un nuovo task', 'New task' => 'Nuovo task', 'Open a task' => 'Apri un task', - 'Do you really want to open this task: "%s"?' => 'Veramente desideri aprire questo task: "%s" ?', + 'Do you really want to open this task: "%s"?' => 'Desideri davvero aprire questo task: "%s" ?', 'Back to the board' => 'Torna alla bacheca', 'There is nobody assigned' => 'Nessuno è assegnato a questo task', 'Column on the board:' => 'Colonna sulla bacheca: ', @@ -121,34 +118,34 @@ return array( 'The project id is required' => 'Si richiede l\'identificatore del progetto', 'The project name is required' => 'Si richiede il nome del progetto', 'The title is required' => 'Si richiede un titolo', - 'Settings saved successfully.' => 'Impostazioni salvate correttamente.', + 'Settings saved successfully.' => 'Impostazioni salvate con successo.', 'Unable to save your settings.' => 'Impossibile salvare le impostazioni.', 'Database optimization done.' => 'Ottimizzazione della base dati conclusa.', - 'Your project have been created successfully.' => 'Il tuo progetto è stato creato correttamente.', + 'Your project have been created successfully.' => 'Il tuo progetto è stato creato con successo.', 'Unable to create your project.' => 'Impossibile creare il progetto.', - 'Project updated successfully.' => 'Progetto aggiornato correttamente.', + 'Project updated successfully.' => 'Progetto aggiornato con successo.', 'Unable to update this project.' => 'Impossibile aggiornare il progetto.', 'Unable to remove this project.' => 'Impossibile cancellare questo progetto.', - 'Project removed successfully.' => 'Progetto cancellato correttamente.', - 'Project activated successfully.' => 'Progetto attivato correttamente.', + 'Project removed successfully.' => 'Progetto cancellato con successo.', + 'Project activated successfully.' => 'Progetto attivato con successo.', 'Unable to activate this project.' => 'Impossibile attivare il progetto.', - 'Project disabled successfully.' => 'Progetto disattivato correttamente.', + 'Project disabled successfully.' => 'Progetto disattivato con successo.', 'Unable to disable this project.' => 'Impossibile disattivare il progetto.', 'Unable to open this task.' => 'Impossibile aprire questo task.', - 'Task opened successfully.' => 'Il task è stato aperto correttamente.', + 'Task opened successfully.' => 'Il task è stato aperto con successo.', 'Unable to close this task.' => 'Impossibile chiudere questo task.', - 'Task closed successfully.' => 'Task chiuso correttamente.', + 'Task closed successfully.' => 'Task chiuso con successo.', 'Unable to update your task.' => 'Impossibile modificare questo task.', - 'Task updated successfully.' => 'Task modificato correttamente.', + 'Task updated successfully.' => 'Task modificato con successo.', 'Unable to create your task.' => 'Impossibile creare questo task.', - 'Task created successfully.' => 'Task creato correttamente.', - 'User created successfully.' => 'Utente creato correttamente.', + 'Task created successfully.' => 'Task creato con successo.', + 'User created successfully.' => 'Utente creato con successo.', 'Unable to create your user.' => 'Impossibile creare l\'utente.', - 'User updated successfully.' => 'Utente aggiornato correttamente.', + 'User updated successfully.' => 'Utente aggiornato con successo.', 'Unable to update your user.' => 'Impossibile aggiornare questo utente.', - 'User removed successfully.' => 'Utente cancellato correttamente.', + 'User removed successfully.' => 'Utente cancellato con successo.', 'Unable to remove this user.' => 'Impossibile cancellare questo utente.', - 'Board updated successfully.' => 'Bacheca aggiornata correttamente.', + 'Board updated successfully.' => 'Bacheca aggiornata con successo.', 'Ready' => 'Pronto', 'Backlog' => 'In attesa', 'Work in progress' => 'In corso', @@ -168,23 +165,21 @@ return array( 'Task count' => 'Numero di task', 'User' => 'Utente', 'Comments' => 'Commenti', - 'Write your text in Markdown' => 'Scrivi il testo in Markdown', 'Leave a comment' => 'Lascia un commento', 'Comment is required' => 'Si richiede un commento', 'Leave a description' => 'Lascia una descrizione', - 'Comment added successfully.' => 'Commenti aggiunti correttamente.', + 'Comment added successfully.' => 'Commenti aggiunti con successo.', 'Unable to create your comment.' => 'Impossibile creare questo commento.', 'Edit this task' => 'Modifica questo task', 'Due Date' => 'Data di scadenza', 'Invalid date' => 'Data non valida', 'Automatic actions' => 'Azioni automatiche', - 'Your automatic action have been created successfully.' => 'l\'azione automatica è stata creata correttamente.', + 'Your automatic action have been created successfully.' => 'l\'azione automatica è stata creata con successo.', 'Unable to create your automatic action.' => 'Impossibile creare quest\'azione automatica.', 'Remove an action' => 'Cancellare un\'azione', 'Unable to remove this action.' => 'Impossibile cancellare questa azione.', - 'Action removed successfully.' => 'Azione cancellata correttamente.', + 'Action removed successfully.' => 'Azione cancellata con successo.', 'Automatic actions for the project "%s"' => 'Azioni automatiche per il progetto "%s"', - 'Defined actions' => 'Azioni definite', 'Add an action' => 'Aggiungi un\'azione', 'Event name' => 'Nome dell\'evento', 'Action name' => 'Nome dell\'azione', @@ -194,8 +189,7 @@ return array( 'When the selected event occurs execute the corresponding action.' => 'Quando si verifica l\'evento selezionato, eseguire l\'azione corrispondente.', 'Next step' => 'Passo successivo', 'Define action parameters' => 'Definire i parametri dell\'azione', - 'Save this action' => 'Salva questa azione', - 'Do you really want to remove this action: "%s"?' => 'Vuoi veramente cancellare la seguente azione: "%s"?', + 'Do you really want to remove this action: "%s"?' => 'Vuoi davvero cancellare la seguente azione: "%s"?', 'Remove an automatic action' => 'Cancella un\'azione automatica', 'Assign the task to a specific user' => 'Assegna il task ad un utente specifico', 'Assign the task to the person who does the action' => 'Assegna il task all\'utente che compie l\'azione', @@ -210,10 +204,10 @@ return array( 'Duplicate to another project' => 'Duplica in un altro progetto', 'Duplicate' => 'Duplica', 'link' => 'relazione', - 'Comment updated successfully.' => 'Commento aggiornato correttamente.', + 'Comment updated successfully.' => 'Commento aggiornato con successo.', 'Unable to update your comment.' => 'Impossibile aggiornare questo commento.', 'Remove a comment' => 'Cancella un commento', - 'Comment removed successfully.' => 'Commento cancellato correttamente.', + 'Comment removed successfully.' => 'Commento cancellato con successo.', 'Unable to remove this comment.' => 'Impossibile cancellare questo commento.', 'Do you really want to remove this comment?' => 'Vuoi davvero cancellare questo commento?', 'Current password for the user "%s"' => 'Password attuale per l\'utente "%s"', @@ -246,7 +240,7 @@ return array( 'External authentication failed' => 'Autenticazione esterna fallita', 'Your external account is linked to your profile successfully.' => 'Il tuo account esterno è stato collegato al tuo profilo con successo.', 'Email' => 'E-mail', - 'Task removed successfully.' => 'Task cancellato correttamente.', + 'Task removed successfully.' => 'Task cancellato con successo.', 'Unable to remove this task.' => 'Impossibile cancellare questo task.', 'Remove a task' => 'Cancella un task', 'Do you really want to remove this task: "%s"?' => 'Vuoi davvero cancellare questo task: "%s"?', @@ -257,25 +251,25 @@ return array( 'Category:' => 'Categoria:', 'Categories' => 'Categorie', 'Category not found.' => 'Categoria non trovata.', - 'Your category have been created successfully.' => 'La tua categoria è stata creata correttamente.', + 'Your category have been created successfully.' => 'La tua categoria è stata creata con successo.', 'Unable to create your category.' => 'Impossibile creare la tua categoria.', - 'Your category have been updated successfully.' => 'La tua categoria è stata aggiornata correttamente.', + 'Your category have been updated successfully.' => 'La tua categoria è stata aggiornata con successo.', 'Unable to update your category.' => 'Impossibile aggiornare la tua categoria.', 'Remove a category' => 'Cancella una categoria', - 'Category removed successfully.' => 'Categoria cancellata correttamente.', + 'Category removed successfully.' => 'Categoria cancellata con successo.', 'Unable to remove this category.' => 'Impossibile cancellare questa categoria.', 'Category modification for the project "%s"' => 'Modifica della categoria per il progetto "%s"', 'Category Name' => 'Nome della categoria', 'Add a new category' => 'Aggiungere una nuova categoria', - 'Do you really want to remove this category: "%s"?' => 'Vuoi veramente cancellare la seguente categoria: "%s"?', + 'Do you really want to remove this category: "%s"?' => 'Vuoi davvero cancellare la seguente categoria: "%s"?', 'All categories' => 'Tutte le categorie', 'No category' => 'Senza categoria', 'The name is required' => 'Si richiede un nome', 'Remove a file' => 'Cancella un file', 'Unable to remove this file.' => 'Impossibile cancellare questo file.', - 'File removed successfully.' => 'File cancellato correttamente.', + 'File removed successfully.' => 'File cancellato con successo.', 'Attach a document' => 'Allega un documento', - 'Do you really want to remove this file: "%s"?' => 'Vuoi veramente cancellare questo file: "%s"?', + 'Do you really want to remove this file: "%s"?' => 'Vuoi davvero cancellare questo file: "%s"?', 'Attachments' => 'Allegati', 'Edit the task' => 'Modifica il task', 'Edit the description' => 'Modifica la descrizione', @@ -285,12 +279,12 @@ return array( // 'Time tracking' => '', 'Estimate:' => 'Stimato:', 'Spent:' => 'Trascorso:', - 'Do you really want to remove this sub-task?' => 'Vuoi veramente cancellare questo sotto-task?', + 'Do you really want to remove this sub-task?' => 'Vuoi davvero cancellare questo sotto-task?', 'Remaining:' => 'Rimangono', 'hours' => 'ore', 'spent' => 'trascorse', 'estimated' => 'stimate', - 'Sub-Tasks' => 'Sotto-tasks', + 'Sub-Tasks' => 'Sotto-task', 'Add a sub-task' => 'Aggiungi un sotto-task', 'Original estimate' => 'Stima originale', 'Create another sub-task' => 'Crea un altro sotto-task', @@ -300,12 +294,12 @@ return array( 'The time must be a numeric value' => 'Il tempo deve essere un valore numerico', 'Todo' => 'Da fare', 'In progress' => 'In corso', - 'Sub-task removed successfully.' => 'Sotto-task cancellato correttamente.', + 'Sub-task removed successfully.' => 'Sotto-task cancellato con successo.', 'Unable to remove this sub-task.' => 'Impossibile cancellare questo sotto-task.', - 'Sub-task updated successfully.' => 'Sotto-task aggiornato correttamente.', + 'Sub-task updated successfully.' => 'Sotto-task aggiornato con successo.', 'Unable to update your sub-task.' => 'Impossibile aggiornare il tuo sotto-task.', 'Unable to create your sub-task.' => 'Impossibile creare il tuo sotto-task.', - 'Sub-task added successfully.' => 'Sotto-task aggiunto correttamente.', + 'Sub-task added successfully.' => 'Sotto-task aggiunto con successo.', 'Maximum size: ' => 'Dimensioni massime: ', 'Unable to upload the file.' => 'Impossibile caricare il file.', 'Display another project' => 'Mostra un altro progetto', @@ -333,17 +327,17 @@ return array( // 'Time tracking:' => '', 'New sub-task' => 'Nuovo sotto-task', 'New attachment added "%s"' => 'Nuovo allegato aggiunto "%s"', - 'Comment updated' => 'Commento aggiornato', 'New comment posted by %s' => 'Nuovo commento aggiunto da "%s"', 'New attachment' => 'Nuovo allegato', 'New comment' => 'Nuovo commento', + 'Comment updated' => 'Commento aggiornato', 'New subtask' => 'Nuovo sotto-task', 'Subtask updated' => 'Sotto-task aggiornato', 'Task updated' => 'Task aggiornato', 'Task closed' => 'Task chiuso', 'Task opened' => 'Task aperto', 'I want to receive notifications only for those projects:' => 'Vorrei ricevere le notifiche solo da questi progetti:', - 'view the task on Kanboard' => 'vedi il task su Kanboard', + 'view the task on Kanboard' => 'visualizza il task su Kanboard', 'Public access' => 'Accesso pubblico', 'Active tasks' => 'Task attivi', 'Disable public access' => 'Disabilita l\'accesso pubblico', @@ -421,7 +415,7 @@ return array( 'Board settings' => 'Impostazioni bacheca', 'URL and token' => 'URL e token', 'Webhook settings' => 'Impostazione Webhook', - 'URL for task creation:' => 'URL per la creazione dei tasks:', + 'URL for task creation:' => 'URL per la creazione dei task:', 'Reset token' => 'Rigenera il token', 'API endpoint:' => 'Endpoint dell\'API:', 'Refresh interval for private board' => 'Intervallo di refresh per le bacheche private', @@ -436,7 +430,6 @@ return array( 'ISO format is always accepted, example: "%s" and "%s"' => 'Il formato ISO è sempre accettato, esempio: "%s" e "%s"', 'New private project' => 'Nuovo progetto privato', 'This project is private' => 'Questo progetto è privato', - 'Type here to create a new sub-task' => 'Scrivi qui per creare un sotto-task', 'Add' => 'Aggiungi', 'Start date' => 'Data di inizio', 'Time estimated' => 'Tempo stimato', @@ -487,9 +480,6 @@ return array( 'Daily project summary export for "%s"' => 'Export del sommario giornaliero del progetto per "%s"', 'Exports' => 'Esporta', 'This export contains the number of tasks per column grouped per day.' => 'Questo export contiene il numero di task per colonna raggruppati per giorno', - 'Nothing to preview...' => 'Nessuna anteprima...', - 'Preview' => 'Anteprima', - 'Write' => 'Scrivi', 'Active swimlanes' => 'Corsie attive', 'Add a new swimlane' => 'Aggiungi una corsia', 'Change default swimlane' => 'Cambia la corsia predefinita', @@ -542,15 +532,14 @@ return array( 'End' => 'Fine', 'Task age in days' => 'Anzianità del task in giorni', 'Days in this column' => 'Giorni in questa colonna', - // '%dd' => '', - 'Add a link' => 'Aggiungi una relazione', + '%dd' => '%dg', 'Add a new link' => 'Aggiungi una nuova relazione', 'Do you really want to remove this link: "%s"?' => 'Vuoi davvero rimuovere la seguente relazione: "%s"?', 'Do you really want to remove this link with task #%d?' => 'Vuoi davvero rimuovere questa relazione dal task #%d?', 'Field required' => 'Campo necessario', 'Link added successfully.' => 'Relazione aggiunta con successo.', 'Link updated successfully.' => 'Relazione aggiornata con successo.', - 'Link removed successfully.' => 'Relazione rimosso con successo.', + 'Link removed successfully.' => 'Relazione rimossa con successo.', 'Link labels' => 'Etichette delle relazioni', 'Link modification' => 'Modifica relazione', 'Links' => 'Relazioni', @@ -643,7 +632,7 @@ return array( 'Screenshot taken %s' => 'Schermata catturata %s', 'Add a screenshot' => 'Aggiungi una schermata', 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => 'Cattura una schermata e premi CTRL+V o ⌘+V per incollarla qui.', - 'Screenshot uploaded successfully.' => 'Schermata caricata correttamente.', + 'Screenshot uploaded successfully.' => 'Schermata caricata con successo.', 'SEK - Swedish Krona' => 'SEK - Corona svedese', 'Identifier' => 'Identificatore', 'Disable two factor authentication' => 'Disabilita l\'autenticazione "two-factor"', @@ -734,7 +723,7 @@ return array( 'Time spent changed: %sh' => 'Tempo trascorso modificato: %sh', 'Time estimated changed: %sh' => 'Tempo stimato modificato: %sh', 'The field "%s" have been updated' => 'Il campo %s è stato aggiornato', - 'The description have been modified' => 'La descrizione è stata modificata', + 'The description has been modified:' => 'La descrizione è stata modificata', 'Do you really want to close the task "%s" as well as all subtasks?' => 'Vuoi veramente chiudere il task "%s" e i relativi sotto-task?', 'I want to receive notifications for:' => 'Voglio ricevere le notifiche per:', 'All tasks' => 'Tutti i task', @@ -753,8 +742,6 @@ return array( 'My activity stream' => 'Il mio flusso di attività', 'My calendar' => 'Il mio calendario', 'Search tasks' => 'Ricerca task', - 'Back to the calendar' => 'Torna al calendario', - 'Filters' => 'Filtri', 'Reset filters' => 'Annulla filtri', 'My tasks due tomorrow' => 'I miei task da completare per domani', 'Tasks due today' => 'Task da completare oggi', @@ -765,7 +752,7 @@ return array( 'Not assigned' => 'Non assegnato', 'View advanced search syntax' => 'Visualizza la sintassi di ricerca avanzata', 'Overview' => 'Panoramica', - // 'Board/Calendar/List view' => '', + 'Board/Calendar/List view' => 'Vista Bacheca/Calendario/Lista', 'Switch to the board view' => 'Passa alla vista "bacheca"', 'Switch to the calendar view' => 'Passa alla vista "calendario"', 'Switch to the list view' => 'Passa alla vista "elenco"', @@ -854,7 +841,6 @@ return array( 'End date:' => 'Data di fine:', 'There is no start date or end date for this project.' => 'Non è prevista una data di inzio o fine per questo progetto.', 'Projects Gantt chart' => 'Grafico Gantt dei progetti', - 'Link type' => 'Tipo di link', 'Change task color when using a specific task link' => 'Cambia colore del task quando si un utilizza una determinata relazione di task', 'Task link creation or modification' => 'Creazione o modifica di relazione di task', // 'Milestone' => '', @@ -906,11 +892,10 @@ return array( 'Shared' => 'Condiviso', 'Owner' => 'Proprietario', 'Unread notifications' => 'Notifiche non lette', - 'My filters' => 'I miei filtri', 'Notification methods:' => 'Metodi di notifica', 'Import tasks from CSV file' => 'Importa task da file CSV', 'Unable to read your file' => 'Impossibile leggere il file', - '%d task(s) have been imported successfully.' => '%d task sono stati importati con sucesso.', + '%d task(s) have been imported successfully.' => '%d task sono stati importati con successo.', 'Nothing have been imported!' => 'Non è stato importato nulla!', 'Import users from CSV file' => 'Importa utenti da file CSV', '%d user(s) have been imported successfully.' => '%d utenti importati con successo.', @@ -944,8 +929,9 @@ return array( 'Usernames must be lowercase and unique' => 'I nomi utente devono essere in minuscolo e univoci', 'Passwords will be encrypted if present' => 'Se presenti, le password verranno criptate', '%s attached a new file to the task %s' => '%s ha allegato un nuovo file al task %s', + 'Link type' => 'Tipo di link', 'Assign automatically a category based on a link' => 'Assegna automaticamente una categoria sulla base di una relazione', - // 'BAM - Konvertible Mark' => '', + 'BAM - Konvertible Mark' => 'BAM - Marco bosniaco', 'Assignee Username' => 'Nome utente dell\'assegnatario', 'Assignee Name' => 'Nome dell\'assegnatario', 'Groups' => 'Gruppi', @@ -954,7 +940,7 @@ return array( 'Group created successfully.' => 'Gruppo creato con successo', 'Unable to create your group.' => 'Impossibile creare il gruppo', 'Edit group' => 'Modifica gruppo', - 'Group updated successfully.' => 'Gruppo aggiornato con sucesso.', + 'Group updated successfully.' => 'Gruppo aggiornato con successo.', 'Unable to update your group.' => 'Impossibile aggiornare il gruppo', 'Add group member to "%s"' => 'Aggiungi un membro al gruppo "%s"', 'Group member added successfully.' => 'Membro del gruppo aggiunto con successo.', @@ -963,7 +949,7 @@ return array( 'User removed successfully from this group.' => 'Utente rimosso dal gruppo con successo.', 'Unable to remove this user from the group.' => 'Impossibile rimuovere l\'utentei dal gruppo.', 'Remove group' => 'Rimuovi gruppo', - 'Group removed successfully.' => 'Gruppo rimosso con sucesso.', + 'Group removed successfully.' => 'Gruppo rimosso con successo.', 'Unable to remove this group.' => 'Impossibile rimuovere questo gruppo.', 'Project Permissions' => 'Permessi del progetto', // 'Manager' => '', @@ -1030,7 +1016,7 @@ return array( 'Expiration' => 'Scadenza', 'Password reset history' => 'Storico cambio password', 'All tasks of the column "%s" and the swimlane "%s" have been closed successfully.' => 'Tutti i task della colonna "%s" e della corsia "%s" sono stati chiusi con successo.', - 'Do you really want to close all tasks of this column?' => 'Vuoi veramente chiudere tutti i task di questa colonna?', + 'Do you really want to close all tasks of this column?' => 'Vuoi davvero chiudere tutti i task di questa colonna?', '%d task(s) in the column "%s" and the swimlane "%s" will be closed.' => '%d task della colonna "%s" e della corsia "%s" saranno chiusi.', 'Close all tasks of this column' => 'Chiudi tutti i task di questa colonna', 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => 'Nessun plugin ha caricato un metodo di notifica di progetto. Puoi tuttavia configurare le notifiche personali dal tuo profilo utente.', @@ -1050,102 +1036,121 @@ return array( 'Lowest priority' => 'Priorità minima', 'Highest priority' => 'Priorità massima', 'If you put zero to the low and high priority, this feature will be disabled.' => 'Se imposti a zero la priorità massima e minima, questa funzionalità sarà disabilitata.', - // 'Close a task when there is no activity' => '', - // 'Duration in days' => '', - // 'Send email when there is no activity on a task' => '', - // 'List of external links' => '', - // 'Unable to fetch link information.' => '', - // 'Daily background job for tasks' => '', + 'Close a task when there is no activity' => 'Chiudi un task quando non c\'è nessuna attività', + 'Duration in days' => 'Durata in giorni', + 'Send email when there is no activity on a task' => 'Invia un\'email quando non c\'è attività sul task', + 'Unable to fetch link information.' => 'Impossibile recuperare informazioni sul link.', + 'Daily background job for tasks' => 'Job giornaliero in background per i task', // 'Auto' => '', - // 'Related' => '', - // 'Attachment' => '', - // 'Title not found' => '', - // 'Web Link' => '', - // 'External links' => '', - // 'Add external link' => '', - // 'Type' => '', - // 'Dependency' => '', - // 'Add internal link' => '', - // 'Add a new external link' => '', - // 'Edit external link' => '', - // 'External link' => '', - // 'Copy and paste your link here...' => '', + 'Related' => 'Correlato', + 'Attachment' => 'Allegato', + 'Title not found' => 'Titolo non trovato', + 'Web Link' => 'Link Web', + 'External links' => 'Link esterni', + 'Add external link' => 'Aggiungi link esterno', + 'Type' => 'Tipo', + 'Dependency' => 'Dipendenza', + 'Add internal link' => 'Aggiungi link interno', + 'Add a new external link' => 'Aggiungi un nuovo link esterno', + 'Edit external link' => 'Modifica link esterno', + 'External link' => 'Link esterno', + 'Copy and paste your link here...' => 'Copia e incolla il tuo link qui...', // 'URL' => '', - // 'There is no external link for the moment.' => '', - // 'Internal links' => '', - // 'There is no internal link for the moment.' => '', - // 'Assign to me' => '', + 'Internal links' => 'Link interni', + 'Assign to me' => 'Assegna a me', // 'Me' => '', - // 'Do not duplicate anything' => '', - // 'Projects management' => '', - // 'Users management' => '', - // 'Groups management' => '', - // 'Create from another project' => '', - // 'There is no subtask at the moment.' => '', - // 'open' => '', - // 'closed' => '', - // 'Priority:' => '', - // 'Reference:' => '', - // 'Complexity:' => '', - // 'Swimlane:' => '', - // 'Column:' => '', - // 'Position:' => '', - // 'Creator:' => '', - // 'Time estimated:' => '', - // '%s hours' => '', - // 'Time spent:' => '', - // 'Created:' => '', - // 'Modified:' => '', - // 'Completed:' => '', - // 'Started:' => '', - // 'Moved:' => '', + 'Do not duplicate anything' => 'Non duplicare nulla', + 'Projects management' => 'Gestione progetti', + 'Users management' => 'Gestione utenti', + 'Groups management' => 'Gestione gruppi', + 'Create from another project' => 'Crea da un\'altro progetto', + 'open' => 'aperto', + 'closed' => 'chiuso', + 'Priority:' => 'Priorità:', + 'Reference:' => 'Riferimento:', + 'Complexity:' => 'Complessità:', + 'Swimlane:' => 'Corsia:', + 'Column:' => 'Colonna:', + 'Position:' => 'Posizione:', + 'Creator:' => 'Creatore:', + 'Time estimated:' => 'Tempo stimato:', + '%s hours' => '%s ore', + 'Time spent:' => 'Tempo trascorso:', + 'Created:' => 'Creato:', + 'Modified:' => 'Modificato:', + 'Completed:' => 'Completato:', + 'Started:' => 'Iniziato:', + 'Moved:' => 'Spostato:', // 'Task #%d' => '', - // 'Sub-tasks' => '', - // 'Date and time format' => '', - // 'Time format' => '', - // 'Start date: ' => '', - // 'End date: ' => '', - // 'New due date: ' => '', - // 'Start date changed: ' => '', - // 'Disable private projects' => '', - // 'Do you really want to remove this custom filter: "%s"?' => '', - // 'Remove a custom filter' => '', - // 'User activated successfully.' => '', - // 'Unable to enable this user.' => '', - // 'User disabled successfully.' => '', - // 'Unable to disable this user.' => '', - // 'All files have been uploaded successfully.' => '', - // 'View uploaded files' => '', - // 'The maximum allowed file size is %sB.' => '', - // 'Choose files again' => '', - // 'Drag and drop your files here' => '', - // 'choose files' => '', - // 'View profile' => '', + 'Date and time format' => 'Formato data e ora', + 'Time format' => 'Formato ora', + 'Start date: ' => 'Data di inizio: ', + 'End date: ' => 'Data di fine: ', + 'New due date: ' => 'Nuova data di scadenza: ', + 'Start date changed: ' => 'Data di inizio cambiata: ', + 'Disable private projects' => 'Disabilita progetti privati', + 'Do you really want to remove this custom filter: "%s"?' => 'Vuoi davvero rimuovere questo filtro personalizato: "%s"?', + 'Remove a custom filter' => 'Rimuovi un filtro personalizzato', + 'User activated successfully.' => 'Utente attivato con successo.', + 'Unable to enable this user.' => 'Impossibile abilitare questo utente.', + 'User disabled successfully.' => 'Utente disabilitato con successo.', + 'Unable to disable this user.' => 'Impossibile disabilitare questo utente.', + 'All files have been uploaded successfully.' => 'Tutti i file sono stati caricati con successo.', + 'View uploaded files' => 'Visualizza i file caricati', + 'The maximum allowed file size is %sB.' => 'La dimensione massima consentita del file è %sB.', + 'Choose files again' => 'Seleziona nuovamente i file', + 'Drag and drop your files here' => 'Trascina i tuoi file qui', + 'choose files' => 'seleziona i file', + 'View profile' => 'Guarda il profilo', // 'Two Factor' => '', - // 'Disable user' => '', - // 'Do you really want to disable this user: "%s"?' => '', - // 'Enable user' => '', - // 'Do you really want to enable this user: "%s"?' => '', - // 'Download' => '', - // 'Uploaded: %s' => '', - // 'Size: %s' => '', - // 'Uploaded by %s' => '', - // 'Filename' => '', - // 'Size' => '', - // 'Column created successfully.' => '', - // 'Another column with the same name exists in the project' => '', - // 'Default filters' => '', - // 'Your board doesn\'t have any column!' => '', - // 'Change column position' => '', - // 'Switch to the project overview' => '', - // 'User filters' => '', - // 'Category filters' => '', - // 'Upload a file' => '', - // 'There is no attachment at the moment.' => '', - // 'View file' => '', - // 'Last activity' => '', - // 'Change subtask position' => '', - // 'This value must be greater than %d' => '', - // 'Another swimlane with the same name exists in the project' => '', - // 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => '', + 'Disable user' => 'Disabilita utente', + 'Do you really want to disable this user: "%s"?' => 'Vuoi davvero disabilitare questo utente: "%s"?', + 'Enable user' => 'Abilita utente', + 'Do you really want to enable this user: "%s"?' => 'Vuoi davvero abilitare questo utente: "%s"?', + 'Download' => 'Scarica', + 'Uploaded: %s' => 'Caricato: %s', + 'Size: %s' => 'Dimensione: %s', + 'Uploaded by %s' => 'Caricato da %s', + 'Filename' => 'Nome del file', + 'Size' => 'Dimensione', + 'Column created successfully.' => 'Colonna creata con successo.', + 'Another column with the same name exists in the project' => 'Un\'altra colonna con lo stesso nome è già esistente in questo progetto', + 'Default filters' => 'Filtri predefiniti', + 'Your board doesn\'t have any column!' => 'La tua bacheca non ha nessuna colonna!', + 'Change column position' => 'Modifica la posizione della colonna', + 'Switch to the project overview' => 'Passa alla panoramica di progetto', + 'User filters' => 'Filtri utente', + 'Category filters' => 'Filtri di categorie', + 'Upload a file' => 'Carica un file', + 'View file' => 'Visualizza file', + 'Last activity' => 'Attività recente', + 'Change subtask position' => 'Cambia la posizione del sotto-task', + 'This value must be greater than %d' => 'Questo valore deve essere magiore di %d', + 'Another swimlane with the same name exists in the project' => 'Un\'altra corsia con lo stesso nome è già esistente in questo progetto', + 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => 'Esempio: http://example.kanboard.net/ (usato per generare URL assolute)', + // 'Actions duplicated successfully.' => '', + // 'Unable to duplicate actions.' => '', + // 'Add a new action' => '', + // 'Import from another project' => '', + // 'There is no action at the moment.' => '', + // 'Import actions from another project' => '', + // 'There is no available project.' => '', + // 'Local File' => '', + // 'Configuration' => '', + // 'PHP version:' => '', + // 'PHP SAPI:' => '', + // 'OS version:' => '', + // 'Database version:' => '', + // 'Browser:' => '', + // 'Task view' => '', + // 'Edit task' => '', + // 'Edit description' => '', + // 'New internal link' => '', + // 'Display list of keyboard shortcuts' => '', + // 'Menu' => '', + // 'Set start date' => '', + // 'Avatar' => '', + // 'Upload my avatar image' => '', + // 'Remove my image' => '', + // 'The OAuth2 state parameter is invalid' => '', ); diff --git a/sources/app/Locale/ja_JP/translations.php b/sources/app/Locale/ja_JP/translations.php index 3d22ce3..b48eabd 100644 --- a/sources/app/Locale/ja_JP/translations.php +++ b/sources/app/Locale/ja_JP/translations.php @@ -8,7 +8,6 @@ return array( 'Edit' => '変更', 'remove' => '削除する', 'Remove' => '削除する', - 'Update' => '変更', 'Yes' => 'はい', 'No' => 'いいえ', 'cancel' => 'キャンセル', @@ -60,7 +59,6 @@ return array( 'Actions' => 'アクション', 'Inactive' => '無効', 'Active' => '有効', - 'Add this column' => 'カラムを追加する', '%d tasks on the board' => '%d 個のタスク', '%d tasks in total' => '合計 %d 個のタスク', 'Unable to update this board.' => 'ボードを更新できませんでした', @@ -74,7 +72,6 @@ return array( 'All projects' => 'すべてのプロジェクト', 'Add a new column' => 'カラムの追加', 'Title' => 'タイトル', - 'Nobody assigned' => '担当なし', 'Assigned to %s' => '%sが担当', 'Remove a column' => 'カラムの削除', 'Remove a column from a board' => 'ボードからカラムの削除', @@ -168,7 +165,6 @@ return array( 'Task count' => 'タスク数', 'User' => 'ユーザ', 'Comments' => 'コメント', - 'Write your text in Markdown' => 'Markdown 記法で書く', 'Leave a comment' => 'コメントを書く', 'Comment is required' => 'コメントを入力してください', 'Leave a description' => '説明を書く', @@ -184,7 +180,6 @@ return array( 'Unable to remove this action.' => '自動アクションの削除に失敗しました。', 'Action removed successfully.' => '自動アクションの削除に成功しました。', 'Automatic actions for the project "%s"' => 'プロジェクト「%s」の自動アクション', - 'Defined actions' => '定義された自動アクション', 'Add an action' => '自動アクションの追加', 'Event name' => 'イベント名', 'Action name' => 'アクション名', @@ -194,7 +189,6 @@ return array( 'When the selected event occurs execute the corresponding action.' => '選択されたイベントが発生した時、対応するアクションを実行する。', 'Next step' => '次のステップ', 'Define action parameters' => 'アクションのパラメーター', - 'Save this action' => 'このアクションを保存する', 'Do you really want to remove this action: "%s"?' => '自動アクション「%s」を削除しますか?', 'Remove an automatic action' => '自動アクションの削除', 'Assign the task to a specific user' => 'タスクの担当者を割り当てる', @@ -333,10 +327,10 @@ return array( 'Time tracking:' => '時間計測:', 'New sub-task' => '新しいサブタスク', 'New attachment added "%s"' => '添付ファイル「%s」が追加されました', - 'Comment updated' => 'コメントが更新されました', 'New comment posted by %s' => '「%s」の新しいコメントが追加されました', 'New attachment' => '新しい添付ファイル', 'New comment' => '新しいコメント', + 'Comment updated' => 'コメントが更新されました', 'New subtask' => '新しいサブタスク', 'Subtask updated' => 'サブタスクの更新', 'Task updated' => 'タスクの更新', @@ -436,7 +430,6 @@ return array( 'ISO format is always accepted, example: "%s" and "%s"' => 'ISO フォーマットが入力できます(例: %s または %s)', 'New private project' => '非公開プロジェクトを作る', 'This project is private' => 'このプロジェクトは非公開です', - 'Type here to create a new sub-task' => 'サブタスクを追加するにはここに入力してください', 'Add' => '追加', 'Start date' => '開始時間', 'Time estimated' => '予想時間', @@ -487,9 +480,6 @@ return array( 'Daily project summary export for "%s"' => '「%s」の日時プロジェクトサマリーの出力', 'Exports' => '出力', 'This export contains the number of tasks per column grouped per day.' => 'この出力は日時のカラムごとのタスク数を集計したものです', - 'Nothing to preview...' => 'プレビューがありません', - 'Preview' => 'プレビュー', - 'Write' => '書く', 'Active swimlanes' => 'アクティブなスイムレーン', 'Add a new swimlane' => '新しいスイムレーン', 'Change default swimlane' => 'デフォルトスイムレーンの変更', @@ -543,7 +533,6 @@ return array( '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を削除しますか?', @@ -734,7 +723,7 @@ return array( // 'Time spent changed: %sh' => '', // 'Time estimated changed: %sh' => '', // 'The field "%s" have been updated' => '', - // 'The description have been modified' => '', + // 'The description has been modified:' => '', // 'Do you really want to close the task "%s" as well as all subtasks?' => '', // 'I want to receive notifications for:' => '', // 'All tasks' => '', @@ -753,8 +742,6 @@ return array( // 'My activity stream' => '', // 'My calendar' => '', // 'Search tasks' => '', - // 'Back to the calendar' => '', - // 'Filters' => '', // 'Reset filters' => '', // 'My tasks due tomorrow' => '', // 'Tasks due today' => '', @@ -854,7 +841,6 @@ return array( // 'End date:' => '', // 'There is no start date or end date for this project.' => '', // 'Projects Gantt chart' => '', - // 'Link type' => '', // 'Change task color when using a specific task link' => '', // 'Task link creation or modification' => '', // 'Milestone' => '', @@ -906,7 +892,6 @@ return array( // 'Shared' => '', // 'Owner' => '', // 'Unread notifications' => '', - // 'My filters' => '', // 'Notification methods:' => '', // 'Import tasks from CSV file' => '', // 'Unable to read your file' => '', @@ -944,6 +929,7 @@ return array( // 'Usernames must be lowercase and unique' => '', // 'Passwords will be encrypted if present' => '', // '%s attached a new file to the task %s' => '', + // 'Link type' => '', // 'Assign automatically a category based on a link' => '', // 'BAM - Konvertible Mark' => '', // 'Assignee Username' => '', @@ -1053,7 +1039,6 @@ return array( // 'Close a task when there is no activity' => '', // 'Duration in days' => '', // 'Send email when there is no activity on a task' => '', - // 'List of external links' => '', // 'Unable to fetch link information.' => '', // 'Daily background job for tasks' => '', // 'Auto' => '', @@ -1071,9 +1056,7 @@ return array( // 'External link' => '', // 'Copy and paste your link here...' => '', // 'URL' => '', - // 'There is no external link for the moment.' => '', // 'Internal links' => '', - // 'There is no internal link for the moment.' => '', // 'Assign to me' => '', // 'Me' => '', // 'Do not duplicate anything' => '', @@ -1081,7 +1064,6 @@ return array( // 'Users management' => '', // 'Groups management' => '', // 'Create from another project' => '', - // 'There is no subtask at the moment.' => '', // 'open' => '', // 'closed' => '', // 'Priority:' => '', @@ -1100,7 +1082,6 @@ return array( // 'Started:' => '', // 'Moved:' => '', // 'Task #%d' => '', - // 'Sub-tasks' => '', // 'Date and time format' => '', // 'Time format' => '', // 'Start date: ' => '', @@ -1141,11 +1122,35 @@ return array( // 'User filters' => '', // 'Category filters' => '', // 'Upload a file' => '', - // 'There is no attachment at the moment.' => '', // 'View file' => '', // 'Last activity' => '', // 'Change subtask position' => '', // 'This value must be greater than %d' => '', // 'Another swimlane with the same name exists in the project' => '', // 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => '', + // 'Actions duplicated successfully.' => '', + // 'Unable to duplicate actions.' => '', + // 'Add a new action' => '', + // 'Import from another project' => '', + // 'There is no action at the moment.' => '', + // 'Import actions from another project' => '', + // 'There is no available project.' => '', + // 'Local File' => '', + // 'Configuration' => '', + // 'PHP version:' => '', + // 'PHP SAPI:' => '', + // 'OS version:' => '', + // 'Database version:' => '', + // 'Browser:' => '', + // 'Task view' => '', + // 'Edit task' => '', + // 'Edit description' => '', + // 'New internal link' => '', + // 'Display list of keyboard shortcuts' => '', + // 'Menu' => '', + // 'Set start date' => '', + // 'Avatar' => '', + // 'Upload my avatar image' => '', + // 'Remove my image' => '', + // 'The OAuth2 state parameter is invalid' => '', ); diff --git a/sources/app/Locale/ko_KR/translations.php b/sources/app/Locale/ko_KR/translations.php new file mode 100644 index 0000000..8379761 --- /dev/null +++ b/sources/app/Locale/ko_KR/translations.php @@ -0,0 +1,1156 @@ + '', + // 'number.thousands_separator' => '', + 'None' => '없음', + 'edit' => '수정', + 'Edit' => '수정', + 'remove' => '삭제', + 'Remove' => '삭제', + 'Yes' => '예', + 'No' => '아니오', + 'cancel' => '취소', + 'or' => '또는', + 'Yellow' => '노랑', + 'Blue' => '파랑', + 'Green' => '초록', + 'Purple' => '보라', + 'Red' => '빨강', + 'Orange' => '주황', + 'Grey' => '회색', + 'Brown' => '브라운', + // 'Deep Orange' => '', + // 'Dark Grey' => '', + // 'Pink' => '', + // 'Teal' => '', + // 'Cyan' => '', + // 'Lime' => '', + // 'Light Green' => '', + // 'Amber' => '', + 'Save' => '저장', + 'Login' => '로그인', + 'Official website:' => '공식 웹사이트:', + 'Unassigned' => '담당자 없음', + 'View this task' => '이 할일 보기', + 'Remove user' => '사용자 삭제', + 'Do you really want to remove this user: "%s"?' => '사용자 "%s"를 정말로 삭제하시겠습니까?', + 'New user' => '사용자를 추가하는 ', + 'All users' => '모든 사용자', + 'Username' => '사용자 이름', + 'Password' => '패스워드', + 'Administrator' => '관리자', + 'Sign in' => '로그인', + 'Users' => '사용자', + 'No user' => '사용자가 없습니다', + 'Forbidden' => '접근 거부', + 'Access Forbidden' => '접속이 거부되었습니다', + 'Edit user' => '사용자를 변경하는 ', + 'Logout' => '로그아웃', + 'Bad username or password' => '사용자 이름 또는 패스워드가 다릅니다.', + 'Edit project' => '프로젝트 수정', + 'Name' => '이름', + 'Projects' => '프로젝트', + 'No project' => '프로젝트가 없습니다', + 'Project' => '프로젝트', + 'Status' => '상태', + 'Tasks' => '할일', + 'Board' => '보드', + 'Actions' => 'Actions', + 'Inactive' => '무효', + 'Active' => '유효', + '%d tasks on the board' => '%d개의 할일', + '%d tasks in total' => '총 %d개의 할일', + 'Unable to update this board.' => '보드를 갱신할 수 없었습니다', + 'Edit board' => '보드를 변경하는 ', + 'Disable' => '비활성화', + 'Enable' => '유효하게 한다', + 'New project' => '새 프로젝트', + // 'Do you really want to remove this project: "%s"?' => '', + 'Remove project' => '프로젝트의 삭제', + // 'Edit the board for "%s"' => '', + 'All projects' => '모든 프로젝트', + 'Add a new column' => '칼럼의 추가', + 'Title' => '제목', + 'Assigned to %s' => '담당자 %s', + 'Remove a column' => '칼럼 삭제', + 'Remove a column from a board' => '보드에서 칼럼 삭제', + 'Unable to remove this column.' => '(※)컬럼을 삭제할 수 없었습니다.', + // 'Do you really want to remove this column: "%s"?' => '', + 'This action will REMOVE ALL TASKS associated to this column!' => '이 조작은 이 컬럼에 할당된 『 모든 할일을 삭제 』합니다!', + 'Settings' => '설정', + 'Application settings' => '애플리케이션의 설정', + 'Language' => '언어', + 'Webhook token:' => 'Webhook토큰:', + 'API token:' => 'API토큰:', + 'Database size:' => '데이터베이스의 사이즈:', + 'Download the database' => '데이터베이스의 다운로드', + 'Optimize the database' => '데이터베이스 최적화', + '(VACUUM command)' => '(VACUUM명령)', + '(Gzip compressed Sqlite file)' => '(GZip명령으로 압축된 Sqlite파일)', + 'Close a task' => '할일 마치기', + 'Edit a task' => '할일 수정', + 'Column' => '칼럼', + 'Color' => '색', + 'Assignee' => '담당자', + 'Create another task' => '다른 할일 추가', + 'New task' => '새로운 할일', + 'Open a task' => '할일 열기', + // 'Do you really want to open this task: "%s"?' => '', + 'Back to the board' => '보드로 돌아가기', + 'There is nobody assigned' => '담당자가 없습니다', + 'Column on the board:' => '칼럼:', + 'Close this task' => '할일 마치기', + 'Open this task' => '할일을 열다', + 'There is no description.' => '설명이 없다', + 'Add a new task' => '할일을 추가하는 ', + 'The username is required' => '사용자 이름이 필요합니다', + // 'The maximum length is %d characters' => '', + // 'The minimum length is %d characters' => '', + 'The password is required' => '패스워드가 필요합니다', + 'This value must be an integer' => '정수로 입력하세요', + 'The username must be unique' => '사용자 이름이 이미 사용되고 있습니다', + 'The user id is required' => '사용자 ID가 필요합니다', + 'Passwords don\'t match' => '패스워드가 일치하지 않습니다', + 'The confirmation is required' => '확인용 패스워드를 입력하세요', + 'The project is required' => '프로젝트가 필요합니다', + 'The id is required' => 'ID가 필요합니다', + 'The project id is required' => '프로젝트 ID가 필요합니다', + 'The project name is required' => '프로젝트 이름이 필요합니다', + 'The title is required' => '제목이 필요합니다', + 'Settings saved successfully.' => '설정을 저장하였습니다', + 'Unable to save your settings.' => '설정의 보존에 실패했습니다.', + 'Database optimization done.' => '데이터베이스 최적화가 끝났습니다.', + 'Your project have been created successfully.' => '프로젝트를 작성했습니다.', + 'Unable to create your project.' => '프로젝트의 작성에 실패했습니다.', + 'Project updated successfully.' => '프로젝트를 갱신했습니다.', + 'Unable to update this project.' => '프로젝트의 갱신에 실패했습니다.', + 'Unable to remove this project.' => '프로젝트의 삭제에 실패했습니다.', + 'Project removed successfully.' => '프로젝트를 삭제했습니다.', + 'Project activated successfully.' => '프로젝트를 유효로 했습니다.', + 'Unable to activate this project.' => '프로젝트의 유효하게 못했어요.', + 'Project disabled successfully.' => '프로젝트를 무효로 했습니다.', + 'Unable to disable this project.' => '프로젝트의 무효화할 수 없었습니다.', + 'Unable to open this task.' => '할일의 오픈에 실패했습니다.', + 'Task opened successfully.' => '할일을 오픈했습니다.', + 'Unable to close this task.' => '할일의 클로즈에 실패했습니다.', + 'Task closed successfully.' => '할일을 마쳤습니다.', + 'Unable to update your task.' => '할일의 갱신에 실패했습니다.', + 'Task updated successfully.' => '할일을 갱신했습니다.', + 'Unable to create your task.' => '할일의 추가에 실패했습니다.', + 'Task created successfully.' => '할일을 추가했습니다.', + 'User created successfully.' => '사용자를 추가했습니다.', + 'Unable to create your user.' => '사용자의 추가에 실패했습니다.', + 'User updated successfully.' => '사용자를 갱신했습니다.', + 'Unable to update your user.' => '사용자의 갱신에 실패했습니다.', + 'User removed successfully.' => '사용자를 삭제했습니다.', + 'Unable to remove this user.' => '사용자 삭제에 실패했습니다.', + 'Board updated successfully.' => '보드를 갱신했습니다.', + 'Ready' => '준비완료', + 'Backlog' => '요구사항', + 'Work in progress' => '진행중', + 'Done' => '완료', + 'Application version:' => '애플리케이션의 버전:', + 'Id' => 'ID', + '%d closed tasks' => '%d개의 마친 할일', + 'No task for this project' => '이 프로젝트에 할일이 없습니다', + 'Public link' => '공개 접속 링크', + 'Change assignee' => '담당자 변경', + 'Change assignee for the task "%s"' => '할일 "%s"의 담당자를 변경', + 'Timezone' => '시간대', + 'Sorry, I didn\'t find this information in my database!' => '데이터베이스에서 정보가 발견되지 않았습니다!', + 'Page not found' => '페이지가 발견되지 않는다', + 'Complexity' => '복잡도', + 'Task limit' => '할일 수 제한', + 'Task count' => '할일 수', + 'User' => '사용자', + 'Comments' => '댓글', + 'Leave a comment' => '댓글 남기기', + 'Comment is required' => '댓글을 입력하세요', + 'Leave a description' => '설명을 입력하세요', + 'Comment added successfully.' => '의견을 추가했습니다.', + 'Unable to create your comment.' => '댓글의 추가에 실패했습니다.', + 'Edit this task' => '할일 수정', + 'Due Date' => '마감일', + 'Invalid date' => '날짜가 무효입니다', + 'Automatic actions' => '자동액션 관리', + 'Your automatic action have been created successfully.' => '자동 액션을 작성했습니다.', + 'Unable to create your automatic action.' => '자동 액션의 작성에 실패했습니다.', + 'Remove an action' => '자동 액션의 삭제', + 'Unable to remove this action.' => '자동 액션의 삭제에 실패했습니다.', + 'Action removed successfully.' => '자동 액션의 삭제에 성공했어요.', + // 'Automatic actions for the project "%s"' => '', + 'Add an action' => '자동 액션 추가', + 'Event name' => '이벤트 이름', + 'Action name' => '액션 이름', + 'Action parameters' => '액션의 바로미터', + 'Action' => '액션', + 'Event' => '이벤트', + 'When the selected event occurs execute the corresponding action.' => '선택된 이벤트가 발생했을 때 대응하는 액션을 실행한다.', + 'Next step' => '다음 단계', + 'Define action parameters' => '액션의 바로미터', + // 'Do you really want to remove this action: "%s"?' => '', + 'Remove an automatic action' => '자동 액션의 삭제', + 'Assign the task to a specific user' => '할일 담당자를 할당', + 'Assign the task to the person who does the action' => '액션을 일으킨 사용자를 담당자이자', + 'Duplicate the task to another project' => ' 다른 프로젝트에 할일을 복제하는 ', + 'Move a task to another column' => '할일을 다른 칼럼에 이동하는 ', + 'Task modification' => '할일 변경', + 'Task creation' => '할일을 만들', + 'Closing a task' => '할일을 닫혔다', + 'Assign a color to a specific user' => '색을 사용자에 할당', + 'Column title' => '칼럼의 제목', + 'Position' => '위치', + 'Duplicate to another project' => '다른 프로젝트에 복사', + 'Duplicate' => '복사', + 'link' => '링크', + 'Comment updated successfully.' => '댓글을 갱신했습니다.', + 'Unable to update your comment.' => '댓글의 갱신에 실패했습니다.', + 'Remove a comment' => '댓글 삭제', + 'Comment removed successfully.' => '댓글을 삭제했습니다.', + 'Unable to remove this comment.' => '댓글의 삭제에 실패했습니다.', + 'Do you really want to remove this comment?' => '댓글을 삭제합니까?', + 'Current password for the user "%s"' => '사용자 "%s"의 현재 패스워드', + 'The current password is required' => '현재의 패스워드를 입력하세요', + 'Wrong password' => '패스워드가 다릅니다', + 'Unknown' => '불명', + 'Last logins' => '마지막 로그인', + 'Login date' => '로그인 일시', + 'Authentication method' => '인증 방법', + 'IP address' => 'IP 주소', + 'User agent' => '사용자 에이전트', + 'Persistent connections' => '세션', + 'No session.' => '세션 없음', + 'Expiration date' => '유효기간', + 'Remember Me' => '자동 로그인', + 'Creation date' => '작성일', + 'Everybody' => '모두', + 'Open' => '열림', + 'Closed' => '닫힘', + 'Search' => '검색', + 'Nothing found.' => '결과가 없습니다', + 'Due date' => '마감일', + 'Others formats accepted: %s and %s' => ' 다른 서식: %s 또는 %s', + 'Description' => '설명', + '%d comments' => '%d개의 댓글', + '%d comment' => '%d개의 댓글', + 'Email address invalid' => '메일 주소가 올바르지 않습니다.', + // 'Your external account is not linked anymore to your profile.' => '', + // 'Unable to unlink your external account.' => '', + // 'External authentication failed' => '', + // 'Your external account is linked to your profile successfully.' => '', + 'Email' => '이메일', + 'Task removed successfully.' => '할일을 삭제했습니다.', + 'Unable to remove this task.' => '할일 삭제에 실패했습니다.', + 'Remove a task' => '할일 삭제', + // 'Do you really want to remove this task: "%s"?' => '', + 'Assign automatically a color based on a category' => '카테고리에 바탕을 두고 색을 바꾸고', + 'Assign automatically a category based on a color' => '색에 바탕을 두고 카테고리를 바꾸었다', + 'Task creation or modification' => '할일의 작성 또는 변경', + 'Category' => '카테고리', + 'Category:' => '카테고리:', + 'Categories' => '카테고리', + 'Category not found.' => '카테고리가 발견되지 않습니다', + 'Your category have been created successfully.' => '카테고리를 작성했습니다.', + 'Unable to create your category.' => '카테고리의 작성에 실패했습니다.', + 'Your category have been updated successfully.' => '카테고리를 갱신했습니다.', + 'Unable to update your category.' => '카테고리의 갱신에 실패했습니다.', + 'Remove a category' => '카테고리의 삭제', + 'Category removed successfully.' => '카테고리를 삭제했습니다.', + 'Unable to remove this category.' => '카테고리를 삭제할 수 없었습니다.', + // 'Category modification for the project "%s"' => '', + 'Category Name' => '카테고리 이름', + 'Add a new category' => '카테고리의 추가', + // 'Do you really want to remove this category: "%s"?' => '', + 'All categories' => '모든 카테고리', + 'No category' => '카테고리 없음', + 'The name is required' => '이름을 입력하십시오', + 'Remove a file' => '파일 삭제', + 'Unable to remove this file.' => '파일 삭제에 실패했습니다.', + 'File removed successfully.' => '파일을 삭제했습니다.', + 'Attach a document' => '문서 첨부', + 'Do you really want to remove this file: "%s"?' => '파일 "%s" 을 삭제할까요?', + 'Attachments' => '첨부', + 'Edit the task' => '할일 수정', + 'Edit the description' => '설명 수정', + 'Add a comment' => '댓글 추가', + 'Edit a comment' => '댓글 수정', + 'Summary' => '개요', + 'Time tracking' => '시간 추적', + 'Estimate:' => '예측:', + 'Spent:' => '경과:', + 'Do you really want to remove this sub-task?' => '서브 할일을 삭제합니까?', + 'Remaining:' => '나머지:', + 'hours' => '시간', + 'spent' => '경과', + 'estimated' => '예측', + 'Sub-Tasks' => '서브 할일', + 'Add a sub-task' => '서브 할일 추가', + 'Original estimate' => '최초 예측시간', + 'Create another sub-task' => '다음 서브 할일 추가', + 'Time spent' => '경과시간', + 'Edit a sub-task' => '서브 할일을 변경하는 ', + 'Remove a sub-task' => '서브 할일을 삭제하는 ', + 'The time must be a numeric value' => '시간은 숫자로 입력하세요', + 'Todo' => '할일 예정', + 'In progress' => '할일 중', + 'Sub-task removed successfully.' => '서브 할일을 삭제했습니다.', + 'Unable to remove this sub-task.' => '서브 할일의 삭제가 실패했습니다.', + 'Sub-task updated successfully.' => '서브 할일을 갱신했습니다.', + 'Unable to update your sub-task.' => '서브 할일의 경신에 실패했습니다.', + 'Unable to create your sub-task.' => '서브 할일의 추가에 실패했습니다.', + 'Sub-task added successfully.' => '서브 할일을 추가했습니다.', + 'Maximum size: ' => '최대: ', + 'Unable to upload the file.' => '파일 업로드에 실패했습니다.', + 'Display another project' => '프로젝트 보기', + 'Created by %s' => '작성자 %s', + 'Tasks Export' => '할일 내보내기', + // 'Tasks exportation for "%s"' => '', + 'Start Date' => '시작일', + 'End Date' => '종료일', + 'Execute' => '실행', + 'Task Id' => '할일 ID', + 'Creator' => '작성자', + 'Modification date' => '변경 일', + 'Completion date' => '완료일', + 'Clone' => '복사', + 'Project cloned successfully.' => '프로젝트를 복제했습니다.', + 'Unable to clone this project.' => '프로젝트의 복제에 실패했습니다.', + 'Enable email notifications' => '이메일 알림 설정', + 'Task position:' => '할일 위치:', + // 'The task #%d have been opened.' => '', + // 'The task #%d have been closed.' => '', + 'Sub-task updated' => '서브 할일 갱신', + 'Title:' => '제목:', + 'Status:' => '상태:', + 'Assignee:' => '담당:', + 'Time tracking:' => '시간 계측:', + 'New sub-task' => '새로운 서브 할일', + // 'New attachment added "%s"' => '', + 'New comment posted by %s' => '"%s"님이 댓글을 추가하였습니다', + 'New attachment' => ' 새로운 첨부 파일', + 'New comment' => ' 새로운 댓글', + 'Comment updated' => '댓글가 갱신되었습니다', + 'New subtask' => ' 새로운 서브 할일', + 'Subtask updated' => '서브 할일 갱신', + 'Task updated' => '할일 업데이트', + 'Task closed' => '할일 마침', + 'Task opened' => '할일 시작', + 'I want to receive notifications only for those projects:' => '다음 프로젝트의 알림만 받겠습니다:', + 'view the task on Kanboard' => 'Kanboard에서 할일을 본다', + 'Public access' => '공개 접속 설정', + 'Active tasks' => '활성화된 할일', + 'Disable public access' => '공개 접속 비활성화', + 'Enable public access' => '공개 접속 활성화', + 'Public access disabled' => '공개 접속 불가', + // 'Do you really want to disable this project: "%s"?' => '', + // 'Do you really want to enable this project: "%s"?' => '', + 'Project activation' => '프로젝트의 액티베ー션', + 'Move the task to another project' => '할일별 프로젝트에 옮기', + 'Move to another project' => '다른 프로젝트로 이동', + 'Do you really want to duplicate this task?' => '할일을 복제합니까?', + 'Duplicate a task' => '할일 복사', + 'External accounts' => '외부 계정', + 'Account type' => '계정종류', + 'Local' => '로컬', + 'Remote' => '원격', + 'Enabled' => '활성화', + 'Disabled' => '비활성화', + 'Username:' => '사용자명', + 'Name:' => '이름:', + 'Email:' => '이메일:', + 'Notifications:' => '알림:', + 'Notifications' => '알림', + 'Account type:' => '계정종류:', + 'Edit profile' => '프로필 변경', + 'Change password' => '패스워드 변경', + 'Password modification' => '패스워드 변경', + 'External authentications' => '외부 인증', + 'Never connected.' => '접속기록없음', + 'No external authentication enabled.' => '외부 인증이 설정되어 있지 않습니다.', + 'Password modified successfully.' => '패스워드를 변경했습니다.', + 'Unable to change the password.' => '비밀 번호가 변경할 수 없었습니다.', + 'Change category for the task "%s"' => '할일 "%s"의 카테고리의 변경', + 'Change category' => '카테고리 수정', + '%s updated the task %s' => '%s이 할일 %s을 업데이트했습니다', + // '%s opened the task %s' => '', + '%s moved the task %s to the position #%d in the column "%s"' => '%s이 할일%s을 위치#%d컬럼%s로 옮겼습니다', + '%s moved the task %s to the column "%s"' => '%s이 할일 %s을 칼럼 "%s" 로 옮겼습니다', + '%s created the task %s' => '%s이 할일%s을 추가했습니다', + '%s closed the task %s' => '%s이 할일%s을 마쳤습니다', + '%s created a subtask for the task %s' => '%s이 할일%s의 서브 할일을 추가했습니다', + '%s updated a subtask for the task %s' => '%s이 할일%s의 서브 할일을 갱신했습니다', + 'Assigned to %s with an estimate of %s/%sh' => '담당자 %s에게 예상 %s/%sh로 할당되었습니다', + // 'Not assigned, estimate of %sh' => '', + '%s updated a comment on the task %s' => '%s이 할일%s의 댓글을 수정했습니다', + '%s commented the task %s' => '%s이 할일%s에 댓글을 남겼습니다', + '%s\'s activity' => '%s의 활동', + 'RSS feed' => 'RSS피드', + // '%s updated a comment on the task #%d' => '', + // '%s commented on the task #%d' => '', + // '%s updated a subtask for the task #%d' => '', + // '%s created a subtask for the task #%d' => '', + '%s updated the task #%d' => '%s이 할일#%d을 갱신했습니다', + '%s created the task #%d' => '%s이 할일#%d을 추가했습니다', + '%s closed the task #%d' => '%s이 할일#%d을 닫혔습니다', + '%s open the task #%d' => '%s이 할일#%d를 오픈했습니다', + '%s moved the task #%d to the column "%s"' => '%s이 할일#%d을 칼럼"%s"로 옮겼습니다', + // '%s moved the task #%d to the position %d in the column "%s"' => '', + 'Activity' => '활동', + // 'Default values are "%s"' => '', + // 'Default columns for new projects (Comma-separated)' => '', + 'Task assignee change' => '담당자의 변경', + // '%s change the assignee of the task #%d to %s' => '', + '%s changed the assignee of the task %s to %s' => '%s이 할일 %s의 담당을 %s로 변경했습니다', + 'New password for the user "%s"' => '사용자 "%s"의 새로운 패스워드', + 'Choose an event' => '행사의 선택', + 'Create a task from an external provider' => '할일을 외부 서비스로부터 작성하는 ', + 'Change the assignee based on an external username' => '담당자를 외부 서비스에 바탕을 두고 변경하는 ', + 'Change the category based on an external label' => '카테고리를 외부 서비스에 바탕을 두고 변경하는 ', + 'Reference' => '참조', + 'Label' => '라벨', + 'Database' => '데이터베이스', + 'About' => '정보', + 'Database driver:' => '데이터베이스 드라이버:', + 'Board settings' => '기본 설정', + 'URL and token' => 'URL와 토큰', + 'Webhook settings' => 'Webhook의 설정', + 'URL for task creation:' => 'Task작성의 URL:', + 'Reset token' => '토큰 리셋', + 'API endpoint:' => 'API엔드 포인트:', + 'Refresh interval for private board' => '비공개 보드의 갱신 빈도', + 'Refresh interval for public board' => '공개 보드의 갱신 빈도', + 'Task highlight period' => '할일의 하이라이트 기간', + // 'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => '', + // 'Frequency in second (60 seconds by default)' => '', + // 'Frequency in second (0 to disable this feature, 10 seconds by default)' => '', + 'Application URL' => '애플리케이션의 URL', + 'Token regenerated.' => '토큰이 다시 생성되었습니다.', + 'Date format' => '데이터 포맷', + // 'ISO format is always accepted, example: "%s" and "%s"' => '', + 'New private project' => '새 비공개 프로젝트', + 'This project is private' => '이 프로젝트는 비공개입니다', + 'Add' => '추가', + 'Start date' => '시작시간', + 'Time estimated' => '예상시간', + 'There is nothing assigned to you.' => '할일이 없습니다. 옆사람의 일을 도와주면 어떨까요?', + 'My tasks' => '내 할일', + 'Activity stream' => '활동기록', + 'Dashboard' => '대시보드', + 'Confirmation' => '확인', + 'Allow everybody to access to this project' => '모든 사람이 이 프로젝트에 접근할 수 있도록 합니다', + 'Everybody have access to this project.' => '누구나 이 프로젝트에 액세스 할 수 있습니다', + 'Webhooks' => 'Webhook', + 'API' => 'API', + 'Create a comment from an external provider' => '외부 서비스로부터 의견을 작성한다', + 'Project management' => '프로젝트 관리', + 'My projects' => '내 프로젝트', + 'Columns' => '칼럼', + 'Task' => '할일', + 'Your are not member of any project.' => '어떤 프로젝트에도 속하지 않습니다.', + 'Percentage' => '비중', + 'Number of tasks' => '할일 수', + 'Task distribution' => '할일 분포', + 'Reportings' => '리포트', + // 'Task repartition for "%s"' => '', + 'Analytics' => '분석', + 'Subtask' => '서브 할일', + 'My subtasks' => '내 서브 할일', + 'User repartition' => '담당자 분포', + // 'User repartition for "%s"' => '', + 'Clone this project' => '이 프로젝트를 복제하는 ', + 'Column removed successfully.' => '(※)컬럼을 삭제했습니다', + 'Not enough data to show the graph.' => '그래프를 선묘화하려면 나왔지만 부족합니다', + 'Previous' => ' 돌아가', + 'The id must be an integer' => 'id은 숫자가 아니면 안 됩니다', + 'The project id must be an integer' => 'project id은 숫자가 아니면 안 됩니다', + 'The status must be an integer' => 'status는 숫자지 않으면 안 됩니다', + 'The subtask id is required' => 'subtask id가 필요합니다', + 'The subtask id must be an integer' => 'subtask id은 숫자가 아니면 안 됩니다', + 'The task id is required' => 'task id가 필요합니다', + 'The task id must be an integer' => 'task id은 숫자가 아니면 안 됩니다', + 'The user id must be an integer' => 'user id은 숫자가 아니면 안 됩니다', + 'This value is required' => '이 값이 필요합니다', + 'This value must be numeric' => '이 값은 숫자가 아니면 안 됩니다', + 'Unable to create this task.' => '이 할일을 작성할 수 없었습니다', + 'Cumulative flow diagram' => '축적 플로', + // 'Cumulative flow diagram for "%s"' => '', + 'Daily project summary' => '일시 프로젝트 개요', + 'Daily project summary export' => '일시 프로젝트 개요의 출력', + // 'Daily project summary export for "%s"' => '', + 'Exports' => '출력', + 'This export contains the number of tasks per column grouped per day.' => '이 출력은 날짜의 칼람별 할일 수를 집계한 것입니다', + 'Active swimlanes' => '액티브한 스윔레인', + 'Add a new swimlane' => ' 새로운 스윔레인', + 'Change default swimlane' => '기본 스윔레인의 변경', + 'Default swimlane' => '기본 스윔레인', + // 'Do you really want to remove this swimlane: "%s"?' => '', + 'Inactive swimlanes' => '인터랙티브한 스윔레인', + 'Remove a swimlane' => '스윔레인의 삭제', + 'Show default swimlane' => '기본 스윔레인의 표시', + // 'Swimlane modification for the project "%s"' => '', + 'Swimlane not found.' => '스윔레인이 발견되지 않습니다.', + 'Swimlane removed successfully.' => '스윔레인을 삭제했습니다.', + 'Swimlanes' => '스윔레인', + 'Swimlane updated successfully.' => '스윔레인을 갱신했습니다.', + 'The default swimlane have been updated successfully.' => '기본 스윔레인을 갱신했습니다.', + '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)' => '', + 'Integrations' => '연계', + 'Integration with third-party services' => '외부 서비스 연계', + 'Subtask Id' => '서브 할일 Id', + 'Subtasks' => '서브 할일', + 'Subtasks Export' => '서브 할일 출력', + // 'Subtasks exportation for "%s"' => '', + 'Task Title' => '할일 제목', + 'Untitled' => '제목 없음', + 'Application default' => '애플리케이션 기본', + 'Language:' => '언어:', + 'Timezone:' => '시간대:', + 'All columns' => '모든 칼럼', + 'Calendar' => '달력', + 'Next' => '다음에 ', + '#%d' => '#%d', + 'All swimlanes' => '모든 스윔레인', + 'All colors' => '모든 색', + // 'Moved to column %s' => '', + 'Change description' => '설명 수정', + 'User dashboard' => '대시보드', + 'Allow only one subtask in progress at the same time for a user' => '한 사용자에 대한 하나의 할일만 진행 중에 가능합니다', + // 'Edit column "%s"' => '', + // '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?' => '프로젝트의 무엇을 복제합니까?', + // 'Disallow login form' => '', + 'Start' => '시작', + 'End' => '종료', + 'Task age in days' => '할일이 생긴 시간', + 'Days in this column' => '이 칼럼에 있는 시간', + '%dd' => '%d일', + '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' => '<1시간', + '%dh' => '%d시간', + 'Expand tasks' => '할일 크게', + 'Collapse tasks' => '할일 작게', + 'Expand/collapse tasks' => '할일 크게/작게', + 'Close dialog box' => '다이얼로그를 닫습니다', + 'Submit a form' => '제출', + 'Board view' => '보드 뷰', + 'Keyboard shortcuts' => '키보드 숏 컷', + 'Open board switcher' => '보드 전환을 열', + 'Application' => '애플리케이션', + 'Compact view' => '컴팩트 뷰', + 'Horizontal scrolling' => '세로 스크롤', + 'Compact/wide view' => '컴팩트/와이드 뷰', + 'No results match:' => '결과가 일치하지 않았습니다', + 'Currency' => '통화', + 'Private project' => '개인 프로젝트', + // 'AUD - Australian Dollar' => '', + // 'CAD - Canadian Dollar' => '', + // 'CHF - Swiss Francs' => '', + 'Custom Stylesheet' => '커스텀 스타일 시트', + 'download' => '다운로드', + // 'EUR - Euro' => '', + // 'GBP - British Pound' => '', + // 'INR - Indian Rupee' => '', + // 'JPY - Japanese Yen' => '', + // 'NZD - New Zealand Dollar' => '', + // 'RSD - Serbian dinar' => '', + // 'USD - US Dollar' => '', + 'Destination column' => '이동 후 칼럼', + 'Move the task to another column when assigned to a user' => '사용자의 할당을 하면 할일을 다른 칼럼에 이동', + 'Move the task to another column when assignee is cleared' => '사용자의 할당이 없어지면 할일을 다른 칼럼에 이동', + 'Source column' => '이동 전 칼럼', + 'Transitions' => '이력', + 'Executer' => '실행자', + 'Time spent in the column' => '칼럼에 있던 시간', + 'Task transitions' => '할일 천이', + 'Task transitions export' => '할일 천이를 출력', + 'This report contains all column moves for each task with the date, the user and the time spent for each transition.' => '이 리포트는 할일의 칼럼 간 이동을 시간, 유저, 경과 시간과 함께 기록한 것입니다.', + 'Currency rates' => '환율', + 'Rate' => '레이트', + 'Change reference currency' => '현재의 기축 통화', + 'Add a new currency rate' => ' 새로운 통화 환율을 추가', + 'Reference currency' => '기축 통화', + // 'The currency rate have been added successfully.' => '', + 'Unable to add this currency rate.' => '이 통화 환율을 추가할 수 없습니다.', + 'Webhook URL' => 'Webhook URL', + '%s remove the assignee of the task %s' => '%s이 할일 %s의 담당을 삭제했습니다', + 'Enable Gravatar images' => 'Gravatar이미지를 활성화', + 'Information' => '정보', + 'Check two factor authentication code' => '2단 인증을 체크한다', + 'The two factor authentication code is not valid.' => '2단 인증 코드는 무효입니다.', + 'The two factor authentication code is valid.' => '2단 인증 코드는 유효합니다.', + 'Code' => '코드', + 'Two factor authentication' => '2단 인증', + // 'This QR code contains the key URI: ' => '', + 'Check my code' => '코드 체크', + // 'Secret key: ' => '', + 'Test your device' => '디바이스 테스트', + // 'Assign a color when the task is moved to a specific column' => '', + '%s via Kanboard' => '%s via E-board', + // 'Burndown chart for "%s"' => '', + // 'Burndown chart' => '', + // 'This chart show the task complexity over the time (Work Remaining).' => '', + 'Screenshot taken %s' => '스크린샷_%s', + 'Add a screenshot' => '스크린샷 추가', + 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => '스크린샷을 CTRL+V 혹은 ⌘+V를 눌러 붙여넣기', + 'Screenshot uploaded successfully.' => '스크린샷을 업로드하였습니다', + // 'SEK - Swedish Krona' => '', + // 'Identifier' => '', + // 'Disable two factor authentication' => '', + // 'Do you really want to disable the two factor authentication for this user: "%s"?' => '', + // 'Edit link' => '', + 'Start to type task title...' => '할일 제목을 처음부터 입력해주세요', + // 'A task cannot be linked to itself' => '', + // 'The exact same link already exists' => '', + // 'Recurrent task is scheduled to be generated' => '', + // 'Score' => '', + // 'The identifier must be unique' => '', + // 'This linked task id doesn\'t exists' => '', + // 'This value must be alphanumeric' => '', + 'Edit recurrence' => '반복 수정', + 'Generate recurrent task' => '반복 할일 만들기', + 'Trigger to generate recurrent task' => '반복 할일 트리거 만들기', + 'Factor to calculate new due date' => '새로운 종료날짜 계산', + 'Timeframe to calculate new due date' => '종료날짜 계산 단위', + 'Base date to calculate new due date' => '새로운 기본 종료날짜 계산', + 'Action date' => '시작날짜', + 'Base date to calculate new due date: ' => '새로운 기본 종료날짜 계산: ', + // 'This task has created this child task: ' => '', + 'Day(s)' => '일', + 'Existing due date' => '기존 종료날짜', + 'Factor to calculate new due date: ' => '새로운 종료날짜 계산: ', + 'Month(s)' => '월', + // 'Recurrence' => '', + // 'This task has been created by: ' => '', + // 'Recurrent task has been generated:' => '', + 'Timeframe to calculate new due date: ' => '종료날짜 계산 단위', + // 'Trigger to generate recurrent task: ' => '', + 'When task is closed' => '할일을 마쳤을때', + 'When task is moved from first column' => '할일이 첫번째 칼럼으로 옮겨졌을때', + 'When task is moved to last column' => '할일이 마지막 칼럼으로 옮겨졌을때', + 'Year(s)' => '년', + // 'Calendar settings' => '', + // 'Project calendar view' => '', + 'Project settings' => '프로젝트 설정', + // 'Show subtasks based on the time tracking' => '', + // 'Show tasks based on the creation date' => '', + // 'Show tasks based on the start date' => '', + // 'Subtasks time tracking' => '', + // 'User calendar view' => '', + // 'Automatically update the start date' => '', + // 'iCal feed' => '', + // 'Preferences' => '', + // 'Security' => '', + 'Two factor authentication disabled' => '2단 인증 비활성화', + // 'Two factor authentication enabled' => '', + // 'Unable to update this user.' => '', + // 'There is no user management for private projects.' => '', + // 'User that will receive the email' => '', + 'Email subject' => '이메일 제목', + 'Date' => '날짜', + // 'Add a comment log when moving the task between columns' => '', + // 'Move the task to another column when the category is changed' => '', + 'Send a task by email to someone' => '할일을 이메일로 보내기', + 'Reopen a task' => '할일 다시 시작', + 'Column change' => '칼럼 이동', + 'Position change' => '위치 이동', + 'Swimlane change' => '스윔레인 변경', + 'Assignee change' => '담당자 변경', + '[%s] Overdue tasks' => '[%s] 마감시간 지남', + 'Notification' => '알림', + // '%s moved the task #%d to the first swimlane' => '', + // '%s moved the task #%d to the swimlane "%s"' => '', + 'Swimlane' => '스윔레인', + // 'Gravatar' => '', + // '%s moved the task %s to the first swimlane' => '', + // '%s moved the task %s to the swimlane "%s"' => '', + // 'This report contains all subtasks information for the given date range.' => '', + // 'This report contains all tasks information for the given date range.' => '', + // 'Project activities for %s' => '', + // 'view the board on Kanboard' => '', + // 'The task have been moved to the first swimlane' => '', + // 'The task have been moved to another swimlane:' => '', + // 'Overdue tasks for the project "%s"' => '', + 'New title: %s' => '제목 변경: %s', + 'The task is not assigned anymore' => '담당자 없음', + 'New assignee: %s' => '담당자 변경: %s', + 'There is no category now' => '카테고리 없음', + 'New category: %s' => '카테고리 변경: %s', + 'New color: %s' => '색깔 변경: %s', + 'New complexity: %d' => '복잡도 변경: %d', + 'The due date have been removed' => '마감날짜 삭제', + 'There is no description anymore' => '설명 없음', + 'Recurrence settings have been modified' => '반복할일 설정 수정', + 'Time spent changed: %sh' => '경과시간 변경: %s시간', + 'Time estimated changed: %sh' => '%s시간으로 예상시간 변경', + // 'The field "%s" have been updated' => '', + // 'The description has been modified:' => '', + 'Do you really want to close the task "%s" as well as all subtasks?' => '할일 "%s"과 서브 할일을 모두 마치시겠습니까?', + 'I want to receive notifications for:' => '다음의 알림을 받기를 원합니다:', + 'All tasks' => '모든 할일', + 'Only for tasks assigned to me' => '내가 담당자인 일', + 'Only for tasks created by me' => '내가 만든 일', + 'Only for tasks created by me and assigned to me' => '내가 만들었거나 내가 담당자인 일', + // '%%Y-%%m-%%d' => '', + // 'Total for all columns' => '', + // 'You need at least 2 days of data to show the chart.' => '', + '<15m' => '<15분', + '<30m' => '<30분', + // 'Stop timer' => '', + 'Start timer' => '타이머 시작', + // 'Add project member' => '', + 'Enable notifications' => '알림 켜기', + 'My activity stream' => '내 활동기록', + 'My calendar' => '내 캘린더', + // 'Search tasks' => '', + 'Reset filters' => '필터 리셋', + 'My tasks due tomorrow' => '내일까지 내 할일', + 'Tasks due today' => '오늘까지 할일', + 'Tasks due tomorrow' => '내일까지 할일', + 'Tasks due yesterday' => '어제까지 할일', + 'Closed tasks' => '닫힌 할일', + 'Open tasks' => '열린 할일', + 'Not assigned' => '담당자가 없는 일', + 'View advanced search syntax' => '추가 검색 문법보기', + 'Overview' => '개요', + // 'Board/Calendar/List view' => '', + // 'Switch to the board view' => '', + // 'Switch to the calendar view' => '', + // 'Switch to the list view' => '', + // 'Go to the search/filter box' => '', + 'There is no activity yet.' => '활동이 없습니다', + // 'No tasks found.' => '', + // 'Keyboard shortcut: "%s"' => '', + 'List' => '목록', + // 'Filter' => '', + 'Advanced search' => '검색 문법', + 'Example of query: ' => '문법 예제 ', + 'Search by project: ' => '프로젝트로 찾기 ', + 'Search by column: ' => '칼럼으로 찾기 ', + 'Search by assignee: ' => '담당자로 찾기 ', + 'Search by color: ' => '색깔로 찾기 ', + 'Search by category: ' => '카테고리로 찾기 ', + 'Search by description: ' => '설명으로 찾기 ', + 'Search by due date: ' => '마감날짜로 찾기 ', + // 'Lead and Cycle time for "%s"' => '', + // 'Average time spent into each column for "%s"' => '', + // 'Average time spent into each column' => '', + // 'Average time spent' => '', + // 'This chart show the average time spent into each column for the last %d tasks.' => '', + // 'Average Lead and Cycle time' => '', + // 'Average lead time: ' => '', + // 'Average cycle time: ' => '', + 'Cycle Time' => '사이클 타임', + 'Lead Time' => '리드 타임', + // 'This chart show the average lead and cycle time for the last %d tasks over the time.' => '', + // 'Average time into each column' => '', + // 'Lead and cycle time' => '', + 'Lead time: ' => '리드 타임: ', + 'Cycle time: ' => '사이클 타임: ', + 'Time spent into each column' => '각 칼럼에서 걸린 시간', + // 'The lead time is the duration between the task creation and the completion.' => '', + // 'The cycle time is the duration between the start date and the completion.' => '', + // 'If the task is not closed the current time is used instead of the completion date.' => '', + // 'Set automatically the start date' => '', + 'Edit Authentication' => '계정 수정', + // 'Remote user' => '', + // 'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => '', + // 'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => '', + 'New remote user' => '새로운 원격유저', + 'New local user' => '새로운 유저', + // 'Default task color' => '', + 'This feature does not work with all browsers.' => '이 기능은 일부 브라우저에서 작동하지 않습니다', + // 'There is no destination project available.' => '', + // 'Trigger automatically subtask time tracking' => '', + // 'Include closed tasks in the cumulative flow diagram' => '', + // 'Current swimlane: %s' => '', + // 'Current column: %s' => '', + // 'Current category: %s' => '', + // 'no category' => '', + // 'Current assignee: %s' => '', + // 'not assigned' => '', + // 'Author:' => '', + // 'contributors' => '', + // 'License:' => '', + // 'License' => '', + // 'Enter the text below' => '', + // 'Gantt chart for %s' => '', + // 'Sort by position' => '', + // 'Sort by date' => '', + // 'Add task' => '', + // 'Start date:' => '', + // 'Due date:' => '', + // 'There is no start date or due date for this task.' => '', + // 'Moving or resizing a task will change the start and due date of the task.' => '', + // 'There is no task in your project.' => '', + 'Gantt chart' => '간트차트', + 'People who are project managers' => '프로젝트 매니저', + 'People who are project members' => '프로젝트 멤버', + // 'NOK - Norwegian Krone' => '', + 'Show this column' => '칼럼 보이기', + 'Hide this column' => '칼럼 숨기기', + 'open file' => '열기', + 'End date' => '종료 날짜', + 'Users overview' => '유저 전체보기', + 'Members' => '멤버', + // 'Shared project' => '', + 'Project managers' => '프로젝트 매니저', + // 'Gantt chart for all projects' => '', + 'Projects list' => '프로젝트 리스트', + 'Gantt chart for this project' => '이 프로젝트 간트차트', + 'Project board' => '프로젝트 보드', + // 'End date:' => '', + 'There is no start date or end date for this project.' => '이 프로젝트에는 시작날짜와 종료날짜가 없습니다', + 'Projects Gantt chart' => '프로젝트 간트차트', + // 'Change task color when using a specific task link' => '', + // 'Task link creation or modification' => '', + // 'Milestone' => '', + // 'Documentation: %s' => '', + // 'Switch to the Gantt chart view' => '', + // 'Reset the search/filter box' => '', + // 'Documentation' => '', + // 'Table of contents' => '', + 'Gantt' => '간트', + // 'Author' => '', + // 'Version' => '', + // 'Plugins' => '', + // 'There is no plugin loaded.' => '', + 'Set maximum column height' => '최대 칼럼 높이 제한하기', + 'Remove maximum column height' => '최대 칼럼 높이 없애기', + 'My notifications' => '내 알림', + 'Custom filters' => '사용자 정의 필터', + // 'Your custom filter have been created successfully.' => '', + // 'Unable to create your custom filter.' => '', + // 'Custom filter removed successfully.' => '', + // 'Unable to remove this custom filter.' => '', + // 'Edit custom filter' => '', + // 'Your custom filter have been updated successfully.' => '', + // 'Unable to update custom filter.' => '', + 'Web' => '웹', + // 'New attachment on task #%d: %s' => '', + 'New comment on task #%d' => '할일 #%d에 새로운 댓글이 달렸습니다', + 'Comment updated on task #%d' => '할일 #%d에 댓글이 업데이트되었습니다', + 'New subtask on task #%d' => '서브 할일 #%d이 업데이트되었습니다', + 'Subtask updated on task #%d' => '서브 할일 #%d가 업데이트되었습니다', + 'New task #%d: %s' => '할일 #%d: %s이 추가되었습니다', + 'Task updated #%d' => '할일 #%d이 업데이트되었습니다', + 'Task #%d closed' => '할일 #%d를 마쳤습니다', + // 'Task #%d opened' => '', + 'Column changed for task #%d' => '할일 #%d의 칼럼이 변경되었습니다', + 'New position for task #%d' => '할일 #%d이 새로운 위치에 등록되었습니다', + // 'Swimlane changed for task #%d' => '', + // 'Assignee changed on task #%d' => '', + // '%d overdue tasks' => '', + // 'Task #%d is overdue' => '', + 'No new notifications.' => '알림이 없습니다', + 'Mark all as read' => '모두 읽음', + 'Mark as read' => '읽음', + // 'Total number of tasks in this column across all swimlanes' => '', + // 'Collapse swimlane' => '', + // 'Expand swimlane' => '', + // 'Add a new filter' => '', + // 'Share with all project members' => '', + // 'Shared' => '', + // 'Owner' => '', + 'Unread notifications' => '읽지않은 알림', + 'Notification methods:' => '알림 방법', + // 'Import tasks from CSV file' => '', + // 'Unable to read your file' => '', + // '%d task(s) have been imported successfully.' => '', + // 'Nothing have been imported!' => '', + // 'Import users from CSV file' => '', + // '%d user(s) have been imported successfully.' => '', + // 'Comma' => '', + // 'Semi-colon' => '', + // 'Tab' => '', + // 'Vertical bar' => '', + // 'Double Quote' => '', + // 'Single Quote' => '', + // '%s attached a file to the task #%d' => '', + // 'There is no column or swimlane activated in your project!' => '', + // 'Append filter (instead of replacement)' => '', + // 'Append/Replace' => '', + // 'Append' => '', + // 'Replace' => '', + 'Import' => '가져오기', + // 'change sorting' => '', + // 'Tasks Importation' => '', + // 'Delimiter' => '', + // 'Enclosure' => '', + // 'CSV File' => '', + // 'Instructions' => '', + // 'Your file must use the predefined CSV format' => '', + // 'Your file must be encoded in UTF-8' => '', + // 'The first row must be the header' => '', + // 'Duplicates are not verified for you' => '', + // 'The due date must use the ISO format: YYYY-MM-DD' => '', + // 'Download CSV template' => '', + 'No external integration registered.' => '설정이 되어있지 않습니다', + // 'Duplicates are not imported' => '', + // 'Usernames must be lowercase and unique' => '', + // 'Passwords will be encrypted if present' => '', + '%s attached a new file to the task %s' => '%s이 새로운 파일을 할일 %s에 추가했습니다', + // 'Link type' => '', + // 'Assign automatically a category based on a link' => '', + // 'BAM - Konvertible Mark' => '', + // 'Assignee Username' => '', + // 'Assignee Name' => '', + // 'Groups' => '', + // 'Members of %s' => '', + // 'New group' => '', + // 'Group created successfully.' => '', + // 'Unable to create your group.' => '', + // 'Edit group' => '', + // 'Group updated successfully.' => '', + // 'Unable to update your group.' => '', + // 'Add group member to "%s"' => '', + // 'Group member added successfully.' => '', + // 'Unable to add group member.' => '', + // 'Remove user from group "%s"' => '', + // 'User removed successfully from this group.' => '', + // 'Unable to remove this user from the group.' => '', + // 'Remove group' => '', + // 'Group removed successfully.' => '', + // 'Unable to remove this group.' => '', + // 'Project Permissions' => '', + 'Manager' => '매니저', + 'Project Manager' => '프로젝트 매니저', + 'Project Member' => '프로젝트 멤버', + // 'Project Viewer' => '', + // 'Your account is locked for %d minutes' => '', + // 'Invalid captcha' => '', + // 'The name must be unique' => '', + 'View all groups' => '모든그룹보기', + // 'View group members' => '', + // 'There is no user available.' => '', + // 'Do you really want to remove the user "%s" from the group "%s"?' => '', + // 'There is no group.' => '', + // 'External Id' => '', + 'Add group member' => '멤버추가', + // 'Do you really want to remove this group: "%s"?' => '', + // 'There is no user in this group.' => '', + // 'Remove this user' => '', + 'Permissions' => '권한', + // 'Allowed Users' => '', + // 'No user have been allowed specifically.' => '', + 'Role' => '역할', + // 'Enter user name...' => '', + // 'Allowed Groups' => '', + // 'No group have been allowed specifically.' => '', + // 'Group' => '', + // 'Group Name' => '', + // 'Enter group name...' => '', + 'Role:' => '역할: ', + 'Project members' => '프로젝트 멤버', + // 'Compare hours for "%s"' => '', + // '%s mentioned you in the task #%d' => '', + // '%s mentioned you in a comment on the task #%d' => '', + // 'You were mentioned in the task #%d' => '', + 'You were mentioned in a comment on the task #%d' => '할일 #%d의 댓글에서 언급되었습니다', + // 'Mentioned' => '', + // 'Compare Estimated Time vs Actual Time' => '', + // 'Estimated hours: ' => '', + // 'Actual hours: ' => '', + // 'Hours Spent' => '', + // 'Hours Estimated' => '', + // 'Estimated Time' => '', + // 'Actual Time' => '', + // 'Estimated vs actual time' => '', + // 'RUB - Russian Ruble' => '', + // 'Assign the task to the person who does the action when the column is changed' => '', + // 'Close a task in a specific column' => '', + 'Time-based One-time Password Algorithm' => '시간에 기반한 1회용 패스워드 알고리즘', + 'Two-Factor Provider: ' => '2단 인증: ', + // 'Disable two-factor authentication' => '', + 'Enable two-factor authentication' => '2단 인증 활성화', + // 'There is no integration registered at the moment.' => '', + // 'Password Reset for Kanboard' => '', + 'Forgot password?' => '비밀번호 찾기', + // 'Enable "Forget Password"' => '', + // 'Password Reset' => '', + // 'New password' => '', + // 'Change Password' => '', + // 'To reset your password click on this link:' => '', + 'Last Password Reset' => '비밀번호 초기화', + 'The password has never been reinitialized.' => '비밀번호가 초기화되지 않았습니다', + // 'Creation' => '', + // 'Expiration' => '', + 'Password reset history' => '비밀번호 초기화 기록', + // 'All tasks of the column "%s" and the swimlane "%s" have been closed successfully.' => '', + // 'Do you really want to close all tasks of this column?' => '', + // '%d task(s) in the column "%s" and the swimlane "%s" will be closed.' => '', + 'Close all tasks of this column' => '칼럼의 모든 할일 마치기', + // 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => '', + 'My dashboard' => '대시보드', + 'My profile' => '프로필', + // 'Project owner: ' => '', + // 'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => '', + // 'Project owner' => '', + // 'Those dates are useful for the project Gantt chart.' => '', + // 'Private projects do not have users and groups management.' => '', + // 'There is no project member.' => '', + // 'Priority' => '', + // 'Task priority' => '', + // 'General' => '', + // 'Dates' => '', + // 'Default priority' => '', + // 'Lowest priority' => '', + // 'Highest priority' => '', + // 'If you put zero to the low and high priority, this feature will be disabled.' => '', + // 'Close a task when there is no activity' => '', + // 'Duration in days' => '', + // 'Send email when there is no activity on a task' => '', + // 'Unable to fetch link information.' => '', + // 'Daily background job for tasks' => '', + // 'Auto' => '', + // 'Related' => '', + // 'Attachment' => '', + // 'Title not found' => '', + // 'Web Link' => '', + // 'External links' => '', + // 'Add external link' => '', + // 'Type' => '', + // 'Dependency' => '', + // 'Add internal link' => '', + // 'Add a new external link' => '', + // 'Edit external link' => '', + // 'External link' => '', + // 'Copy and paste your link here...' => '', + // 'URL' => '', + // 'Internal links' => '', + // 'Assign to me' => '', + // 'Me' => '', + // 'Do not duplicate anything' => '', + // 'Projects management' => '', + // 'Users management' => '', + // 'Groups management' => '', + // 'Create from another project' => '', + // 'open' => '', + // 'closed' => '', + // 'Priority:' => '', + // 'Reference:' => '', + // 'Complexity:' => '', + // 'Swimlane:' => '', + // 'Column:' => '', + // 'Position:' => '', + // 'Creator:' => '', + // 'Time estimated:' => '', + // '%s hours' => '', + // 'Time spent:' => '', + // 'Created:' => '', + // 'Modified:' => '', + // 'Completed:' => '', + // 'Started:' => '', + // 'Moved:' => '', + // 'Task #%d' => '', + // 'Date and time format' => '', + // 'Time format' => '', + // 'Start date: ' => '', + // 'End date: ' => '', + // 'New due date: ' => '', + // 'Start date changed: ' => '', + // 'Disable private projects' => '', + // 'Do you really want to remove this custom filter: "%s"?' => '', + // 'Remove a custom filter' => '', + // 'User activated successfully.' => '', + // 'Unable to enable this user.' => '', + // 'User disabled successfully.' => '', + // 'Unable to disable this user.' => '', + // 'All files have been uploaded successfully.' => '', + // 'View uploaded files' => '', + // 'The maximum allowed file size is %sB.' => '', + // 'Choose files again' => '', + // 'Drag and drop your files here' => '', + // 'choose files' => '', + // 'View profile' => '', + // 'Two Factor' => '', + // 'Disable user' => '', + // 'Do you really want to disable this user: "%s"?' => '', + // 'Enable user' => '', + // 'Do you really want to enable this user: "%s"?' => '', + // 'Download' => '', + // 'Uploaded: %s' => '', + // 'Size: %s' => '', + // 'Uploaded by %s' => '', + // 'Filename' => '', + // 'Size' => '', + // 'Column created successfully.' => '', + // 'Another column with the same name exists in the project' => '', + // 'Default filters' => '', + // 'Your board doesn\'t have any column!' => '', + // 'Change column position' => '', + // 'Switch to the project overview' => '', + // 'User filters' => '', + // 'Category filters' => '', + // 'Upload a file' => '', + // 'View file' => '', + // 'Last activity' => '', + // 'Change subtask position' => '', + // 'This value must be greater than %d' => '', + // 'Another swimlane with the same name exists in the project' => '', + // 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => '', + // 'Actions duplicated successfully.' => '', + // 'Unable to duplicate actions.' => '', + // 'Add a new action' => '', + // 'Import from another project' => '', + // 'There is no action at the moment.' => '', + // 'Import actions from another project' => '', + // 'There is no available project.' => '', + // 'Local File' => '', + // 'Configuration' => '', + // 'PHP version:' => '', + // 'PHP SAPI:' => '', + // 'OS version:' => '', + // 'Database version:' => '', + // 'Browser:' => '', + // 'Task view' => '', + // 'Edit task' => '', + // 'Edit description' => '', + // 'New internal link' => '', + // 'Display list of keyboard shortcuts' => '', + // 'Menu' => '', + // 'Set start date' => '', + // 'Avatar' => '', + // 'Upload my avatar image' => '', + // 'Remove my image' => '', + // 'The OAuth2 state parameter is invalid' => '', +); diff --git a/sources/app/Locale/my_MY/translations.php b/sources/app/Locale/my_MY/translations.php index e2bc611..36b3db0 100644 --- a/sources/app/Locale/my_MY/translations.php +++ b/sources/app/Locale/my_MY/translations.php @@ -8,7 +8,6 @@ return array( 'Edit' => 'Sunting', 'remove' => 'hapus', 'Remove' => 'Hapus', - 'Update' => 'Kemaskini', 'Yes' => 'Ya', 'No' => 'Tidak', 'cancel' => 'batal', @@ -60,7 +59,6 @@ return array( 'Actions' => 'Tindakan', 'Inactive' => 'Tidak Aktif', 'Active' => 'Aktif', - 'Add this column' => 'Tambahkan kolom ini', '%d tasks on the board' => '%d tugasan di papan', '%d tasks in total' => 'Sejumlah %d tugasan', 'Unable to update this board.' => 'Tidak berupaya mengemaskini papan ini', @@ -74,7 +72,6 @@ return array( 'All projects' => 'Semua projek', 'Add a new column' => 'Tambah kolom baru', 'Title' => 'Judul', - 'Nobody assigned' => 'Tidak ada yang ditugaskan', 'Assigned to %s' => 'Ditugaskan ke %s', 'Remove a column' => 'Hapus kolom', 'Remove a column from a board' => 'Hapus kolom dari papan', @@ -168,7 +165,6 @@ return array( 'Task count' => 'Jumlah tugas', 'User' => 'Pengguna', 'Comments' => 'Komentar', - 'Write your text in Markdown' => 'Menulis teks anda didalam Markdown', 'Leave a comment' => 'Tinggalkan komentar', 'Comment is required' => 'Komentar diperlukan', 'Leave a description' => 'Tinggalkan deskripsi', @@ -184,7 +180,6 @@ return array( 'Unable to remove this action.' => 'Tidak dapat menghapus tindakan ini', 'Action removed successfully.' => 'Tindakan berhasil dihapus.', 'Automatic actions for the project "%s"' => 'Tindakan otomatis untuk projek ini « %s »', - 'Defined actions' => 'Tindakan didefinisikan', 'Add an action' => 'Tambah tindakan', 'Event name' => 'Nama acara', 'Action name' => 'Nama tindakan', @@ -194,7 +189,6 @@ return array( 'When the selected event occurs execute the corresponding action.' => 'Ketika acara yang dipilih terjadi, melakukan tindakan yang sesuai.', 'Next step' => 'Langkah selanjutnya', 'Define action parameters' => 'Definisi parameter tindakan', - 'Save this action' => 'Simpan tindakan ini', 'Do you really want to remove this action: "%s"?' => 'Apakah anda yakin akan menghapus tindakan ini « %s » ?', 'Remove an automatic action' => 'Hapus tindakan otomatis', 'Assign the task to a specific user' => 'Menetapkan tugas untuk pengguna tertentu', @@ -333,10 +327,10 @@ return array( 'Time tracking:' => 'Pelacakan waktu :', 'New sub-task' => 'Sub-tugas baru', 'New attachment added "%s"' => 'Lampiran baru ditambahkan « %s »', - 'Comment updated' => 'Komentar diperbaharui', 'New comment posted by %s' => 'Komentar baru ditambahkan oleh « %s »', 'New attachment' => 'Lampirkan baru', 'New comment' => 'Komentar baru', + 'Comment updated' => 'Komentar diperbaharui', 'New subtask' => 'Sub-tugas baru', 'Subtask updated' => 'Sub-tugas diperbaharui', 'Task updated' => 'Tugas diperbaharui', @@ -436,7 +430,6 @@ return array( 'ISO format is always accepted, example: "%s" and "%s"' => 'Format ISO selalunya diterima, contoh: « %s » et « %s »', 'New private project' => 'Projek peribadi baharu', 'This project is private' => 'projek ini adalah peribadi', - 'Type here to create a new sub-task' => 'Ketik disini untuk membuat sub-tugas baru', 'Add' => 'Tambah', 'Start date' => 'Tarikh mula', 'Time estimated' => 'Anggaran masa', @@ -487,9 +480,6 @@ return array( 'Daily project summary export for "%s"' => 'Ekspor ringkasan projek harian untuk « %s »', 'Exports' => 'Ekspor', 'This export contains the number of tasks per column grouped per day.' => 'Ekspor ini berisi jumlah dari tugas per kolom dikelompokan perhari.', - 'Nothing to preview...' => 'Tiada yang dapat diintai...', - 'Preview' => 'Intai', - 'Write' => 'Tulis', 'Active swimlanes' => 'Swimlanes aktif', 'Add a new swimlane' => 'Tambah swimlane baharu', 'Change default swimlane' => 'Tukar piawai swimlane', @@ -543,7 +533,6 @@ return array( 'Task age in days' => 'Usia tugas dalam bentuk harian', 'Days in this column' => 'Hari dalam kolom ini', '%dd' => '%dj', - 'Add a link' => 'Menambahkan pautan', 'Add a new link' => 'Tambah Pautan baru', 'Do you really want to remove this link: "%s"?' => 'Anda yakin akan menghapus Pautan ini : « %s » ?', 'Do you really want to remove this link with task #%d?' => 'Anda yakin akan menghapus Pautan ini dengan tugas n°%d ?', @@ -734,7 +723,7 @@ return array( 'Time spent changed: %sh' => 'Waktu yang dihabiskan berubah : %sh', 'Time estimated changed: %sh' => 'Perkiraan waktu berubah : %sh', 'The field "%s" have been updated' => 'Field « %s » telah diperbaharui', - 'The description have been modified' => 'Deskripsi telah dimodifikasi', + 'The description has been modified:' => 'Deskripsi telah dimodifikasi', 'Do you really want to close the task "%s" as well as all subtasks?' => 'Apakah anda yakin akan menutup tugas « %s » beserta semua sub-tugasnya ?', 'I want to receive notifications for:' => 'Saya ingin menerima pemberitahuan untuk :', 'All tasks' => 'Semua tugas', @@ -753,8 +742,6 @@ return array( 'My activity stream' => 'Aliran kegiatan saya', 'My calendar' => 'Kalender saya', 'Search tasks' => 'Cari tugas', - 'Back to the calendar' => 'Kembali ke kalender', - 'Filters' => 'Filter', 'Reset filters' => 'Reset ulang filter', 'My tasks due tomorrow' => 'Tugas saya yang berakhir besok', 'Tasks due today' => 'Tugas yang berakhir hari ini', @@ -854,7 +841,6 @@ return array( 'End date:' => 'Waktu berakhir :', 'There is no start date or end date for this project.' => 'Tidak ada waktu mula atau waktu berakhir pada projek ini', 'Projects Gantt chart' => 'projekkan carta Gantt', - 'Link type' => 'Jenis pautan', 'Change task color when using a specific task link' => 'Rubah warna tugas ketika menggunakan Pautan tugas yang spesifik', 'Task link creation or modification' => 'Pautan tugas pada penciptaan atau penyuntingan', 'Milestone' => 'Batu Tanda', @@ -906,7 +892,6 @@ return array( // 'Shared' => '', // 'Owner' => '', // 'Unread notifications' => '', - // 'My filters' => '', // 'Notification methods:' => '', // 'Import tasks from CSV file' => '', // 'Unable to read your file' => '', @@ -944,6 +929,7 @@ return array( // 'Usernames must be lowercase and unique' => '', // 'Passwords will be encrypted if present' => '', // '%s attached a new file to the task %s' => '', + 'Link type' => 'Jenis pautan', // 'Assign automatically a category based on a link' => '', // 'BAM - Konvertible Mark' => '', // 'Assignee Username' => '', @@ -1053,7 +1039,6 @@ return array( // 'Close a task when there is no activity' => '', // 'Duration in days' => '', // 'Send email when there is no activity on a task' => '', - // 'List of external links' => '', // 'Unable to fetch link information.' => '', // 'Daily background job for tasks' => '', // 'Auto' => '', @@ -1071,9 +1056,7 @@ return array( // 'External link' => '', // 'Copy and paste your link here...' => '', // 'URL' => '', - // 'There is no external link for the moment.' => '', // 'Internal links' => '', - // 'There is no internal link for the moment.' => '', // 'Assign to me' => '', // 'Me' => '', // 'Do not duplicate anything' => '', @@ -1081,7 +1064,6 @@ return array( // 'Users management' => '', // 'Groups management' => '', // 'Create from another project' => '', - // 'There is no subtask at the moment.' => '', // 'open' => '', // 'closed' => '', // 'Priority:' => '', @@ -1100,7 +1082,6 @@ return array( // 'Started:' => '', // 'Moved:' => '', // 'Task #%d' => '', - // 'Sub-tasks' => '', // 'Date and time format' => '', // 'Time format' => '', // 'Start date: ' => '', @@ -1141,11 +1122,35 @@ return array( // 'User filters' => '', // 'Category filters' => '', // 'Upload a file' => '', - // 'There is no attachment at the moment.' => '', // 'View file' => '', // 'Last activity' => '', // 'Change subtask position' => '', // 'This value must be greater than %d' => '', // 'Another swimlane with the same name exists in the project' => '', // 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => '', + // 'Actions duplicated successfully.' => '', + // 'Unable to duplicate actions.' => '', + // 'Add a new action' => '', + // 'Import from another project' => '', + // 'There is no action at the moment.' => '', + // 'Import actions from another project' => '', + // 'There is no available project.' => '', + // 'Local File' => '', + // 'Configuration' => '', + // 'PHP version:' => '', + // 'PHP SAPI:' => '', + // 'OS version:' => '', + // 'Database version:' => '', + // 'Browser:' => '', + // 'Task view' => '', + // 'Edit task' => '', + // 'Edit description' => '', + // 'New internal link' => '', + // 'Display list of keyboard shortcuts' => '', + // 'Menu' => '', + // 'Set start date' => '', + // 'Avatar' => '', + // 'Upload my avatar image' => '', + // 'Remove my image' => '', + // 'The OAuth2 state parameter is invalid' => '', ); diff --git a/sources/app/Locale/nb_NO/translations.php b/sources/app/Locale/nb_NO/translations.php index 229e499..465efb5 100644 --- a/sources/app/Locale/nb_NO/translations.php +++ b/sources/app/Locale/nb_NO/translations.php @@ -8,7 +8,6 @@ return array( 'Edit' => 'Rediger', 'remove' => 'fjern', 'Remove' => 'Fjern', - 'Update' => 'Oppdater', 'Yes' => 'Ja', 'No' => 'Nei', 'cancel' => 'avbryt', @@ -60,7 +59,6 @@ return array( 'Actions' => 'Handlinger', 'Inactive' => 'Inaktiv', 'Active' => 'Aktiv', - 'Add this column' => 'Legg til denne kolonnen', '%d tasks on the board' => '%d Oppgaver på hovedsiden', '%d tasks in total' => '%d Oppgaver i alt', 'Unable to update this board.' => 'Ikke mulig at oppdatere hovedsiden', @@ -74,7 +72,6 @@ return array( 'All projects' => 'Alle prosjekter', 'Add a new column' => 'Legg til en ny kolonne', 'Title' => 'Tittel', - 'Nobody assigned' => 'Ikke tildelt', 'Assigned to %s' => 'Tildelt: %s', 'Remove a column' => 'Fjern en kolonne', 'Remove a column from a board' => 'Fjern en kolonne fra et board', @@ -168,7 +165,6 @@ return array( 'Task count' => 'Antall oppgaver', 'User' => 'Bruker', 'Comments' => 'Kommentarer', - 'Write your text in Markdown' => 'Skriv din tekst i markdown', 'Leave a comment' => 'Legg inn en kommentar', 'Comment is required' => 'Kommentar må legges inn', 'Leave a description' => 'Legg inn en beskrivelse...', @@ -184,7 +180,6 @@ return array( 'Unable to remove this action.' => 'Handlingen kunne ikke fjernes.', 'Action removed successfully.' => 'Handlingen er fjernet.', 'Automatic actions for the project "%s"' => 'Automatiske handlinger for prosjektet "%s"', - 'Defined actions' => 'Definerte handlinger', 'Add an action' => 'Legg til en handling', 'Event name' => 'Hendelsehet', 'Action name' => 'Handling', @@ -194,7 +189,6 @@ return array( 'When the selected event occurs execute the corresponding action.' => 'Når den valgte hendelsen oppstår, utfør tilsvarende handling.', 'Next step' => 'Neste', 'Define action parameters' => 'Definer handlingsparametre', - 'Save this action' => 'Lagre handlingen', 'Do you really want to remove this action: "%s"?' => 'Vil du slette denne handlingen: "%s"?', 'Remove an automatic action' => 'Fjern en automatisk handling', 'Assign the task to a specific user' => 'Tildel oppgaven til en bestemt bruker', @@ -333,10 +327,10 @@ return array( 'Time tracking:' => 'Tidsmåling:', 'New sub-task' => 'Ny deloppgave', 'New attachment added "%s"' => 'Nytt vedlegg er lagt tilet "%s"', - 'Comment updated' => 'Kommentar oppdatert', 'New comment posted by %s' => 'Ny kommentar fra %s', 'New attachment' => 'Nytt vedlegg', 'New comment' => 'Ny kommentar', + 'Comment updated' => 'Kommentar oppdatert', 'New subtask' => 'Ny deloppgave', 'Subtask updated' => 'Deloppgave oppdatert', 'Task updated' => 'Oppgave oppdatert', @@ -436,7 +430,6 @@ return array( 'ISO format is always accepted, example: "%s" and "%s"' => 'ISO format er alltid akseptert, eksempelvis: "%s" og "%s"', 'New private project' => 'Nytt privat prosjekt', 'This project is private' => 'Dette projektet er privat', - 'Type here to create a new sub-task' => 'Skriv her for ø opprette en ny deloppgave', 'Add' => 'Legg til', 'Start date' => 'Start dato', 'Time estimated' => 'Tid estimert', @@ -487,9 +480,6 @@ return array( // 'Daily project summary export for "%s"' => '', 'Exports' => 'Eksporter', // 'This export contains the number of tasks per column grouped per day.' => '', - 'Nothing to preview...' => 'Ingenting å forhåndsvise', - 'Preview' => 'Forhåndsvisning', - 'Write' => 'Skriv', 'Active swimlanes' => 'Aktive svømmebaner', 'Add a new swimlane' => 'Legg til en ny svømmebane', 'Change default swimlane' => 'Endre standard svømmebane', @@ -543,7 +533,6 @@ return array( 'Task age in days' => 'Dager siden oppgaven ble opprettet', 'Days in this column' => 'Dager siden oppgaven ble lagt i denne kolonnen', // '%dd' => '', - 'Add a link' => 'Legg til en relasjon', 'Add a new link' => 'Legg til en ny relasjon', // 'Do you really want to remove this link: "%s"?' => '', // 'Do you really want to remove this link with task #%d?' => '', @@ -734,7 +723,7 @@ return array( // 'Time spent changed: %sh' => '', // 'Time estimated changed: %sh' => '', // 'The field "%s" have been updated' => '', - // 'The description have been modified' => '', + // 'The description has been modified:' => '', // 'Do you really want to close the task "%s" as well as all subtasks?' => '', 'I want to receive notifications for:' => 'Jeg vil motta varslinger om:', 'All tasks' => 'Alle oppgaver', @@ -753,8 +742,6 @@ return array( 'My activity stream' => 'Aktivitetslogg', 'My calendar' => 'Min kalender', 'Search tasks' => 'Søk oppgave', - 'Back to the calendar' => 'Tilbake til kalender', - 'Filters' => 'Filtere', 'Reset filters' => 'Nullstill filter', 'My tasks due tomorrow' => 'Mine oppgaver med frist i morgen', 'Tasks due today' => 'Oppgaver med frist i dag', @@ -854,7 +841,6 @@ return array( 'End date:' => 'Sluttdato:', // 'There is no start date or end date for this project.' => '', 'Projects Gantt chart' => 'Gantt skjema for prosjekter', - 'Link type' => 'Relasjonstype', // 'Change task color when using a specific task link' => '', // 'Task link creation or modification' => '', 'Milestone' => 'Milepæl', @@ -906,7 +892,6 @@ return array( // 'Shared' => '', // 'Owner' => '', // 'Unread notifications' => '', - // 'My filters' => '', // 'Notification methods:' => '', // 'Import tasks from CSV file' => '', // 'Unable to read your file' => '', @@ -944,6 +929,7 @@ return array( // 'Usernames must be lowercase and unique' => '', // 'Passwords will be encrypted if present' => '', // '%s attached a new file to the task %s' => '', + 'Link type' => 'Relasjonstype', // 'Assign automatically a category based on a link' => '', // 'BAM - Konvertible Mark' => '', // 'Assignee Username' => '', @@ -1053,7 +1039,6 @@ return array( // 'Close a task when there is no activity' => '', // 'Duration in days' => '', // 'Send email when there is no activity on a task' => '', - // 'List of external links' => '', // 'Unable to fetch link information.' => '', // 'Daily background job for tasks' => '', // 'Auto' => '', @@ -1071,9 +1056,7 @@ return array( // 'External link' => '', // 'Copy and paste your link here...' => '', // 'URL' => '', - // 'There is no external link for the moment.' => '', // 'Internal links' => '', - // 'There is no internal link for the moment.' => '', // 'Assign to me' => '', // 'Me' => '', // 'Do not duplicate anything' => '', @@ -1081,7 +1064,6 @@ return array( // 'Users management' => '', // 'Groups management' => '', // 'Create from another project' => '', - // 'There is no subtask at the moment.' => '', // 'open' => '', // 'closed' => '', // 'Priority:' => '', @@ -1100,7 +1082,6 @@ return array( // 'Started:' => '', // 'Moved:' => '', // 'Task #%d' => '', - // 'Sub-tasks' => '', // 'Date and time format' => '', // 'Time format' => '', // 'Start date: ' => '', @@ -1141,11 +1122,35 @@ return array( // 'User filters' => '', // 'Category filters' => '', // 'Upload a file' => '', - // 'There is no attachment at the moment.' => '', // 'View file' => '', // 'Last activity' => '', // 'Change subtask position' => '', // 'This value must be greater than %d' => '', // 'Another swimlane with the same name exists in the project' => '', // 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => '', + // 'Actions duplicated successfully.' => '', + // 'Unable to duplicate actions.' => '', + // 'Add a new action' => '', + // 'Import from another project' => '', + // 'There is no action at the moment.' => '', + // 'Import actions from another project' => '', + // 'There is no available project.' => '', + // 'Local File' => '', + // 'Configuration' => '', + // 'PHP version:' => '', + // 'PHP SAPI:' => '', + // 'OS version:' => '', + // 'Database version:' => '', + // 'Browser:' => '', + // 'Task view' => '', + // 'Edit task' => '', + // 'Edit description' => '', + // 'New internal link' => '', + // 'Display list of keyboard shortcuts' => '', + // 'Menu' => '', + // 'Set start date' => '', + // 'Avatar' => '', + // 'Upload my avatar image' => '', + // 'Remove my image' => '', + // 'The OAuth2 state parameter is invalid' => '', ); diff --git a/sources/app/Locale/nl_NL/translations.php b/sources/app/Locale/nl_NL/translations.php index d1d47a3..3c3fa1e 100644 --- a/sources/app/Locale/nl_NL/translations.php +++ b/sources/app/Locale/nl_NL/translations.php @@ -1,14 +1,13 @@ '', - // 'number.thousands_separator' => '', + 'number.decimals_separator' => ',', + 'number.thousands_separator' => '.', 'None' => 'Geen', 'edit' => 'bewerken', 'Edit' => 'Bewerken', 'remove' => 'verwijderen', 'Remove' => 'Verwijderen', - 'Update' => 'Update', 'Yes' => 'Ja', 'No' => 'Nee', 'cancel' => 'annuleren', @@ -20,15 +19,15 @@ return array( 'Red' => 'Rood', 'Orange' => 'Oranje', 'Grey' => 'Grijs', - // 'Brown' => '', - // 'Deep Orange' => '', - // 'Dark Grey' => '', - // 'Pink' => '', + 'Brown' => 'Bruin', + 'Deep Orange' => 'Dieporanje', + 'Dark Grey' => 'Donkergrijs', + 'Pink' => 'Roze', // 'Teal' => '', - // 'Cyan' => '', - // 'Lime' => '', - // 'Light Green' => '', - // 'Amber' => '', + 'Cyan' => 'Cyaan', + 'Lime' => 'Limoen', + 'Light Green' => 'Lichtgroen', + 'Amber' => 'Amber', 'Save' => 'Opslaan', 'Login' => 'Inloggen', 'Official website:' => 'Officiële website :', @@ -60,7 +59,6 @@ return array( 'Actions' => 'Acties', 'Inactive' => 'Inactief', 'Active' => 'Actief', - 'Add this column' => 'Deze kolom toevoegen', '%d tasks on the board' => '%d taken op het bord', '%d tasks in total' => '%d taken in totaal', 'Unable to update this board.' => 'Update van dit bord niet mogelijk.', @@ -74,7 +72,6 @@ return array( 'All projects' => 'Alle projecten', 'Add a new column' => 'Kolom toevoegen', 'Title' => 'Titel', - 'Nobody assigned' => 'Niemand toegewezen', 'Assigned to %s' => 'Toegewezen aan %s', 'Remove a column' => 'Kolom verwijderen', 'Remove a column from a board' => 'Kolom verwijderen van het bord', @@ -168,7 +165,6 @@ return array( 'Task count' => 'Aantal taken', 'User' => 'Gebruiker', 'Comments' => 'Commentaar', - 'Write your text in Markdown' => 'Schrijf uw tekst in Markdown', 'Leave a comment' => 'Schrijf een commentaar', 'Comment is required' => 'Commentaar is verplicht', 'Leave a description' => 'Schrijf een omschrijving', @@ -184,7 +180,6 @@ return array( 'Unable to remove this action.' => 'Actie verwijderen niet gelukt', 'Action removed successfully.' => 'Actie succesvol verwijder.', 'Automatic actions for the project "%s"' => 'Automatiseer acties voor project « %s »', - 'Defined actions' => 'Gedefinieerde acties', 'Add an action' => 'Actie toevoegen', 'Event name' => 'Naam gebeurtenis', 'Action name' => 'Actie naam', @@ -194,7 +189,6 @@ return array( 'When the selected event occurs execute the corresponding action.' => 'Als de geselecteerde gebeurtenis optreedt de volgende actie uitvoeren', 'Next step' => 'Volgende stap', 'Define action parameters' => 'Bepaal actie parameters', - 'Save this action' => 'Actie opslaan', 'Do you really want to remove this action: "%s"?' => 'Weet u zeker dat u de volgende actie wil verwijderen : « %s » ?', 'Remove an automatic action' => 'Automatische actie verwijderen', 'Assign the task to a specific user' => 'Taak toewijzen aan een gebruiker', @@ -333,10 +327,10 @@ return array( 'Time tracking:' => 'Tijdschrijven :', 'New sub-task' => 'Nieuwe subtaak', 'New attachment added "%s"' => 'Nieuwe bijlage toegevoegd « %s »', - 'Comment updated' => 'Commentaar aangepast', 'New comment posted by %s' => 'Nieuw commentaar geplaatst door « %s »', 'New attachment' => 'Nieuwe bijlage', 'New comment' => 'Nieuw commentaar', + 'Comment updated' => 'Commentaar aangepast', 'New subtask' => 'Nieuwe subtaak', 'Subtask updated' => 'Subtaak aangepast', 'Task updated' => 'Taak aangepast', @@ -436,7 +430,6 @@ return array( 'ISO format is always accepted, example: "%s" and "%s"' => 'ISO formaat is altijd geaccepteerd, bijvoorbeeld : « %s » et « %s »', 'New private project' => 'Nieuw privé project', 'This project is private' => 'Dit project is privé', - 'Type here to create a new sub-task' => 'Typ hier om een nieuwe subtaak aan te maken', 'Add' => 'Toevoegen', 'Start date' => 'Startdatum', 'Time estimated' => 'Geschatte tijd', @@ -487,9 +480,6 @@ return array( 'Daily project summary export for "%s"' => 'Dagelijkse project samenvatting voor « %s »', 'Exports' => 'Exports', 'This export contains the number of tasks per column grouped per day.' => 'Dit rapport bevat het aantal taken per kolom gegroupeerd per dag.', - 'Nothing to preview...' => 'Niets om te previewen...', - 'Preview' => 'Preview', - 'Write' => 'Schrijf', 'Active swimlanes' => 'Actieve swinlanes', 'Add a new swimlane' => 'Nieuwe swimlane toevoegen', 'Change default swimlane' => 'Standaard swimlane aapassen', @@ -543,7 +533,6 @@ return array( 'Task age in days' => 'Leeftijd taak in dagen', 'Days in this column' => 'Dagen in deze kolom', '%dd' => '%dj', - 'Add a link' => 'Link toevoegen', 'Add a new link' => 'Nieuwe link toevoegen', 'Do you really want to remove this link: "%s"?' => 'Weet u zeker dat u deze link wil verwijderen : « %s » ?', 'Do you really want to remove this link with task #%d?' => 'Weet u zeker dat u deze link met taak %d wil verwijderen?', @@ -575,7 +564,7 @@ return array( 'is a milestone of' => 'is een milestone voor', 'fixes' => 'corrigeert', 'is fixed by' => 'word gecorrigeerd door', - 'This task' => 'Deze taal', + 'This task' => 'Deze taak', '<1h' => '<1h', '%dh' => '%dh', 'Expand tasks' => 'Taken uitklappen', @@ -587,42 +576,42 @@ return array( 'Keyboard shortcuts' => 'Keyboard snelkoppelingen', 'Open board switcher' => 'Open bord switcher', 'Application' => 'Applicatie', - // 'Compact view' => '', + 'Compact view' => 'Compacte weergave', // 'Horizontal scrolling' => '', - // 'Compact/wide view' => '', - // 'No results match:' => '', - // 'Currency' => '', - // 'Private project' => '', + 'Compact/wide view' => 'Compacte/breedbeeld-weergave', + 'No results match:' => 'Geen resultaten voor', + 'Currency' => 'Valuta', + 'Private project' => 'Privé project', // 'AUD - Australian Dollar' => '', // 'CAD - Canadian Dollar' => '', // 'CHF - Swiss Francs' => '', // 'Custom Stylesheet' => '', // 'download' => '', - // 'EUR - Euro' => '', + 'EUR - Euro' => 'EUR - Euro', // 'GBP - British Pound' => '', // 'INR - Indian Rupee' => '', // 'JPY - Japanese Yen' => '', // 'NZD - New Zealand Dollar' => '', // 'RSD - Serbian dinar' => '', // 'USD - US Dollar' => '', - // 'Destination column' => '', + 'Destination column' => 'Doel kolom', // 'Move the task to another column when assigned to a user' => '', // 'Move the task to another column when assignee is cleared' => '', - // 'Source column' => '', + 'Source column' => 'Bron kolom', // 'Transitions' => '', // 'Executer' => '', // 'Time spent in the column' => '', // 'Task transitions' => '', // 'Task transitions export' => '', // 'This report contains all column moves for each task with the date, the user and the time spent for each transition.' => '', - // 'Currency rates' => '', - // 'Rate' => '', + 'Currency rates' => 'Wisselkoersen', + 'Rate' => 'Koers', // 'Change reference currency' => '', // 'Add a new currency rate' => '', // 'Reference currency' => '', // 'The currency rate have been added successfully.' => '', // 'Unable to add this currency rate.' => '', - // 'Webhook URL' => '', + 'Webhook URL' => 'Webhook URL', // '%s remove the assignee of the task %s' => '', // 'Enable Gravatar images' => '', // 'Information' => '', @@ -648,7 +637,7 @@ return array( // 'Identifier' => '', // 'Disable two factor authentication' => '', // 'Do you really want to disable the two factor authentication for this user: "%s"?' => '', - // 'Edit link' => '', + 'Edit link' => 'Bewerk link', // 'Start to type task title...' => '', // 'A task cannot be linked to itself' => '', // 'The exact same link already exists' => '', @@ -666,10 +655,10 @@ return array( // 'Action date' => '', // 'Base date to calculate new due date: ' => '', // 'This task has created this child task: ' => '', - // 'Day(s)' => '', + 'Day(s)' => 'Dag(en)', // 'Existing due date' => '', // 'Factor to calculate new due date: ' => '', - // 'Month(s)' => '', + 'Month(s)' => 'Maand(en)', // 'Recurrence' => '', // 'This task has been created by: ' => '', // 'Recurrent task has been generated:' => '', @@ -678,10 +667,10 @@ return array( // 'When task is closed' => '', // 'When task is moved from first column' => '', // 'When task is moved to last column' => '', - // 'Year(s)' => '', - // 'Calendar settings' => '', + 'Year(s)' => 'Jaar/Jaren', + 'Calendar settings' => 'Kalender instellingen', // 'Project calendar view' => '', - // 'Project settings' => '', + 'Project settings' => 'Project instellingen', // 'Show subtasks based on the time tracking' => '', // 'Show tasks based on the creation date' => '', // 'Show tasks based on the start date' => '', @@ -689,19 +678,19 @@ return array( // 'User calendar view' => '', // 'Automatically update the start date' => '', // 'iCal feed' => '', - // 'Preferences' => '', + 'Preferences' => 'Voorkeuren', // 'Security' => '', - // 'Two factor authentication disabled' => '', - // 'Two factor authentication enabled' => '', - // 'Unable to update this user.' => '', + 'Two factor authentication disabled' => 'Authenticatie in twee stappen uitgeschakeld', + 'Two factor authentication enabled' => 'Authenticatie in twee stappen ingeschakeld', + 'Unable to update this user.' => 'Niet mogelijk om deze gebruiker bij te werken', // 'There is no user management for private projects.' => '', - // 'User that will receive the email' => '', - // 'Email subject' => '', - // 'Date' => '', + 'User that will receive the email' => 'Gebruiker die de mail ontvangt', + 'Email subject' => 'Email onderwerp', + 'Date' => 'Datum', // 'Add a comment log when moving the task between columns' => '', // 'Move the task to another column when the category is changed' => '', // 'Send a task by email to someone' => '', - // 'Reopen a task' => '', + 'Reopen a task' => 'Heropen een taak', // 'Column change' => '', // 'Position change' => '', // 'Swimlane change' => '', @@ -710,10 +699,10 @@ return array( // 'Notification' => '', // '%s moved the task #%d to the first swimlane' => '', // '%s moved the task #%d to the swimlane "%s"' => '', - // 'Swimlane' => '', - // 'Gravatar' => '', - // '%s moved the task %s to the first swimlane' => '', - // '%s moved the task %s to the swimlane "%s"' => '', + 'Swimlane' => 'Swimlane', + 'Gravatar' => 'Gravatar', + '%s moved the task %s to the first swimlane' => '%s heeft de taak %s naar de eerste swimlane verplaatst', + '%s moved the task %s to the swimlane "%s"' => '%s heeft taak %s naar swimlane "%s" verplaatst', // 'This report contains all subtasks information for the given date range.' => '', // 'This report contains all tasks information for the given date range.' => '', // 'Project activities for %s' => '', @@ -721,7 +710,7 @@ return array( // 'The task have been moved to the first swimlane' => '', // 'The task have been moved to another swimlane:' => '', // 'Overdue tasks for the project "%s"' => '', - // 'New title: %s' => '', + 'New title: %s' => 'Nieuw titel: %s', // 'The task is not assigned anymore' => '', // 'New assignee: %s' => '', // 'There is no category now' => '', @@ -734,37 +723,35 @@ return array( // 'Time spent changed: %sh' => '', // 'Time estimated changed: %sh' => '', // 'The field "%s" have been updated' => '', - // 'The description have been modified' => '', + // 'The description has been modified:' => '', // 'Do you really want to close the task "%s" as well as all subtasks?' => '', - // 'I want to receive notifications for:' => '', - // 'All tasks' => '', + 'I want to receive notifications for:' => 'Ik wil notificaties ontvangen voor:', + 'All tasks' => 'Alle taken', // 'Only for tasks assigned to me' => '', // 'Only for tasks created by me' => '', // 'Only for tasks created by me and assigned to me' => '', - // '%%Y-%%m-%%d' => '', + '%%Y-%%m-%%d' => '%%d-%%m-%%Y', // 'Total for all columns' => '', // 'You need at least 2 days of data to show the chart.' => '', - // '<15m' => '', - // '<30m' => '', - // 'Stop timer' => '', - // 'Start timer' => '', - // 'Add project member' => '', - // 'Enable notifications' => '', - // 'My activity stream' => '', - // 'My calendar' => '', - // 'Search tasks' => '', - // 'Back to the calendar' => '', - // 'Filters' => '', - // 'Reset filters' => '', + '<15m' => '<15m', + '<30m' => '<30m', + 'Stop timer' => 'Stop timer', + 'Start timer' => 'Start timer', + 'Add project member' => 'Voeg projectlid toe', + 'Enable notifications' => 'Schakel notificaties in', + 'My activity stream' => 'Mijn activiteiten', + 'My calendar' => 'Mijn kalender', + 'Search tasks' => 'Zoek taken', + 'Reset filters' => 'Reset filters', // 'My tasks due tomorrow' => '', // 'Tasks due today' => '', // 'Tasks due tomorrow' => '', // 'Tasks due yesterday' => '', - // 'Closed tasks' => '', - // 'Open tasks' => '', + 'Closed tasks' => 'Gesloten taken', + 'Open tasks' => 'Open taken', // 'Not assigned' => '', // 'View advanced search syntax' => '', - // 'Overview' => '', + 'Overview' => 'Overzicht', // 'Board/Calendar/List view' => '', // 'Switch to the board view' => '', // 'Switch to the calendar view' => '', @@ -773,9 +760,9 @@ return array( // 'There is no activity yet.' => '', // 'No tasks found.' => '', // 'Keyboard shortcut: "%s"' => '', - // 'List' => '', - // 'Filter' => '', - // 'Advanced search' => '', + 'List' => 'Lijst', + 'Filter' => 'Filter', + 'Advanced search' => 'Uitgebreid zoeken', // 'Example of query: ' => '', // 'Search by project: ' => '', // 'Search by column: ' => '', @@ -839,12 +826,12 @@ return array( // 'People who are project managers' => '', // 'People who are project members' => '', // 'NOK - Norwegian Krone' => '', - // 'Show this column' => '', - // 'Hide this column' => '', - // 'open file' => '', + 'Show this column' => 'Toon deze kolom', + 'Hide this column' => 'Verberg deze kolom', + 'open file' => 'open bestand', // 'End date' => '', // 'Users overview' => '', - // 'Members' => '', + 'Members' => 'Leden', // 'Shared project' => '', // 'Project managers' => '', // 'Gantt chart for all projects' => '', @@ -854,10 +841,9 @@ return array( // 'End date:' => '', // 'There is no start date or end date for this project.' => '', // 'Projects Gantt chart' => '', - // 'Link type' => '', // 'Change task color when using a specific task link' => '', // 'Task link creation or modification' => '', - // 'Milestone' => '', + 'Milestone' => 'Mijlpaal', // 'Documentation: %s' => '', // 'Switch to the Gantt chart view' => '', // 'Reset the search/filter box' => '', @@ -906,7 +892,6 @@ return array( // 'Shared' => '', // 'Owner' => '', // 'Unread notifications' => '', - // 'My filters' => '', // 'Notification methods:' => '', // 'Import tasks from CSV file' => '', // 'Unable to read your file' => '', @@ -944,6 +929,7 @@ return array( // 'Usernames must be lowercase and unique' => '', // 'Passwords will be encrypted if present' => '', // '%s attached a new file to the task %s' => '', + // 'Link type' => '', // 'Assign automatically a category based on a link' => '', // 'BAM - Konvertible Mark' => '', // 'Assignee Username' => '', @@ -1053,7 +1039,6 @@ return array( // 'Close a task when there is no activity' => '', // 'Duration in days' => '', // 'Send email when there is no activity on a task' => '', - // 'List of external links' => '', // 'Unable to fetch link information.' => '', // 'Daily background job for tasks' => '', // 'Auto' => '', @@ -1071,9 +1056,7 @@ return array( // 'External link' => '', // 'Copy and paste your link here...' => '', // 'URL' => '', - // 'There is no external link for the moment.' => '', // 'Internal links' => '', - // 'There is no internal link for the moment.' => '', // 'Assign to me' => '', // 'Me' => '', // 'Do not duplicate anything' => '', @@ -1081,7 +1064,6 @@ return array( // 'Users management' => '', // 'Groups management' => '', // 'Create from another project' => '', - // 'There is no subtask at the moment.' => '', // 'open' => '', // 'closed' => '', // 'Priority:' => '', @@ -1100,7 +1082,6 @@ return array( // 'Started:' => '', // 'Moved:' => '', // 'Task #%d' => '', - // 'Sub-tasks' => '', // 'Date and time format' => '', // 'Time format' => '', // 'Start date: ' => '', @@ -1141,11 +1122,35 @@ return array( // 'User filters' => '', // 'Category filters' => '', // 'Upload a file' => '', - // 'There is no attachment at the moment.' => '', // 'View file' => '', // 'Last activity' => '', // 'Change subtask position' => '', // 'This value must be greater than %d' => '', // 'Another swimlane with the same name exists in the project' => '', // 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => '', + // 'Actions duplicated successfully.' => '', + // 'Unable to duplicate actions.' => '', + // 'Add a new action' => '', + // 'Import from another project' => '', + // 'There is no action at the moment.' => '', + // 'Import actions from another project' => '', + // 'There is no available project.' => '', + // 'Local File' => '', + // 'Configuration' => '', + // 'PHP version:' => '', + // 'PHP SAPI:' => '', + // 'OS version:' => '', + // 'Database version:' => '', + // 'Browser:' => '', + // 'Task view' => '', + // 'Edit task' => '', + // 'Edit description' => '', + // 'New internal link' => '', + // 'Display list of keyboard shortcuts' => '', + // 'Menu' => '', + // 'Set start date' => '', + // 'Avatar' => '', + // 'Upload my avatar image' => '', + // 'Remove my image' => '', + // 'The OAuth2 state parameter is invalid' => '', ); diff --git a/sources/app/Locale/pl_PL/translations.php b/sources/app/Locale/pl_PL/translations.php index 9caa6b8..d06e347 100644 --- a/sources/app/Locale/pl_PL/translations.php +++ b/sources/app/Locale/pl_PL/translations.php @@ -8,7 +8,6 @@ return array( 'Edit' => 'Edytuj', 'remove' => 'usuń', 'Remove' => 'Usuń', - 'Update' => 'Aktualizuj', 'Yes' => 'Tak', 'No' => 'Nie', 'cancel' => 'anuluj', @@ -60,7 +59,6 @@ return array( 'Actions' => 'Akcje', 'Inactive' => 'Nieaktywny', 'Active' => 'Aktywny', - 'Add this column' => 'Dodaj kolumnę', '%d tasks on the board' => '%d zadań na tablicy', '%d tasks in total' => '%d wszystkich zadań', 'Unable to update this board.' => 'Nie można zaktualizować tablicy.', @@ -74,7 +72,6 @@ return array( 'All projects' => 'Wszystkie projekty', 'Add a new column' => 'Dodaj nową kolumnę', 'Title' => 'Nazwa', - 'Nobody assigned' => 'Nikt nie przypisany', 'Assigned to %s' => 'Przypisane do %s', 'Remove a column' => 'Usuń kolumnę', 'Remove a column from a board' => 'Usuń kolumnę z tablicy', @@ -168,7 +165,6 @@ return array( 'Task count' => 'Liczba zadań', 'User' => 'Użytkownik', 'Comments' => 'Komentarze', - 'Write your text in Markdown' => 'Zobacz jak formatować tekst z użyciem Markdown', 'Leave a comment' => 'Wstaw komentarz', 'Comment is required' => 'Komentarz jest wymagany', 'Leave a description' => 'Dodaj opis', @@ -184,7 +180,6 @@ return array( 'Unable to remove this action.' => 'Nie można usunąć akcji', 'Action removed successfully.' => 'Akcja usunięta', 'Automatic actions for the project "%s"' => 'Akcje automatyczne dla projektu "%s"', - 'Defined actions' => 'Zdefiniowane akcje', 'Add an action' => 'Nowa akcja', 'Event name' => 'Nazwa zdarzenia', 'Action name' => 'Nazwa akcji', @@ -194,7 +189,6 @@ return array( 'When the selected event occurs execute the corresponding action.' => 'Gdy następuje wybrane zdarzenie, uruchom odpowiednią akcję', 'Next step' => 'Następny krok', 'Define action parameters' => 'Zdefiniuj parametry akcji', - 'Save this action' => 'Zapisz akcję', 'Do you really want to remove this action: "%s"?' => 'Na pewno chcesz usunąć akcję "%s"?', 'Remove an automatic action' => 'Usuń akcję automatyczną', 'Assign the task to a specific user' => 'Przypisz zadanie do wybranego użytkownika', @@ -333,10 +327,10 @@ return array( 'Time tracking:' => 'Śledzenie czasu: ', 'New sub-task' => 'Nowe Pod-zadanie', 'New attachment added "%s"' => 'Nowy załącznik dodany "%s"', - 'Comment updated' => 'Komentarz zaktualizowany', 'New comment posted by %s' => 'Nowy komentarz dodany przez %s', 'New attachment' => 'Nowy załącznik', 'New comment' => 'Nowy Komentarz', + 'Comment updated' => 'Komentarz zaktualizowany', 'New subtask' => 'Nowe pod-zadanie', 'Subtask updated' => 'Zaktualizowane pod-zadanie', 'Task updated' => 'Zaktualizowane zadanie', @@ -436,7 +430,6 @@ return array( 'ISO format is always accepted, example: "%s" and "%s"' => 'Format ISO jest zawsze akceptowany, przykłady: "%s", "%s"', 'New private project' => 'Nowy projekt prywatny', 'This project is private' => 'Ten projekt jest prywatny', - 'Type here to create a new sub-task' => 'Nazwa podzadania', 'Add' => 'Dodaj', 'Start date' => 'Data rozpoczęcia', 'Time estimated' => 'Szacowany czas', @@ -487,9 +480,6 @@ return array( 'Daily project summary export for "%s"' => 'Wygeneruj dzienny raport dla projektu: "%s"', 'Exports' => 'Eksporty', 'This export contains the number of tasks per column grouped per day.' => 'Ten eksport zawiera ilość zadań zgrupowanych w kolumnach na dzień', - 'Nothing to preview...' => 'Nic do podejrzenia...', - 'Preview' => 'Podgląd', - 'Write' => 'Edycja', 'Active swimlanes' => 'Aktywne procesy', 'Add a new swimlane' => 'Dodaj proces', 'Change default swimlane' => 'Zmień domyślny proces', @@ -543,7 +533,6 @@ return array( 'Task age in days' => 'Wiek zadania w dniach', 'Days in this column' => 'Dni w tej kolumnie', // '%dd' => '', - 'Add a link' => 'Dodaj link', 'Add a new link' => 'Dodaj nowy link', 'Do you really want to remove this link: "%s"?' => 'Czy na pewno chcesz usunąć ten link: "%s"?', 'Do you really want to remove this link with task #%d?' => 'Czy na pewno chcesz usunąć ten link razem z zadaniem nr %d?', @@ -734,7 +723,7 @@ return array( // 'Time spent changed: %sh' => '', // 'Time estimated changed: %sh' => '', // 'The field "%s" have been updated' => '', - // 'The description have been modified' => '', + // 'The description has been modified:' => '', // 'Do you really want to close the task "%s" as well as all subtasks?' => '', 'I want to receive notifications for:' => 'Wysyłaj powiadomienia dla:', 'All tasks' => 'Wszystkich zadań', @@ -753,8 +742,6 @@ return array( 'My activity stream' => 'Moja aktywność', 'My calendar' => 'Mój kalendarz', 'Search tasks' => 'Szukaj zadań', - 'Back to the calendar' => 'Wróć do kalendarza', - 'Filters' => 'Filtry', 'Reset filters' => 'Resetuj zastosowane filtry', 'My tasks due tomorrow' => 'Moje zadania do jutra', 'Tasks due today' => 'Zadania do dzisiaj', @@ -854,7 +841,6 @@ return array( 'End date:' => 'Data zakończenia:', 'There is no start date or end date for this project.' => 'Nie zdefiniowano czasu trwania projektu', 'Projects Gantt chart' => 'Wykres Gantta dla projektów', - 'Link type' => 'Rodzaj link\'u', 'Change task color when using a specific task link' => 'Zmień kolor zadania używając specjalnego adresu URL', 'Task link creation or modification' => 'Adres URL do utworzenia zadania lub modyfikacji', 'Milestone' => 'Kamień milowy', @@ -906,7 +892,6 @@ return array( // 'Shared' => '', 'Owner' => 'Właściciel', 'Unread notifications' => 'Nieprzeczytane powiadomienia', - 'My filters' => 'Moje filtry', 'Notification methods:' => 'Metody powiadomień:', // 'Import tasks from CSV file' => '', // 'Unable to read your file' => '', @@ -944,6 +929,7 @@ return array( // 'Usernames must be lowercase and unique' => '', // 'Passwords will be encrypted if present' => '', // '%s attached a new file to the task %s' => '', + 'Link type' => 'Rodzaj link\'u', // 'Assign automatically a category based on a link' => '', // 'BAM - Konvertible Mark' => '', // 'Assignee Username' => '', @@ -1036,7 +1022,7 @@ return array( 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => 'Wtyczki obsługujące dodatkowe powiadomienia nie zostały zainstalowane. Dalej jednak możesz korzystać z standardowych powiadomień (sprawdź w ustawieniach Twojego profilu).', 'My dashboard' => 'Mój dashboard', 'My profile' => 'Mój profil', - 'Project owner:' => 'Właściciel:', + // 'Project owner: ' => '', 'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => 'Identyfikator projektu jest opcjonalny i musi być alfanumeryczny, przykład: MYPROJECT.', 'Project owner' => 'Właściciel projektu', 'Those dates are useful for the project Gantt chart.' => 'Daty te są przydatne dla wykresu Gantta.', @@ -1053,7 +1039,6 @@ return array( // 'Close a task when there is no activity' => '', // 'Duration in days' => '', // 'Send email when there is no activity on a task' => '', - // 'List of external links' => '', // 'Unable to fetch link information.' => '', // 'Daily background job for tasks' => '', 'Auto' => 'Automatyczny', @@ -1071,9 +1056,7 @@ return array( 'External link' => 'Link zewnętrzny', 'Copy and paste your link here...' => 'Skopiuj i wklej link tutaj ...', // 'URL' => '', - 'There is no external link for the moment.' => 'Brak linków zewnętrznych.', 'Internal links' => 'Linki do innych zadań', - 'There is no internal link for the moment.' => 'Brak powiązań do innych zadań.', // 'Assign to me' => '', 'Me' => 'JA', 'Do not duplicate anything' => 'Nie kopiuj żadnego projektu', @@ -1081,7 +1064,6 @@ return array( 'Users management' => 'Zarządzanie użytkownikami', 'Groups management' => 'Zarządzanie grupami', 'Create from another project' => 'Utwórz na podstawie innego projektu', - 'There is no subtask at the moment.' => 'Brak podzadań.', 'open' => 'otwarty', 'closed' => 'zamknięty', 'Priority:' => 'Priorytet:', @@ -1100,7 +1082,6 @@ return array( 'Started:' => 'Rozpoczęte:', 'Moved:' => 'Przesunięcie:', 'Task #%d' => 'Zadanie #%d', - 'Sub-tasks' => 'Podzadania', // 'Date and time format' => '', // 'Time format' => '', // 'Start date: ' => '', @@ -1141,11 +1122,35 @@ return array( // 'User filters' => '', // 'Category filters' => '', 'Upload a file' => 'Prześlij plik', - 'There is no attachment at the moment.' => 'Brak załączników.', 'View file' => 'Wyświetl plik', 'Last activity' => 'Ostatnia aktywność', // 'Change subtask position' => '', // 'This value must be greater than %d' => '', // 'Another swimlane with the same name exists in the project' => '', // 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => '', + // 'Actions duplicated successfully.' => '', + // 'Unable to duplicate actions.' => '', + // 'Add a new action' => '', + // 'Import from another project' => '', + // 'There is no action at the moment.' => '', + // 'Import actions from another project' => '', + // 'There is no available project.' => '', + // 'Local File' => '', + // 'Configuration' => '', + // 'PHP version:' => '', + // 'PHP SAPI:' => '', + // 'OS version:' => '', + // 'Database version:' => '', + // 'Browser:' => '', + // 'Task view' => '', + // 'Edit task' => '', + // 'Edit description' => '', + // 'New internal link' => '', + // 'Display list of keyboard shortcuts' => '', + // 'Menu' => '', + // 'Set start date' => '', + // 'Avatar' => '', + // 'Upload my avatar image' => '', + // 'Remove my image' => '', + // 'The OAuth2 state parameter is invalid' => '', ); diff --git a/sources/app/Locale/pt_BR/translations.php b/sources/app/Locale/pt_BR/translations.php index bcbd03d..050d1a9 100644 --- a/sources/app/Locale/pt_BR/translations.php +++ b/sources/app/Locale/pt_BR/translations.php @@ -8,7 +8,6 @@ return array( 'Edit' => 'Editar', 'remove' => 'remover', 'Remove' => 'Remover', - 'Update' => 'Atualizar', 'Yes' => 'Sim', 'No' => 'Não', 'cancel' => 'cancelar', @@ -60,7 +59,6 @@ return array( 'Actions' => 'Ações', 'Inactive' => 'Inativo', 'Active' => 'Ativo', - 'Add this column' => 'Adicionar esta coluna', '%d tasks on the board' => '%d tarefas no board', '%d tasks in total' => '%d tarefas no total', 'Unable to update this board.' => 'Não foi possível atualizar este board.', @@ -74,7 +72,6 @@ return array( 'All projects' => 'Todos os projetos', 'Add a new column' => 'Adicionar uma nova coluna', 'Title' => 'Título', - 'Nobody assigned' => 'Ninguém designado', 'Assigned to %s' => 'Designado para %s', 'Remove a column' => 'Remover uma coluna', 'Remove a column from a board' => 'Remover uma coluna do board', @@ -168,7 +165,6 @@ return array( 'Task count' => 'Número de tarefas', 'User' => 'Usuário', 'Comments' => 'Comentários', - 'Write your text in Markdown' => 'Escreva seu texto em Markdown', 'Leave a comment' => 'Deixe um comentário', 'Comment is required' => 'Comentário é obrigatório', 'Leave a description' => 'Deixe uma descrição', @@ -184,7 +180,6 @@ return array( 'Unable to remove this action.' => 'Não é possível remover esta ação.', 'Action removed successfully.' => 'Ação removida com sucesso.', 'Automatic actions for the project "%s"' => 'Ações automáticas para o projeto "%s"', - 'Defined actions' => 'Ações definidas', 'Add an action' => 'Adicionar Ação', 'Event name' => 'Nome do evento', 'Action name' => 'Nome da ação', @@ -194,7 +189,6 @@ return array( 'When the selected event occurs execute the corresponding action.' => 'Quando o evento selecionado ocorrer execute a ação correspondente.', 'Next step' => 'Próximo passo', 'Define action parameters' => 'Definir parêmetros da ação', - 'Save this action' => 'Salvar esta ação', 'Do you really want to remove this action: "%s"?' => 'Você realmente deseja remover esta ação: "%s"?', 'Remove an automatic action' => 'Remover uma ação automática', 'Assign the task to a specific user' => 'Designar a tarefa para um usuário específico', @@ -333,10 +327,10 @@ return array( 'Time tracking:' => 'Controle de tempo:', 'New sub-task' => 'Nova subtarefa', 'New attachment added "%s"' => 'Novo anexo adicionado "%s"', - 'Comment updated' => 'Comentário atualizado', 'New comment posted by %s' => 'Novo comentário postado por %s', 'New attachment' => 'Novo anexo', 'New comment' => 'Novo comentário', + 'Comment updated' => 'Comentário atualizado', 'New subtask' => 'Nova subtarefa', 'Subtask updated' => 'Subtarefa alterada', 'Task updated' => 'Tarefa alterada', @@ -436,7 +430,6 @@ return array( 'ISO format is always accepted, example: "%s" and "%s"' => 'O formato ISO é sempre aceito, exemplo: "%s" e "%s"', 'New private project' => 'Novo projeto privado', 'This project is private' => 'Este projeto é privado', - 'Type here to create a new sub-task' => 'Digite aqui para criar uma nova subtarefa', 'Add' => 'Adicionar', 'Start date' => 'Data de início', 'Time estimated' => 'Tempo estimado', @@ -487,9 +480,6 @@ return array( 'Daily project summary export for "%s"' => 'Exportação diária do resumo do projeto para "%s"', 'Exports' => 'Exportar', 'This export contains the number of tasks per column grouped per day.' => 'Esta exportação contém o número de tarefas por coluna agrupada por dia.', - 'Nothing to preview...' => 'Nada para pré-visualizar...', - 'Preview' => 'Pré-visualizar', - 'Write' => 'Escrever', 'Active swimlanes' => 'Ativar swimlanes', 'Add a new swimlane' => 'Adicionar swimlane', 'Change default swimlane' => 'Alterar swimlane padrão', @@ -543,7 +533,6 @@ return array( 'Task age in days' => 'Idade da tarefa em dias', 'Days in this column' => 'Dias nesta coluna', '%dd' => '%dd', - 'Add a link' => 'Adicionar uma associação', 'Add a new link' => 'Adicionar uma nova associação', 'Do you really want to remove this link: "%s"?' => 'Você realmente deseja remover esta associação: "%s"?', 'Do you really want to remove this link with task #%d?' => 'Você realmente deseja remover esta associação com a tarefa #%d?', @@ -734,7 +723,7 @@ return array( 'Time spent changed: %sh' => 'O tempo despendido foi mudado: %sh', 'Time estimated changed: %sh' => 'O tempo estimado foi mudado/ %sh', 'The field "%s" have been updated' => 'O campo "%s" foi atualizada', - 'The description have been modified' => 'A descrição foi modificada', + 'The description has been modified:' => 'A descrição foi modificada', 'Do you really want to close the task "%s" as well as all subtasks?' => 'Você realmente deseja finalizar a tarefa "%s" e todas as suas subtarefas?', 'I want to receive notifications for:' => 'Eu quero receber as notificações para:', 'All tasks' => 'Todas as tarefas', @@ -753,8 +742,6 @@ return array( 'My activity stream' => 'Meu feed de atividades', 'My calendar' => 'Minha agenda', 'Search tasks' => 'Pesquisar tarefas', - 'Back to the calendar' => 'Voltar ao calendário', - 'Filters' => 'Filtros', 'Reset filters' => 'Redefinir os filtros', 'My tasks due tomorrow' => 'Minhas tarefas que expiram amanhã', 'Tasks due today' => 'Tarefas que expiram hoje', @@ -854,7 +841,6 @@ return array( 'End date:' => 'Data de término:', 'There is no start date or end date for this project.' => 'Não há data de início ou data de término para este projeto.', 'Projects Gantt chart' => 'Gráfico de Gantt dos projetos', - 'Link type' => 'Tipo de link', 'Change task color when using a specific task link' => 'Mudar a cor da tarefa quando um link específico é utilizado', 'Task link creation or modification' => 'Criação ou modificação de um link em uma tarefa', 'Milestone' => 'Milestone', @@ -906,7 +892,6 @@ return array( 'Shared' => 'Compartilhado', 'Owner' => 'Líder', 'Unread notifications' => 'Notificações não lidas', - 'My filters' => 'Meus filtros', 'Notification methods:' => 'Métodos de notificação:', 'Import tasks from CSV file' => 'Importar tarefas a partir de arquivo CSV', 'Unable to read your file' => 'Não foi possível ler seu arquivo', @@ -944,6 +929,7 @@ return array( 'Usernames must be lowercase and unique' => 'Nomes de usuário devem ser únicos e em letras minúsculas', 'Passwords will be encrypted if present' => 'Senhas serão encriptadas, se presentes', '%s attached a new file to the task %s' => '%s anexou um novo arquivo a tarefa %s', + 'Link type' => 'Tipo de link', 'Assign automatically a category based on a link' => 'Atribuir automaticamente uma categoria baseada num link', 'BAM - Konvertible Mark' => 'BAM - Mark conversível', 'Assignee Username' => 'Usuário designado', @@ -1053,7 +1039,6 @@ return array( 'Close a task when there is no activity' => 'Fechar uma tarefa sem atividade', 'Duration in days' => 'Duração em dias', 'Send email when there is no activity on a task' => 'Enviar um e-mail quando não há nenhuma atividade em uma tarefa', - 'List of external links' => 'Lista dos links externos', 'Unable to fetch link information.' => 'Não foi possível obter informações sobre o link.', 'Daily background job for tasks' => 'Tarefa agendada diariamente para as tarefas', 'Auto' => 'Auto', @@ -1071,9 +1056,7 @@ return array( // 'External link' => '', // 'Copy and paste your link here...' => '', // 'URL' => '', - // 'There is no external link for the moment.' => '', // 'Internal links' => '', - // 'There is no internal link for the moment.' => '', // 'Assign to me' => '', // 'Me' => '', // 'Do not duplicate anything' => '', @@ -1081,7 +1064,6 @@ return array( // 'Users management' => '', // 'Groups management' => '', // 'Create from another project' => '', - // 'There is no subtask at the moment.' => '', // 'open' => '', // 'closed' => '', // 'Priority:' => '', @@ -1100,7 +1082,6 @@ return array( // 'Started:' => '', // 'Moved:' => '', // 'Task #%d' => '', - // 'Sub-tasks' => '', // 'Date and time format' => '', // 'Time format' => '', // 'Start date: ' => '', @@ -1141,11 +1122,35 @@ return array( // 'User filters' => '', // 'Category filters' => '', // 'Upload a file' => '', - // 'There is no attachment at the moment.' => '', // 'View file' => '', // 'Last activity' => '', // 'Change subtask position' => '', // 'This value must be greater than %d' => '', // 'Another swimlane with the same name exists in the project' => '', // 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => '', + // 'Actions duplicated successfully.' => '', + // 'Unable to duplicate actions.' => '', + // 'Add a new action' => '', + // 'Import from another project' => '', + // 'There is no action at the moment.' => '', + // 'Import actions from another project' => '', + // 'There is no available project.' => '', + // 'Local File' => '', + // 'Configuration' => '', + // 'PHP version:' => '', + // 'PHP SAPI:' => '', + // 'OS version:' => '', + // 'Database version:' => '', + // 'Browser:' => '', + // 'Task view' => '', + // 'Edit task' => '', + // 'Edit description' => '', + // 'New internal link' => '', + // 'Display list of keyboard shortcuts' => '', + // 'Menu' => '', + // 'Set start date' => '', + // 'Avatar' => '', + // 'Upload my avatar image' => '', + // 'Remove my image' => '', + // 'The OAuth2 state parameter is invalid' => '', ); diff --git a/sources/app/Locale/pt_PT/translations.php b/sources/app/Locale/pt_PT/translations.php index 8241273..1c32788 100644 --- a/sources/app/Locale/pt_PT/translations.php +++ b/sources/app/Locale/pt_PT/translations.php @@ -8,7 +8,6 @@ return array( 'Edit' => 'Editar', 'remove' => 'remover', 'Remove' => 'Remover', - 'Update' => 'Actualizar', 'Yes' => 'Sim', 'No' => 'Não', 'cancel' => 'cancelar', @@ -60,7 +59,6 @@ return array( 'Actions' => 'Acções', 'Inactive' => 'Inactivo', 'Active' => 'Activo', - 'Add this column' => 'Adicionar esta coluna', '%d tasks on the board' => '%d tarefas no quadro', '%d tasks in total' => '%d tarefas no total', 'Unable to update this board.' => 'Não foi possível actualizar este quadro.', @@ -74,7 +72,6 @@ return array( 'All projects' => 'Todos os projectos', 'Add a new column' => 'Adicionar uma nova coluna', 'Title' => 'Título', - 'Nobody assigned' => 'Ninguém assignado', 'Assigned to %s' => 'Designado para %s', 'Remove a column' => 'Remover uma coluna', 'Remove a column from a board' => 'Remover uma coluna do quadro', @@ -168,7 +165,6 @@ return array( 'Task count' => 'Número de tarefas', 'User' => 'Utilizador', 'Comments' => 'Comentários', - 'Write your text in Markdown' => 'Escreva o seu texto em Markdown', 'Leave a comment' => 'Deixe um comentário', 'Comment is required' => 'Comentário é obrigatório', 'Leave a description' => 'Deixe uma descrição', @@ -184,7 +180,6 @@ return array( 'Unable to remove this action.' => 'Não é possível remover esta acção.', 'Action removed successfully.' => 'Acção removida com sucesso.', 'Automatic actions for the project "%s"' => 'Acções automáticas para o projecto "%s"', - 'Defined actions' => 'Acções definidas', 'Add an action' => 'Adicionar Acção', 'Event name' => 'Nome do evento', 'Action name' => 'Nome da acção', @@ -194,7 +189,6 @@ return array( 'When the selected event occurs execute the corresponding action.' => 'Quando o evento selecionado ocorrer execute a acção correspondente.', 'Next step' => 'Próximo passo', 'Define action parameters' => 'Definir parêmetros da acção', - 'Save this action' => 'Guardar esta acção', 'Do you really want to remove this action: "%s"?' => 'Tem a certeza que quer remover esta acção: "%s"?', 'Remove an automatic action' => 'Remover uma acção automática', 'Assign the task to a specific user' => 'Designar a tarefa para um utilizador específico', @@ -333,10 +327,10 @@ return array( 'Time tracking:' => 'Controle de tempo:', 'New sub-task' => 'Nova subtarefa', 'New attachment added "%s"' => 'Novo anexo adicionado "%s"', - 'Comment updated' => 'Comentário actualizado', 'New comment posted by %s' => 'Novo comentário por %s', 'New attachment' => 'Novo anexo', 'New comment' => 'Novo comentário', + 'Comment updated' => 'Comentário actualizado', 'New subtask' => 'Nova subtarefa', 'Subtask updated' => 'Subtarefa alterada', 'Task updated' => 'Tarefa alterada', @@ -436,7 +430,6 @@ return array( 'ISO format is always accepted, example: "%s" and "%s"' => 'O formato ISO é sempre aceite, exemplo: "%s" e "%s"', 'New private project' => 'Novo projecto privado', 'This project is private' => 'Este projecto é privado', - 'Type here to create a new sub-task' => 'Escreva aqui para criar uma nova subtarefa', 'Add' => 'Adicionar', 'Start date' => 'Data de início', 'Time estimated' => 'Tempo estimado', @@ -487,9 +480,6 @@ return array( 'Daily project summary export for "%s"' => 'Exportação diária do resumo do projecto para "%s"', 'Exports' => 'Exportar', 'This export contains the number of tasks per column grouped per day.' => 'Esta exportação contém o número de tarefas por coluna agrupada por dia.', - 'Nothing to preview...' => 'Nada para pré-visualizar...', - 'Preview' => 'Pré-visualizar', - 'Write' => 'Escrever', 'Active swimlanes' => 'Activar swimlanes', 'Add a new swimlane' => 'Adicionar novo swimlane', 'Change default swimlane' => 'Alterar swimlane padrão', @@ -543,7 +533,6 @@ return array( 'Task age in days' => 'Idade da tarefa em dias', 'Days in this column' => 'Dias nesta coluna', // '%dd' => '', - 'Add a link' => 'Adicionar uma associação', 'Add a new link' => 'Adicionar uma nova associação', 'Do you really want to remove this link: "%s"?' => 'Tem a certeza que quer remover esta associação: "%s"?', 'Do you really want to remove this link with task #%d?' => 'Tem a certeza que quer remover esta associação com a tarefa n°%d?', @@ -734,7 +723,7 @@ return array( 'Time spent changed: %sh' => 'O tempo despendido foi mudado: %sh', 'Time estimated changed: %sh' => 'O tempo estimado foi mudado/ %sh', 'The field "%s" have been updated' => 'O campo "%s" foi actualizada', - 'The description have been modified' => 'A descrição foi modificada', + 'The description has been modified:' => 'A descrição foi modificada', 'Do you really want to close the task "%s" as well as all subtasks?' => 'Tem a certeza que quer fechar a tarefa "%s" e todas as suas sub-tarefas?', 'I want to receive notifications for:' => 'Eu quero receber as notificações para:', 'All tasks' => 'Todas as tarefas', @@ -753,8 +742,6 @@ return array( 'My activity stream' => 'O meu feed de actividade', 'My calendar' => 'A minha agenda', 'Search tasks' => 'Pesquisar tarefas', - 'Back to the calendar' => 'Voltar ao calendário', - 'Filters' => 'Filtros', 'Reset filters' => 'Redefinir os filtros', 'My tasks due tomorrow' => 'A minhas tarefas que expiram amanhã', 'Tasks due today' => 'Tarefas que expiram hoje', @@ -854,7 +841,6 @@ return array( 'End date:' => 'Data de fim:', 'There is no start date or end date for this project.' => 'Não existe data de inicio ou fim para este projecto.', 'Projects Gantt chart' => 'Gráfico de Gantt dos projectos', - 'Link type' => 'Tipo de ligação', 'Change task color when using a specific task link' => 'Alterar cor da tarefa quando se usar um tipo especifico de ligação de tarefa', 'Task link creation or modification' => 'Criação ou modificação de ligação de tarefa', 'Milestone' => 'Objectivo', @@ -906,7 +892,6 @@ return array( 'Shared' => 'Partilhado', 'Owner' => 'Dono', 'Unread notifications' => 'Notificações por ler', - 'My filters' => 'Os meus filtros', 'Notification methods:' => 'Métodos de notificação:', 'Import tasks from CSV file' => 'Importar tarefas de um ficheiro CSV', 'Unable to read your file' => 'Não foi possivel ler o ficheiro', @@ -944,6 +929,7 @@ return array( 'Usernames must be lowercase and unique' => 'Utilizadores tem de estar em letra pequena e ser unicos', 'Passwords will be encrypted if present' => 'Senhas serão encriptadas se presentes', '%s attached a new file to the task %s' => '%s anexou um novo ficheiro à tarefa %s', + 'Link type' => 'Tipo de ligação', 'Assign automatically a category based on a link' => 'Assignar automáticamente a categoria baseada num link', 'BAM - Konvertible Mark' => 'BAM - Marca Conversível', 'Assignee Username' => 'Utilizador do Assignado', @@ -1053,7 +1039,6 @@ return array( 'Close a task when there is no activity' => 'Fechar tarefa quando não há actividade', 'Duration in days' => 'Duração em dias', 'Send email when there is no activity on a task' => 'Enviar email quando não há actividade numa tarefa', - 'List of external links' => 'Lista de ligações externas', 'Unable to fetch link information.' => 'Impossivel obter informação da ligação.', 'Daily background job for tasks' => 'Trabalho diário em segundo plano para tarefas', 'Auto' => 'Auto', @@ -1071,9 +1056,7 @@ return array( 'External link' => 'Ligação externa', 'Copy and paste your link here...' => 'Copie e cole a sua ligação aqui...', 'URL' => 'URL', - 'There is no external link for the moment.' => 'De momento não existe nenhuma ligação externa.', 'Internal links' => 'Ligações internas', - 'There is no internal link for the moment.' => 'De momento não existe nenhuma ligação interna.', 'Assign to me' => 'Assignar a mim', 'Me' => 'Eu', 'Do not duplicate anything' => 'Não duplicar nada', @@ -1081,7 +1064,6 @@ return array( 'Users management' => 'Gestão de utilizadores', 'Groups management' => 'Gestão de grupos', 'Create from another project' => 'Criar apartir de outro projecto', - 'There is no subtask at the moment.' => 'De momento não existe sub-tarefa.', 'open' => 'aberto', 'closed' => 'fechado', 'Priority:' => 'Prioridade:', @@ -1100,7 +1082,6 @@ return array( 'Started:' => 'Iniciado:', 'Moved:' => 'Movido:', 'Task #%d' => 'Tarefa #%d', - 'Sub-tasks' => 'Sub-tarefa', 'Date and time format' => 'Formato tempo e data', 'Time format' => 'Formato tempo', 'Start date: ' => 'Data inicio: ', @@ -1132,20 +1113,44 @@ return array( 'Uploaded by %s' => 'Enviado por %s', 'Filename' => 'Nome do ficheiro', 'Size' => 'Tamanho', - // 'Column created successfully.' => '', - // 'Another column with the same name exists in the project' => '', - // 'Default filters' => '', - // 'Your board doesn\'t have any column!' => '', - // 'Change column position' => '', - // 'Switch to the project overview' => '', - // 'User filters' => '', - // 'Category filters' => '', - // 'Upload a file' => '', - // 'There is no attachment at the moment.' => '', - // 'View file' => '', - // 'Last activity' => '', - // 'Change subtask position' => '', - // 'This value must be greater than %d' => '', - // 'Another swimlane with the same name exists in the project' => '', - // 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => '', + 'Column created successfully.' => 'Coluna criada com sucesso.', + 'Another column with the same name exists in the project' => 'Já existe outra coluna com o mesmo nome no projecto', + 'Default filters' => 'Filtros padrão', + 'Your board doesn\'t have any column!' => 'O seu quadro não tem nenhuma coluna!', + 'Change column position' => 'Mudar posição da coluna', + 'Switch to the project overview' => 'Mudar para vista geral do projecto', + 'User filters' => 'Filtros de utilizador', + 'Category filters' => 'Filtros de categoria', + 'Upload a file' => 'Enviar um ficheiro', + 'View file' => 'Ver ficheiro', + 'Last activity' => 'Ultima actividade', + 'Change subtask position' => 'Mudar posição da sub-tarefa', + 'This value must be greater than %d' => 'Este valor tem de ser maior que %d', + 'Another swimlane with the same name exists in the project' => 'Já existe outra swimlane com o mesmo nome no projecto', + 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => 'Exemplo: http://example.kanboard.net/ (usado para gerar URLs absolutos)', + 'Actions duplicated successfully.' => 'Acções duplicadas com sucesso.', + 'Unable to duplicate actions.' => 'Não foi possivel duplicar acções.', + 'Add a new action' => 'Adicionar nova acção', + 'Import from another project' => 'Importar de outro projecto', + 'There is no action at the moment.' => 'De momento não existe acção.', + 'Import actions from another project' => 'Importar acções de outro projecto', + 'There is no available project.' => 'Não existe projecto disponivel.', + // 'Local File' => '', + // 'Configuration' => '', + // 'PHP version:' => '', + // 'PHP SAPI:' => '', + // 'OS version:' => '', + // 'Database version:' => '', + // 'Browser:' => '', + // 'Task view' => '', + // 'Edit task' => '', + // 'Edit description' => '', + // 'New internal link' => '', + // 'Display list of keyboard shortcuts' => '', + // 'Menu' => '', + // 'Set start date' => '', + // 'Avatar' => '', + // 'Upload my avatar image' => '', + // 'Remove my image' => '', + // 'The OAuth2 state parameter is invalid' => '', ); diff --git a/sources/app/Locale/ru_RU/translations.php b/sources/app/Locale/ru_RU/translations.php index 0d73f90..3cb3c6b 100644 --- a/sources/app/Locale/ru_RU/translations.php +++ b/sources/app/Locale/ru_RU/translations.php @@ -8,7 +8,6 @@ return array( 'Edit' => 'Изменить', 'remove' => 'удалить', 'Remove' => 'Удалить', - 'Update' => 'Обновить', 'Yes' => 'Да', 'No' => 'Нет', 'cancel' => 'Отменить', @@ -60,7 +59,6 @@ return array( 'Actions' => 'Действия', 'Inactive' => 'Неактивен', 'Active' => 'Активен', - 'Add this column' => 'Добавить колонку', '%d tasks on the board' => '%d задач на доске', '%d tasks in total' => 'всего %d задач', 'Unable to update this board.' => 'Не удалось обновить эту доску.', @@ -74,7 +72,6 @@ return array( 'All projects' => 'Все проекты', 'Add a new column' => 'Добавить новую колонку', 'Title' => 'Название', - 'Nobody assigned' => 'Никто не назначен', 'Assigned to %s' => 'Назначено %s', 'Remove a column' => 'Удалить колонку', 'Remove a column from a board' => 'Удалить колонку с доски', @@ -168,7 +165,6 @@ return array( 'Task count' => 'Количество задач', 'User' => 'Пользователь', 'Comments' => 'Комментарии', - 'Write your text in Markdown' => 'Справка по синтаксису Markdown', 'Leave a comment' => 'Оставить комментарий', 'Comment is required' => 'Нужен комментарий', 'Leave a description' => 'Напишите описание', @@ -184,7 +180,6 @@ return array( 'Unable to remove this action.' => 'Не удалось удалить действие', 'Action removed successfully.' => 'Действие удалено.', 'Automatic actions for the project "%s"' => 'Автоматические действия для проекта « %s »', - 'Defined actions' => 'Заданные действия', 'Add an action' => 'Добавить действие', 'Event name' => 'Имя события', 'Action name' => 'Имя действия', @@ -194,7 +189,6 @@ return array( 'When the selected event occurs execute the corresponding action.' => 'Когда случится ВЫБРАННОЕ событие выполняется СООТВЕТСТВУЮЩЕЕ действие.', 'Next step' => 'Следующий шаг', 'Define action parameters' => 'Задать параметры действия', - 'Save this action' => 'Сохранить это действие', 'Do you really want to remove this action: "%s"?' => 'Вы точно хотите удалить это действие: « %s » ?', 'Remove an automatic action' => 'Удалить автоматическое действие', 'Assign the task to a specific user' => 'Назначить задачу определенному пользователю', @@ -333,10 +327,10 @@ return array( 'Time tracking:' => 'Отслеживание времени:', 'New sub-task' => 'Новая подзадача', 'New attachment added "%s"' => 'Добавлено вложение « %s »', - 'Comment updated' => 'Комментарий обновлен', 'New comment posted by %s' => 'Новый комментарий написан « %s »', 'New attachment' => 'Новое вложение', 'New comment' => 'Новый комментарий', + 'Comment updated' => 'Комментарий обновлен', 'New subtask' => 'Новая подзадача', 'Subtask updated' => 'Подзадача обновлена', 'Task updated' => 'Задача обновлена', @@ -436,7 +430,6 @@ return array( 'ISO format is always accepted, example: "%s" and "%s"' => 'Время должно быть в ISO-формате, например: "%s" или "%s"', 'New private project' => 'Новый проект с ограниченным доступом', 'This project is private' => 'Это проект с ограниченным доступом', - 'Type here to create a new sub-task' => 'Печатайте сюда чтобы создать подзадачу', 'Add' => 'Добавить', 'Start date' => 'Дата начала', 'Time estimated' => 'Запланировано', @@ -487,9 +480,6 @@ return array( 'Daily project summary export for "%s"' => 'Экспорт ежедневного резюме проекта "%s"', 'Exports' => 'Экспорт', 'This export contains the number of tasks per column grouped per day.' => 'Этот экспорт содержит ряд задач в колонках, сгруппированные по дням.', - 'Nothing to preview...' => 'Нет данных для предпросмотра...', - 'Preview' => 'Предпросмотр', - 'Write' => 'Написание', 'Active swimlanes' => 'Активные дорожки', 'Add a new swimlane' => 'Добавить новую дорожку', 'Change default swimlane' => 'Сменить стандартную дорожку', @@ -543,7 +533,6 @@ return array( 'Task age in days' => 'Возраст задачи в днях', 'Days in this column' => 'Дней в этой колонке', '%dd' => '%dd', - '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?', @@ -734,7 +723,7 @@ return array( 'Time spent changed: %sh' => 'Изменение количества затраченного времени: %sh', 'Time estimated changed: %sh' => 'Ожидаемый срок изменен: %sh', 'The field "%s" have been updated' => 'Поле "%s" ,было изменено', - 'The description have been modified' => 'Описание было изменено', + 'The description has been modified:' => 'Описание было изменено', 'Do you really want to close the task "%s" as well as all subtasks?' => 'Вы действительно хотите закрыть задачу "%s", а также все подзадачи?', 'I want to receive notifications for:' => 'Я хочу получать уведомления для:', 'All tasks' => 'Все задачи', @@ -753,8 +742,6 @@ return array( 'My activity stream' => 'Лента моей активности', 'My calendar' => 'Мой календарь', 'Search tasks' => 'Поиск задачи', - 'Back to the calendar' => 'Вернуться в календарь', - 'Filters' => 'Фильтры', 'Reset filters' => 'Сбросить фильтры', 'My tasks due tomorrow' => 'Мои задачи на завтра', 'Tasks due today' => 'Задачи, завершающиеся сегодня', @@ -854,7 +841,6 @@ return array( 'End date:' => 'Дата завершения:', 'There is no start date or end date for this project.' => 'В проекте не указаны дата начала или завершения.', 'Projects Gantt chart' => 'Диаграмма Ганта проектов', - 'Link type' => 'Тип ссылки', 'Change task color when using a specific task link' => 'Изменение цвета задач при использовании ссылки на определенные задачи', 'Task link creation or modification' => 'Ссылка на создание или модификацию задачи', 'Milestone' => 'Веха', @@ -906,7 +892,6 @@ return array( 'Shared' => 'Общие', 'Owner' => 'Владелец', 'Unread notifications' => 'Непрочитанные уведомления', - 'My filters' => 'Мои фильтры', 'Notification methods:' => 'Способы уведомления:', 'Import tasks from CSV file' => 'Импорт задач из CSV-файла', 'Unable to read your file' => 'Невозможно прочитать файл', @@ -944,6 +929,7 @@ return array( 'Usernames must be lowercase and unique' => 'Логины пользователей должны быть строчными и уникальными', 'Passwords will be encrypted if present' => 'Пароли будут зашифрованы (если указаны)', '%s attached a new file to the task %s' => '%s добавил новый файл к задаче %s', + 'Link type' => 'Тип ссылки', 'Assign automatically a category based on a link' => 'Автоматически назначать категории на основе ссылки', 'BAM - Konvertible Mark' => 'BAM - Конвертируемая марка', 'Assignee Username' => 'Логин назначенного', @@ -1053,7 +1039,6 @@ return array( 'Close a task when there is no activity' => 'Закрывать задачу, когда нет активности', 'Duration in days' => 'Длительность в днях', 'Send email when there is no activity on a task' => 'Отправлять email, когда активность по задаче отсутствует', - 'List of external links' => 'Список внешних ссылок', 'Unable to fetch link information.' => 'Не удалось получить информацию о ссылке', 'Daily background job for tasks' => 'Ежедневные фоновые работы для задач', 'Auto' => 'Авто', @@ -1071,9 +1056,7 @@ return array( 'External link' => 'Внешняя ссылка', 'Copy and paste your link here...' => 'Скопируйте и вставьте вашу ссылку здесь', 'URL' => 'URL', - 'There is no external link for the moment.' => 'На данный момент внешние ссылки отсутствуют', 'Internal links' => 'Внутренние ссылки', - 'There is no internal link for the moment.' => 'На данные момент внутреннии ссылки отсутствуют', 'Assign to me' => 'Связать со мной', 'Me' => 'Мне', 'Do not duplicate anything' => 'Не дублировать ничего', @@ -1081,7 +1064,6 @@ return array( 'Users management' => 'Управление пользователями', 'Groups management' => 'Управление группами', 'Create from another project' => 'Создать из другого проекта', - 'There is no subtask at the moment.' => 'На данный момент подзадачи отсутствуют', 'open' => 'открыто', 'closed' => 'закрыто', 'Priority:' => 'Приоритет:', @@ -1100,7 +1082,6 @@ return array( 'Started:' => 'Начата:', 'Moved:' => 'Перемещена:', 'Task #%d' => 'Задача #%d', - 'Sub-tasks' => 'Подзадачи', 'Date and time format' => 'Формат даты и времени', 'Time format' => 'Формат времени', 'Start date: ' => 'Дата начала:', @@ -1132,20 +1113,44 @@ return array( 'Uploaded by %s' => 'Загружено пользователем: %s', 'Filename' => 'Имя файла', 'Size' => 'Размер', - // 'Column created successfully.' => '', - // 'Another column with the same name exists in the project' => '', - // 'Default filters' => '', - // 'Your board doesn\'t have any column!' => '', - // 'Change column position' => '', - // 'Switch to the project overview' => '', - // 'User filters' => '', - // 'Category filters' => '', - // 'Upload a file' => '', - // 'There is no attachment at the moment.' => '', - // 'View file' => '', - // 'Last activity' => '', - // 'Change subtask position' => '', - // 'This value must be greater than %d' => '', - // 'Another swimlane with the same name exists in the project' => '', - // 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => '', + 'Column created successfully.' => 'Столбец успешно создан', + 'Another column with the same name exists in the project' => 'Столбец с таким именем уже существует в этом проекте', + 'Default filters' => 'Стандартные фильтры', + 'Your board doesn\'t have any column!' => 'Ваша доска не имеет ни одного столбца!', + 'Change column position' => 'Смена позиции столбца', + 'Switch to the project overview' => 'Переключение на обзор проекта', + 'User filters' => 'Фильтры по пользователям', + 'Category filters' => 'Фильтры по категориям', + 'Upload a file' => 'Загрузить файл', + 'View file' => 'Просмотр файла', + 'Last activity' => 'Последняя активность', + 'Change subtask position' => 'Смена позиции подзадачи', + 'This value must be greater than %d' => 'Это значение должно быть больше чем %d', + 'Another swimlane with the same name exists in the project' => 'Другая дорожка с таким же именем уже существует в этом проекте', + 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => 'Пример: http://example.kanboard.net/ (используется для генерации абсолютных URLs)', + 'Actions duplicated successfully.' => 'Дублирование действий прошло успешно', + 'Unable to duplicate actions.' => 'Дублирование действий закончилось неудачно', + 'Add a new action' => 'Добавить новое действие', + 'Import from another project' => 'Импорт из другого проекта', + 'There is no action at the moment.' => 'Действия на данный момент отсутствуют', + 'Import actions from another project' => 'Импорт действий из другого проекта', + 'There is no available project.' => 'Нет доступного проекта', + 'Local File' => 'Локальный файл', + 'Configuration' => 'Конфигурация', + 'PHP version:' => 'Версия PHP:', + 'PHP SAPI:' => 'PHP SAPI:', + 'OS version:' => 'Версия ОС:', + 'Database version:' => 'Версия БД:', + 'Browser:' => 'Браузер:', + 'Task view' => 'Просмотр задачи', + 'Edit task' => 'Изменение задачи', + 'Edit description' => 'Изменение описания', + 'New internal link' => 'Новая внутренняя ссылка', + 'Display list of keyboard shortcuts' => 'Показать список клавиатурных сокращений', + 'Menu' => 'Меню', + 'Set start date' => 'Установить дату начала', + // 'Avatar' => '', + // 'Upload my avatar image' => '', + // 'Remove my image' => '', + // 'The OAuth2 state parameter is invalid' => '', ); diff --git a/sources/app/Locale/sr_Latn_RS/translations.php b/sources/app/Locale/sr_Latn_RS/translations.php index 3825ecd..c7070a8 100644 --- a/sources/app/Locale/sr_Latn_RS/translations.php +++ b/sources/app/Locale/sr_Latn_RS/translations.php @@ -8,7 +8,6 @@ return array( 'Edit' => 'Izmeni', 'remove' => 'ukloni', 'Remove' => 'Ukloni', - 'Update' => 'Ažuriraj', 'Yes' => 'Da', 'No' => 'Ne', 'cancel' => 'odustani', @@ -60,7 +59,6 @@ return array( 'Actions' => 'Akcje', 'Inactive' => 'Neaktivan', 'Active' => 'Aktivan', - 'Add this column' => 'Dodaj kolonu', '%d tasks on the board' => '%d zadataka na tabli', '%d tasks in total' => '%d zadataka ukupno', 'Unable to update this board.' => 'Nemogu da ažuriram ovu tablu.', @@ -74,7 +72,6 @@ return array( 'All projects' => 'Svi projekti', 'Add a new column' => 'Dodaj novu kolonu', 'Title' => 'Naslov', - 'Nobody assigned' => 'Niko nije dodeljen', 'Assigned to %s' => 'Dodeljen korisniku %s', 'Remove a column' => 'Ukloni kolonu', 'Remove a column from a board' => 'Ukloni kolonu sa table', @@ -168,7 +165,6 @@ return array( 'Task count' => 'Broj zadataka', 'User' => 'Korisnik', 'Comments' => 'Komentari', - 'Write your text in Markdown' => 'Pisanje teksta pomoću Markdown', 'Leave a comment' => 'Ostavi komentar', 'Comment is required' => 'Komentar je obavezan', 'Leave a description' => 'Dodaj opis', @@ -184,7 +180,6 @@ return array( 'Unable to remove this action.' => 'Nije moguće obrisati akciju', 'Action removed successfully.' => 'Akcija obrisana', 'Automatic actions for the project "%s"' => 'Akcje za automatizaciju projekta "%s"', - 'Defined actions' => 'Definisane akcje', 'Add an action' => 'dodaj akcju', 'Event name' => 'Naziv događaja', 'Action name' => 'Naziv akcije', @@ -194,7 +189,6 @@ return array( 'When the selected event occurs execute the corresponding action.' => 'Kad se događaj desi izvrši odgovarajuću akciju', 'Next step' => 'Sledeći korak', 'Define action parameters' => 'Definiši parametre akcije', - 'Save this action' => 'Snimi akciju', 'Do you really want to remove this action: "%s"?' => 'Da li da obrišem akciju "%s"?', 'Remove an automatic action' => 'Obriši automatsku akciju', 'Assign the task to a specific user' => 'Dodeli zadatak određenom korisniku', @@ -333,10 +327,10 @@ return array( 'Time tracking:' => 'Praćenje vremena: ', 'New sub-task' => 'Novi Pod-zadatak', 'New attachment added "%s"' => 'Novi prilog ubačen "%s"', - 'Comment updated' => 'Komentar izmenjen', 'New comment posted by %s' => 'Novi komentar ostavio %s', // 'New attachment' => '', // 'New comment' => '', + 'Comment updated' => 'Komentar izmenjen', // 'New subtask' => '', // 'Subtask updated' => '', // 'Task updated' => '', @@ -436,7 +430,6 @@ return array( 'ISO format is always accepted, example: "%s" and "%s"' => 'Format ISO je uvek prihvatljiv, primer: "%s", "%s"', 'New private project' => 'Novi privatni projekat', 'This project is private' => 'Ovaj projekat je privatan', - 'Type here to create a new sub-task' => 'Kucaj ovde za kreiranje novog pod-zadatka', 'Add' => 'Dodaj', 'Start date' => 'Datum početka', 'Time estimated' => 'Procenjeno vreme', @@ -487,9 +480,6 @@ return array( 'Daily project summary export for "%s"' => 'Izvoz zbirnig pregleda po danima za "%s"', 'Exports' => 'Izvoz', // 'This export contains the number of tasks per column grouped per day.' => '', - 'Nothing to preview...' => 'Ništa za prikazivanje...', - 'Preview' => 'Pregled', - 'Write' => 'Piši', 'Active swimlanes' => 'Aktivni razdelnik', 'Add a new swimlane' => 'Dodaj razdelnik', 'Change default swimlane' => 'Zameni osnovni razdelnik', @@ -543,7 +533,6 @@ return array( // 'Task age in days' => '', // 'Days in this column' => '', // '%dd' => '', - 'Add a link' => 'Dodaj 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?' => '', @@ -734,7 +723,7 @@ return array( // 'Time spent changed: %sh' => '', // 'Time estimated changed: %sh' => '', // 'The field "%s" have been updated' => '', - // 'The description have been modified' => '', + // 'The description has been modified:' => '', // 'Do you really want to close the task "%s" as well as all subtasks?' => '', // 'I want to receive notifications for:' => '', // 'All tasks' => '', @@ -753,8 +742,6 @@ return array( // 'My activity stream' => '', // 'My calendar' => '', // 'Search tasks' => '', - // 'Back to the calendar' => '', - // 'Filters' => '', // 'Reset filters' => '', // 'My tasks due tomorrow' => '', // 'Tasks due today' => '', @@ -854,7 +841,6 @@ return array( // 'End date:' => '', // 'There is no start date or end date for this project.' => '', // 'Projects Gantt chart' => '', - // 'Link type' => '', // 'Change task color when using a specific task link' => '', // 'Task link creation or modification' => '', // 'Milestone' => '', @@ -906,7 +892,6 @@ return array( // 'Shared' => '', // 'Owner' => '', // 'Unread notifications' => '', - // 'My filters' => '', // 'Notification methods:' => '', // 'Import tasks from CSV file' => '', // 'Unable to read your file' => '', @@ -944,6 +929,7 @@ return array( // 'Usernames must be lowercase and unique' => '', // 'Passwords will be encrypted if present' => '', // '%s attached a new file to the task %s' => '', + // 'Link type' => '', // 'Assign automatically a category based on a link' => '', // 'BAM - Konvertible Mark' => '', // 'Assignee Username' => '', @@ -1053,7 +1039,6 @@ return array( // 'Close a task when there is no activity' => '', // 'Duration in days' => '', // 'Send email when there is no activity on a task' => '', - // 'List of external links' => '', // 'Unable to fetch link information.' => '', // 'Daily background job for tasks' => '', // 'Auto' => '', @@ -1071,9 +1056,7 @@ return array( // 'External link' => '', // 'Copy and paste your link here...' => '', // 'URL' => '', - // 'There is no external link for the moment.' => '', // 'Internal links' => '', - // 'There is no internal link for the moment.' => '', // 'Assign to me' => '', // 'Me' => '', // 'Do not duplicate anything' => '', @@ -1081,7 +1064,6 @@ return array( // 'Users management' => '', // 'Groups management' => '', // 'Create from another project' => '', - // 'There is no subtask at the moment.' => '', // 'open' => '', // 'closed' => '', // 'Priority:' => '', @@ -1100,7 +1082,6 @@ return array( // 'Started:' => '', // 'Moved:' => '', // 'Task #%d' => '', - // 'Sub-tasks' => '', // 'Date and time format' => '', // 'Time format' => '', // 'Start date: ' => '', @@ -1141,11 +1122,35 @@ return array( // 'User filters' => '', // 'Category filters' => '', // 'Upload a file' => '', - // 'There is no attachment at the moment.' => '', // 'View file' => '', // 'Last activity' => '', // 'Change subtask position' => '', // 'This value must be greater than %d' => '', // 'Another swimlane with the same name exists in the project' => '', // 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => '', + // 'Actions duplicated successfully.' => '', + // 'Unable to duplicate actions.' => '', + // 'Add a new action' => '', + // 'Import from another project' => '', + // 'There is no action at the moment.' => '', + // 'Import actions from another project' => '', + // 'There is no available project.' => '', + // 'Local File' => '', + // 'Configuration' => '', + // 'PHP version:' => '', + // 'PHP SAPI:' => '', + // 'OS version:' => '', + // 'Database version:' => '', + // 'Browser:' => '', + // 'Task view' => '', + // 'Edit task' => '', + // 'Edit description' => '', + // 'New internal link' => '', + // 'Display list of keyboard shortcuts' => '', + // 'Menu' => '', + // 'Set start date' => '', + // 'Avatar' => '', + // 'Upload my avatar image' => '', + // 'Remove my image' => '', + // 'The OAuth2 state parameter is invalid' => '', ); diff --git a/sources/app/Locale/sv_SE/translations.php b/sources/app/Locale/sv_SE/translations.php index 96a28b2..e4728d2 100644 --- a/sources/app/Locale/sv_SE/translations.php +++ b/sources/app/Locale/sv_SE/translations.php @@ -8,7 +8,6 @@ return array( 'Edit' => 'Redigera', 'remove' => 'ta bort', 'Remove' => 'Ta bort', - 'Update' => 'Uppdatera', 'Yes' => 'Ja', 'No' => 'Nej', 'cancel' => 'avbryt', @@ -60,7 +59,6 @@ return array( 'Actions' => 'Åtgärder', 'Inactive' => 'Inaktiv', 'Active' => 'Aktiv', - 'Add this column' => 'Lägg till kolumnen', '%d tasks on the board' => '%d uppgifter på tavlan', '%d tasks in total' => '%d uppgifter totalt', 'Unable to update this board.' => 'Kunde inte uppdatera tavlan', @@ -74,7 +72,6 @@ return array( 'All projects' => 'Alla projekt', 'Add a new column' => 'Lägg till ny kolumn', 'Title' => 'Titel', - 'Nobody assigned' => 'Ingen tilldelad', 'Assigned to %s' => 'Tilldelad %s', 'Remove a column' => 'Ta bort en kolumn', 'Remove a column from a board' => 'Ta bort en kolumn från tavlan', @@ -168,7 +165,6 @@ return array( 'Task count' => 'Antal uppgifter', 'User' => 'Användare', 'Comments' => 'Kommentarer', - 'Write your text in Markdown' => 'Exempelsyntax för text', 'Leave a comment' => 'Lämna en kommentar', 'Comment is required' => 'En kommentar måste lämnas', 'Leave a description' => 'Lämna en beskrivning', @@ -184,7 +180,6 @@ return array( 'Unable to remove this action.' => 'Kunde inte ta bort denna åtgärd.', 'Action removed successfully.' => 'Åtgärden har tagits bort.', 'Automatic actions for the project "%s"' => 'Automatiska åtgärder för projektet "%s"', - 'Defined actions' => 'Definierade åtgärder', 'Add an action' => 'Lägg till en åtgärd', 'Event name' => 'Händelsenamn', 'Action name' => 'Åtgärdsnamn', @@ -194,7 +189,6 @@ return array( 'When the selected event occurs execute the corresponding action.' => 'När händelsen inträffar, kör inställd åtgärd.', 'Next step' => 'Nästa steg', 'Define action parameters' => 'Definiera upp händelseparametrar', - 'Save this action' => 'Spara denna åtgärd', 'Do you really want to remove this action: "%s"?' => 'Vill du verkligen ta bort denna åtgärd: "%s"?', 'Remove an automatic action' => 'Ta bort en automatiskt åtgärd', 'Assign the task to a specific user' => 'Tilldela uppgiften till en specifik användare', @@ -333,10 +327,10 @@ return array( 'Time tracking:' => 'Tidsspårning', 'New sub-task' => 'Ny deluppgift', 'New attachment added "%s"' => 'Ny bifogning tillagd "%s"', - 'Comment updated' => 'Kommentaren har uppdaterats', 'New comment posted by %s' => 'Ny kommentar postad av %s', 'New attachment' => 'Ny bifogning', 'New comment' => 'Ny kommentar', + 'Comment updated' => 'Kommentaren har uppdaterats', 'New subtask' => 'Ny deluppgift', 'Subtask updated' => 'Deluppgiften har uppdaterats', 'Task updated' => 'Uppgiften har uppdaterats', @@ -436,7 +430,6 @@ return array( 'ISO format is always accepted, example: "%s" and "%s"' => 'ISO-format är alltid tillåtet, exempel: "%s" och "%s"', 'New private project' => 'Nytt privat projekt', 'This project is private' => 'Det här projektet är privat', - 'Type here to create a new sub-task' => 'Skriv här för att skapa en ny deluppgift', 'Add' => 'Lägg till', 'Start date' => 'Startdatum', 'Time estimated' => 'Uppskattad tid', @@ -487,9 +480,6 @@ return array( 'Daily project summary export for "%s"' => 'Export av daglig projektsummering för "%s"', 'Exports' => 'Exporter', 'This export contains the number of tasks per column grouped per day.' => 'Denna export innehåller antalet uppgifter per kolumn grupperade per dag.', - 'Nothing to preview...' => 'Inget att förhandsgrandska...', - 'Preview' => 'Förhandsgranska', - 'Write' => 'Skriva', 'Active swimlanes' => 'Aktiva swimlanes', 'Add a new swimlane' => 'Lägg till en nytt swimlane', 'Change default swimlane' => 'Ändra standard swimlane', @@ -543,7 +533,6 @@ return array( '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?', @@ -734,7 +723,7 @@ return array( 'Time spent changed: %sh' => 'Spenderad tid har ändrats: %sh', 'Time estimated changed: %sh' => 'Tidsuppskattning ändrad: %sh', 'The field "%s" have been updated' => 'Fältet "%s" har uppdaterats', - 'The description have been modified' => 'Beskrivningen har modifierats', + 'The description has been modified:' => 'Beskrivningen har modifierats', 'Do you really want to close the task "%s" as well as all subtasks?' => 'Vill du verkligen stänga uppgiften "%s" och alla deluppgifter?', 'I want to receive notifications for:' => 'Jag vill få notiser för:', 'All tasks' => 'Alla uppgifter', @@ -753,8 +742,6 @@ return array( 'My activity stream' => 'Min aktivitetsström', 'My calendar' => 'Min kalender', 'Search tasks' => 'Sök uppgifter', - 'Back to the calendar' => 'Tillbaka till kalendern', - 'Filters' => 'Filter', 'Reset filters' => 'Återställ filter', 'My tasks due tomorrow' => 'Mina uppgifter förfaller imorgon', 'Tasks due today' => 'Uppgifter förfaller idag', @@ -854,7 +841,6 @@ return array( // 'End date:' => '', // 'There is no start date or end date for this project.' => '', // 'Projects Gantt chart' => '', - // 'Link type' => '', // 'Change task color when using a specific task link' => '', // 'Task link creation or modification' => '', // 'Milestone' => '', @@ -906,7 +892,6 @@ return array( // 'Shared' => '', // 'Owner' => '', // 'Unread notifications' => '', - // 'My filters' => '', // 'Notification methods:' => '', // 'Import tasks from CSV file' => '', // 'Unable to read your file' => '', @@ -944,6 +929,7 @@ return array( // 'Usernames must be lowercase and unique' => '', // 'Passwords will be encrypted if present' => '', // '%s attached a new file to the task %s' => '', + // 'Link type' => '', // 'Assign automatically a category based on a link' => '', // 'BAM - Konvertible Mark' => '', // 'Assignee Username' => '', @@ -1053,7 +1039,6 @@ return array( // 'Close a task when there is no activity' => '', // 'Duration in days' => '', // 'Send email when there is no activity on a task' => '', - // 'List of external links' => '', // 'Unable to fetch link information.' => '', // 'Daily background job for tasks' => '', // 'Auto' => '', @@ -1071,9 +1056,7 @@ return array( // 'External link' => '', // 'Copy and paste your link here...' => '', // 'URL' => '', - // 'There is no external link for the moment.' => '', // 'Internal links' => '', - // 'There is no internal link for the moment.' => '', // 'Assign to me' => '', // 'Me' => '', // 'Do not duplicate anything' => '', @@ -1081,7 +1064,6 @@ return array( // 'Users management' => '', // 'Groups management' => '', // 'Create from another project' => '', - // 'There is no subtask at the moment.' => '', // 'open' => '', // 'closed' => '', // 'Priority:' => '', @@ -1100,7 +1082,6 @@ return array( // 'Started:' => '', // 'Moved:' => '', // 'Task #%d' => '', - // 'Sub-tasks' => '', // 'Date and time format' => '', // 'Time format' => '', // 'Start date: ' => '', @@ -1141,11 +1122,35 @@ return array( // 'User filters' => '', // 'Category filters' => '', // 'Upload a file' => '', - // 'There is no attachment at the moment.' => '', // 'View file' => '', // 'Last activity' => '', // 'Change subtask position' => '', // 'This value must be greater than %d' => '', // 'Another swimlane with the same name exists in the project' => '', // 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => '', + // 'Actions duplicated successfully.' => '', + // 'Unable to duplicate actions.' => '', + // 'Add a new action' => '', + // 'Import from another project' => '', + // 'There is no action at the moment.' => '', + // 'Import actions from another project' => '', + // 'There is no available project.' => '', + // 'Local File' => '', + // 'Configuration' => '', + // 'PHP version:' => '', + // 'PHP SAPI:' => '', + // 'OS version:' => '', + // 'Database version:' => '', + // 'Browser:' => '', + // 'Task view' => '', + // 'Edit task' => '', + // 'Edit description' => '', + // 'New internal link' => '', + // 'Display list of keyboard shortcuts' => '', + // 'Menu' => '', + // 'Set start date' => '', + // 'Avatar' => '', + // 'Upload my avatar image' => '', + // 'Remove my image' => '', + // 'The OAuth2 state parameter is invalid' => '', ); diff --git a/sources/app/Locale/th_TH/translations.php b/sources/app/Locale/th_TH/translations.php index f26ee30..1e2fb98 100644 --- a/sources/app/Locale/th_TH/translations.php +++ b/sources/app/Locale/th_TH/translations.php @@ -8,7 +8,6 @@ return array( 'Edit' => 'แก้ไข', 'remove' => 'ลบ', 'Remove' => 'ลบ', - 'Update' => 'ปรับปรุง', 'Yes' => 'ใช่', 'No' => 'ไม่', 'cancel' => 'ยกเลิก', @@ -20,15 +19,15 @@ return array( 'Red' => 'สีแดง', 'Orange' => 'สีส้ม', 'Grey' => 'สีเทา', - 'Brown' => 'สีน้ำตาล', - 'Deep Orange' => 'สีส้มเข้ม', - 'Dark Grey' => 'สีเทาเข้ม', - 'Pink' => 'สีชมพู', - 'Teal' => 'สีเขียวหัวเป็ด', + 'Brown' => 'สีน้ำตาล', + 'Deep Orange' => 'สีส้มเข้ม', + 'Dark Grey' => 'สีเทาเข้ม', + 'Pink' => 'สีชมพู', + 'Teal' => 'สีเขียวหัวเป็ด', 'Cyan' => 'สีฟ้า', - 'Lime' => 'สีมะนาว', - 'Light Green' => 'สีเขียวสว่าง', - 'Amber' => 'สีเหลืองอำพัน', + 'Lime' => 'สีมะนาว', + 'Light Green' => 'สีเขียวสว่าง', + 'Amber' => 'สีเหลืองอำพัน', 'Save' => 'บันทึก', 'Login' => 'เข้าสู่ระบบ', 'Official website:' => 'เวบไซต์อย่างเป็นทางการ:', @@ -60,7 +59,6 @@ return array( 'Actions' => 'การกระทำ', 'Inactive' => 'ไม่เปิดใช้งาน', 'Active' => 'เปิดใช้งาน', - 'Add this column' => 'เพิ่มคอลัมน์', '%d tasks on the board' => '%d งานบนบอร์ด', '%d tasks in total' => '%d งานทั้งหมด', 'Unable to update this board.' => 'ไม่สามารถปรับปรุงบอร์ดได้.', @@ -72,10 +70,8 @@ return array( 'Remove project' => 'ลบโปรเจค', 'Edit the board for "%s"' => 'แก้ไขบอร์ดสำหรับ « %s »', 'All projects' => 'โปรเจคทั้งหมด', - 'Change columns' => 'เปลี่ยนคอลัมน์', 'Add a new column' => 'เพิ่มคอลัมน์ใหม่', 'Title' => 'หัวเรื่อง', - 'Nobody assigned' => 'ไม่กำหนดใคร', 'Assigned to %s' => 'กำหนดให้ %s', 'Remove a column' => 'ลบคอลัมน์', 'Remove a column from a board' => 'ลบคอลัมน์ออกจากบอร์ด', @@ -169,7 +165,6 @@ return array( 'Task count' => 'นับงาน', 'User' => 'ผู้ใช้', 'Comments' => 'ความคิดเห็น', - 'Write your text in Markdown' => 'เขียนข้อความในรูปแบบ Markdown', 'Leave a comment' => 'ออกความคิดเห็น', 'Comment is required' => 'ต้องการความคิดเห็น', 'Leave a description' => 'แสดงคำอธิบาย', @@ -185,7 +180,6 @@ return array( 'Unable to remove this action.' => 'ไม่สามารถลบการกระทำ', 'Action removed successfully.' => 'ลบการกระทำเรียบร้อยแล้ว', 'Automatic actions for the project "%s"' => 'การกระทำอัตโนมัติสำหรับโปรเจค « %s »', - 'Defined actions' => 'กำหนดการกระทำ', 'Add an action' => 'เพิ่มการกระทำ', 'Event name' => 'ชื่อเหตุกาณ์', 'Action name' => 'ชื่อการกระทำ', @@ -195,7 +189,6 @@ return array( 'When the selected event occurs execute the corresponding action.' => 'เหตุการ์ที่เลือกจะเกิดขึ้นเมื่อมีการกระทำที่สอดคล้องกัน', 'Next step' => 'ขั้นตอนต่อไป', 'Define action parameters' => 'กำหนดพารามิเตอร์ของการกระทำ', - 'Save this action' => 'บันทึกการกระทำนี้', 'Do you really want to remove this action: "%s"?' => 'คุณต้องการลบการกระทำ « %s » ใช่หรือไม่?', 'Remove an automatic action' => 'ลบการกระทำอัตโนมัติ', 'Assign the task to a specific user' => 'กำหนดงานให้ผู้ใช้แบบเจาะจง', @@ -208,8 +201,6 @@ return array( 'Assign a color to a specific user' => 'กำหนดสีให้ผู้ใช้แบบเจาะจง', 'Column title' => 'หัวเรื่องคอลัมน์', 'Position' => 'ตำแหน่ง', - 'Move Up' => 'ย้ายขึ้น', - 'Move Down' => 'ย้ายลง', 'Duplicate to another project' => 'ทำซ้ำในโปรเจคอื่น', 'Duplicate' => 'ทำซ้ำ', 'link' => 'ลิงค์', @@ -245,9 +236,9 @@ return array( '%d comment' => '%d ความคิดเห็น', 'Email address invalid' => 'อีเมลผิด', 'Your external account is not linked anymore to your profile.' => 'บัญชีภายนอกของคุณไม่ได้เชื่อมโยงอีกต่อไปในโปรไฟล์ของคุณ', - 'Unable to unlink your external account.' => 'ไม่สามารถยกเลิกการเชื่อมโยงบัญชีภายนอกของคุณ', - 'External authentication failed' => 'การตรวจสอบภายนอกล้มเหลว', - 'Your external account is linked to your profile successfully.' => 'บัญชีภายนอกของคุณลิงค์กับโปรไฟล์ของคุณเรียบร้อย', + 'Unable to unlink your external account.' => 'ไม่สามารถยกเลิกการเชื่อมโยงบัญชีภายนอกของคุณ', + 'External authentication failed' => 'การตรวจสอบภายนอกล้มเหลว', + 'Your external account is linked to your profile successfully.' => 'บัญชีภายนอกของคุณลิงค์กับโปรไฟล์ของคุณเรียบร้อย', 'Email' => 'อีเมล', 'Task removed successfully.' => 'ลบงานเรียบร้อยแล้ว', 'Unable to remove this task.' => 'ไม่สามารถลบงานนี้', @@ -295,7 +286,7 @@ return array( 'estimated' => 'ประมาณ', 'Sub-Tasks' => 'งานย่อย', 'Add a sub-task' => 'เพิ่มงานย่อย', - 'Original estimate' => 'ประมาณการเดิม', + 'Original estimate' => 'ประมาณการเดิม', 'Create another sub-task' => 'สร้างงานย่อยอื่น', 'Time spent' => 'ใช้เวลา', 'Edit a sub-task' => 'แก้ไขงานย่อย', @@ -336,10 +327,10 @@ return array( 'Time tracking:' => 'การติดตามเวลา:', 'New sub-task' => 'งานย่อยใหม่', 'New attachment added "%s"' => 'เพิ่มการแนบใหม่ "%s"', - 'Comment updated' => 'ปรับปรุงความคิดเห็น', 'New comment posted by %s' => 'ความคิดเห็นใหม่จาก %s', 'New attachment' => 'การแนบใหม่', 'New comment' => 'ความคิดเห็นใหม่', + 'Comment updated' => 'ปรับปรุงความคิดเห็น', 'New subtask' => 'งานย่อยใหม่', 'Subtask updated' => 'ปรับปรุงงานย่อยแล้ว', 'Task updated' => 'ปรับปรุงงานแล้ว', @@ -409,14 +400,14 @@ return array( 'Default values are "%s"' => 'ค่าเริ่มต้น "%s"', 'Default columns for new projects (Comma-separated)' => 'คอลัมน์เริ่มต้นสำหรับโปรเจคใหม่ (Comma-separated)', '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', + '%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', 'New password for the user "%s"' => 'รหัสผ่านใหม่สำหรับผู้ใช้ "%s"', 'Choose an event' => 'เลือกเหตุการณ์', - 'Create a task from an external provider' => 'สร้างงานจากบริการภายนอก', - 'Change the assignee based on an external username' => 'เปลี่ยนผู้รับผิดชอบขึ้นอยู่กับชื่อผู้ใช้ภายนอก', - 'Change the category based on an external label' => 'เปลี่ยนหมวดขึ้นอยู่กับป้ายชื่อภายนอก', - 'Reference' => 'อ้างถึง', + 'Create a task from an external provider' => 'สร้างงานจากบริการภายนอก', + 'Change the assignee based on an external username' => 'เปลี่ยนผู้รับผิดชอบขึ้นอยู่กับชื่อผู้ใช้ภายนอก', + 'Change the category based on an external label' => 'เปลี่ยนหมวดขึ้นอยู่กับป้ายชื่อภายนอก', + 'Reference' => 'อ้างถึง', 'Label' => 'ป้ายชื่อ', 'Database' => 'ฐานข้อมูล', 'About' => 'เกี่ยวกับ', @@ -436,10 +427,9 @@ return array( // 'Application URL' => '', // 'Token regenerated.' => '', 'Date format' => 'รูปแบบวันที่', - 'ISO format is always accepted, example: "%s" and "%s"' => 'ยอมรับรูปแบบ ISO ตัวอย่าง: "%s" และ "%s"', + 'ISO format is always accepted, example: "%s" and "%s"' => 'ยอมรับรูปแบบ ISO ตัวอย่าง: "%s" และ "%s"', 'New private project' => 'เพิ่มโปรเจคส่วนตัวใหม่', 'This project is private' => 'โปรเจคนี้เป็นโปรเจคส่วนตัว', - 'Type here to create a new sub-task' => 'พิมพ์ที่นี้เพื่อสร้างงานย่อยใหม่', 'Add' => 'เพิ่ม', 'Start date' => 'เริ่มวันที่', 'Time estimated' => 'เวลาโดยประมาณ', @@ -452,7 +442,7 @@ return array( 'Everybody have access to this project.' => 'ทุกคนสามารถเข้าถึงโปรเจคนี้', // 'Webhooks' => '', // 'API' => '', - 'Create a comment from an external provider' => 'สร้างความคิดเห็นจากบริการภายนอก', + 'Create a comment from an external provider' => 'สร้างความคิดเห็นจากบริการภายนอก', 'Project management' => 'การจัดการโปรเจค', 'My projects' => 'โปรเจคของฉัน', 'Columns' => 'คอลัมน์', @@ -490,9 +480,6 @@ return array( 'Daily project summary export for "%s"' => 'ส่งออกสรุปโปรเจครายวันสำหรับ "%s"', 'Exports' => 'ส่งออก', 'This export contains the number of tasks per column grouped per day.' => 'การส่งออกนี้เป็นการนับจำนวนงานในแต่ละคอลัมน์ในแต่ละวัน', - 'Nothing to preview...' => 'ไม่มีพรีวิว...', - 'Preview' => 'พรีวิว', - 'Write' => 'เขียน', 'Active swimlanes' => 'สวิมเลนพร้อมใช้งาน', 'Add a new swimlane' => 'เพิ่มสวิมเลนใหม่', 'Change default swimlane' => 'เปลี่ยนสวิมเลนเริ่มต้น', @@ -500,7 +487,6 @@ return array( 'Do you really want to remove this swimlane: "%s"?' => 'คุณต้องการลบสวิมเลนนี้ : "%s"?', 'Inactive swimlanes' => 'สวิมเลนไม่ทำงาน', 'Remove a swimlane' => 'ลบสวิมเลน', - 'Rename' => 'เปลี่ยนชื่อ', 'Show default swimlane' => 'แสดงสวิมเลนเริ่มต้น', 'Swimlane modification for the project "%s"' => 'แก้ไขสวิมเลนสำหรับโปรเจค "%s"', 'Swimlane not found.' => 'หาสวิมเลนไม่พบ', @@ -508,7 +494,6 @@ return array( 'Swimlanes' => 'สวิมเลน', 'Swimlane updated successfully.' => 'ปรับปรุงสวิมเลนเรียบร้อยแล้ว', 'The default swimlane have been updated successfully.' => 'สวิมเลนเริ่มต้นปรับปรุงเรียบร้อยแล้ว', - 'Unable to create your swimlane.' => 'ไม่สามารถสร้างสวิมเลนของคุณได้', 'Unable to remove this swimlane.' => 'ไม่สามารถลบสวิมเลนนี้', 'Unable to update this swimlane.' => 'ไม่สามารถปรับปรุงสวิมเลนนี้', 'Your swimlane have been created successfully.' => 'สวิมเลนของคุณถูกสร้างเรียบร้อยแล้ว', @@ -528,7 +513,7 @@ return array( 'All columns' => 'คอลัมน์ทั้งหมด', 'Calendar' => 'ปฏิทิน', 'Next' => 'ต่อไป', - '#%d' => '#%d', + '#%d' => '#%d', 'All swimlanes' => 'สวิมเลนทั้งหมด', 'All colors' => 'สีทั้งหมด', 'Moved to column %s' => 'เคลื่อนไปคอลัมน์ %s', @@ -541,17 +526,16 @@ return array( 'There is nothing to show.' => 'ไม่มีที่ต้องแสดง', 'Time Tracking' => 'ติดตามเวลา', 'You already have one subtask in progress' => 'คุณมีหนึ่งงานย่อยที่กำลังทำงาน', - 'Which parts of the project do you want to duplicate?' => 'เลือกส่วนของโปรเจคที่คุณต้องการทำซ้ำ?', - 'Disallow login form' => 'ไม่อนุญาตให้ใช้แบบฟอร์มการเข้าสู่ระบบ', + 'Which parts of the project do you want to duplicate?' => 'เลือกส่วนของโปรเจคที่คุณต้องการทำซ้ำ?', + 'Disallow login form' => 'ไม่อนุญาตให้ใช้แบบฟอร์มการเข้าสู่ระบบ', 'Start' => 'เริ่ม', 'End' => 'จบ', 'Task age in days' => 'อายุงาน', 'Days in this column' => 'วันในคอลัมน์นี้', - '%dd' => '%d วัน', - 'Add a link' => 'เพิ่มลิงค์', + '%dd' => '%d วัน', '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?', + 'Do you really want to remove this link with task #%d?' => 'คุณต้องการลบลิงค์นี้ของงาน #%d?', 'Field required' => 'ต้องใส่', 'Link added successfully.' => 'เพิ่มลิงค์เรียบร้อยแล้ว', 'Link updated successfully.' => 'ปรับปรุงลิงค์เรียบร้อยแล้ว', @@ -581,8 +565,8 @@ return array( 'fixes' => 'เจาะจง', 'is fixed by' => 'ถูกเจาะจงด้วย', 'This task' => 'งานนี้', - '<1h' => '<1 ชม.', - '%dh' => '%d ชม.', + '<1h' => '<1 ชม.', + '%dh' => '%d ชม.', 'Expand tasks' => 'ขยายงาน', 'Collapse tasks' => 'ย่องาน', 'Expand/collapse tasks' => 'ขยาย/ย่อ งาน', @@ -597,21 +581,19 @@ return array( 'Compact/wide view' => 'พอดี/กว้าง มุมมอง', 'No results match:' => 'ไม่มีผลลัพท์ที่ตรง', 'Currency' => 'สกุลเงิน', - 'Files' => 'ไฟล์', - 'Images' => 'รูปภาพ', 'Private project' => 'โปรเจคส่วนตัว', - 'AUD - Australian Dollar' => 'AUD - ดอลลาร์ออสเตรเลีย', - 'CAD - Canadian Dollar' => 'CAD - ดอลลาร์แคนาดา', - 'CHF - Swiss Francs' => 'CHF - ฟรังก์สวิส', - 'Custom Stylesheet' => 'สไตล์ที่กำหนดเอง', + 'AUD - Australian Dollar' => 'AUD - ดอลลาร์ออสเตรเลีย', + 'CAD - Canadian Dollar' => 'CAD - ดอลลาร์แคนาดา', + 'CHF - Swiss Francs' => 'CHF - ฟรังก์สวิส', + 'Custom Stylesheet' => 'สไตล์ที่กำหนดเอง', 'download' => 'ดาวน์โหลด', - 'EUR - Euro' => 'EUR - ยูโร', - 'GBP - British Pound' => 'GBP - ปอนด์อังกฤษ', - 'INR - Indian Rupee' => 'INR - รูปี', - 'JPY - Japanese Yen' => 'JPY - เยน', - 'NZD - New Zealand Dollar' => 'NZD - ดอลลาร์นิวซีแลนด์', - 'RSD - Serbian dinar' => 'RSD - ดีนาร์เซอร์เบีย', - 'USD - US Dollar' => 'USD - ดอลลาร์สหรัฐ', + 'EUR - Euro' => 'EUR - ยูโร', + 'GBP - British Pound' => 'GBP - ปอนด์อังกฤษ', + 'INR - Indian Rupee' => 'INR - รูปี', + 'JPY - Japanese Yen' => 'JPY - เยน', + 'NZD - New Zealand Dollar' => 'NZD - ดอลลาร์นิวซีแลนด์', + 'RSD - Serbian dinar' => 'RSD - ดีนาร์เซอร์เบีย', + 'USD - US Dollar' => 'USD - ดอลลาร์สหรัฐ', 'Destination column' => 'คอลัมน์เป้าหมาย', 'Move the task to another column when assigned to a user' => 'ย้ายงานไปคอลัมน์อื่นเมื่อกำหนดบุคคลรับผิดชอบ', 'Move the task to another column when assignee is cleared' => 'ย้ายงานไปคอลัมน์อื่นเมื่อไม่กำหนดบุคคลรับผิดชอบ', @@ -621,16 +603,16 @@ return array( 'Time spent in the column' => 'เวลาที่ใช้ในคอลัมน์', 'Task transitions' => 'การเปลี่ยนคอลัมน์งาน', 'Task transitions export' => 'ส่งออกการเปลี่ยนคอลัมน์งาน', - 'This report contains all column moves for each task with the date, the user and the time spent for each transition.' => 'รายงานนี้มีการเคลื่อนไหวคอลัมน์ทั้งหมดของงานแต่ละงานมีวันที่ผู้ใช้และเวลาที่ใช้สำหรับแต่ละการเปลี่ยนแปลง', + 'This report contains all column moves for each task with the date, the user and the time spent for each transition.' => 'รายงานนี้มีการเคลื่อนไหวคอลัมน์ทั้งหมดของงานแต่ละงานมีวันที่ผู้ใช้และเวลาที่ใช้สำหรับแต่ละการเปลี่ยนแปลง', 'Currency rates' => 'อัตราค่าเงิน', 'Rate' => 'อัตรา', - 'Change reference currency' => 'เปลี่ยนการอ้างถึงค่าเงิน', + 'Change reference currency' => 'เปลี่ยนการอ้างถึงค่าเงิน', 'Add a new currency rate' => 'เพิ่มอัตราค่าเงินใหม่', - 'Reference currency' => 'อ้างถึงค่าเงิน', - 'The currency rate have been added successfully.' => 'เพิ่มอัตราค่าเงินเรียบร้อย', - 'Unable to add this currency rate.' => 'ไม่สามารถเพิ่มค่าเงินนี้', + 'Reference currency' => 'อ้างถึงค่าเงิน', + 'The currency rate have been added successfully.' => 'เพิ่มอัตราค่าเงินเรียบร้อย', + 'Unable to add this currency rate.' => 'ไม่สามารถเพิ่มค่าเงินนี้', // 'Webhook URL' => '', - '%s remove the assignee of the task %s' => '%s เอาผู้รับผิดชอบออกจากงาน %s', + '%s remove the assignee of the task %s' => '%s เอาผู้รับผิดชอบออกจากงาน %s', 'Enable Gravatar images' => 'สามารถใช้งานภาพ Gravatar', 'Information' => 'ข้อมูลสารสนเทศ', // 'Check two factor authentication code' => '', @@ -644,46 +626,43 @@ return array( 'Test your device' => 'ทดสอบอุปกรณ์ของคุณ', 'Assign a color when the task is moved to a specific column' => 'กำหนดสีเมื่องานถูกย้ายไปคอลัมน์ที่กำหนดไว้', // '%s via Kanboard' => '', - 'uploaded by: %s' => 'อัพโหลดโดย: %s', - 'uploaded on: %s' => 'อัพโหลดบน: %s', - 'size: %s' => 'ขนาด: %s', 'Burndown chart for "%s"' => 'แผนภูมิงานกับเวลา "%s"', 'Burndown chart' => 'แผนภูมิงานกับเวลา', - 'This chart show the task complexity over the time (Work Remaining).' => 'แผนภูมิแสดงความซับซ้อนของงานตามเวลา (งานที่เหลือ)', - 'Screenshot taken %s' => 'จับภาพหน้าจอ %s', + 'This chart show the task complexity over the time (Work Remaining).' => 'แผนภูมิแสดงความซับซ้อนของงานตามเวลา (งานที่เหลือ)', + 'Screenshot taken %s' => 'จับภาพหน้าจอ %s', 'Add a screenshot' => 'เพิ่ม screenshot', - 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => 'จับภาพหน้าจอ (screenshot) และกด CTRL+V หรือ ⌘+V เพื่อวางที่นี้', + 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => 'จับภาพหน้าจอ (screenshot) และกด CTRL+V หรือ ⌘+V เพื่อวางที่นี้', 'Screenshot uploaded successfully.' => 'อัพโหลด screenshot เรียบร้อยแล้ว', - 'SEK - Swedish Krona' => 'SEK - โครนสวีเดน', - 'Identifier' => 'ตัวบ่งชี้', + 'SEK - Swedish Krona' => 'SEK - โครนสวีเดน', + 'Identifier' => 'ตัวบ่งชี้', // 'Disable two factor authentication' => '', - 'Do you really want to disable the two factor authentication for this user: "%s"?' => 'คุณต้องการยกเลิก the two factor authentication สำหรับผู้ใช้นีั: "%s"?', + 'Do you really want to disable the two factor authentication for this user: "%s"?' => 'คุณต้องการยกเลิก the two factor authentication สำหรับผู้ใช้นีั: "%s"?', 'Edit link' => 'แก้ไขลิงค์', 'Start to type task title...' => 'พิมพ์ชื่องาน', 'A task cannot be linked to itself' => 'งานไม่สามารถลิงค์ตัวเอง', // 'The exact same link already exists' => '', 'Recurrent task is scheduled to be generated' => 'งานแบบวนลูปถูกสร้างตามที่กำหนดไว้', 'Score' => 'คะแนน', - 'The identifier must be unique' => 'ตัวบ่งชี้ต้องไม่ซ้ำ', + 'The identifier must be unique' => 'ตัวบ่งชี้ต้องไม่ซ้ำ', // 'This linked task id doesn\'t exists' => '', 'This value must be alphanumeric' => 'ค่านี้ต้องเป็นตัวอักษร', 'Edit recurrence' => 'แก้ไขการวนลูป', 'Generate recurrent task' => 'สร้างงานที่เป็นวนลูป', 'Trigger to generate recurrent task' => 'จะสร้างงานแบบวนลูป', - 'Factor to calculate new due date' => 'ปัจจัยการคำนวณวันครบกำหนดใหม่', - 'Timeframe to calculate new due date' => 'ระยะเวลาการคำนวณวันครบกำหนดใหม่', - 'Base date to calculate new due date' => 'ฐานวันที่การคำนวณวันครบกำหนดใหม่', - 'Action date' => 'วันที่ทำ', - 'Base date to calculate new due date: ' => 'ฐานวันที่การคำนวณวันครบกำหนดใหม่: ', + 'Factor to calculate new due date' => 'ปัจจัยการคำนวณวันครบกำหนดใหม่', + 'Timeframe to calculate new due date' => 'ระยะเวลาการคำนวณวันครบกำหนดใหม่', + 'Base date to calculate new due date' => 'ฐานวันที่การคำนวณวันครบกำหนดใหม่', + 'Action date' => 'วันที่ทำ', + 'Base date to calculate new due date: ' => 'ฐานวันที่การคำนวณวันครบกำหนดใหม่: ', 'This task has created this child task: ' => 'งานนี้สร้างงานลูกคือ', 'Day(s)' => 'วัน', - 'Existing due date' => 'วันครบกำหนดที่มีอยู่', - 'Factor to calculate new due date: ' => 'ปัจจัยการคำนวณวันครบกำหนดใหม่: ', + 'Existing due date' => 'วันครบกำหนดที่มีอยู่', + 'Factor to calculate new due date: ' => 'ปัจจัยการคำนวณวันครบกำหนดใหม่: ', 'Month(s)' => 'เดือน', 'Recurrence' => 'วนลูป', 'This task has been created by: ' => 'งานนี้ถูกสร้างโดย', 'Recurrent task has been generated:' => 'งานแบบวนลูปถูกสร้าง', - 'Timeframe to calculate new due date: ' => 'ระยะเวลาการคำนวณวันครบกำหนดใหม่: ', + 'Timeframe to calculate new due date: ' => 'ระยะเวลาการคำนวณวันครบกำหนดใหม่: ', 'Trigger to generate recurrent task: ' => 'จะสร้างงานแบบวนลูป', 'When task is closed' => 'เมื่อปิดงาน', 'When task is moved from first column' => 'เมื่องานถูกย้ายจากคอลัมน์แรก', @@ -705,416 +684,473 @@ return array( // 'Two factor authentication enabled' => '', 'Unable to update this user.' => 'ไม่สามารถปรับปรุงผู้ใช้นี้', 'There is no user management for private projects.' => 'ไม่มีการจัดการผู้ใช้สำหรับโปรเจคส่วนตัว', - 'User that will receive the email' => 'ผู้ใช้จะได้รับอีเมล์', - 'Email subject' => 'หัวเรื่องอีเมล์', - 'Date' => 'วันที่', - 'Add a comment log when moving the task between columns' => 'เพิ่มล็อกความคิดเห็นเมื่อย้ายงานระหว่างคอลัมน์', - 'Move the task to another column when the category is changed' => 'ย้ายงานไปคอลัมน์อื่นเมื่อหมวดถูกเปลี่ยน', - 'Send a task by email to someone' => 'ส่งงานโดยถึงบางคน', - 'Reopen a task' => 'เปิดงานอีกครั้ง', + 'User that will receive the email' => 'ผู้ใช้จะได้รับอีเมล์', + 'Email subject' => 'หัวเรื่องอีเมล์', + 'Date' => 'วันที่', + 'Add a comment log when moving the task between columns' => 'เพิ่มล็อกความคิดเห็นเมื่อย้ายงานระหว่างคอลัมน์', + 'Move the task to another column when the category is changed' => 'ย้ายงานไปคอลัมน์อื่นเมื่อหมวดถูกเปลี่ยน', + 'Send a task by email to someone' => 'ส่งงานโดยถึงบางคน', + 'Reopen a task' => 'เปิดงานอีกครั้ง', 'Column change' => 'เปลี่ยนคอลัมน์', - 'Position change' => 'เปลี่ยนตำแหน่ง', - 'Swimlane change' => 'เปลี่ยนสวิมเลน', - 'Assignee change' => 'เปลี่ยนการผู้รับผิดชอบ', - '[%s] Overdue tasks' => '[%s] งานที่เกินกำหนด', - 'Notification' => 'แจ้งเตือน', - '%s moved the task #%d to the first swimlane' => '%s ย้ายงาน #%d ไปสวินเลนแรก', - '%s moved the task #%d to the swimlane "%s"' => '%s ย้ายงาน #%d ไปสวินเลน "%s"', - 'Swimlane' => 'สวิมเลน', - 'Gravatar' => 'รูปแทนตัว', - '%s moved the task %s to the first swimlane' => '%s ย้ายงาน %s ไปสวินเลนแรก', - '%s moved the task %s to the swimlane "%s"' => '%s ย้ายงาน %s ไปสวินเลนไปสวินเลน "%s"', - 'This report contains all subtasks information for the given date range.' => 'รายงานนี้มีข้อมูลงานย่อยทั้งหมดในช่วงวันที่กำหนด', - 'This report contains all tasks information for the given date range.' => 'รายงานนี้มีข้อมูลงานทั้งหมดสำหรับช่วงวันที่ที่กำหนด', - 'Project activities for %s' => 'กิจกรรมโปรเจคสำหรับ %s', - 'view the board on Kanboard' => 'แสดงบอร์ดบนคังบอร์ด', - 'The task have been moved to the first swimlane' => 'งานถูกย้านไปสวิมเลนแรก', - 'The task have been moved to another swimlane:' => 'งานถูกย้านไปสวิมเลนอื่น:', - 'Overdue tasks for the project "%s"' => 'งานที่เกินกำหนดสำหรับโปรเจค "%s"', - 'New title: %s' => 'ชื่อเรื่องใหม่: %s', - 'The task is not assigned anymore' => 'ไม่กำหนดผู้รับผิดชอบ', - 'New assignee: %s' => 'ผู้รับผิดชอบใหม่: %s', - 'There is no category now' => 'ปัจจุบันไม่มีหมวด', - 'New category: %s' => 'หมวดใหม่: %s', - 'New color: %s' => 'สีใหม่: %s', - 'New complexity: %d' => 'ความซับซ้อนใหม่: %d', - 'The due date have been removed' => 'วันครบกำหนดถูกลบ', - 'There is no description anymore' => 'ไม่มีคำอธิบาย', - 'Recurrence settings have been modified' => 'แก้ไขการตั้งค่าการวนลูป', - 'Time spent changed: %sh' => 'เวลาที่ใช้ในการเปลี่ยน: %s ชม.', - 'Time estimated changed: %sh' => 'เวลาโดยประมาณในการเปลี่ยน: %s ชม.', - 'The field "%s" have been updated' => 'ฟิลด์ "%s" ถูกปรับปรุง', - 'The description have been modified' => 'คำอธิบายถูกแก้ไข', - 'Do you really want to close the task "%s" as well as all subtasks?' => 'คุณต้องการปิดงาน "%s" เช่นเดียวกับงานย่อยทั้งหมด?', - 'I want to receive notifications for:' => 'ฉันต้องการรับการแจ้งเตือนสำหรับ:', - 'All tasks' => 'ทุกงาน', - 'Only for tasks assigned to me' => 'เฉพาะงานที่ฉันรับผิดชอบ', - 'Only for tasks created by me' => 'เฉพาะงานที่ฉันสร้าง', - 'Only for tasks created by me and assigned to me' => 'เฉพาะงานที่ฉันสร้างและฉันรับผิดชอบ', + 'Position change' => 'เปลี่ยนตำแหน่ง', + 'Swimlane change' => 'เปลี่ยนสวิมเลน', + 'Assignee change' => 'เปลี่ยนการผู้รับผิดชอบ', + '[%s] Overdue tasks' => '[%s] งานที่เกินกำหนด', + 'Notification' => 'แจ้งเตือน', + '%s moved the task #%d to the first swimlane' => '%s ย้ายงาน #%d ไปสวินเลนแรก', + '%s moved the task #%d to the swimlane "%s"' => '%s ย้ายงาน #%d ไปสวินเลน "%s"', + 'Swimlane' => 'สวิมเลน', + 'Gravatar' => 'รูปแทนตัว', + '%s moved the task %s to the first swimlane' => '%s ย้ายงาน %s ไปสวินเลนแรก', + '%s moved the task %s to the swimlane "%s"' => '%s ย้ายงาน %s ไปสวินเลนไปสวินเลน "%s"', + 'This report contains all subtasks information for the given date range.' => 'รายงานนี้มีข้อมูลงานย่อยทั้งหมดในช่วงวันที่กำหนด', + 'This report contains all tasks information for the given date range.' => 'รายงานนี้มีข้อมูลงานทั้งหมดสำหรับช่วงวันที่ที่กำหนด', + 'Project activities for %s' => 'กิจกรรมโปรเจคสำหรับ %s', + 'view the board on Kanboard' => 'แสดงบอร์ดบนคังบอร์ด', + 'The task have been moved to the first swimlane' => 'งานถูกย้านไปสวิมเลนแรก', + 'The task have been moved to another swimlane:' => 'งานถูกย้านไปสวิมเลนอื่น:', + 'Overdue tasks for the project "%s"' => 'งานที่เกินกำหนดสำหรับโปรเจค "%s"', + 'New title: %s' => 'ชื่อเรื่องใหม่: %s', + 'The task is not assigned anymore' => 'ไม่กำหนดผู้รับผิดชอบ', + 'New assignee: %s' => 'ผู้รับผิดชอบใหม่: %s', + 'There is no category now' => 'ปัจจุบันไม่มีหมวด', + 'New category: %s' => 'หมวดใหม่: %s', + 'New color: %s' => 'สีใหม่: %s', + 'New complexity: %d' => 'ความซับซ้อนใหม่: %d', + 'The due date have been removed' => 'วันครบกำหนดถูกลบ', + 'There is no description anymore' => 'ไม่มีคำอธิบาย', + 'Recurrence settings have been modified' => 'แก้ไขการตั้งค่าการวนลูป', + 'Time spent changed: %sh' => 'เวลาที่ใช้ในการเปลี่ยน: %s ชม.', + 'Time estimated changed: %sh' => 'เวลาโดยประมาณในการเปลี่ยน: %s ชม.', + 'The field "%s" have been updated' => 'ฟิลด์ "%s" ถูกปรับปรุง', + 'The description has been modified:' => 'คำอธิบายถูกแก้ไข', + 'Do you really want to close the task "%s" as well as all subtasks?' => 'คุณต้องการปิดงาน "%s" เช่นเดียวกับงานย่อยทั้งหมด?', + 'I want to receive notifications for:' => 'ฉันต้องการรับการแจ้งเตือนสำหรับ:', + 'All tasks' => 'ทุกงาน', + 'Only for tasks assigned to me' => 'เฉพาะงานที่ฉันรับผิดชอบ', + 'Only for tasks created by me' => 'เฉพาะงานที่ฉันสร้าง', + 'Only for tasks created by me and assigned to me' => 'เฉพาะงานที่ฉันสร้างและฉันรับผิดชอบ', // '%%Y-%%m-%%d' => '', - 'Total for all columns' => 'จำนวนคอลัมน์ทั้งหมด', - 'You need at least 2 days of data to show the chart.' => 'คุณต้องการอย่างน้อย 2 วันในการแสดงแผนภูมิ', - '<15m' => '<15นาที', - '<30m' => '<30นาที', - 'Stop timer' => 'หยุดจับเวลา', - 'Start timer' => 'เริ่มจับเวลา', - 'Add project member' => 'เพิ่มสมาชิกโปรเจค', - 'Enable notifications' => 'เปิดการแจ้งเตือน', - 'My activity stream' => 'กิจกรรมที่เกิดขึ้นของฉัน', - 'My calendar' => 'ปฎิทินของฉัน', - 'Search tasks' => 'ค้นหางาน', - 'Back to the calendar' => 'กลับไปที่ปฎิทิน', - 'Filters' => 'ตัวกรอง', - 'Reset filters' => 'ล้างตัวกรอง', - 'My tasks due tomorrow' => 'งานถึงกำหนดของฉันวันพรุ่งนี้', - 'Tasks due today' => 'งานถึงกำหนดวันนี้', - 'Tasks due tomorrow' => 'งานถึงกำหนดพรุ่งนี้', - 'Tasks due yesterday' => 'งานถึงกำหนดเมื่อวาน', - 'Closed tasks' => 'งานปิด', - 'Open tasks' => 'งานเปิด', - 'Not assigned' => 'ไม่กำหนดใคร', - 'View advanced search syntax' => 'แสดงรูปแบบการค้นหาขั้นสูง', - 'Overview' => 'ภาพรวม', - 'Board/Calendar/List view' => 'มุมมอง บอร์ด/ปฎิทิน/ลิสต์', - 'Switch to the board view' => 'เปลี่ยนเป็นมุมมองบอร์ด', - 'Switch to the calendar view' => 'เปลี่ยนเป็นมุมมองปฎิทิน', - 'Switch to the list view' => 'เปลี่ยนเป็นมุมมองลิสต์', - 'Go to the search/filter box' => 'ไปที่กล่องค้นหา/ตัวกรอง', - 'There is no activity yet.' => 'ตอนนี้ไม่มีกิจกรรม', - 'No tasks found.' => 'ไม่พบงาน', - 'Keyboard shortcut: "%s"' => 'คีย์ลัด: %s', - 'List' => 'ลิสต์', - 'Filter' => 'ตัวกรอง', - 'Advanced search' => 'ค้นหาขั้นสูง', - 'Example of query: ' => 'ตัวอย่างคิวรี: ', - 'Search by project: ' => 'ค้นหาตามโปรเจค: ', - 'Search by column: ' => 'ค้นหาตามคอลัมน์: ', - 'Search by assignee: ' => 'ค้นหาตามผู้รับผิดชอบ: ', - 'Search by color: ' => 'ค้นหาตามสี: ', - 'Search by category: ' => 'ค้นหาตามหมวด: ', - 'Search by description: ' => 'ค้นหาตามคำอธิบาย: ', + 'Total for all columns' => 'จำนวนคอลัมน์ทั้งหมด', + 'You need at least 2 days of data to show the chart.' => 'คุณต้องการอย่างน้อย 2 วันในการแสดงแผนภูมิ', + '<15m' => '<15นาที', + '<30m' => '<30นาที', + 'Stop timer' => 'หยุดจับเวลา', + 'Start timer' => 'เริ่มจับเวลา', + 'Add project member' => 'เพิ่มสมาชิกโปรเจค', + 'Enable notifications' => 'เปิดการแจ้งเตือน', + 'My activity stream' => 'กิจกรรมที่เกิดขึ้นของฉัน', + 'My calendar' => 'ปฎิทินของฉัน', + 'Search tasks' => 'ค้นหางาน', + 'Reset filters' => 'ล้างตัวกรอง', + 'My tasks due tomorrow' => 'งานถึงกำหนดของฉันวันพรุ่งนี้', + 'Tasks due today' => 'งานถึงกำหนดวันนี้', + 'Tasks due tomorrow' => 'งานถึงกำหนดพรุ่งนี้', + 'Tasks due yesterday' => 'งานถึงกำหนดเมื่อวาน', + 'Closed tasks' => 'งานปิด', + 'Open tasks' => 'งานเปิด', + 'Not assigned' => 'ไม่กำหนดใคร', + 'View advanced search syntax' => 'แสดงรูปแบบการค้นหาขั้นสูง', + 'Overview' => 'ภาพรวม', + 'Board/Calendar/List view' => 'มุมมอง บอร์ด/ปฎิทิน/ลิสต์', + 'Switch to the board view' => 'เปลี่ยนเป็นมุมมองบอร์ด', + 'Switch to the calendar view' => 'เปลี่ยนเป็นมุมมองปฎิทิน', + 'Switch to the list view' => 'เปลี่ยนเป็นมุมมองลิสต์', + 'Go to the search/filter box' => 'ไปที่กล่องค้นหา/ตัวกรอง', + 'There is no activity yet.' => 'ตอนนี้ไม่มีกิจกรรม', + 'No tasks found.' => 'ไม่พบงาน', + 'Keyboard shortcut: "%s"' => 'คีย์ลัด: %s', + 'List' => 'ลิสต์', + 'Filter' => 'ตัวกรอง', + 'Advanced search' => 'ค้นหาขั้นสูง', + 'Example of query: ' => 'ตัวอย่างคิวรี: ', + 'Search by project: ' => 'ค้นหาตามโปรเจค: ', + 'Search by column: ' => 'ค้นหาตามคอลัมน์: ', + 'Search by assignee: ' => 'ค้นหาตามผู้รับผิดชอบ: ', + 'Search by color: ' => 'ค้นหาตามสี: ', + 'Search by category: ' => 'ค้นหาตามหมวด: ', + 'Search by description: ' => 'ค้นหาตามคำอธิบาย: ', 'Search by due date: ' => 'ค้นหาตามวันครบกำหนด: ', - 'Lead and Cycle time for "%s"' => 'เวลานำและรอบเวลาสำหรับ "%s"', - 'Average time spent into each column for "%s"' => 'ค่าเฉลี่ยเวลาที่ใช้แต่ละคอลัมน์สำหรับ "%s"', - 'Average time spent into each column' => 'ค่าเฉลี่ยเวลาที่ใช้แต่ละคอลัมน์', - 'Average time spent' => 'ค่าเฉลี่ยเวลาที่ใช้', - 'This chart show the average time spent into each column for the last %d tasks.' => 'แผนภูมิแสดงค่าเฉลี่ยเวลาที่ใช้แต่ละคอลัมน์สำหรับ %d งานล่าสุด', - 'Average Lead and Cycle time' => 'ค่าเฉลี่ยเวลานำและรอบเวลา', - 'Average lead time: ' => 'ค่าเฉลี่ยเวลานำ: ', - 'Average cycle time: ' => 'ค่าเฉลี่ยรอบเวลา: ', - 'Cycle Time' => 'รอบเวลา', - 'Lead Time' => 'เวลานำ', - 'This chart show the average lead and cycle time for the last %d tasks over the time.' => 'แผนภูมิแสดงค่าเฉลี่ยเวลานำและรอบเวลาสำหรับ %d งานล่าสุดเมื่อเวลาผ่านไป', - 'Average time into each column' => 'ค่าเฉลี่ยเวลาแต่ละคอลัมน์', - 'Lead and cycle time' => 'เวลานำและรอบเวลา', - 'Lead time: ' => 'เวลานำ: ', - 'Cycle time: ' => 'รอบเวลา: ', - 'Time spent into each column' => 'เวลาที่ใช้แต่ละคอลัมน์', - 'The lead time is the duration between the task creation and the completion.' => 'เวลานำคือระหว่างสร้างงานและจบงาน', - 'The cycle time is the duration between the start date and the completion.' => 'รอบเวลาคือระหว่างวันที่เริ่มและจบงาน', + 'Lead and Cycle time for "%s"' => 'เวลานำและรอบเวลาสำหรับ "%s"', + 'Average time spent into each column for "%s"' => 'ค่าเฉลี่ยเวลาที่ใช้แต่ละคอลัมน์สำหรับ "%s"', + 'Average time spent into each column' => 'ค่าเฉลี่ยเวลาที่ใช้แต่ละคอลัมน์', + 'Average time spent' => 'ค่าเฉลี่ยเวลาที่ใช้', + 'This chart show the average time spent into each column for the last %d tasks.' => 'แผนภูมิแสดงค่าเฉลี่ยเวลาที่ใช้แต่ละคอลัมน์สำหรับ %d งานล่าสุด', + 'Average Lead and Cycle time' => 'ค่าเฉลี่ยเวลานำและรอบเวลา', + 'Average lead time: ' => 'ค่าเฉลี่ยเวลานำ: ', + 'Average cycle time: ' => 'ค่าเฉลี่ยรอบเวลา: ', + 'Cycle Time' => 'รอบเวลา', + 'Lead Time' => 'เวลานำ', + 'This chart show the average lead and cycle time for the last %d tasks over the time.' => 'แผนภูมิแสดงค่าเฉลี่ยเวลานำและรอบเวลาสำหรับ %d งานล่าสุดเมื่อเวลาผ่านไป', + 'Average time into each column' => 'ค่าเฉลี่ยเวลาแต่ละคอลัมน์', + 'Lead and cycle time' => 'เวลานำและรอบเวลา', + 'Lead time: ' => 'เวลานำ: ', + 'Cycle time: ' => 'รอบเวลา: ', + 'Time spent into each column' => 'เวลาที่ใช้แต่ละคอลัมน์', + 'The lead time is the duration between the task creation and the completion.' => 'เวลานำคือระหว่างสร้างงานและจบงาน', + 'The cycle time is the duration between the start date and the completion.' => 'รอบเวลาคือระหว่างวันที่เริ่มและจบงาน', // 'If the task is not closed the current time is used instead of the completion date.' => '', - 'Set automatically the start date' => 'ตั้งค่าวันที่เริ่มต้นอัตโนมัติ', - 'Edit Authentication' => 'แก้ไขการตรวจสอบ', - 'Remote user' => 'ผู้ใช้รีโมท', + 'Set automatically the start date' => 'ตั้งค่าวันที่เริ่มต้นอัตโนมัติ', + 'Edit Authentication' => 'แก้ไขการตรวจสอบ', + 'Remote user' => 'ผู้ใช้รีโมท', // 'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => '', // 'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => '', - 'New remote user' => 'เพิ่มผู้ใช้รีโมทใหม่', - 'New local user' => 'เพิ่มผู้ใช้ท้องถิ่นใหม่', - 'Default task color' => 'สีเริ่มต้นของงาน', - 'This feature does not work with all browsers.' => 'คุณลักษณะนี้ไม่สามารถทำงานได้ทุกเบราเซอร์', + 'New remote user' => 'เพิ่มผู้ใช้รีโมทใหม่', + 'New local user' => 'เพิ่มผู้ใช้ท้องถิ่นใหม่', + 'Default task color' => 'สีเริ่มต้นของงาน', + 'This feature does not work with all browsers.' => 'คุณลักษณะนี้ไม่สามารถทำงานได้ทุกเบราเซอร์', // 'There is no destination project available.' => '', - 'Trigger automatically subtask time tracking' => 'เรียกโดยอัตโนมัติการติดตามเวลางานย่อย', + 'Trigger automatically subtask time tracking' => 'เรียกโดยอัตโนมัติการติดตามเวลางานย่อย', // 'Include closed tasks in the cumulative flow diagram' => '', - 'Current swimlane: %s' => 'สวิมเลนปัจจุบัน: %s', - 'Current column: %s' => 'คอลัมน์ปัจจุบัน: %s', - 'Current category: %s' => 'หมวดปัจจุบัน: %s', - 'no category' => 'ไม่มีหมวด', - 'Current assignee: %s' => 'ผู้รับผิดชอบปัจจุบัน: %s', - 'not assigned' => 'ไม่กำหนด', - 'Author:' => 'ผู้แต่ง:', - 'contributors' => 'ผู้ให้กำเนิด', - 'License:' => 'สัญญาอนุญาต:', - 'License' => 'สัญญาอนุญาต', - 'Enter the text below' => 'พิมพ์ข้อความด้านล่าง', - 'Gantt chart for %s' => 'แผนภูมิแกรนท์สำหรับ %s', - 'Sort by position' => 'เรียงตามตำแหน่ง', - 'Sort by date' => 'เรียงตามวัน', - 'Add task' => 'เพิ่มงาน', - 'Start date:' => 'วันที่เริ่ม:', - 'Due date:' => 'วันครบกำหนด:', - 'There is no start date or due date for this task.' => 'งานนี้ไม่มีวันที่เริ่มหรือวันครบกำหนด', - 'Moving or resizing a task will change the start and due date of the task.' => 'การย้ายหรือปรับขนาดงานจะมีการเปลี่ยนแปลงที่วันเริ่มต้นและวันที่ครบกำหนดของงาน', - 'There is no task in your project.' => 'โปรเจคนี้ไม่มีงาน', - 'Gantt chart' => 'แผนภูมิแกรนท์', - 'People who are project managers' => 'คนที่เป็นผู้จัดการโปรเจค', - 'People who are project members' => 'คนที่เป็นสมาชิกโปรเจค', - 'NOK - Norwegian Krone' => 'NOK - โครนนอร์เวย์', - 'Show this column' => 'แสดงคอลัมนี้', - 'Hide this column' => 'ซ่อนคอลัมน์นี้', - 'open file' => 'เปิดไฟล์', - 'End date' => 'วันจบ', - 'Users overview' => 'ภาพรวมผู้ใช้', - 'Members' => 'สมาชิก', - 'Shared project' => 'แชร์โปรเจค', - 'Project managers' => 'ผู้จัดการโปรเจค', - 'Gantt chart for all projects' => 'แผนภูมิแกรนท์สำหรับทุกโปรเจค', - 'Projects list' => 'รายการโปรเจค', - 'Gantt chart for this project' => 'แผนภูมิแกรนท์สำหรับโปรเจคนี้', - 'Project board' => 'บอร์ดโปรเจค', - 'End date:' => 'วันที่จบ:', - 'There is no start date or end date for this project.' => 'ไม่มีวันที่เริ่มหรือวันที่จบของโปรเจคนี้', - 'Projects Gantt chart' => 'แผนภูมิแกรน์ของโปรเจค', - 'Link type' => 'ประเภทลิงค์', - 'Change task color when using a specific task link' => 'เปลี่ยนสีงานเมื่อมีการใช้การเชื่อมโยงงาน', - 'Task link creation or modification' => 'การสร้างการเชื่อมโยงงานหรือการปรับเปลี่ยน', - 'Milestone' => 'ขั้น', - 'Documentation: %s' => 'เอกสาร: %s', - 'Switch to the Gantt chart view' => 'เปลี่ยนเป็นมุมมองแผนภูมิแกรนท์', - 'Reset the search/filter box' => 'รีเซตกล่องค้นหา/ตัวกรอง', - 'Documentation' => 'เอกสาร', - 'Table of contents' => 'สารบัญ', - 'Gantt' => 'แกรนท์', - 'Author' => 'ผู้แต่ง', - 'Version' => 'เวอร์ชัน', - 'Plugins' => 'ปลั๊กอิน', - 'There is no plugin loaded.' => 'ไม่มีปลั๊กอินถูกโหลดไว้', - 'Set maximum column height' => 'กำหนดความสูงสูงสุดของคอลัมน์', - 'Remove maximum column height' => 'เอาความสูงสูงสุดของคอลัมน์ออก', - 'My notifications' => 'การแจ้งเตือนของฉัน', - 'Custom filters' => 'ตัวกรองกำหนดเอง', - 'Your custom filter have been created successfully.' => 'ตัวกรองกำหนดเองของคุณสร้างเรียบร้อย', - 'Unable to create your custom filter.' => 'ไม่สามารถสร้างตัวกรองกำหนดเอง', - 'Custom filter removed successfully.' => 'ลบตัวกรองกำหนดเองเรียบร้อย', - 'Unable to remove this custom filter.' => 'ไม่สามารถลบตัวกรองกำหนดเอง', - 'Edit custom filter' => 'แก้ไขตัวกรองกำหนดเอง', - 'Your custom filter have been updated successfully.' => 'ตัวกรองกำหนดเองของคุณแก้ไขเรียบร้อย', - 'Unable to update custom filter.' => 'ไม่สามารถแก้ไขตัวกรองกำหนดเอง', - 'Web' => 'เวบ', - 'New attachment on task #%d: %s' => 'แนบใหม่ของงาน #%d: %s', - 'New comment on task #%d' => 'ความคิดเห็นใหม่ของงาน #%d', - 'Comment updated on task #%d' => 'แก้ไขความคิดเห็นของงาน #%d', - 'New subtask on task #%d' => 'งานย่อยใหม่ของงาน #%d', - 'Subtask updated on task #%d' => 'แก้ไขงานย่อยของงาน #%d', - 'New task #%d: %s' => 'งานใหม่ #%d: %s', - 'Task updated #%d' => 'แก้ไขงาน #%d', - 'Task #%d closed' => 'ปิดงาน #%d', - 'Task #%d opened' => 'เปิดงาน #%d', - 'Column changed for task #%d' => 'เปลี่ยนคอลัมน์สำหรับงาน #%d', - 'New position for task #%d' => 'ตำแหน่งใหม่ของงาน #%d', - 'Swimlane changed for task #%d' => 'เปลี่ยนสวิมเลนสำหรับงาน #%d', - 'Assignee changed on task #%d' => 'เปลี่ยนผู้รับผิดชอบงาน #%d', - '%d overdue tasks' => '%d งานเกินกำหนด', - 'Task #%d is overdue' => 'งาน #%d เกินกำหนด', - 'No new notifications.' => 'ไม่มีการแจ้งเตือนใหม่', - 'Mark all as read' => 'มาร์คทั้งหมดว่าอ่านแล้ว', - 'Mark as read' => 'มาร์คว่าอ่านแล้ว', + 'Current swimlane: %s' => 'สวิมเลนปัจจุบัน: %s', + 'Current column: %s' => 'คอลัมน์ปัจจุบัน: %s', + 'Current category: %s' => 'หมวดปัจจุบัน: %s', + 'no category' => 'ไม่มีหมวด', + 'Current assignee: %s' => 'ผู้รับผิดชอบปัจจุบัน: %s', + 'not assigned' => 'ไม่กำหนด', + 'Author:' => 'ผู้แต่ง:', + 'contributors' => 'ผู้ให้กำเนิด', + 'License:' => 'สัญญาอนุญาต:', + 'License' => 'สัญญาอนุญาต', + 'Enter the text below' => 'พิมพ์ข้อความด้านล่าง', + 'Gantt chart for %s' => 'แผนภูมิแกรนท์สำหรับ %s', + 'Sort by position' => 'เรียงตามตำแหน่ง', + 'Sort by date' => 'เรียงตามวัน', + 'Add task' => 'เพิ่มงาน', + 'Start date:' => 'วันที่เริ่ม:', + 'Due date:' => 'วันครบกำหนด:', + 'There is no start date or due date for this task.' => 'งานนี้ไม่มีวันที่เริ่มหรือวันครบกำหนด', + 'Moving or resizing a task will change the start and due date of the task.' => 'การย้ายหรือปรับขนาดงานจะมีการเปลี่ยนแปลงที่วันเริ่มต้นและวันที่ครบกำหนดของงาน', + 'There is no task in your project.' => 'โปรเจคนี้ไม่มีงาน', + 'Gantt chart' => 'แผนภูมิแกรนท์', + 'People who are project managers' => 'คนที่เป็นผู้จัดการโปรเจค', + 'People who are project members' => 'คนที่เป็นสมาชิกโปรเจค', + 'NOK - Norwegian Krone' => 'NOK - โครนนอร์เวย์', + 'Show this column' => 'แสดงคอลัมนี้', + 'Hide this column' => 'ซ่อนคอลัมน์นี้', + 'open file' => 'เปิดไฟล์', + 'End date' => 'วันจบ', + 'Users overview' => 'ภาพรวมผู้ใช้', + 'Members' => 'สมาชิก', + 'Shared project' => 'แชร์โปรเจค', + 'Project managers' => 'ผู้จัดการโปรเจค', + 'Gantt chart for all projects' => 'แผนภูมิแกรนท์สำหรับทุกโปรเจค', + 'Projects list' => 'รายการโปรเจค', + 'Gantt chart for this project' => 'แผนภูมิแกรนท์สำหรับโปรเจคนี้', + 'Project board' => 'บอร์ดโปรเจค', + 'End date:' => 'วันที่จบ:', + 'There is no start date or end date for this project.' => 'ไม่มีวันที่เริ่มหรือวันที่จบของโปรเจคนี้', + 'Projects Gantt chart' => 'แผนภูมิแกรน์ของโปรเจค', + 'Change task color when using a specific task link' => 'เปลี่ยนสีงานเมื่อมีการใช้การเชื่อมโยงงาน', + 'Task link creation or modification' => 'การสร้างการเชื่อมโยงงานหรือการปรับเปลี่ยน', + 'Milestone' => 'ขั้น', + 'Documentation: %s' => 'เอกสาร: %s', + 'Switch to the Gantt chart view' => 'เปลี่ยนเป็นมุมมองแผนภูมิแกรนท์', + 'Reset the search/filter box' => 'รีเซตกล่องค้นหา/ตัวกรอง', + 'Documentation' => 'เอกสาร', + 'Table of contents' => 'สารบัญ', + 'Gantt' => 'แกรนท์', + 'Author' => 'ผู้แต่ง', + 'Version' => 'เวอร์ชัน', + 'Plugins' => 'ปลั๊กอิน', + 'There is no plugin loaded.' => 'ไม่มีปลั๊กอินถูกโหลดไว้', + 'Set maximum column height' => 'กำหนดความสูงสูงสุดของคอลัมน์', + 'Remove maximum column height' => 'เอาความสูงสูงสุดของคอลัมน์ออก', + 'My notifications' => 'การแจ้งเตือนของฉัน', + 'Custom filters' => 'ตัวกรองกำหนดเอง', + 'Your custom filter have been created successfully.' => 'ตัวกรองกำหนดเองของคุณสร้างเรียบร้อย', + 'Unable to create your custom filter.' => 'ไม่สามารถสร้างตัวกรองกำหนดเอง', + 'Custom filter removed successfully.' => 'ลบตัวกรองกำหนดเองเรียบร้อย', + 'Unable to remove this custom filter.' => 'ไม่สามารถลบตัวกรองกำหนดเอง', + 'Edit custom filter' => 'แก้ไขตัวกรองกำหนดเอง', + 'Your custom filter have been updated successfully.' => 'ตัวกรองกำหนดเองของคุณแก้ไขเรียบร้อย', + 'Unable to update custom filter.' => 'ไม่สามารถแก้ไขตัวกรองกำหนดเอง', + 'Web' => 'เวบ', + 'New attachment on task #%d: %s' => 'แนบใหม่ของงาน #%d: %s', + 'New comment on task #%d' => 'ความคิดเห็นใหม่ของงาน #%d', + 'Comment updated on task #%d' => 'แก้ไขความคิดเห็นของงาน #%d', + 'New subtask on task #%d' => 'งานย่อยใหม่ของงาน #%d', + 'Subtask updated on task #%d' => 'แก้ไขงานย่อยของงาน #%d', + 'New task #%d: %s' => 'งานใหม่ #%d: %s', + 'Task updated #%d' => 'แก้ไขงาน #%d', + 'Task #%d closed' => 'ปิดงาน #%d', + 'Task #%d opened' => 'เปิดงาน #%d', + 'Column changed for task #%d' => 'เปลี่ยนคอลัมน์สำหรับงาน #%d', + 'New position for task #%d' => 'ตำแหน่งใหม่ของงาน #%d', + 'Swimlane changed for task #%d' => 'เปลี่ยนสวิมเลนสำหรับงาน #%d', + 'Assignee changed on task #%d' => 'เปลี่ยนผู้รับผิดชอบงาน #%d', + '%d overdue tasks' => '%d งานเกินกำหนด', + 'Task #%d is overdue' => 'งาน #%d เกินกำหนด', + 'No new notifications.' => 'ไม่มีการแจ้งเตือนใหม่', + 'Mark all as read' => 'มาร์คทั้งหมดว่าอ่านแล้ว', + 'Mark as read' => 'มาร์คว่าอ่านแล้ว', // 'Total number of tasks in this column across all swimlanes' => '', - 'Collapse swimlane' => 'ย่อสวิมเลน', - 'Expand swimlane' => 'ขยายสวิมเลน', - 'Add a new filter' => 'เพิ่มตัวกรองใหม่', - 'Share with all project members' => 'แชร์ให้สมาชิกทุกคนของโปรเจค', - 'Shared' => 'แชร์', - 'Owner' => 'เจ้าของ', - 'Unread notifications' => 'การแจ้งเตือนยังไม่ได้อ่าน', - 'My filters' => 'ตัวกรองของฉัน', - 'Notification methods:' => 'ลักษณะการแจ้งเตือน:', - 'Import tasks from CSV file' => 'นำเข้างานจากไฟล์ CSV', - 'Unable to read your file' => 'ไม่สามารถอ่านไฟล์ของคุณ', - '%d task(s) have been imported successfully.' => '%d งานนำเข้าเรียบร้อย', - 'Nothing have been imported!' => 'ไม่มีอะไรถูกนำเข้า', - 'Import users from CSV file' => 'นำเข้าผู้ใช้จากไฟล์ CSV', - '%d user(s) have been imported successfully.' => '%d ผู้ใช้นำเข้าเรียบร้อย', - 'Comma' => ', - Comma', - 'Semi-colon' => '; - Semi-colon', - 'Tab' => 'Tab - Tab', - 'Vertical bar' => '| - Vertical bar', - 'Double Quote' => '" " - Double Quote', - 'Single Quote' => '\' \' - Single Quote', - '%s attached a file to the task #%d' => '%s แนบไฟล์ในงาน #%d', - 'There is no column or swimlane activated in your project!' => 'ไม่มีคอลัมน์หรือสวิมเลนเปิดใช้งานในโปรเจคของคุณ!', + 'Collapse swimlane' => 'ย่อสวิมเลน', + 'Expand swimlane' => 'ขยายสวิมเลน', + 'Add a new filter' => 'เพิ่มตัวกรองใหม่', + 'Share with all project members' => 'แชร์ให้สมาชิกทุกคนของโปรเจค', + 'Shared' => 'แชร์', + 'Owner' => 'เจ้าของ', + 'Unread notifications' => 'การแจ้งเตือนยังไม่ได้อ่าน', + 'Notification methods:' => 'ลักษณะการแจ้งเตือน:', + 'Import tasks from CSV file' => 'นำเข้างานจากไฟล์ CSV', + 'Unable to read your file' => 'ไม่สามารถอ่านไฟล์ของคุณ', + '%d task(s) have been imported successfully.' => '%d งานนำเข้าเรียบร้อย', + 'Nothing have been imported!' => 'ไม่มีอะไรถูกนำเข้า', + 'Import users from CSV file' => 'นำเข้าผู้ใช้จากไฟล์ CSV', + '%d user(s) have been imported successfully.' => '%d ผู้ใช้นำเข้าเรียบร้อย', + 'Comma' => ', - Comma', + 'Semi-colon' => '; - Semi-colon', + 'Tab' => 'Tab - Tab', + 'Vertical bar' => '| - Vertical bar', + 'Double Quote' => '" " - Double Quote', + 'Single Quote' => '\' \' - Single Quote', + '%s attached a file to the task #%d' => '%s แนบไฟล์ในงาน #%d', + 'There is no column or swimlane activated in your project!' => 'ไม่มีคอลัมน์หรือสวิมเลนเปิดใช้งานในโปรเจคของคุณ!', // 'Append filter (instead of replacement)' => '', - 'Append/Replace' => 'เพิ่มเติม/แทนที่', - 'Append' => 'เพิ่มเติม', - 'Replace' => 'แทนที่', - 'Import' => 'นำเข้า', - 'change sorting' => 'เปลี่ยนการเรียง', - 'Tasks Importation' => 'การนำเข้างาน', - 'Delimiter' => 'คั่น', - 'Enclosure' => 'กำหนดข้อความ', - 'CSV File' => 'ไฟล์ CSV', - 'Instructions' => 'คำสั่ง', - 'Your file must use the predefined CSV format' => 'ไฟล์ของคุณจะต้องใช้รูปแบบ CSV ที่กำหนดไว้ล่วงหน้า', - 'Your file must be encoded in UTF-8' => 'ไฟล์ของคุณต้องเอนโค้ดด้วย UTF-8', - 'The first row must be the header' => 'แถวแรกต้องเป็นหัวข้อ', - 'Duplicates are not verified for you' => 'รายการที่ซ้ำกันจะไม่ได้รับการตรวจสอบสำหรับคุณ', - 'The due date must use the ISO format: YYYY-MM-DD' => 'วันที่ต้องอยู่ในรูปแบบ ISO: YYYY-MM-DD', - 'Download CSV template' => 'ดาวน์โหลด CSV ต้นฉบับ', - 'No external integration registered.' => 'ไม่มีการรวมภายนอกถูกลงทะเบียนไว้', - 'Duplicates are not imported' => 'ซ้ำกันไม่สามารถนำเข้าได้', - 'Usernames must be lowercase and unique' => 'ชื่อผู้ใช้ต้องเป็นตัวพิมพ์เล็กและไม่ซ้ำ', + 'Append/Replace' => 'เพิ่มเติม/แทนที่', + 'Append' => 'เพิ่มเติม', + 'Replace' => 'แทนที่', + 'Import' => 'นำเข้า', + 'change sorting' => 'เปลี่ยนการเรียง', + 'Tasks Importation' => 'การนำเข้างาน', + 'Delimiter' => 'คั่น', + 'Enclosure' => 'กำหนดข้อความ', + 'CSV File' => 'ไฟล์ CSV', + 'Instructions' => 'คำสั่ง', + 'Your file must use the predefined CSV format' => 'ไฟล์ของคุณจะต้องใช้รูปแบบ CSV ที่กำหนดไว้ล่วงหน้า', + 'Your file must be encoded in UTF-8' => 'ไฟล์ของคุณต้องเอนโค้ดด้วย UTF-8', + 'The first row must be the header' => 'แถวแรกต้องเป็นหัวข้อ', + 'Duplicates are not verified for you' => 'รายการที่ซ้ำกันจะไม่ได้รับการตรวจสอบสำหรับคุณ', + 'The due date must use the ISO format: YYYY-MM-DD' => 'วันที่ต้องอยู่ในรูปแบบ ISO: YYYY-MM-DD', + 'Download CSV template' => 'ดาวน์โหลด CSV ต้นฉบับ', + 'No external integration registered.' => 'ไม่มีการรวมภายนอกถูกลงทะเบียนไว้', + 'Duplicates are not imported' => 'ซ้ำกันไม่สามารถนำเข้าได้', + 'Usernames must be lowercase and unique' => 'ชื่อผู้ใช้ต้องเป็นตัวพิมพ์เล็กและไม่ซ้ำ', // 'Passwords will be encrypted if present' => '', - '%s attached a new file to the task %s' => '%s แนบไฟล์ใหม่ในงาน %s', - 'Assign automatically a category based on a link' => 'กำหนดหมวดอัตโนมัติตามลิงค์', + '%s attached a new file to the task %s' => '%s แนบไฟล์ใหม่ในงาน %s', + 'Link type' => 'ประเภทลิงค์', + 'Assign automatically a category based on a link' => 'กำหนดหมวดอัตโนมัติตามลิงค์', // 'BAM - Konvertible Mark' => '', 'Assignee Username' => 'กำหนดชื่อผู้ใช้', - 'Assignee Name' => 'กำหนดชื่อ', - 'Groups' => 'กลุ่ม', - 'Members of %s' => 'สมาชิกของ %s', - 'New group' => 'กลุ่มใหม่', - 'Group created successfully.' => 'สร้างกลุ่มสำเร็จ', - 'Unable to create your group.' => 'ไม่สามารถสร้างกลุ่มของคุณ', - 'Edit group' => 'แก้ไขกลุ่ม', - 'Group updated successfully.' => 'แก้ไขกลุ่มเรียบร้อย', - 'Unable to update your group.' => 'ไม่สามารถแก้ไขกลุ่มของคุณ', - 'Add group member to "%s"' => 'เพิ่มสมาชิกในกลุ่ม %s', - 'Group member added successfully.' => 'เพิ่มสมาชิกกลุ่มเรียบร้อย', - 'Unable to add group member.' => 'ไม่สามารถเพิ่มสมาชิกกลุ่ม', - 'Remove user from group "%s"' => 'เอาผู้ใช้ออกจากกลุ่ม %s', - 'User removed successfully from this group.' => 'เอาผู้ใช้ออกจากกลุ่มนี้เรียบร้อย', - 'Unable to remove this user from the group.' => 'ไม่สามารถลบผู้ใช้ออกจากกลุ่มนี้', - 'Remove group' => 'ลบกลุ่ม', - 'Group removed successfully.' => 'ลบกลุ่มเรียบร้อย', - 'Unable to remove this group.' => 'ไม่สามารถลบกลุ่มนี้', - 'Project Permissions' => 'การอนุญาตใช้งานโปรเจค', - 'Manager' => 'ผู้จัดการ', - 'Project Manager' => 'ผู้จัดการโปรเจค', - 'Project Member' => 'สมาชิกโปรเจค', - 'Project Viewer' => 'ผู้ดูโปรเจค', - 'Your account is locked for %d minutes' => 'บัญชีของคุณถูกล็อก %d นาที', - 'Invalid captcha' => 'captcha ไม่ถูกต้อง', - 'The name must be unique' => 'ชื่อต้องไม่ซ้ำ', - 'View all groups' => 'แสดงกลุ่มทั้งหมด', - 'View group members' => 'แสดงสมาชิกกลุ่ม', + 'Assignee Name' => 'กำหนดชื่อ', + 'Groups' => 'กลุ่ม', + 'Members of %s' => 'สมาชิกของ %s', + 'New group' => 'กลุ่มใหม่', + 'Group created successfully.' => 'สร้างกลุ่มสำเร็จ', + 'Unable to create your group.' => 'ไม่สามารถสร้างกลุ่มของคุณ', + 'Edit group' => 'แก้ไขกลุ่ม', + 'Group updated successfully.' => 'แก้ไขกลุ่มเรียบร้อย', + 'Unable to update your group.' => 'ไม่สามารถแก้ไขกลุ่มของคุณ', + 'Add group member to "%s"' => 'เพิ่มสมาชิกในกลุ่ม %s', + 'Group member added successfully.' => 'เพิ่มสมาชิกกลุ่มเรียบร้อย', + 'Unable to add group member.' => 'ไม่สามารถเพิ่มสมาชิกกลุ่ม', + 'Remove user from group "%s"' => 'เอาผู้ใช้ออกจากกลุ่ม %s', + 'User removed successfully from this group.' => 'เอาผู้ใช้ออกจากกลุ่มนี้เรียบร้อย', + 'Unable to remove this user from the group.' => 'ไม่สามารถลบผู้ใช้ออกจากกลุ่มนี้', + 'Remove group' => 'ลบกลุ่ม', + 'Group removed successfully.' => 'ลบกลุ่มเรียบร้อย', + 'Unable to remove this group.' => 'ไม่สามารถลบกลุ่มนี้', + 'Project Permissions' => 'การอนุญาตใช้งานโปรเจค', + 'Manager' => 'ผู้จัดการ', + 'Project Manager' => 'ผู้จัดการโปรเจค', + 'Project Member' => 'สมาชิกโปรเจค', + 'Project Viewer' => 'ผู้ดูโปรเจค', + 'Your account is locked for %d minutes' => 'บัญชีของคุณถูกล็อก %d นาที', + 'Invalid captcha' => 'captcha ไม่ถูกต้อง', + 'The name must be unique' => 'ชื่อต้องไม่ซ้ำ', + 'View all groups' => 'แสดงกลุ่มทั้งหมด', + 'View group members' => 'แสดงสมาชิกกลุ่ม', // 'There is no user available.' => '', - 'Do you really want to remove the user "%s" from the group "%s"?' => 'คุณต้องการลบผู้ใช้ "%s" ออกจากกลุ่ม "%s"?', - 'There is no group.' => 'ไม่มีกลุ่ม', - 'External Id' => 'ไอดีภายนอก', - 'Add group member' => 'เพิ่มสมาชิกกลุ่ม', - 'Do you really want to remove this group: "%s"?' => 'คุณต้องการลบกลุ่มนี้: "%s"?', - 'There is no user in this group.' => 'ไม่มีผู้ใช้ในกลุ่มนี้', - 'Remove this user' => 'เอาผู้ใช้คนนี้ออก', - 'Permissions' => 'การอนุญาตใช้งาน', - 'Allowed Users' => 'การอนุญาตผู้ใช้', - 'No user have been allowed specifically.' => 'ไม่มีผู้ใช้ได้รับอนุญาติเป็นพิเศษ', - 'Role' => 'บทบาท', - 'Enter user name...' => 'พิมพ์ชื่อผู้ใช้...', - 'Allowed Groups' => 'อนุญาตกลุ่ม', - 'No group have been allowed specifically.' => 'ไม่มีกลุ่มได้รับอนุญาติเป็นพิเศษ', - 'Group' => 'กลุ่ม', - 'Group Name' => 'ชื่อกลุ่ม', - 'Enter group name...' => 'พิมพ์ชื่อกลุ่ม...', - 'Role:' => 'บทบาท:', - 'Project members' => 'สมาชิกโปรเจค', - 'Compare hours for "%s"' => 'เปรียบเทียบรายชั่วโมงสำหรับ %s', - '%s mentioned you in the task #%d' => '%s กล่าวถึงคุณในงาน #%d', - '%s mentioned you in a comment on the task #%d' => '%s กล่าวถึงคุณในความคิดเห็นของงาน #%d', - 'You were mentioned in the task #%d' => 'คุณได้รับการกล่าวถึงในงาน #%d', - 'You were mentioned in a comment on the task #%d' => 'คุณได้รับการกล่าวถึงในความคิดเห็นของงาน #%d', + 'Do you really want to remove the user "%s" from the group "%s"?' => 'คุณต้องการลบผู้ใช้ "%s" ออกจากกลุ่ม "%s"?', + 'There is no group.' => 'ไม่มีกลุ่ม', + 'External Id' => 'ไอดีภายนอก', + 'Add group member' => 'เพิ่มสมาชิกกลุ่ม', + 'Do you really want to remove this group: "%s"?' => 'คุณต้องการลบกลุ่มนี้: "%s"?', + 'There is no user in this group.' => 'ไม่มีผู้ใช้ในกลุ่มนี้', + 'Remove this user' => 'เอาผู้ใช้คนนี้ออก', + 'Permissions' => 'การอนุญาตใช้งาน', + 'Allowed Users' => 'การอนุญาตผู้ใช้', + 'No user have been allowed specifically.' => 'ไม่มีผู้ใช้ได้รับอนุญาติเป็นพิเศษ', + 'Role' => 'บทบาท', + 'Enter user name...' => 'พิมพ์ชื่อผู้ใช้...', + 'Allowed Groups' => 'อนุญาตกลุ่ม', + 'No group have been allowed specifically.' => 'ไม่มีกลุ่มได้รับอนุญาติเป็นพิเศษ', + 'Group' => 'กลุ่ม', + 'Group Name' => 'ชื่อกลุ่ม', + 'Enter group name...' => 'พิมพ์ชื่อกลุ่ม...', + 'Role:' => 'บทบาท:', + 'Project members' => 'สมาชิกโปรเจค', + 'Compare hours for "%s"' => 'เปรียบเทียบรายชั่วโมงสำหรับ %s', + '%s mentioned you in the task #%d' => '%s กล่าวถึงคุณในงาน #%d', + '%s mentioned you in a comment on the task #%d' => '%s กล่าวถึงคุณในความคิดเห็นของงาน #%d', + 'You were mentioned in the task #%d' => 'คุณได้รับการกล่าวถึงในงาน #%d', + 'You were mentioned in a comment on the task #%d' => 'คุณได้รับการกล่าวถึงในความคิดเห็นของงาน #%d', 'Mentioned' => 'กล่าวถึง', - 'Compare Estimated Time vs Actual Time' => 'เปรียบเทียบเวลาโดยประมาณกับเวลาที่เกิดขึ้นจริง', - 'Estimated hours: ' => 'เวลาโดยประมาณ:', - 'Actual hours: ' => 'เวลาที่เกิดขึ้นจริง:', - 'Hours Spent' => 'เวลาที่ใช้', - 'Hours Estimated' => 'เวลาโดยประมาณ', - 'Estimated Time' => 'เวลาโดยประมาณ', - 'Actual Time' => 'เวลาที่ใช้', - 'Estimated vs actual time' => 'เวลาโดยประมาณกับเวลาจริง', - 'RUB - Russian Ruble' => 'RUB - รูเบิลรัสเซีย', - 'Assign the task to the person who does the action when the column is changed' => 'กำหนดผู้รับผิดชอบงานเมื่อเปลี่ยนคอลัมน์', - 'Close a task in a specific column' => 'ปิดงานในคอลัมน์ที่เฉพาะเจาะจง', + 'Compare Estimated Time vs Actual Time' => 'เปรียบเทียบเวลาโดยประมาณกับเวลาที่เกิดขึ้นจริง', + 'Estimated hours: ' => 'เวลาโดยประมาณ:', + 'Actual hours: ' => 'เวลาที่เกิดขึ้นจริง:', + 'Hours Spent' => 'เวลาที่ใช้', + 'Hours Estimated' => 'เวลาโดยประมาณ', + 'Estimated Time' => 'เวลาโดยประมาณ', + 'Actual Time' => 'เวลาที่ใช้', + 'Estimated vs actual time' => 'เวลาโดยประมาณกับเวลาจริง', + 'RUB - Russian Ruble' => 'RUB - รูเบิลรัสเซีย', + 'Assign the task to the person who does the action when the column is changed' => 'กำหนดผู้รับผิดชอบงานเมื่อเปลี่ยนคอลัมน์', + 'Close a task in a specific column' => 'ปิดงานในคอลัมน์ที่เฉพาะเจาะจง', // 'Time-based One-time Password Algorithm' => '', // 'Two-Factor Provider: ' => '', // 'Disable two-factor authentication' => '', // 'Enable two-factor authentication' => '', // 'There is no integration registered at the moment.' => '', - 'Password Reset for Kanboard' => 'รีเซตรหัสผ่านสำหรับคังบอร์ด', - 'Forgot password?' => 'ลืมรหัสผ่าน?', - 'Enable "Forget Password"' => 'เปิดการใช้งาน "ลืมรหัสผ่าน"', - 'Password Reset' => 'รีเซตรหัสผ่าน', - 'New password' => 'รหัสผ่านใหม่', - 'Change Password' => 'เปลี่ยนรหัสผ่าน', - 'To reset your password click on this link:' => 'ในการรีเซตรหัสผ่านของคุณคลิ๊กที่ลิงค์นี้:', - 'Last Password Reset' => 'รีเซตรหัสผ่านครั้งล่าสุด', - 'The password has never been reinitialized.' => 'รหัสผ่านไม่เคยเริ่มใหม่อีกครั้ง', - 'Creation' => 'สร้าง', - 'Expiration' => 'สิ้นสุด', - 'Password reset history' => 'ประวัติการรีเซตรหัสผ่าน', - 'All tasks of the column "%s" and the swimlane "%s" have been closed successfully.' => 'ทุกงานของคอลัมน์ "%s" และสวิมเลน "%s" ถูกปิดเรียบร้อย', + 'Password Reset for Kanboard' => 'รีเซตรหัสผ่านสำหรับคังบอร์ด', + 'Forgot password?' => 'ลืมรหัสผ่าน?', + 'Enable "Forget Password"' => 'เปิดการใช้งาน "ลืมรหัสผ่าน"', + 'Password Reset' => 'รีเซตรหัสผ่าน', + 'New password' => 'รหัสผ่านใหม่', + 'Change Password' => 'เปลี่ยนรหัสผ่าน', + 'To reset your password click on this link:' => 'ในการรีเซตรหัสผ่านของคุณคลิ๊กที่ลิงค์นี้:', + 'Last Password Reset' => 'รีเซตรหัสผ่านครั้งล่าสุด', + 'The password has never been reinitialized.' => 'รหัสผ่านไม่เคยเริ่มใหม่อีกครั้ง', + 'Creation' => 'สร้าง', + 'Expiration' => 'สิ้นสุด', + 'Password reset history' => 'ประวัติการรีเซตรหัสผ่าน', + 'All tasks of the column "%s" and the swimlane "%s" have been closed successfully.' => 'ทุกงานของคอลัมน์ "%s" และสวิมเลน "%s" ถูกปิดเรียบร้อย', 'Do you really want to close all tasks of this column?' => 'คุณต้องการปิดทุกงานในคอลัมนี้ใช่หรือไม่?', - '%d task(s) in the column "%s" and the swimlane "%s" will be closed.' => '%d งานในคอลัมน์ "%s" และสวิมเลน "%s" จะปิด', - 'Close all tasks of this column' => 'ปิดทุกงานในคอลัมน์นี้', - 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => 'ปลั๊กอินไม่ได้ลงทะเบียนการแจ้งเตือนในโปรเจค คุณยังสามารถกำหนดค่าการแจ้งเตือนรายบุคคลในโปรไฟล์ผู้ใช้ของคุณ', - 'My dashboard' => 'แดชบอร์ดของฉํน', - 'My profile' => 'โปรเจคของฉัน', - 'Project owner: ' => 'เจ้าของโปรเจค: ', - 'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => 'ตัวบ่งชี้โปรโจคเป็นตัวเลือกเสริมและต้องเป็นตัวอักษรหรือตัวเลข ตัวอย่าง: MYPROJECT', - 'Project owner' => 'เจ้าของโปรเจค', - 'Those dates are useful for the project Gantt chart.' => 'วันที่ใช้สำหรับแผนภูมิแกรนท์ของโปรเจค', - 'Private projects do not have users and groups management.' => 'โปรเจคส่วนตัวไม่มีการจัดการผู้ใช้และกลุ่ม', - 'There is no project member.' => 'ไม่มีสมาชิกโปรเจค', - 'Priority' => 'ความสำคัญ', - 'Task priority' => 'ความสำคัญของงาน', - 'General' => 'ทั่วไป', - 'Dates' => 'วันที่', - 'Default priority' => 'ความสำคัญเริ่มต้น', - 'Lowest priority' => 'ความสำคัญต่ำสุด', - 'Highest priority' => 'ความสำคัญสูงสุด', - 'If you put zero to the low and high priority, this feature will be disabled.' => 'ถ้าคุณใส่เลขศูนย์ทั้งความสำคัญต่ำและความสำคัญสูง จะเป็นการปิดการทำงานคุณลักษณะนี้', - 'Close a task when there is no activity' => 'ปิดงานเมื่อไม่มีกิจกกรมเกิดขึ้น', - 'Duration in days' => 'ระยะเวลาวันที่', - 'Send email when there is no activity on a task' => 'ส่งอีเมลเมื่อไม่มีกิจกรรมเกิดขึ้นในงาน', - 'List of external links' => 'รายการเชื่อมโยงภายนอก', - 'Unable to fetch link information.' => 'ไม่สามารถดึงข้อมูลการเชื่อมโยง', + '%d task(s) in the column "%s" and the swimlane "%s" will be closed.' => '%d งานในคอลัมน์ "%s" และสวิมเลน "%s" จะปิด', + 'Close all tasks of this column' => 'ปิดทุกงานในคอลัมน์นี้', + 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => 'ปลั๊กอินไม่ได้ลงทะเบียนการแจ้งเตือนในโปรเจค คุณยังสามารถกำหนดค่าการแจ้งเตือนรายบุคคลในโปรไฟล์ผู้ใช้ของคุณ', + 'My dashboard' => 'แดชบอร์ดของฉํน', + 'My profile' => 'โปรเจคของฉัน', + 'Project owner: ' => 'เจ้าของโปรเจค: ', + 'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => 'ตัวบ่งชี้โปรโจคเป็นตัวเลือกเสริมและต้องเป็นตัวอักษรหรือตัวเลข ตัวอย่าง: MYPROJECT', + 'Project owner' => 'เจ้าของโปรเจค', + 'Those dates are useful for the project Gantt chart.' => 'วันที่ใช้สำหรับแผนภูมิแกรนท์ของโปรเจค', + 'Private projects do not have users and groups management.' => 'โปรเจคส่วนตัวไม่มีการจัดการผู้ใช้และกลุ่ม', + 'There is no project member.' => 'ไม่มีสมาชิกโปรเจค', + 'Priority' => 'ความสำคัญ', + 'Task priority' => 'ความสำคัญของงาน', + 'General' => 'ทั่วไป', + 'Dates' => 'วันที่', + 'Default priority' => 'ความสำคัญเริ่มต้น', + 'Lowest priority' => 'ความสำคัญต่ำสุด', + 'Highest priority' => 'ความสำคัญสูงสุด', + 'If you put zero to the low and high priority, this feature will be disabled.' => 'ถ้าคุณใส่เลขศูนย์ทั้งความสำคัญต่ำและความสำคัญสูง จะเป็นการปิดการทำงานคุณลักษณะนี้', + 'Close a task when there is no activity' => 'ปิดงานเมื่อไม่มีกิจกกรมเกิดขึ้น', + 'Duration in days' => 'ระยะเวลาวันที่', + 'Send email when there is no activity on a task' => 'ส่งอีเมลเมื่อไม่มีกิจกรรมเกิดขึ้นในงาน', + 'Unable to fetch link information.' => 'ไม่สามารถดึงข้อมูลการเชื่อมโยง', // 'Daily background job for tasks' => '', - 'Auto' => 'อัตโนมัติ', - 'Related' => 'ที่เกี่ยวข้อง', - 'Attachment' => 'แนบ', - 'Title not found' => 'ไม่พบหัวเรื่อง', - 'Web Link' => 'เวบลิงค์', - 'External links' => 'เชื่อมโยงภายนอก', - 'Add external link' => 'เพิ่มการเชื่อมโยงภายนอก', - 'Type' => 'ประเภท', - 'Dependency' => 'ขึ้นอยู่กับ', - 'Add internal link' => 'เพิ่มการเชื่อมโยงภายใน', - 'Add a new external link' => 'เพิ่มการเชื่อมโยงภายนอกใหม่', - 'Edit external link' => 'แก้ไขการเชื่อมโยงภายนอก', - 'External link' => 'เชื่อมโยงภายนอก', - 'Copy and paste your link here...' => 'คัดลอกและวางลิงค์ของคุณที่นี้...', - 'URL' => 'URL', - 'There is no external link for the moment.' => 'ขณะนี้ไม่มีการเชื่อมโยงภายนอก', - 'Internal links' => 'เชื่อมโยงภายใน', - 'There is no internal link for the moment.' => 'ขณะนี้ไม่มีการเชื่อมโยงภายใน', - 'Assign to me' => 'ฉันรับผิดชอบ', - 'Me' => 'ฉัน', + 'Auto' => 'อัตโนมัติ', + 'Related' => 'ที่เกี่ยวข้อง', + 'Attachment' => 'แนบ', + 'Title not found' => 'ไม่พบหัวเรื่อง', + 'Web Link' => 'เวบลิงค์', + 'External links' => 'เชื่อมโยงภายนอก', + 'Add external link' => 'เพิ่มการเชื่อมโยงภายนอก', + 'Type' => 'ประเภท', + 'Dependency' => 'ขึ้นอยู่กับ', + 'Add internal link' => 'เพิ่มการเชื่อมโยงภายใน', + 'Add a new external link' => 'เพิ่มการเชื่อมโยงภายนอกใหม่', + 'Edit external link' => 'แก้ไขการเชื่อมโยงภายนอก', + 'External link' => 'เชื่อมโยงภายนอก', + 'Copy and paste your link here...' => 'คัดลอกและวางลิงค์ของคุณที่นี้...', + 'URL' => 'URL', + 'Internal links' => 'เชื่อมโยงภายใน', + 'Assign to me' => 'ฉันรับผิดชอบ', + 'Me' => 'ฉัน', // 'Do not duplicate anything' => '', - 'Projects management' => 'การจัดการโปรเจค', - 'Users management' => 'การจัดการผู้ใช้', - 'Groups management' => 'การจัดการกลุ่ม', - 'Create from another project' => 'สร้างโปรเจคอื่น', - 'There is no subtask at the moment.' => 'ขณะนี้ไม่มีงานย่อย', - 'open' => 'เปิด', - 'closed' => 'ปิด', + 'Projects management' => 'การจัดการโปรเจค', + 'Users management' => 'การจัดการผู้ใช้', + 'Groups management' => 'การจัดการกลุ่ม', + 'Create from another project' => 'สร้างโปรเจคอื่น', + 'open' => 'เปิด', + 'closed' => 'ปิด', 'Priority:' => 'ความสำคัญ:', - 'Reference:' => 'อ้างถึง:', - 'Complexity:' => 'ความซับซ้อน:', - 'Swimlane:' => 'สวิมเลน:', - 'Column:' => 'คอลัมน์:', - 'Position:' => 'ตำแหน่ง:', - 'Creator:' => 'ผู้สร้าง:', - 'Time estimated:' => 'เวลาเฉลี่ย:', - '%s hours' => '%s ชั่วโมง', - 'Time spent:' => 'ใช้เวลา:', - 'Created:' => 'สร้าง:', - 'Modified:' => 'แก้ไข:', - 'Completed:' => 'เสร็จสิ้น:', - 'Started:' => 'เริ่ม:', + 'Reference:' => 'อ้างถึง:', + 'Complexity:' => 'ความซับซ้อน:', + 'Swimlane:' => 'สวิมเลน:', + 'Column:' => 'คอลัมน์:', + 'Position:' => 'ตำแหน่ง:', + 'Creator:' => 'ผู้สร้าง:', + 'Time estimated:' => 'เวลาเฉลี่ย:', + '%s hours' => '%s ชั่วโมง', + 'Time spent:' => 'ใช้เวลา:', + 'Created:' => 'สร้าง:', + 'Modified:' => 'แก้ไข:', + 'Completed:' => 'เสร็จสิ้น:', + 'Started:' => 'เริ่ม:', 'Moved:' => 'ย้าย:', - 'Task #%d' => 'งานที่ #%d', - 'Sub-tasks' => 'งานย่อย', - 'Date and time format' => 'รูปแบบของวันเวลา', - 'Time format' => 'รูปแบบของเวลา', - 'Start date: ' => 'เริ่มวันที่:', - 'End date: ' => 'จบวันที่:', - 'New due date: ' => 'วันครบกำหนดใหม่', - 'Start date changed: ' => 'เปลี่ยนวันที่เริ่ม', + 'Task #%d' => 'งานที่ #%d', + 'Date and time format' => 'รูปแบบของวันเวลา', + 'Time format' => 'รูปแบบของเวลา', + 'Start date: ' => 'เริ่มวันที่:', + 'End date: ' => 'จบวันที่:', + 'New due date: ' => 'วันครบกำหนดใหม่', + 'Start date changed: ' => 'เปลี่ยนวันที่เริ่ม', + // 'Disable private projects' => '', + // 'Do you really want to remove this custom filter: "%s"?' => '', + // 'Remove a custom filter' => '', + // 'User activated successfully.' => '', + // 'Unable to enable this user.' => '', + // 'User disabled successfully.' => '', + // 'Unable to disable this user.' => '', + // 'All files have been uploaded successfully.' => '', + // 'View uploaded files' => '', + // 'The maximum allowed file size is %sB.' => '', + // 'Choose files again' => '', + // 'Drag and drop your files here' => '', + // 'choose files' => '', + // 'View profile' => '', + // 'Two Factor' => '', + // 'Disable user' => '', + // 'Do you really want to disable this user: "%s"?' => '', + // 'Enable user' => '', + // 'Do you really want to enable this user: "%s"?' => '', + // 'Download' => '', + // 'Uploaded: %s' => '', + // 'Size: %s' => '', + // 'Uploaded by %s' => '', + // 'Filename' => '', + // 'Size' => '', + // 'Column created successfully.' => '', + // 'Another column with the same name exists in the project' => '', + // 'Default filters' => '', + // 'Your board doesn\'t have any column!' => '', + // 'Change column position' => '', + // 'Switch to the project overview' => '', + // 'User filters' => '', + // 'Category filters' => '', + // 'Upload a file' => '', + // 'View file' => '', + // 'Last activity' => '', + // 'Change subtask position' => '', + // 'This value must be greater than %d' => '', + // 'Another swimlane with the same name exists in the project' => '', + // 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => '', + // 'Actions duplicated successfully.' => '', + // 'Unable to duplicate actions.' => '', + // 'Add a new action' => '', + // 'Import from another project' => '', + // 'There is no action at the moment.' => '', + // 'Import actions from another project' => '', + // 'There is no available project.' => '', + // 'Local File' => '', + // 'Configuration' => '', + // 'PHP version:' => '', + // 'PHP SAPI:' => '', + // 'OS version:' => '', + // 'Database version:' => '', + // 'Browser:' => '', + // 'Task view' => '', + // 'Edit task' => '', + // 'Edit description' => '', + // 'New internal link' => '', + // 'Display list of keyboard shortcuts' => '', + // 'Menu' => '', + // 'Set start date' => '', + // 'Avatar' => '', + // 'Upload my avatar image' => '', + // 'Remove my image' => '', + // 'The OAuth2 state parameter is invalid' => '', ); diff --git a/sources/app/Locale/tr_TR/translations.php b/sources/app/Locale/tr_TR/translations.php index aa73c1c..6e8fae2 100644 --- a/sources/app/Locale/tr_TR/translations.php +++ b/sources/app/Locale/tr_TR/translations.php @@ -8,7 +8,6 @@ return array( 'Edit' => 'Düzenle', 'remove' => 'sil', 'Remove' => 'Sil', - 'Update' => 'Güncelle', 'Yes' => 'Evet', 'No' => 'Hayır', 'cancel' => 'İptal', @@ -60,7 +59,6 @@ return array( 'Actions' => 'İşlemler', 'Inactive' => 'Aktif değil', 'Active' => 'Aktif', - '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.', @@ -74,7 +72,6 @@ return array( 'All projects' => 'Tüm projeler', 'Add a new column' => 'Yeni sütun ekle', 'Title' => 'Başlık', - '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', @@ -168,7 +165,6 @@ return array( 'Task count' => 'Görev sayısı', 'User' => 'Kullanıcı', 'Comments' => 'Yorumlar', - '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', @@ -184,7 +180,6 @@ return array( '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ı', @@ -194,7 +189,6 @@ return array( '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', 'Assign the task to a specific user' => 'Görevi bir kullanıcıya ata', @@ -333,10 +327,10 @@ return array( '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', 'New attachment' => 'Yeni dosya eki', 'New comment' => 'Yeni yorum', + 'Comment updated' => 'Yorum güncellendi', 'New subtask' => 'Yeni alt görev', 'Subtask updated' => 'Alt görev güncellendi', 'Task updated' => 'Görev güncellendi', @@ -436,7 +430,6 @@ return array( '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', 'Start date' => 'Başlangıç tarihi', 'Time estimated' => 'Tahmini süre', @@ -487,9 +480,6 @@ return array( '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', @@ -543,7 +533,6 @@ return array( '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?', @@ -734,7 +723,7 @@ return array( 'Time spent changed: %sh' => 'Harcanan zaman değiştirildi: %sh', 'Time estimated changed: %sh' => 'Tahmini süre değiştirildi: %sh', 'The field "%s" have been updated' => '"%s" hanesi değiştirildi', - 'The description have been modified' => 'Açıklama değiştirildi', + 'The description has been modified:' => 'Açıklama değiştirildi', 'Do you really want to close the task "%s" as well as all subtasks?' => '"%s" görevini ve tüm alt görevlerini kapatmak istediğinize emin misiniz?', 'I want to receive notifications for:' => 'Bununla ilgili bildirimler almak istiyorum:', 'All tasks' => 'Tüm görevler', @@ -753,8 +742,6 @@ return array( 'My activity stream' => 'Olay akışım', 'My calendar' => 'Takvimim', 'Search tasks' => 'Görevleri ara', - 'Back to the calendar' => 'Takvime geri dön', - 'Filters' => 'Filtreler', 'Reset filters' => 'Filtreleri sıfırla', 'My tasks due tomorrow' => 'Yarına tamamlanması gereken görevlerim', 'Tasks due today' => 'Bugün tamamlanması gereken görevler', @@ -854,7 +841,6 @@ return array( 'End date:' => 'Bitiş tarihi:', 'There is no start date or end date for this project.' => 'Bu proje için başlangıç veya bitiş tarihi yok.', 'Projects Gantt chart' => 'Projeler Gantt diyagramı', - 'Link type' => 'Bağlantı türü', 'Change task color when using a specific task link' => 'Belirli bir görev bağlantısı kullanıldığında görevin rengini değiştir', 'Task link creation or modification' => 'Görev bağlantısı oluşturulması veya değiştirilmesi', 'Milestone' => 'Kilometre taşı', @@ -906,7 +892,6 @@ return array( 'Shared' => 'Paylaşılan', 'Owner' => 'Sahibi', 'Unread notifications' => 'Okunmamış bildirimler', - 'My filters' => 'Filtrelerim', 'Notification methods:' => 'Bildirim yöntemleri:', 'Import tasks from CSV file' => 'CSV dosyasından görevleri içeri aktar', 'Unable to read your file' => 'Dosya okunamıyor', @@ -944,6 +929,7 @@ return array( 'Usernames must be lowercase and unique' => 'Kullanıcı adları küçük harf ve tekil olmalı', 'Passwords will be encrypted if present' => 'Şifreler (eğer varsa) kriptolanır', '%s attached a new file to the task %s' => '%s, %s görevine yeni dosya ekledi', + 'Link type' => 'Bağlantı türü', 'Assign automatically a category based on a link' => 'Bir bağlantıya göre otomatik olarak kategori ata', 'BAM - Konvertible Mark' => 'BAM - Konvertible Mark', 'Assignee Username' => 'Atanan kullanıcı adı', @@ -1053,7 +1039,6 @@ return array( // 'Close a task when there is no activity' => '', // 'Duration in days' => '', // 'Send email when there is no activity on a task' => '', - // 'List of external links' => '', // 'Unable to fetch link information.' => '', // 'Daily background job for tasks' => '', // 'Auto' => '', @@ -1071,9 +1056,7 @@ return array( // 'External link' => '', // 'Copy and paste your link here...' => '', // 'URL' => '', - // 'There is no external link for the moment.' => '', // 'Internal links' => '', - // 'There is no internal link for the moment.' => '', // 'Assign to me' => '', // 'Me' => '', // 'Do not duplicate anything' => '', @@ -1081,7 +1064,6 @@ return array( // 'Users management' => '', // 'Groups management' => '', // 'Create from another project' => '', - // 'There is no subtask at the moment.' => '', // 'open' => '', // 'closed' => '', // 'Priority:' => '', @@ -1100,7 +1082,6 @@ return array( // 'Started:' => '', // 'Moved:' => '', // 'Task #%d' => '', - // 'Sub-tasks' => '', // 'Date and time format' => '', // 'Time format' => '', // 'Start date: ' => '', @@ -1141,11 +1122,35 @@ return array( // 'User filters' => '', // 'Category filters' => '', // 'Upload a file' => '', - // 'There is no attachment at the moment.' => '', // 'View file' => '', // 'Last activity' => '', // 'Change subtask position' => '', // 'This value must be greater than %d' => '', // 'Another swimlane with the same name exists in the project' => '', // 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => '', + // 'Actions duplicated successfully.' => '', + // 'Unable to duplicate actions.' => '', + // 'Add a new action' => '', + // 'Import from another project' => '', + // 'There is no action at the moment.' => '', + // 'Import actions from another project' => '', + // 'There is no available project.' => '', + // 'Local File' => '', + // 'Configuration' => '', + // 'PHP version:' => '', + // 'PHP SAPI:' => '', + // 'OS version:' => '', + // 'Database version:' => '', + // 'Browser:' => '', + // 'Task view' => '', + // 'Edit task' => '', + // 'Edit description' => '', + // 'New internal link' => '', + // 'Display list of keyboard shortcuts' => '', + // 'Menu' => '', + // 'Set start date' => '', + // 'Avatar' => '', + // 'Upload my avatar image' => '', + // 'Remove my image' => '', + // 'The OAuth2 state parameter is invalid' => '', ); diff --git a/sources/app/Locale/zh_CN/translations.php b/sources/app/Locale/zh_CN/translations.php index 55d5463..decd49d 100644 --- a/sources/app/Locale/zh_CN/translations.php +++ b/sources/app/Locale/zh_CN/translations.php @@ -8,7 +8,6 @@ return array( 'Edit' => '编辑', 'remove' => '移除', 'Remove' => '移除', - 'Update' => '更新', 'Yes' => '是', 'No' => '否', 'cancel' => '取消', @@ -60,7 +59,6 @@ return array( 'Actions' => '动作', 'Inactive' => '未激活', 'Active' => '激活', - 'Add this column' => '加入该栏目', '%d tasks on the board' => '看板目前有%d个任务', '%d tasks in total' => '总共有%d个任务', 'Unable to update this board.' => '无法更新该看板。', @@ -74,7 +72,6 @@ return array( 'All projects' => '所有项目', 'Add a new column' => '添加新栏目', 'Title' => '标题', - 'Nobody assigned' => '无人被指派', 'Assigned to %s' => '指派给 %s', 'Remove a column' => '移除一个栏目', 'Remove a column from a board' => '从看板移除一个栏目', @@ -168,7 +165,6 @@ return array( 'Task count' => '任务数', 'User' => '用户', 'Comments' => '评论', - 'Write your text in Markdown' => '用Markdown格式编写', 'Leave a comment' => '留言', 'Comment is required' => '必须得有评论', 'Leave a description' => '给一个描述', @@ -184,7 +180,6 @@ return array( 'Unable to remove this action.' => '无法移除该动作', 'Action removed successfully.' => '成功移除动作。', 'Automatic actions for the project "%s"' => '项目"%s"的自动动作', - 'Defined actions' => '已定义的动作', 'Add an action' => '添加动作', 'Event name' => '事件名称', 'Action name' => '动作名称', @@ -194,7 +189,6 @@ return array( 'When the selected event occurs execute the corresponding action.' => '当所选事件发生时执行相应动作。', 'Next step' => '下一步', 'Define action parameters' => '定义动作参数', - 'Save this action' => '保存该动作', 'Do you really want to remove this action: "%s"?' => '确定要移除动作"%s"吗?', 'Remove an automatic action' => '移除一个自动动作', 'Assign the task to a specific user' => '将该任务指派给一个用户', @@ -333,10 +327,10 @@ return array( 'Time tracking:' => '时间记录', 'New sub-task' => '新建子任务', 'New attachment added "%s"' => '新附件已添加"%s"', - 'Comment updated' => '更新了评论', 'New comment posted by %s' => '%s 的新评论', 'New attachment' => '新建附件', 'New comment' => '新建评论', + 'Comment updated' => '更新了评论', 'New subtask' => '新建子任务', 'Subtask updated' => '子任务更新', 'Task updated' => '任务更新', @@ -436,7 +430,6 @@ return array( 'ISO format is always accepted, example: "%s" and "%s"' => 'ISO 格式总是允许的,例如:"%s" 和 "%s"', 'New private project' => '新建私有项目', 'This project is private' => '此项目为私有项目', - 'Type here to create a new sub-task' => '要创建新的子任务,请在此输入', 'Add' => '添加', 'Start date' => '启动日期', 'Time estimated' => '预计时间', @@ -487,9 +480,6 @@ return array( 'Daily project summary export for "%s"' => '导出项目"%s"的每日汇总', 'Exports' => '导出', 'This export contains the number of tasks per column grouped per day.' => '此导出包含每列的任务数,按天分组', - 'Nothing to preview...' => '没有需要预览的内容', - 'Preview' => '预览', - 'Write' => '书写', 'Active swimlanes' => '活动里程碑', 'Add a new swimlane' => '添加新里程碑', 'Change default swimlane' => '修改默认里程碑', @@ -543,7 +533,6 @@ return array( '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 的关联吗?', @@ -734,7 +723,7 @@ return array( 'Time spent changed: %sh' => '时间花费已变更:%sh', 'Time estimated changed: %sh' => '时间预估已变更:%sh', 'The field "%s" have been updated' => '"%s"字段已更新', - 'The description have been modified' => '描述已更改', + 'The description has been modified:' => '描述已更改', 'Do you really want to close the task "%s" as well as all subtasks?' => '你是否要移除所有子任务的同时父任务"%s"', 'I want to receive notifications for:' => '我想接收以下相关通知:', 'All tasks' => '所有任务', @@ -753,8 +742,6 @@ return array( 'My activity stream' => '我的活动流', 'My calendar' => '我的日程表', 'Search tasks' => '搜索任务', - 'Back to the calendar' => '返回日程', - 'Filters' => '过滤器', 'Reset filters' => '重置过滤器', 'My tasks due tomorrow' => '我的明天到期的任务', 'Tasks due today' => '今天到期的任务', @@ -854,7 +841,6 @@ return array( 'End date:' => '结束日期', 'There is no start date or end date for this project.' => '当前项目没有开始或结束日期', 'Projects Gantt chart' => '项目甘特图', - 'Link type' => '关联类型', 'Change task color when using a specific task link' => '当任务关联到指定任务时改变颜色', 'Task link creation or modification' => '任务链接创建或更新时间', 'Milestone' => '里程碑', @@ -906,7 +892,6 @@ return array( 'Shared' => '共享', 'Owner' => '所有人', 'Unread notifications' => '未读通知', - 'My filters' => '我的过滤器', 'Notification methods:' => '通知提醒方式:', 'Import tasks from CSV file' => '从CSV文件导入任务', 'Unable to read your file' => '无法读取文件', @@ -944,6 +929,7 @@ return array( 'Usernames must be lowercase and unique' => '用户名必须小写且唯一', 'Passwords will be encrypted if present' => '密码将被加密', '%s attached a new file to the task %s' => '"%s"添加了附件到任务"%s"', + 'Link type' => '关联类型', 'Assign automatically a category based on a link' => '基于链接自动关联分类', 'BAM - Konvertible Mark' => '波斯尼亚马克', 'Assignee Username' => '指派用户名', @@ -1053,7 +1039,6 @@ return array( 'Close a task when there is no activity' => '当任务没有活动记录时关闭任务', 'Duration in days' => '持续天数', 'Send email when there is no activity on a task' => '当任务没有活动记录时发送邮件', - 'List of external links' => '列出外部关联', 'Unable to fetch link information.' => '无法获取关联信息', 'Daily background job for tasks' => '每日后台任务', 'Auto' => '自动', @@ -1071,9 +1056,7 @@ return array( 'External link' => '外部关联', 'Copy and paste your link here...' => '复制并粘贴链接到当前位置...', 'URL' => 'URL', - 'There is no external link for the moment.' => '当前没有外部关联。', 'Internal links' => '内部关联', - 'There is no internal link for the moment.' => '当前没有内部关联。', 'Assign to me' => '指派给我', 'Me' => '我', 'Do not duplicate anything' => '不再重复', @@ -1081,7 +1064,6 @@ return array( 'Users management' => '用户管理', 'Groups management' => '用户组管理', 'Create from another project' => '从另一个项目中创建', - 'There is no subtask at the moment.' => '当前没有子任务。', 'open' => '打开', 'closed' => '已关闭', 'Priority:' => '优先级:', @@ -1100,7 +1082,6 @@ return array( 'Started:' => '已开始:', 'Moved:' => '已移走', 'Task #%d' => '任务#%d', - 'Sub-tasks' => '子任务', 'Date and time format' => '时间和日期格式', 'Time format' => '时间格式', 'Start date: ' => '开始时间:', @@ -1132,20 +1113,44 @@ return array( 'Uploaded by %s' => '由%s上传', 'Filename' => '文件名', 'Size' => '大小', - // 'Column created successfully.' => '', - // 'Another column with the same name exists in the project' => '', - // 'Default filters' => '', - // 'Your board doesn\'t have any column!' => '', - // 'Change column position' => '', - // 'Switch to the project overview' => '', - // 'User filters' => '', - // 'Category filters' => '', - // 'Upload a file' => '', - // 'There is no attachment at the moment.' => '', - // 'View file' => '', - // 'Last activity' => '', - // 'Change subtask position' => '', - // 'This value must be greater than %d' => '', - // 'Another swimlane with the same name exists in the project' => '', - // 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => '', + 'Column created successfully.' => '新增任务栏成功。', + 'Another column with the same name exists in the project' => '当前项目中重名任务栏已存在', + 'Default filters' => '默认过滤器', + 'Your board doesn\'t have any column!' => '你的看板没有任何栏目', + 'Change column position' => '更改任务栏位置', + 'Switch to the project overview' => '切换到项目视图', + 'User filters' => '用户过滤器', + 'Category filters' => '分类过滤器', + 'Upload a file' => '上传文件', + 'View file' => '查看文件', + 'Last activity' => '最后活动', + 'Change subtask position' => '更改子任务位置', + 'This value must be greater than %d' => '当前输入值必须大于%d', + 'Another swimlane with the same name exists in the project' => '当前项目中重名里程碑已存在', + 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => '例如: http://example.kanboard.net/(通常用于生成绝对地址)', + 'Actions duplicated successfully.' => '动作复制成功。', + 'Unable to duplicate actions.' => '无法复制动作。', + 'Add a new action' => '添加新动作', + 'Import from another project' => '从另一个项目中导入', + 'There is no action at the moment.' => '当前没有动作。', + 'Import actions from another project' => '从另一个项目中导入动作', + 'There is no available project.' => '当前没有可用项目', + // 'Local File' => '', + // 'Configuration' => '', + // 'PHP version:' => '', + // 'PHP SAPI:' => '', + // 'OS version:' => '', + // 'Database version:' => '', + // 'Browser:' => '', + // 'Task view' => '', + // 'Edit task' => '', + // 'Edit description' => '', + // 'New internal link' => '', + // 'Display list of keyboard shortcuts' => '', + // 'Menu' => '', + // 'Set start date' => '', + // 'Avatar' => '', + // 'Upload my avatar image' => '', + // 'Remove my image' => '', + // 'The OAuth2 state parameter is invalid' => '', ); diff --git a/sources/app/Model/Action.php b/sources/app/Model/Action.php index 4da2fb8..f055d9d 100644 --- a/sources/app/Model/Action.php +++ b/sources/app/Model/Action.php @@ -151,7 +151,7 @@ class Action extends Base * * @author Antonio Rabelo * @param integer $src_project_id Source project id - * @return integer $dst_project_id Destination project id + * @param integer $dst_project_id Destination project id * @return boolean */ public function duplicate($src_project_id, $dst_project_id) diff --git a/sources/app/Model/AvatarFile.php b/sources/app/Model/AvatarFile.php new file mode 100644 index 0000000..52d0796 --- /dev/null +++ b/sources/app/Model/AvatarFile.php @@ -0,0 +1,111 @@ +db->table(User::TABLE)->eq('id', $user_id)->findOneColumn('avatar_path'); + } + + /** + * Add avatar in the user profile + * + * @access public + * @param integer $user_id Foreign key + * @param string $path Path on the disk + * @return bool + */ + public function create($user_id, $path) + { + $result = $this->db->table(User::TABLE)->eq('id', $user_id)->update(array( + 'avatar_path' => $path, + )); + + $this->userSession->refresh($user_id); + + return $result; + } + + /** + * Remove avatar from the user profile + * + * @access public + * @param integer $user_id Foreign key + * @return bool + */ + public function remove($user_id) + { + try { + $this->objectStorage->remove($this->getFilename($user_id)); + $result = $this->db->table(User::TABLE)->eq('id', $user_id)->update(array('avatar_path' => '')); + $this->userSession->refresh($user_id); + return $result; + } catch (Exception $e) { + $this->logger->error($e->getMessage()); + return false; + } + } + + /** + * Upload avatar image + * + * @access public + * @param integer $user_id + * @param array $file + */ + public function uploadFile($user_id, array $file) + { + try { + if ($file['error'] == UPLOAD_ERR_OK && $file['size'] > 0) { + $destination_filename = $this->generatePath($user_id, $file['name']); + $this->objectStorage->moveUploadedFile($file['tmp_name'], $destination_filename); + $this->create($user_id, $destination_filename); + } else { + throw new Exception('File not uploaded: '.var_export($file['error'], true)); + } + + } catch (Exception $e) { + $this->logger->error($e->getMessage()); + return false; + } + + return true; + } + + /** + * Generate the path for a new filename + * + * @access public + * @param integer $user_id + * @param string $filename + * @return string + */ + public function generatePath($user_id, $filename) + { + return implode(DIRECTORY_SEPARATOR, array(self::PATH_PREFIX, $user_id, hash('sha1', $filename.time()))); + } +} diff --git a/sources/app/Model/Base.php b/sources/app/Model/Base.php index 6fe3d74..714b430 100644 --- a/sources/app/Model/Base.php +++ b/sources/app/Model/Base.php @@ -32,86 +32,6 @@ abstract class Base extends \Kanboard\Core\Base }); } - /** - * Remove keys from an array - * - * @access public - * @param array $values Input array - * @param string[] $keys List of keys to remove - */ - public function removeFields(array &$values, array $keys) - { - foreach ($keys as $key) { - if (array_key_exists($key, $values)) { - unset($values[$key]); - } - } - } - - /** - * Remove keys from an array if empty - * - * @access public - * @param array $values Input array - * @param string[] $keys List of keys to remove - */ - public function removeEmptyFields(array &$values, array $keys) - { - foreach ($keys as $key) { - if (array_key_exists($key, $values) && empty($values[$key])) { - unset($values[$key]); - } - } - } - - /** - * Force fields to be at 0 if empty - * - * @access public - * @param array $values Input array - * @param string[] $keys List of keys - */ - public function resetFields(array &$values, array $keys) - { - foreach ($keys as $key) { - if (isset($values[$key]) && empty($values[$key])) { - $values[$key] = 0; - } - } - } - - /** - * Force some fields to be integer - * - * @access public - * @param array $values Input array - * @param string[] $keys List of keys - */ - public function convertIntegerFields(array &$values, array $keys) - { - foreach ($keys as $key) { - if (isset($values[$key])) { - $values[$key] = (int) $values[$key]; - } - } - } - - /** - * Force some fields to be null if empty - * - * @access public - * @param array $values Input array - * @param string[] $keys List of keys - */ - public function convertNullFields(array &$values, array $keys) - { - foreach ($keys as $key) { - if (array_key_exists($key, $values) && empty($values[$key])) { - $values[$key] = null; - } - } - } - /** * Build SQL condition for a given time range * @@ -135,23 +55,4 @@ abstract class Base extends \Kanboard\Core\Base return $start_column.' IS NOT NULL AND '.$start_column.' > 0 AND ('.implode(' OR ', $conditions).')'; } - - /** - * Group a collection of records by a column - * - * @access public - * @param array $collection - * @param string $column - * @return array - */ - public function groupByColumn(array $collection, $column) - { - $result = array(); - - foreach ($collection as $item) { - $result[$item[$column]][] = $item; - } - - return $result; - } } diff --git a/sources/app/Model/Board.php b/sources/app/Model/Board.php index c10be19..d41ecaf 100644 --- a/sources/app/Model/Board.php +++ b/sources/app/Model/Board.php @@ -77,7 +77,7 @@ class Board extends Base * * @author Antonio Rabelo * @param integer $project_from Project Template - * @return integer $project_to Project that receives the copy + * @param integer $project_to Project that receives the copy * @return boolean */ public function duplicate($project_from, $project_to) diff --git a/sources/app/Model/Category.php b/sources/app/Model/Category.php index 883fc28..1d5f654 100644 --- a/sources/app/Model/Category.php +++ b/sources/app/Model/Category.php @@ -22,12 +22,11 @@ class Category extends Base * * @access public * @param integer $category_id Category id - * @param integer $project_id Project id * @return boolean */ - public function exists($category_id, $project_id) + public function exists($category_id) { - return $this->db->table(self::TABLE)->eq('id', $category_id)->eq('project_id', $project_id)->exists(); + return $this->db->table(self::TABLE)->eq('id', $category_id)->exists(); } /** @@ -115,25 +114,29 @@ class Category extends Base } /** - * Create default cetegories during project creation (transaction already started in Project::create()) + * Create default categories during project creation (transaction already started in Project::create()) * * @access public * @param integer $project_id + * @return boolean */ public function createDefaultCategories($project_id) { + $results = array(); $categories = explode(',', $this->config->get('project_categories')); foreach ($categories as $category) { $category = trim($category); if (! empty($category)) { - $this->db->table(self::TABLE)->insert(array( + $results[] = $this->db->table(self::TABLE)->insert(array( 'project_id' => $project_id, 'name' => $category, )); } } + + return in_array(false, $results, true); } /** @@ -188,14 +191,14 @@ class Category extends Base * * @author Antonio Rabelo * @param integer $src_project_id Source project id - * @return integer $dst_project_id Destination project id + * @param integer $dst_project_id Destination project id * @return boolean */ public function duplicate($src_project_id, $dst_project_id) { $categories = $this->db ->table(self::TABLE) - ->columns('name') + ->columns('name', 'description') ->eq('project_id', $src_project_id) ->asc('name') ->findAll(); diff --git a/sources/app/Model/Color.php b/sources/app/Model/Color.php index d341dd3..dee2864 100644 --- a/sources/app/Model/Color.php +++ b/sources/app/Model/Color.php @@ -141,6 +141,7 @@ class Color extends Base * Get available colors * * @access public + * @param bool $prepend * @return array */ public function getList($prepend = false) @@ -177,7 +178,7 @@ class Color extends Base } /** - * Get Bordercolor from string + * Get border color from string * * @access public * @param string $color_id Color id diff --git a/sources/app/Model/Comment.php b/sources/app/Model/Comment.php index 6eb4a1e..f7ac4ea 100644 --- a/sources/app/Model/Comment.php +++ b/sources/app/Model/Comment.php @@ -48,7 +48,8 @@ class Comment extends Base self::TABLE.'.comment', User::TABLE.'.username', User::TABLE.'.name', - User::TABLE.'.email' + User::TABLE.'.email', + User::TABLE.'.avatar_path' ) ->join(User::TABLE, 'id', 'user_id') ->orderBy(self::TABLE.'.date_creation', $sorting) diff --git a/sources/app/Model/Config.php b/sources/app/Model/Config.php index 6f00917..0c363fb 100644 --- a/sources/app/Model/Config.php +++ b/sources/app/Model/Config.php @@ -90,6 +90,7 @@ class Config extends Setting 'fi_FI' => 'Suomi', 'sv_SE' => 'Svenska', 'tr_TR' => 'Türkçe', + 'ko_KR' => '한국어', 'zh_CN' => '中文(简体)', 'ja_JP' => '日本語', 'th_TH' => 'ไทย', @@ -129,6 +130,7 @@ class Config extends Setting 'fi_FI' => 'fi', 'sv_SE' => 'sv', 'tr_TR' => 'tr', + 'ko_KR' => 'ko', 'zh_CN' => 'zh-cn', 'ja_JP' => 'ja', 'th_TH' => 'th', @@ -239,6 +241,7 @@ class Config extends Setting * Prepare data before save * * @access public + * @param array $values * @return array */ public function prepare(array $values) diff --git a/sources/app/Model/File.php b/sources/app/Model/File.php index 03ea691..e383235 100644 --- a/sources/app/Model/File.php +++ b/sources/app/Model/File.php @@ -3,8 +3,8 @@ namespace Kanboard\Model; use Exception; +use Kanboard\Core\Thumbnail; use Kanboard\Event\FileEvent; -use Kanboard\Core\Tool; use Kanboard\Core\ObjectStorage\ObjectStorageException; /** @@ -315,15 +315,15 @@ abstract class File extends Base */ public function generateThumbnailFromData($destination_filename, &$data) { - $temp_filename = tempnam(sys_get_temp_dir(), 'datafile'); + $blob = Thumbnail::createFromString($data) + ->resize() + ->toString(); - file_put_contents($temp_filename, $data); - $this->generateThumbnailFromFile($temp_filename, $destination_filename); - unlink($temp_filename); + $this->objectStorage->put($this->getThumbnailPath($destination_filename), $blob); } /** - * Generate thumbnail from a blob + * Generate thumbnail from a local file * * @access public * @param string $uploaded_filename @@ -331,8 +331,10 @@ abstract class File extends Base */ public function generateThumbnailFromFile($uploaded_filename, $destination_filename) { - $thumbnail_filename = tempnam(sys_get_temp_dir(), 'thumbnail'); - Tool::generateThumbnail($uploaded_filename, $thumbnail_filename); - $this->objectStorage->moveFile($thumbnail_filename, $this->getThumbnailPath($destination_filename)); + $blob = Thumbnail::createFromFile($uploaded_filename) + ->resize() + ->toString(); + + $this->objectStorage->put($this->getThumbnailPath($destination_filename), $blob); } } diff --git a/sources/app/Model/Link.php b/sources/app/Model/Link.php index 7b81a23..903a98d 100644 --- a/sources/app/Model/Link.php +++ b/sources/app/Model/Link.php @@ -90,7 +90,7 @@ class Link extends Base * * @access public * @param integer $exclude_id Exclude this link - * @param booelan $prepend Prepend default value + * @param boolean $prepend Prepend default value * @return array */ public function getList($exclude_id = 0, $prepend = true) diff --git a/sources/app/Model/Metadata.php b/sources/app/Model/Metadata.php index 690b226..01799a4 100644 --- a/sources/app/Model/Metadata.php +++ b/sources/app/Model/Metadata.php @@ -76,23 +76,37 @@ abstract class Metadata extends Base * @access public * @param integer $entity_id * @param array $values + * @return boolean */ public function save($entity_id, array $values) { $results = array(); + $user_id = $this->userSession->getId(); + $timestamp = time(); $this->db->startTransaction(); foreach ($values as $key => $value) { if ($this->exists($entity_id, $key)) { - $results[] = $this->db->table(static::TABLE)->eq($this->getEntityKey(), $entity_id)->eq('name', $key)->update(array('value' => $value)); + $results[] = $this->db->table(static::TABLE) + ->eq($this->getEntityKey(), $entity_id) + ->eq('name', $key)->update(array( + 'value' => $value, + 'changed_on' => $timestamp, + 'changed_by' => $user_id, + )); } else { - $results[] = $this->db->table(static::TABLE)->insert(array('name' => $key, 'value' => $value, $this->getEntityKey() => $entity_id)); + $results[] = $this->db->table(static::TABLE)->insert(array( + 'name' => $key, + 'value' => $value, + $this->getEntityKey() => $entity_id, + 'changed_on' => $timestamp, + 'changed_by' => $user_id, + )); } } $this->db->closeTransaction(); - return ! in_array(false, $results, true); } diff --git a/sources/app/Model/NotificationType.php b/sources/app/Model/NotificationType.php index 9d8317b..289aae9 100644 --- a/sources/app/Model/NotificationType.php +++ b/sources/app/Model/NotificationType.php @@ -80,7 +80,7 @@ abstract class NotificationType extends Base * * @access public * @param string $type - * @return NotificationInterface + * @return \Kanboard\Notification\NotificationInterface */ public function getType($type) { diff --git a/sources/app/Model/OverdueNotification.php b/sources/app/Model/OverdueNotification.php deleted file mode 100644 index 8456554..0000000 --- a/sources/app/Model/OverdueNotification.php +++ /dev/null @@ -1,58 +0,0 @@ -taskFinder->getOverdueTasks(); - - foreach ($this->groupByColumn($tasks, 'project_id') as $project_id => $project_tasks) { - $users = $this->userNotification->getUsersWithNotificationEnabled($project_id); - - foreach ($users as $user) { - $this->sendUserOverdueTaskNotifications($user, $project_tasks); - } - } - - return $tasks; - } - - /** - * Send overdue tasks for a given user - * - * @access public - * @param array $user - * @param array $tasks - */ - public function sendUserOverdueTaskNotifications(array $user, array $tasks) - { - $user_tasks = array(); - - foreach ($tasks as $task) { - if ($this->userNotificationFilter->shouldReceiveNotification($user, array('task' => $task))) { - $user_tasks[] = $task; - } - } - - if (! empty($user_tasks)) { - $this->userNotification->sendUserNotification( - $user, - Task::EVENT_OVERDUE, - array('tasks' => $user_tasks, 'project_name' => $tasks[0]['project_name']) - ); - } - } -} diff --git a/sources/app/Model/PasswordReset.php b/sources/app/Model/PasswordReset.php index c2d7dde..5cfd3c9 100644 --- a/sources/app/Model/PasswordReset.php +++ b/sources/app/Model/PasswordReset.php @@ -20,7 +20,7 @@ class PasswordReset extends Base /** * Token duration (30 minutes) * - * @var string + * @var integer */ const DURATION = 1800; diff --git a/sources/app/Model/Project.php b/sources/app/Model/Project.php index a79e46a..d2e5b7c 100644 --- a/sources/app/Model/Project.php +++ b/sources/app/Model/Project.php @@ -334,7 +334,7 @@ class Project extends Base $values['identifier'] = strtoupper($values['identifier']); } - $this->convertIntegerFields($values, array('priority_default', 'priority_start', 'priority_end')); + $this->helper->model->convertIntegerFields($values, array('priority_default', 'priority_start', 'priority_end')); if (! $this->db->table(self::TABLE)->save($values)) { $this->db->cancelTransaction(); @@ -402,7 +402,7 @@ class Project extends Base $values['identifier'] = strtoupper($values['identifier']); } - $this->convertIntegerFields($values, array('priority_default', 'priority_start', 'priority_end')); + $this->helper->model->convertIntegerFields($values, array('priority_default', 'priority_start', 'priority_end')); return $this->exists($values['id']) && $this->db->table(self::TABLE)->eq('id', $values['id'])->save($values); diff --git a/sources/app/Model/ProjectActivity.php b/sources/app/Model/ProjectActivity.php index 74df26a..d399d5c 100644 --- a/sources/app/Model/ProjectActivity.php +++ b/sources/app/Model/ProjectActivity.php @@ -88,7 +88,8 @@ class ProjectActivity extends Base self::TABLE.'.*', User::TABLE.'.username AS author_username', User::TABLE.'.name AS author_name', - User::TABLE.'.email' + User::TABLE.'.email', + User::TABLE.'.avatar_path' ) ->in('project_id', $project_ids) ->join(User::TABLE, 'id', 'creator_id') @@ -117,7 +118,8 @@ class ProjectActivity extends Base self::TABLE.'.*', User::TABLE.'.username AS author_username', User::TABLE.'.name AS author_name', - User::TABLE.'.email' + User::TABLE.'.email', + User::TABLE.'.avatar_path' ) ->eq('task_id', $task_id) ->join(User::TABLE, 'id', 'creator_id') diff --git a/sources/app/Model/ProjectDailyColumnStats.php b/sources/app/Model/ProjectDailyColumnStats.php index 2bcc4d5..0706a11 100644 --- a/sources/app/Model/ProjectDailyColumnStats.php +++ b/sources/app/Model/ProjectDailyColumnStats.php @@ -165,7 +165,7 @@ class ProjectDailyColumnStats extends Base { foreach ($metrics as $metric) { if ($metric['day'] === $day && $metric['column_id'] == $column_id) { - return $metric[$field]; + return (int) $metric[$field]; } } diff --git a/sources/app/Model/ProjectDailyStats.php b/sources/app/Model/ProjectDailyStats.php index 957ad51..974f581 100644 --- a/sources/app/Model/ProjectDailyStats.php +++ b/sources/app/Model/ProjectDailyStats.php @@ -56,12 +56,19 @@ class ProjectDailyStats extends Base */ public function getRawMetrics($project_id, $from, $to) { - return $this->db->table(self::TABLE) + $metrics = $this->db->table(self::TABLE) ->columns('day', 'avg_lead_time', 'avg_cycle_time') ->eq('project_id', $project_id) ->gte('day', $from) ->lte('day', $to) ->asc('day') ->findAll(); + + foreach ($metrics as &$metric) { + $metric['avg_lead_time'] = (int) $metric['avg_lead_time']; + $metric['avg_cycle_time'] = (int) $metric['avg_cycle_time']; + } + + return $metrics; } } diff --git a/sources/app/Model/ProjectGroupRole.php b/sources/app/Model/ProjectGroupRole.php index 750ba7f..afad4a4 100644 --- a/sources/app/Model/ProjectGroupRole.php +++ b/sources/app/Model/ProjectGroupRole.php @@ -166,7 +166,7 @@ class ProjectGroupRole extends Base * Copy group access from a project to another one * * @param integer $project_src_id Project Template - * @return integer $project_dst_id Project that receives the copy + * @param integer $project_dst_id Project that receives the copy * @return boolean */ public function duplicate($project_src_id, $project_dst_id) diff --git a/sources/app/Model/Setting.php b/sources/app/Model/Setting.php index 44e6c06..f98d7ce 100644 --- a/sources/app/Model/Setting.php +++ b/sources/app/Model/Setting.php @@ -75,19 +75,31 @@ abstract class Setting extends Base * * @access public * @param array $values + * @return boolean */ public function save(array $values) { $results = array(); $values = $this->prepare($values); + $user_id = $this->userSession->getId(); + $timestamp = time(); $this->db->startTransaction(); foreach ($values as $option => $value) { if ($this->exists($option)) { - $results[] = $this->db->table(self::TABLE)->eq('option', $option)->update(array('value' => $value)); + $results[] = $this->db->table(self::TABLE)->eq('option', $option)->update(array( + 'value' => $value, + 'changed_on' => $timestamp, + 'changed_by' => $user_id, + )); } else { - $results[] = $this->db->table(self::TABLE)->insert(array('option' => $option, 'value' => $value)); + $results[] = $this->db->table(self::TABLE)->insert(array( + 'option' => $option, + 'value' => $value, + 'changed_on' => $timestamp, + 'changed_by' => $user_id, + )); } } diff --git a/sources/app/Model/Subtask.php b/sources/app/Model/Subtask.php index b5898fc..3f5cfe8 100644 --- a/sources/app/Model/Subtask.php +++ b/sources/app/Model/Subtask.php @@ -168,8 +168,8 @@ class Subtask extends Base */ public function prepare(array &$values) { - $this->removeFields($values, array('another_subtask')); - $this->resetFields($values, array('time_estimated', 'time_spent')); + $this->helper->model->removeFields($values, array('another_subtask')); + $this->helper->model->resetFields($values, array('time_estimated', 'time_spent')); } /** diff --git a/sources/app/Model/TaskCreation.php b/sources/app/Model/TaskCreation.php index 576eb18..2d2e550 100644 --- a/sources/app/Model/TaskCreation.php +++ b/sources/app/Model/TaskCreation.php @@ -52,8 +52,8 @@ class TaskCreation extends Base $values = $this->dateParser->convert($values, array('date_due')); $values = $this->dateParser->convert($values, array('date_started'), true); - $this->removeFields($values, array('another_task')); - $this->resetFields($values, array('date_started', 'creator_id', 'owner_id', 'swimlane_id', 'date_due', 'score', 'category_id', 'time_estimated')); + $this->helper->model->removeFields($values, array('another_task')); + $this->helper->model->resetFields($values, array('date_started', 'creator_id', 'owner_id', 'swimlane_id', 'date_due', 'score', 'category_id', 'time_estimated')); if (empty($values['column_id'])) { $values['column_id'] = $this->column->getFirstColumnId($values['project_id']); diff --git a/sources/app/Model/TaskDuplication.php b/sources/app/Model/TaskDuplication.php index b081aac..ebdd4d2 100644 --- a/sources/app/Model/TaskDuplication.php +++ b/sources/app/Model/TaskDuplication.php @@ -155,6 +155,7 @@ class TaskDuplication extends Base * * @access public * @param array $values + * @return array */ public function checkDestinationProjectValues(array &$values) { diff --git a/sources/app/Model/TaskFinder.php b/sources/app/Model/TaskFinder.php index 0492a9b..7bca228 100644 --- a/sources/app/Model/TaskFinder.php +++ b/sources/app/Model/TaskFinder.php @@ -127,6 +127,8 @@ class TaskFinder extends Base 'tasks.time_spent', User::TABLE.'.username AS assignee_username', User::TABLE.'.name AS assignee_name', + User::TABLE.'.email AS assignee_email', + User::TABLE.'.avatar_path AS assignee_avatar_path', Category::TABLE.'.name AS category_name', Category::TABLE.'.description AS category_description', Column::TABLE.'.title AS column_name', diff --git a/sources/app/Model/TaskLink.php b/sources/app/Model/TaskLink.php index a57bf3b..e46ea47 100644 --- a/sources/app/Model/TaskLink.php +++ b/sources/app/Model/TaskLink.php @@ -76,6 +76,7 @@ class TaskLink extends Base Task::TABLE.'.is_active', Task::TABLE.'.project_id', Task::TABLE.'.column_id', + Task::TABLE.'.color_id', Task::TABLE.'.time_spent AS task_time_spent', Task::TABLE.'.time_estimated AS task_time_estimated', Task::TABLE.'.owner_id AS task_assignee_id', diff --git a/sources/app/Model/TaskModification.php b/sources/app/Model/TaskModification.php index 8e59b3f..a77b78a 100644 --- a/sources/app/Model/TaskModification.php +++ b/sources/app/Model/TaskModification.php @@ -87,9 +87,9 @@ class TaskModification extends Base $values = $this->dateParser->convert($values, array('date_due')); $values = $this->dateParser->convert($values, array('date_started'), true); - $this->removeFields($values, array('another_task', 'id')); - $this->resetFields($values, array('date_due', 'date_started', 'score', 'category_id', 'time_estimated', 'time_spent')); - $this->convertIntegerFields($values, array('priority', 'is_active', 'recurrence_status', 'recurrence_trigger', 'recurrence_factor', 'recurrence_timeframe', 'recurrence_basedate')); + $this->helper->model->removeFields($values, array('another_task', 'id')); + $this->helper->model->resetFields($values, array('date_due', 'date_started', 'score', 'category_id', 'time_estimated', 'time_spent')); + $this->helper->model->convertIntegerFields($values, array('priority', 'is_active', 'recurrence_status', 'recurrence_trigger', 'recurrence_factor', 'recurrence_timeframe', 'recurrence_basedate')); $values['date_modification'] = time(); } diff --git a/sources/app/Model/TaskPermission.php b/sources/app/Model/TaskPermission.php index fac2153..b1e0258 100644 --- a/sources/app/Model/TaskPermission.php +++ b/sources/app/Model/TaskPermission.php @@ -18,7 +18,8 @@ class TaskPermission extends Base * Regular users can't remove tasks from other people * * @public - * @return boolean + * @param array $task + * @return bool */ public function canRemoveTask(array $task) { diff --git a/sources/app/Model/Transition.php b/sources/app/Model/Transition.php index aa76d58..870d95f 100644 --- a/sources/app/Model/Transition.php +++ b/sources/app/Model/Transition.php @@ -3,7 +3,7 @@ namespace Kanboard\Model; /** - * Transition model + * Transition * * @package model * @author Frederic Guillot @@ -21,20 +21,22 @@ class Transition extends Base * Save transition event * * @access public - * @param integer $user_id - * @param array $task - * @return boolean + * @param integer $user_id + * @param array $task_event + * @return bool */ - public function save($user_id, array $task) + public function save($user_id, array $task_event) { + $time = time(); + return $this->db->table(self::TABLE)->insert(array( 'user_id' => $user_id, - 'project_id' => $task['project_id'], - 'task_id' => $task['task_id'], - 'src_column_id' => $task['src_column_id'], - 'dst_column_id' => $task['dst_column_id'], - 'date' => time(), - 'time_spent' => time() - $task['date_moved'] + 'project_id' => $task_event['project_id'], + 'task_id' => $task_event['task_id'], + 'src_column_id' => $task_event['src_column_id'], + 'dst_column_id' => $task_event['dst_column_id'], + 'date' => $time, + 'time_spent' => $time - $task_event['date_moved'] )); } @@ -116,71 +118,11 @@ class Transition extends Base ->lte('date', $to) ->eq(self::TABLE.'.project_id', $project_id) ->desc('date') + ->desc(self::TABLE.'.id') ->join(Task::TABLE, 'id', 'task_id') ->join(User::TABLE, 'id', 'user_id') ->join(Column::TABLE.' as src', 'id', 'src_column_id', self::TABLE, 'src') ->join(Column::TABLE.' as dst', 'id', 'dst_column_id', self::TABLE, 'dst') ->findAll(); } - - /** - * Get project export - * - * @access public - * @param integer $project_id Project id - * @param mixed $from Start date (timestamp or user formatted date) - * @param mixed $to End date (timestamp or user formatted date) - * @return array - */ - public function export($project_id, $from, $to) - { - $results = array($this->getColumns()); - $transitions = $this->getAllByProjectAndDate($project_id, $from, $to); - - foreach ($transitions as $transition) { - $results[] = $this->format($transition); - } - - return $results; - } - - /** - * Get column titles - * - * @access public - * @return string[] - */ - public function getColumns() - { - return array( - e('Id'), - e('Task Title'), - e('Source column'), - e('Destination column'), - e('Executer'), - e('Date'), - e('Time spent'), - ); - } - - /** - * Format the output of a transition array - * - * @access public - * @param array $transition - * @return array - */ - public function format(array $transition) - { - $values = array(); - $values[] = $transition['id']; - $values[] = $transition['title']; - $values[] = $transition['src_column']; - $values[] = $transition['dst_column']; - $values[] = $transition['name'] ?: $transition['username']; - $values[] = date('Y-m-d H:i', $transition['date']); - $values[] = round($transition['time_spent'] / 3600, 2); - - return $values; - } } diff --git a/sources/app/Model/User.php b/sources/app/Model/User.php index 2d87d35..5799300 100644 --- a/sources/app/Model/User.php +++ b/sources/app/Model/User.php @@ -253,10 +253,10 @@ class User extends Base } } - $this->removeFields($values, array('confirmation', 'current_password')); - $this->resetFields($values, array('is_ldap_user', 'disable_login_form')); - $this->convertNullFields($values, array('gitlab_id')); - $this->convertIntegerFields($values, array('gitlab_id')); + $this->helper->model->removeFields($values, array('confirmation', 'current_password')); + $this->helper->model->resetFields($values, array('is_ldap_user', 'disable_login_form')); + $this->helper->model->convertNullFields($values, array('gitlab_id')); + $this->helper->model->convertIntegerFields($values, array('gitlab_id')); } /** @@ -283,12 +283,7 @@ class User extends Base { $this->prepare($values); $result = $this->db->table(self::TABLE)->eq('id', $values['id'])->update($values); - - // If the user is connected refresh his session - if ($this->userSession->getId() == $values['id']) { - $this->userSession->initialize($this->getById($this->userSession->getId())); - } - + $this->userSession->refresh($values['id']); return $result; } @@ -325,6 +320,8 @@ class User extends Base */ public function remove($user_id) { + $this->avatarFile->remove($user_id); + return $this->db->transaction(function (Database $db) use ($user_id) { // All assigned tasks are now unassigned (no foreign key) diff --git a/sources/app/Model/UserNotification.php b/sources/app/Model/UserNotification.php index e8a967a..7795da2 100644 --- a/sources/app/Model/UserNotification.php +++ b/sources/app/Model/UserNotification.php @@ -117,23 +117,20 @@ class UserNotification extends Base */ public function saveSettings($user_id, array $values) { - $this->db->startTransaction(); + $types = empty($values['notification_types']) ? array() : array_keys($values['notification_types']); - if (isset($values['notifications_enabled']) && $values['notifications_enabled'] == 1) { + if (! empty($types)) { $this->enableNotification($user_id); - - $filter = empty($values['notifications_filter']) ? UserNotificationFilter::FILTER_BOTH : $values['notifications_filter']; - $projects = empty($values['notification_projects']) ? array() : array_keys($values['notification_projects']); - $types = empty($values['notification_types']) ? array() : array_keys($values['notification_types']); - - $this->userNotificationFilter->saveFilter($user_id, $filter); - $this->userNotificationFilter->saveSelectedProjects($user_id, $projects); - $this->userNotificationType->saveSelectedTypes($user_id, $types); } else { $this->disableNotification($user_id); } - $this->db->closeTransaction(); + $filter = empty($values['notifications_filter']) ? UserNotificationFilter::FILTER_BOTH : $values['notifications_filter']; + $project_ids = empty($values['notification_projects']) ? array() : array_keys($values['notification_projects']); + + $this->userNotificationFilter->saveFilter($user_id, $filter); + $this->userNotificationFilter->saveSelectedProjects($user_id, $project_ids); + $this->userNotificationType->saveSelectedTypes($user_id, $types); } /** diff --git a/sources/app/Model/UserNotificationFilter.php b/sources/app/Model/UserNotificationFilter.php index d4afd27..780ddfc 100644 --- a/sources/app/Model/UserNotificationFilter.php +++ b/sources/app/Model/UserNotificationFilter.php @@ -61,10 +61,11 @@ class UserNotificationFilter extends Base * @access public * @param integer $user_id * @param string $filter + * @return boolean */ public function saveFilter($user_id, $filter) { - $this->db->table(User::TABLE)->eq('id', $user_id)->update(array( + return $this->db->table(User::TABLE)->eq('id', $user_id)->update(array( 'notifications_filter' => $filter, )); } @@ -87,17 +88,21 @@ class UserNotificationFilter extends Base * @access public * @param integer $user_id * @param integer[] $project_ids + * @return boolean */ public function saveSelectedProjects($user_id, array $project_ids) { + $results = array(); $this->db->table(self::PROJECT_TABLE)->eq('user_id', $user_id)->remove(); foreach ($project_ids as $project_id) { - $this->db->table(self::PROJECT_TABLE)->insert(array( + $results[] = $this->db->table(self::PROJECT_TABLE)->insert(array( 'user_id' => $user_id, 'project_id' => $project_id, )); } + + return !in_array(false, $results, true); } /** diff --git a/sources/app/Schema/Mysql.php b/sources/app/Schema/Mysql.php index 9a551e9..934b063 100644 --- a/sources/app/Schema/Mysql.php +++ b/sources/app/Schema/Mysql.php @@ -6,7 +6,38 @@ use PDO; use Kanboard\Core\Security\Token; use Kanboard\Core\Security\Role; -const VERSION = 107; +const VERSION = 110; + +function version_110(PDO $pdo) +{ + $pdo->exec("ALTER TABLE user_has_notifications DROP FOREIGN KEY `user_has_notifications_ibfk_1`"); + $pdo->exec("ALTER TABLE user_has_notifications DROP FOREIGN KEY `user_has_notifications_ibfk_2`"); + $pdo->exec("DROP INDEX `project_id` ON user_has_notifications"); + $pdo->exec("ALTER TABLE user_has_notifications DROP KEY `user_id`"); + $pdo->exec("CREATE UNIQUE INDEX `user_has_notifications_unique_idx` ON `user_has_notifications` (`user_id`, `project_id`)"); + $pdo->exec("ALTER TABLE user_has_notifications ADD CONSTRAINT user_has_notifications_ibfk_1 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE"); + $pdo->exec("ALTER TABLE user_has_notifications ADD CONSTRAINT user_has_notifications_ibfk_2 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE"); +} + +function version_109(PDO $pdo) +{ + $pdo->exec("ALTER TABLE users ADD COLUMN avatar_path VARCHAR(255)"); +} + +function version_108(PDO $pdo) +{ + $pdo->exec("ALTER TABLE user_has_metadata ADD COLUMN changed_by INT DEFAULT 0 NOT NULL"); + $pdo->exec("ALTER TABLE user_has_metadata ADD COLUMN changed_on INT DEFAULT 0 NOT NULL"); + + $pdo->exec("ALTER TABLE project_has_metadata ADD COLUMN changed_by INT DEFAULT 0 NOT NULL"); + $pdo->exec("ALTER TABLE project_has_metadata ADD COLUMN changed_on INT DEFAULT 0 NOT NULL"); + + $pdo->exec("ALTER TABLE task_has_metadata ADD COLUMN changed_by INT DEFAULT 0 NOT NULL"); + $pdo->exec("ALTER TABLE task_has_metadata ADD COLUMN changed_on INT DEFAULT 0 NOT NULL"); + + $pdo->exec("ALTER TABLE settings ADD COLUMN changed_by INT DEFAULT 0 NOT NULL"); + $pdo->exec("ALTER TABLE settings ADD COLUMN changed_on INT DEFAULT 0 NOT NULL"); +} function version_107(PDO $pdo) { diff --git a/sources/app/Schema/Postgres.php b/sources/app/Schema/Postgres.php index 6aed149..3ef4949 100644 --- a/sources/app/Schema/Postgres.php +++ b/sources/app/Schema/Postgres.php @@ -6,7 +6,27 @@ use PDO; use Kanboard\Core\Security\Token; use Kanboard\Core\Security\Role; -const VERSION = 87; +const VERSION = 89; + +function version_89(PDO $pdo) +{ + $pdo->exec("ALTER TABLE users ADD COLUMN avatar_path VARCHAR(255)"); +} + +function version_88(PDO $pdo) +{ + $pdo->exec("ALTER TABLE user_has_metadata ADD COLUMN changed_by INTEGER DEFAULT 0 NOT NULL"); + $pdo->exec("ALTER TABLE user_has_metadata ADD COLUMN changed_on INTEGER DEFAULT 0 NOT NULL"); + + $pdo->exec("ALTER TABLE project_has_metadata ADD COLUMN changed_by INTEGER DEFAULT 0 NOT NULL"); + $pdo->exec("ALTER TABLE project_has_metadata ADD COLUMN changed_on INTEGER DEFAULT 0 NOT NULL"); + + $pdo->exec("ALTER TABLE task_has_metadata ADD COLUMN changed_by INTEGER DEFAULT 0 NOT NULL"); + $pdo->exec("ALTER TABLE task_has_metadata ADD COLUMN changed_on INTEGER DEFAULT 0 NOT NULL"); + + $pdo->exec("ALTER TABLE settings ADD COLUMN changed_by INTEGER DEFAULT 0 NOT NULL"); + $pdo->exec("ALTER TABLE settings ADD COLUMN changed_on INTEGER DEFAULT 0 NOT NULL"); +} function version_87(PDO $pdo) { diff --git a/sources/app/Schema/Sqlite.php b/sources/app/Schema/Sqlite.php index 8bcad29..9ded7ed 100644 --- a/sources/app/Schema/Sqlite.php +++ b/sources/app/Schema/Sqlite.php @@ -6,7 +6,28 @@ use Kanboard\Core\Security\Token; use Kanboard\Core\Security\Role; use PDO; -const VERSION = 99; +const VERSION = 101; + +function version_101(PDO $pdo) +{ + $pdo->exec("ALTER TABLE users ADD COLUMN avatar_path TEXT"); +} + +function version_100(PDO $pdo) +{ + $pdo->exec("ALTER TABLE user_has_metadata ADD COLUMN changed_by INTEGER DEFAULT 0 NOT NULL"); + $pdo->exec("ALTER TABLE user_has_metadata ADD COLUMN changed_on INTEGER DEFAULT 0 NOT NULL"); + + $pdo->exec("ALTER TABLE project_has_metadata ADD COLUMN changed_by INTEGER DEFAULT 0 NOT NULL"); + $pdo->exec("ALTER TABLE project_has_metadata ADD COLUMN changed_on INTEGER DEFAULT 0 NOT NULL"); + + $pdo->exec("ALTER TABLE task_has_metadata ADD COLUMN changed_by INTEGER DEFAULT 0 NOT NULL"); + $pdo->exec("ALTER TABLE task_has_metadata ADD COLUMN changed_on INTEGER DEFAULT 0 NOT NULL"); + + $pdo->exec("ALTER TABLE settings ADD COLUMN changed_by INTEGER DEFAULT 0 NOT NULL"); + $pdo->exec("ALTER TABLE settings ADD COLUMN changed_on INTEGER DEFAULT 0 NOT NULL"); + +} function version_99(PDO $pdo) { diff --git a/sources/app/ServiceProvider/AuthenticationProvider.php b/sources/app/ServiceProvider/AuthenticationProvider.php index 700fe05..776e65d 100644 --- a/sources/app/ServiceProvider/AuthenticationProvider.php +++ b/sources/app/ServiceProvider/AuthenticationProvider.php @@ -67,6 +67,8 @@ class AuthenticationProvider implements ServiceProviderInterface $acl->setRoleHierarchy(Role::PROJECT_MEMBER, array(Role::PROJECT_VIEWER)); $acl->add('Action', '*', Role::PROJECT_MANAGER); + $acl->add('ActionProject', '*', Role::PROJECT_MANAGER); + $acl->add('ActionCreation', '*', Role::PROJECT_MANAGER); $acl->add('Analytic', '*', Role::PROJECT_MANAGER); $acl->add('Board', 'save', Role::PROJECT_MEMBER); $acl->add('BoardPopover', '*', Role::PROJECT_MEMBER); @@ -92,10 +94,8 @@ class AuthenticationProvider implements ServiceProviderInterface $acl->add('Taskduplication', '*', Role::PROJECT_MEMBER); $acl->add('TaskRecurrence', '*', Role::PROJECT_MEMBER); $acl->add('TaskImport', '*', Role::PROJECT_MANAGER); - $acl->add('Tasklink', '*', Role::PROJECT_MEMBER); - $acl->add('Tasklink', array('show'), Role::PROJECT_VIEWER); + $acl->add('TaskInternalLink', '*', Role::PROJECT_MEMBER); $acl->add('TaskExternalLink', '*', Role::PROJECT_MEMBER); - $acl->add('TaskExternalLink', array('show'), Role::PROJECT_VIEWER); $acl->add('Taskmodification', '*', Role::PROJECT_MEMBER); $acl->add('Taskstatus', '*', Role::PROJECT_MEMBER); $acl->add('UserHelper', array('mention'), Role::PROJECT_MEMBER); @@ -125,6 +125,7 @@ class AuthenticationProvider implements ServiceProviderInterface $acl->add('Board', 'readonly', Role::APP_PUBLIC); $acl->add('Ical', '*', Role::APP_PUBLIC); $acl->add('Feed', '*', Role::APP_PUBLIC); + $acl->add('AvatarFile', 'show', Role::APP_PUBLIC); $acl->add('Config', '*', Role::APP_ADMIN); $acl->add('Currency', '*', Role::APP_ADMIN); diff --git a/sources/app/ServiceProvider/AvatarProvider.php b/sources/app/ServiceProvider/AvatarProvider.php new file mode 100644 index 0000000..aac4fca --- /dev/null +++ b/sources/app/ServiceProvider/AvatarProvider.php @@ -0,0 +1,35 @@ +register(new LetterAvatarProvider($container)); + $container['avatarManager']->register(new GravatarProvider($container)); + $container['avatarManager']->register(new AvatarFileProvider($container)); + return $container; + } +} diff --git a/sources/app/ServiceProvider/ClassProvider.php b/sources/app/ServiceProvider/ClassProvider.php index 0f2fbab..3e654a4 100644 --- a/sources/app/ServiceProvider/ClassProvider.php +++ b/sources/app/ServiceProvider/ClassProvider.php @@ -24,6 +24,7 @@ class ClassProvider implements ServiceProviderInterface 'Model' => array( 'Action', 'ActionParameter', + 'AvatarFile', 'Board', 'Category', 'Color', @@ -37,7 +38,6 @@ class ClassProvider implements ServiceProviderInterface 'LastLogin', 'Link', 'Notification', - 'OverdueNotification', 'PasswordReset', 'Project', 'ProjectFile', @@ -54,14 +54,12 @@ class ClassProvider implements ServiceProviderInterface 'ProjectUserRoleFilter', 'RememberMeSession', 'Subtask', - 'SubtaskExport', 'SubtaskTimeTracking', 'Swimlane', 'Task', 'TaskAnalytic', 'TaskCreation', 'TaskDuplication', - 'TaskExport', 'TaskExternalLink', 'TaskFinder', 'TaskFile', @@ -71,11 +69,9 @@ class ClassProvider implements ServiceProviderInterface 'TaskPermission', 'TaskPosition', 'TaskStatus', - 'TaskImport', 'TaskMetadata', 'Transition', 'User', - 'UserImport', 'UserLocking', 'UserMention', 'UserNotification', @@ -111,11 +107,18 @@ class ClassProvider implements ServiceProviderInterface 'TaskLinkValidator', 'UserValidator', ), + 'Import' => array( + 'TaskImport', + 'UserImport', + ), + 'Export' => array( + 'SubtaskExport', + 'TaskExport', + 'TransitionExport', + ), 'Core' => array( 'DateParser', - 'Helper', 'Lexer', - 'Template', ), 'Core\Event' => array( 'EventManager', diff --git a/sources/app/ServiceProvider/DatabaseProvider.php b/sources/app/ServiceProvider/DatabaseProvider.php index 8cede8a..d323807 100644 --- a/sources/app/ServiceProvider/DatabaseProvider.php +++ b/sources/app/ServiceProvider/DatabaseProvider.php @@ -44,8 +44,8 @@ class DatabaseProvider implements ServiceProviderInterface if ($db->schema()->check(\Schema\VERSION)) { return $db; } else { - $errors = $db->getLogMessages(); - throw new RuntimeException('Unable to migrate database schema: '.(isset($errors[0]) ? $errors[0] : 'Unknown error')); + $messages = $db->getLogMessages(); + throw new RuntimeException('Unable to run SQL migrations: '.implode(', ', $messages).' (You may have to fix it manually)'); } } diff --git a/sources/app/ServiceProvider/ExternalLinkProvider.php b/sources/app/ServiceProvider/ExternalLinkProvider.php index c4bbc4c..8b71ec8 100644 --- a/sources/app/ServiceProvider/ExternalLinkProvider.php +++ b/sources/app/ServiceProvider/ExternalLinkProvider.php @@ -7,6 +7,7 @@ use Pimple\ServiceProviderInterface; use Kanboard\Core\ExternalLink\ExternalLinkManager; use Kanboard\ExternalLink\WebLinkProvider; use Kanboard\ExternalLink\AttachmentLinkProvider; +use Kanboard\ExternalLink\FileLinkProvider; /** * External Link Provider @@ -28,6 +29,7 @@ class ExternalLinkProvider implements ServiceProviderInterface $container['externalLinkManager'] = new ExternalLinkManager($container); $container['externalLinkManager']->register(new WebLinkProvider($container)); $container['externalLinkManager']->register(new AttachmentLinkProvider($container)); + $container['externalLinkManager']->register(new FileLinkProvider($container)); return $container; } diff --git a/sources/app/ServiceProvider/HelperProvider.php b/sources/app/ServiceProvider/HelperProvider.php new file mode 100644 index 0000000..43a78e3 --- /dev/null +++ b/sources/app/ServiceProvider/HelperProvider.php @@ -0,0 +1,36 @@ +register('app', '\Kanboard\Helper\AppHelper'); + $container['helper']->register('asset', '\Kanboard\Helper\AssetHelper'); + $container['helper']->register('board', '\Kanboard\Helper\BoardHelper'); + $container['helper']->register('dt', '\Kanboard\Helper\DateHelper'); + $container['helper']->register('file', '\Kanboard\Helper\FileHelper'); + $container['helper']->register('form', '\Kanboard\Helper\FormHelper'); + $container['helper']->register('hook', '\Kanboard\Helper\HookHelper'); + $container['helper']->register('layout', '\Kanboard\Helper\LayoutHelper'); + $container['helper']->register('model', '\Kanboard\Helper\ModelHelper'); + $container['helper']->register('subtask', '\Kanboard\Helper\SubtaskHelper'); + $container['helper']->register('task', '\Kanboard\Helper\TaskHelper'); + $container['helper']->register('text', '\Kanboard\Helper\TextHelper'); + $container['helper']->register('url', '\Kanboard\Helper\UrlHelper'); + $container['helper']->register('user', '\Kanboard\Helper\UserHelper'); + $container['helper']->register('avatar', '\Kanboard\Helper\AvatarHelper'); + $container['helper']->register('projectHeader', '\Kanboard\Helper\ProjectHeaderHelper'); + + $container['template'] = new Template($container['helper']); + + return $container; + } +} diff --git a/sources/app/ServiceProvider/RouteProvider.php b/sources/app/ServiceProvider/RouteProvider.php index d551f25..0e7548d 100644 --- a/sources/app/ServiceProvider/RouteProvider.php +++ b/sources/app/ServiceProvider/RouteProvider.php @@ -101,8 +101,6 @@ class RouteProvider implements ServiceProviderInterface $container['route']->addRoute('project/:project_id/task/:task_id/analytics', 'task', 'analytics'); $container['route']->addRoute('project/:project_id/task/:task_id/subtasks', 'subtask', 'show'); $container['route']->addRoute('project/:project_id/task/:task_id/time-tracking', 'task', 'timetracking'); - $container['route']->addRoute('project/:project_id/task/:task_id/internal/links', 'tasklink', 'show'); - $container['route']->addRoute('project/:project_id/task/:task_id/external/links', 'TaskExternalLink', 'show'); // Exports $container['route']->addRoute('export/tasks/:project_id', 'export', 'tasks'); diff --git a/sources/app/Subscriber/AuthSubscriber.php b/sources/app/Subscriber/AuthSubscriber.php index e839385..dfb95a0 100644 --- a/sources/app/Subscriber/AuthSubscriber.php +++ b/sources/app/Subscriber/AuthSubscriber.php @@ -89,6 +89,7 @@ class AuthSubscriber extends BaseSubscriber implements EventSubscriberInterface * Increment failed login counter * * @access public + * @param AuthFailureEvent $event */ public function onLoginFailure(AuthFailureEvent $event) { diff --git a/sources/app/Template/action/index.php b/sources/app/Template/action/index.php index 66cfed7..63d6388 100644 --- a/sources/app/Template/action/index.php +++ b/sources/app/Template/action/index.php @@ -1,75 +1,71 @@ - + +

+ + + + + + + -

-
- - - - - - - - - - - - - -
-
    -
  • - = - text->in($action['event_name'], $available_events) ?> -
  • -
  • - = - text->in($action['action_name'], $available_actions) ?> -
  • -
      -
-
    - $param_value): ?> -
  • - text->in($param_name, $available_params[$action['action_name']]) ?> = - - text->contains($param_name, 'column_id')): ?> - text->in($param_value, $columns_list) ?> - text->contains($param_name, 'user_id')): ?> - text->in($param_value, $users_list) ?> - text->contains($param_name, 'project_id')): ?> - text->in($param_value, $projects_list) ?> - text->contains($param_name, 'color_id')): ?> - text->in($param_value, $colors_list) ?> - text->contains($param_name, 'category_id')): ?> - text->in($param_value, $categories_list) ?> - text->contains($param_name, 'link_id')): ?> - text->in($param_value, $links_list) ?> - - e($param_value) ?> - - -
  • - -
-
- url->link(t('Remove'), 'action', 'confirm', array('project_id' => $project['id'], 'action_id' => $action['id']), false, 'popover') ?> -
- - - -

-
- form->csrf() ?> - form->hidden('project_id', $values) ?> - - form->label(t('Action'), 'action_name') ?> - form->select('action_name', $available_actions, $values) ?> - -
- -
-
\ No newline at end of file + + + +