summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/Action/TaskEmail.php1
-rw-r--r--app/Api/Authorization/ProjectAuthorization.php4
-rw-r--r--app/Api/Authorization/TagAuthorization.php23
-rw-r--r--app/Api/Authorization/TaskAuthorization.php4
-rw-r--r--app/Api/Middleware/AuthenticationMiddleware.php3
-rw-r--r--app/Api/Procedure/ActionProcedure.php6
-rw-r--r--app/Api/Procedure/BoardProcedure.php3
-rw-r--r--app/Api/Procedure/MeProcedure.php2
-rw-r--r--app/Api/Procedure/ProjectPermissionProcedure.php4
-rw-r--r--app/Api/Procedure/ProjectProcedure.php7
-rw-r--r--app/Api/Procedure/TagProcedure.php44
-rw-r--r--app/Api/Procedure/TaskMetadataProcedure.php2
-rw-r--r--app/Api/Procedure/TaskProcedure.php14
-rw-r--r--app/Api/Procedure/TaskTagProcedure.php26
-rw-r--r--app/Auth/ApiAccessTokenAuth.php119
-rw-r--r--app/Auth/DatabaseAuth.php2
-rw-r--r--app/Auth/LdapAuth.php2
-rw-r--r--app/Auth/RememberMeAuth.php4
-rw-r--r--app/Auth/ReverseProxyAuth.php4
-rw-r--r--app/Auth/TotpAuth.php2
-rw-r--r--app/Console/DatabaseMigrationCommand.php23
-rw-r--r--app/Console/DatabaseVersionCommand.php23
-rw-r--r--app/Console/JobCommand.php35
-rw-r--r--app/Controller/BoardAjaxController.php3
-rw-r--r--app/Controller/BoardViewController.php5
-rw-r--r--app/Controller/CalendarController.php1
-rw-r--r--app/Controller/ColumnController.php18
-rw-r--r--app/Controller/CommentController.php14
-rw-r--r--app/Controller/ConfigController.php1
-rw-r--r--app/Controller/CurrencyController.php59
-rw-r--r--app/Controller/CustomFilterController.php34
-rw-r--r--app/Controller/ExportController.php34
-rw-r--r--app/Controller/ExternalTaskCreationController.php97
-rw-r--r--app/Controller/ExternalTaskViewController.php30
-rw-r--r--app/Controller/FileViewerController.php53
-rw-r--r--app/Controller/GroupAjaxController.php6
-rw-r--r--app/Controller/ICalendarController.php5
-rw-r--r--app/Controller/LinkController.php50
-rw-r--r--app/Controller/PasswordResetController.php10
-rw-r--r--app/Controller/PluginController.php1
-rw-r--r--app/Controller/ProjectEditController.php95
-rw-r--r--app/Controller/ProjectFileController.php2
-rw-r--r--app/Controller/ProjectGanttController.php3
-rw-r--r--app/Controller/ProjectPermissionController.php2
-rw-r--r--app/Controller/TaskAjaxController.php27
-rw-r--r--app/Controller/TaskBulkController.php2
-rw-r--r--app/Controller/TaskCreationController.php23
-rw-r--r--app/Controller/TaskExternalLinkController.php21
-rw-r--r--app/Controller/TaskFileController.php2
-rw-r--r--app/Controller/TaskGanttController.php3
-rw-r--r--app/Controller/TaskGanttCreationController.php64
-rw-r--r--app/Controller/TaskImportController.php9
-rw-r--r--app/Controller/TaskModificationController.php51
-rw-r--r--app/Controller/TaskMovePositionController.php9
-rw-r--r--app/Controller/TaskStatusController.php10
-rw-r--r--app/Controller/UserAjaxController.php8
-rw-r--r--app/Controller/UserApiAccessController.php50
-rw-r--r--app/Controller/UserCreationController.php7
-rw-r--r--app/Controller/UserImportController.php2
-rw-r--r--app/Controller/UserInviteController.php107
-rw-r--r--app/Core/Base.php22
-rw-r--r--app/Core/DateParser.php9
-rw-r--r--app/Core/ExternalTask/AccessForbiddenException.php13
-rw-r--r--app/Core/ExternalTask/ExternalTaskException.php15
-rw-r--r--app/Core/ExternalTask/ExternalTaskInterface.php26
-rw-r--r--app/Core/ExternalTask/ExternalTaskManager.php58
-rw-r--r--app/Core/ExternalTask/ExternalTaskProviderInterface.php77
-rw-r--r--app/Core/ExternalTask/NotFoundException.php13
-rw-r--r--app/Core/ExternalTask/ProviderNotFoundException.php13
-rw-r--r--app/Core/Filter/FormatterInterface.php2
-rw-r--r--app/Core/Helper.php2
-rw-r--r--app/Core/Http/Request.php15
-rw-r--r--app/Core/Http/Response.php12
-rw-r--r--app/Core/Mail/Transport/Mail.php4
-rw-r--r--app/Core/Mail/Transport/Smtp.php1
-rw-r--r--app/Core/Markdown.php26
-rw-r--r--app/Core/Paginator.php45
-rw-r--r--app/Core/Plugin/Base.php13
-rw-r--r--app/Core/Plugin/Directory.php13
-rw-r--r--app/Core/Plugin/Loader.php48
-rw-r--r--app/Core/Plugin/PluginException.php15
-rw-r--r--app/Core/Plugin/PluginInstallerException.php4
-rw-r--r--app/Core/Plugin/Version.php38
-rw-r--r--app/Core/Queue/QueueManager.php2
-rw-r--r--app/Core/Session/SessionStorage.php1
-rw-r--r--app/Core/Tool.php25
-rw-r--r--app/Core/Translator.php26
-rw-r--r--app/Decorator/UserCacheDecorator.php59
-rw-r--r--app/Event/GenericEvent.php22
-rw-r--r--app/Event/ProjectFileEvent.php8
-rw-r--r--app/Filter/TaskStartsWithIdFilter.php38
-rw-r--r--app/Formatter/BaseFormatter.php14
-rw-r--r--app/Formatter/BaseTaskCalendarFormatter.php4
-rw-r--r--app/Formatter/BoardColumnFormatter.php2
-rw-r--r--app/Formatter/BoardFormatter.php2
-rw-r--r--app/Formatter/BoardSwimlaneFormatter.php2
-rw-r--r--app/Formatter/GroupAutoCompleteFormatter.php22
-rw-r--r--app/Formatter/TaskAutoCompleteFormatter.php28
-rw-r--r--app/Formatter/TaskSuggestMenuFormatter.php63
-rw-r--r--app/Formatter/UserAutoCompleteFormatter.php6
-rw-r--r--app/Formatter/UserMentionFormatter.php60
-rw-r--r--app/Helper/AppHelper.php23
-rw-r--r--app/Helper/CalendarHelper.php26
-rw-r--r--app/Helper/DateHelper.php2
-rw-r--r--app/Helper/FileHelper.php29
-rw-r--r--app/Helper/FormHelper.php71
-rw-r--r--app/Helper/ICalHelper.php11
-rw-r--r--app/Helper/LayoutHelper.php18
-rw-r--r--app/Helper/MailHelper.php23
-rw-r--r--app/Helper/ModalHelper.php83
-rw-r--r--app/Helper/ProjectActivityHelper.php9
-rw-r--r--app/Helper/ProjectRoleHelper.php2
-rw-r--r--app/Helper/SubtaskHelper.php8
-rw-r--r--app/Helper/TaskHelper.php98
-rw-r--r--app/Helper/TextHelper.php4
-rw-r--r--app/Helper/UrlHelper.php33
-rw-r--r--app/Job/CommentEventJob.php4
-rw-r--r--app/Job/TaskEventJob.php3
-rw-r--r--app/Job/UserMentionJob.php73
-rw-r--r--app/Locale/bs_BA/translations.php83
-rw-r--r--app/Locale/cs_CZ/translations.php83
-rw-r--r--app/Locale/da_DK/translations.php83
-rw-r--r--app/Locale/de_DE/translations.php195
-rw-r--r--app/Locale/el_GR/translations.php83
-rw-r--r--app/Locale/es_ES/translations.php83
-rw-r--r--app/Locale/fi_FI/translations.php83
-rw-r--r--app/Locale/fr_FR/translations.php90
-rw-r--r--app/Locale/hu_HU/translations.php83
-rw-r--r--app/Locale/id_ID/translations.php1323
-rw-r--r--app/Locale/it_IT/translations.php285
-rw-r--r--app/Locale/ja_JP/translations.php83
-rw-r--r--app/Locale/ko_KR/translations.php299
-rw-r--r--app/Locale/my_MY/translations.php83
-rw-r--r--app/Locale/nb_NO/translations.php83
-rw-r--r--app/Locale/nl_NL/translations.php83
-rw-r--r--app/Locale/pl_PL/translations.php83
-rw-r--r--app/Locale/pt_BR/translations.php83
-rw-r--r--app/Locale/pt_PT/translations.php97
-rw-r--r--app/Locale/ru_RU/translations.php103
-rw-r--r--app/Locale/sr_Latn_RS/translations.php83
-rw-r--r--app/Locale/sv_SE/translations.php83
-rw-r--r--app/Locale/th_TH/translations.php83
-rw-r--r--app/Locale/tr_TR/translations.php795
-rw-r--r--app/Locale/zh_CN/translations.php445
-rw-r--r--app/Middleware/BootstrapMiddleware.php1
-rw-r--r--app/Model/CommentModel.php7
-rw-r--r--app/Model/CurrencyModel.php2
-rw-r--r--app/Model/FileModel.php32
-rw-r--r--app/Model/InviteModel.php73
-rw-r--r--app/Model/ProjectModel.php16
-rw-r--r--app/Model/ProjectPermissionModel.php24
-rw-r--r--app/Model/UserMentionModel.php62
-rw-r--r--app/Schema/Mysql.php47
-rw-r--r--app/Schema/Postgres.php43
-rw-r--r--app/Schema/Sql/mysql.sql89
-rw-r--r--app/Schema/Sql/postgres.sql594
-rw-r--r--app/Schema/Sqlite.php38
-rw-r--r--app/ServiceProvider/ApiProvider.php4
-rw-r--r--app/ServiceProvider/AuthenticationProvider.php29
-rw-r--r--app/ServiceProvider/CacheProvider.php8
-rw-r--r--app/ServiceProvider/ClassProvider.php2
-rw-r--r--app/ServiceProvider/CommandProvider.php6
-rw-r--r--app/ServiceProvider/DatabaseProvider.php41
-rw-r--r--app/ServiceProvider/ExternalTaskProvider.php29
-rw-r--r--app/ServiceProvider/FilterProvider.php4
-rw-r--r--app/ServiceProvider/FormatterProvider.php48
-rw-r--r--app/ServiceProvider/HelperProvider.php1
-rw-r--r--app/ServiceProvider/JobProvider.php5
-rw-r--r--app/ServiceProvider/RouteProvider.php6
-rw-r--r--app/Subscriber/NotificationSubscriber.php38
-rw-r--r--app/Template/action/index.php12
-rw-r--r--app/Template/action/remove.php10
-rw-r--r--app/Template/action_creation/create.php10
-rw-r--r--app/Template/action_creation/event.php11
-rw-r--r--app/Template/action_creation/params.php9
-rw-r--r--app/Template/activity/project.php14
-rw-r--r--app/Template/analytic/avg_time_columns.php34
-rw-r--r--app/Template/analytic/burndown.php32
-rw-r--r--app/Template/analytic/cfd.php31
-rw-r--r--app/Template/analytic/layout.php18
-rw-r--r--app/Template/analytic/lead_cycle_time.php47
-rw-r--r--app/Template/analytic/sidebar.php15
-rw-r--r--app/Template/analytic/task_distribution.php12
-rw-r--r--app/Template/analytic/time_comparison.php30
-rw-r--r--app/Template/analytic/user_distribution.php12
-rw-r--r--app/Template/board/table_column.php9
-rw-r--r--app/Template/board/task_footer.php2
-rw-r--r--app/Template/board/tooltip_files.php4
-rw-r--r--app/Template/board_popover/close_all_tasks_column.php29
-rw-r--r--app/Template/calendar/show.php12
-rw-r--r--app/Template/category/edit.php13
-rw-r--r--app/Template/category/index.php4
-rw-r--r--app/Template/category/remove.php28
-rw-r--r--app/Template/column/create.php17
-rw-r--r--app/Template/column/edit.php11
-rw-r--r--app/Template/column/index.php15
-rw-r--r--app/Template/column/remove.php9
-rw-r--r--app/Template/column_move_restriction/create.php34
-rw-r--r--app/Template/column_move_restriction/remove.php9
-rw-r--r--app/Template/column_restriction/create.php32
-rw-r--r--app/Template/column_restriction/remove.php9
-rw-r--r--app/Template/comment/create.php23
-rw-r--r--app/Template/comment/edit.php19
-rw-r--r--app/Template/comment/remove.php10
-rw-r--r--app/Template/comment/show.php10
-rw-r--r--app/Template/comments/create.php15
-rw-r--r--app/Template/comments/show.php4
-rw-r--r--app/Template/config/about.php8
-rw-r--r--app/Template/config/api.php12
-rw-r--r--app/Template/config/application.php40
-rw-r--r--app/Template/config/board.php21
-rw-r--r--app/Template/config/calendar.php28
-rw-r--r--app/Template/config/email.php15
-rw-r--r--app/Template/config/integrations.php8
-rw-r--r--app/Template/config/keyboard_shortcuts.php2
-rw-r--r--app/Template/config/project.php29
-rw-r--r--app/Template/config/sidebar.php6
-rw-r--r--app/Template/config/webhook.php22
-rw-r--r--app/Template/currency/change.php9
-rw-r--r--app/Template/currency/create.php11
-rw-r--r--app/Template/currency/index.php54
-rw-r--r--app/Template/currency/show.php34
-rw-r--r--app/Template/custom_filter/create.php (renamed from app/Template/custom_filter/add.php)9
-rw-r--r--app/Template/custom_filter/edit.php11
-rw-r--r--app/Template/custom_filter/index.php16
-rw-r--r--app/Template/custom_filter/remove.php28
-rw-r--r--app/Template/dashboard/calendar.php9
-rw-r--r--app/Template/dashboard/layout.php12
-rw-r--r--app/Template/dashboard/notifications.php6
-rw-r--r--app/Template/dashboard/show.php2
-rw-r--r--app/Template/doc/show.php3
-rw-r--r--app/Template/export/header.php17
-rw-r--r--app/Template/export/sidebar.php17
-rw-r--r--app/Template/export/subtasks.php16
-rw-r--r--app/Template/export/summary.php16
-rw-r--r--app/Template/export/tasks.php16
-rw-r--r--app/Template/export/transitions.php17
-rw-r--r--app/Template/external_task_creation/step1.php16
-rw-r--r--app/Template/external_task_creation/step2.php22
-rw-r--r--app/Template/external_task_modification/show.php22
-rw-r--r--app/Template/group/associate.php17
-rw-r--r--app/Template/group/dissociate.php10
-rw-r--r--app/Template/group/index.php14
-rw-r--r--app/Template/group/remove.php10
-rw-r--r--app/Template/group/users.php7
-rw-r--r--app/Template/group_creation/show.php8
-rw-r--r--app/Template/group_modification/show.php8
-rw-r--r--app/Template/header/board_selector.php26
-rw-r--r--app/Template/header/creation_dropdown.php7
-rw-r--r--app/Template/header/user_dropdown.php27
-rw-r--r--app/Template/layout.php1
-rw-r--r--app/Template/link/create.php12
-rw-r--r--app/Template/link/edit.php6
-rw-r--r--app/Template/link/index.php33
-rw-r--r--app/Template/link/remove.php10
-rw-r--r--app/Template/link/show.php36
-rw-r--r--app/Template/notification/comment_create.php2
-rw-r--r--app/Template/notification/comment_delete.php2
-rw-r--r--app/Template/notification/comment_update.php2
-rw-r--r--app/Template/notification/comment_user_mention.php2
-rw-r--r--app/Template/notification/task_assignee_change.php2
-rw-r--r--app/Template/notification/task_create.php2
-rw-r--r--app/Template/notification/task_update.php2
-rw-r--r--app/Template/notification/task_user_mention.php2
-rw-r--r--app/Template/password_reset/create.php1
-rw-r--r--app/Template/plugin/directory.php6
-rw-r--r--app/Template/plugin/remove.php10
-rw-r--r--app/Template/plugin/show.php43
-rw-r--r--app/Template/project/dropdown.php23
-rw-r--r--app/Template/project/sidebar.php10
-rw-r--r--app/Template/project_action_duplication/show.php8
-rw-r--r--app/Template/project_creation/create.php12
-rw-r--r--app/Template/project_edit/dates.php22
-rw-r--r--app/Template/project_edit/description.php19
-rw-r--r--app/Template/project_edit/general.php36
-rw-r--r--app/Template/project_edit/show.php68
-rw-r--r--app/Template/project_edit/task_priority.php29
-rw-r--r--app/Template/project_file/create.php43
-rw-r--r--app/Template/project_file/remove.php10
-rw-r--r--app/Template/project_gantt/show.php16
-rw-r--r--app/Template/project_header/dropdown.php35
-rw-r--r--app/Template/project_header/views.php15
-rw-r--r--app/Template/project_list/show.php18
-rw-r--r--app/Template/project_overview/attachments.php2
-rw-r--r--app/Template/project_overview/description.php4
-rw-r--r--app/Template/project_overview/files.php13
-rw-r--r--app/Template/project_overview/images.php24
-rw-r--r--app/Template/project_overview/information.php8
-rw-r--r--app/Template/project_overview/show.php1
-rw-r--r--app/Template/project_permission/groups.php60
-rw-r--r--app/Template/project_permission/index.php132
-rw-r--r--app/Template/project_permission/users.php53
-rw-r--r--app/Template/project_role/create.php8
-rw-r--r--app/Template/project_role/edit.php8
-rw-r--r--app/Template/project_role/remove.php9
-rw-r--r--app/Template/project_role/show.php27
-rw-r--r--app/Template/project_role_restriction/create.php8
-rw-r--r--app/Template/project_role_restriction/remove.php9
-rw-r--r--app/Template/project_status/disable.php9
-rw-r--r--app/Template/project_status/enable.php9
-rw-r--r--app/Template/project_status/remove.php9
-rw-r--r--app/Template/project_tag/create.php8
-rw-r--r--app/Template/project_tag/edit.php8
-rw-r--r--app/Template/project_tag/index.php9
-rw-r--r--app/Template/project_tag/remove.php10
-rw-r--r--app/Template/project_user_overview/layout.php17
-rw-r--r--app/Template/project_user_overview/sidebar.php21
-rw-r--r--app/Template/project_view/share.php8
-rw-r--r--app/Template/project_view/show.php8
-rw-r--r--app/Template/search/activity.php5
-rw-r--r--app/Template/search/index.php5
-rw-r--r--app/Template/subtask/create.php15
-rw-r--r--app/Template/subtask/edit.php21
-rw-r--r--app/Template/subtask/menu.php9
-rw-r--r--app/Template/subtask/remove.php10
-rw-r--r--app/Template/subtask/table.php6
-rw-r--r--app/Template/subtask_converter/show.php10
-rw-r--r--app/Template/subtask_restriction/show.php8
-rw-r--r--app/Template/swimlane/create.php12
-rw-r--r--app/Template/swimlane/edit.php12
-rw-r--r--app/Template/swimlane/edit_default.php10
-rw-r--r--app/Template/swimlane/index.php3
-rw-r--r--app/Template/swimlane/remove.php28
-rw-r--r--app/Template/swimlane/table.php14
-rw-r--r--app/Template/tag/create.php8
-rw-r--r--app/Template/tag/edit.php8
-rw-r--r--app/Template/tag/index.php9
-rw-r--r--app/Template/tag/remove.php10
-rw-r--r--app/Template/task/analytics.php11
-rw-r--r--app/Template/task/changes.php6
-rw-r--r--app/Template/task/details.php14
-rw-r--r--app/Template/task/dropdown.php39
-rw-r--r--app/Template/task/sidebar.php66
-rw-r--r--app/Template/task/time_tracking_summary.php20
-rw-r--r--app/Template/task_bulk/show.php13
-rw-r--r--app/Template/task_creation/duplicate_projects.php9
-rw-r--r--app/Template/task_creation/show.php65
-rw-r--r--app/Template/task_duplication/copy.php30
-rw-r--r--app/Template/task_duplication/duplicate.php10
-rw-r--r--app/Template/task_duplication/move.php29
-rw-r--r--app/Template/task_external_link/create.php9
-rw-r--r--app/Template/task_external_link/edit.php9
-rw-r--r--app/Template/task_external_link/find.php8
-rw-r--r--app/Template/task_external_link/remove.php10
-rw-r--r--app/Template/task_external_link/table.php6
-rw-r--r--app/Template/task_file/create.php43
-rw-r--r--app/Template/task_file/files.php12
-rw-r--r--app/Template/task_file/images.php26
-rw-r--r--app/Template/task_file/remove.php10
-rw-r--r--app/Template/task_file/screenshot.php10
-rw-r--r--app/Template/task_gantt/show.php9
-rw-r--r--app/Template/task_gantt_creation/show.php46
-rw-r--r--app/Template/task_import/show.php15
-rw-r--r--app/Template/task_import/sidebar.php8
-rw-r--r--app/Template/task_internal_link/create.php8
-rw-r--r--app/Template/task_internal_link/edit.php6
-rw-r--r--app/Template/task_internal_link/remove.php10
-rw-r--r--app/Template/task_internal_link/table.php6
-rw-r--r--app/Template/task_modification/show.php44
-rw-r--r--app/Template/task_move_position/show.php47
-rw-r--r--app/Template/task_recurrence/edit.php10
-rw-r--r--app/Template/task_status/close.php10
-rw-r--r--app/Template/task_status/open.php10
-rw-r--r--app/Template/task_suppression/remove.php10
-rw-r--r--app/Template/twofactor/disable.php9
-rw-r--r--app/Template/twofactor/show.php2
-rw-r--r--app/Template/user_api_access/show.php17
-rw-r--r--app/Template/user_creation/remote.php51
-rw-r--r--app/Template/user_creation/show.php67
-rw-r--r--app/Template/user_credential/authentication.php12
-rw-r--r--app/Template/user_credential/password.php14
-rw-r--r--app/Template/user_import/show.php9
-rw-r--r--app/Template/user_invite/email.php12
-rw-r--r--app/Template/user_invite/show.php15
-rw-r--r--app/Template/user_invite/signup.php (renamed from app/Template/user_creation/local.php)45
-rw-r--r--app/Template/user_list/dropdown.php12
-rw-r--r--app/Template/user_list/show.php16
-rw-r--r--app/Template/user_modification/show.php33
-rw-r--r--app/Template/user_status/disable.php10
-rw-r--r--app/Template/user_status/enable.php10
-rw-r--r--app/Template/user_status/remove.php10
-rw-r--r--app/Template/user_view/layout.php17
-rw-r--r--app/Template/user_view/profile.php14
-rw-r--r--app/Template/user_view/share.php6
-rw-r--r--app/Template/user_view/show.php16
-rw-r--r--app/Template/user_view/sidebar.php5
-rw-r--r--app/Validator/ProjectValidator.php14
-rw-r--r--app/Validator/TaskValidator.php2
-rw-r--r--app/Validator/UserValidator.php2
-rw-r--r--app/common.php2
-rw-r--r--app/constants.php4
-rw-r--r--app/functions.php52
392 files changed, 7835 insertions, 4735 deletions
diff --git a/app/Action/TaskEmail.php b/app/Action/TaskEmail.php
index fdfe7987..559c2c0b 100644
--- a/app/Action/TaskEmail.php
+++ b/app/Action/TaskEmail.php
@@ -34,6 +34,7 @@ class TaskEmail extends Base
return array(
TaskModel::EVENT_MOVE_COLUMN,
TaskModel::EVENT_CLOSE,
+ TaskModel::EVENT_CREATE,
);
}
diff --git a/app/Api/Authorization/ProjectAuthorization.php b/app/Api/Authorization/ProjectAuthorization.php
index 21ecf311..7dcdc445 100644
--- a/app/Api/Authorization/ProjectAuthorization.php
+++ b/app/Api/Authorization/ProjectAuthorization.php
@@ -23,13 +23,13 @@ class ProjectAuthorization extends Base
protected function checkProjectPermission($class, $method, $project_id)
{
if (empty($project_id)) {
- throw new AccessDeniedException('Project not found');
+ throw new AccessDeniedException('Project Not Found');
}
$role = $this->projectUserRoleModel->getUserRole($project_id, $this->userSession->getId());
if (! $this->apiProjectAuthorization->isAllowed($class, $method, $role)) {
- throw new AccessDeniedException('Project access denied');
+ throw new AccessDeniedException('Project Access Denied');
}
}
}
diff --git a/app/Api/Authorization/TagAuthorization.php b/app/Api/Authorization/TagAuthorization.php
new file mode 100644
index 00000000..247f57db
--- /dev/null
+++ b/app/Api/Authorization/TagAuthorization.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace Kanboard\Api\Authorization;
+
+/**
+ * Class TagAuthorization
+ *
+ * @package Kanboard\Api\Authorization
+ * @author Frederic Guillot
+ */
+class TagAuthorization extends ProjectAuthorization
+{
+ public function check($class, $method, $tag_id)
+ {
+ if ($this->userSession->isLogged()) {
+ $tag = $this->tagModel->getById($tag_id);
+
+ if (! empty($tag)) {
+ $this->checkProjectPermission($class, $method, $tag['project_id']);
+ }
+ }
+ }
+}
diff --git a/app/Api/Authorization/TaskAuthorization.php b/app/Api/Authorization/TaskAuthorization.php
index db93b76b..6e044211 100644
--- a/app/Api/Authorization/TaskAuthorization.php
+++ b/app/Api/Authorization/TaskAuthorization.php
@@ -10,10 +10,10 @@ namespace Kanboard\Api\Authorization;
*/
class TaskAuthorization extends ProjectAuthorization
{
- public function check($class, $method, $category_id)
+ public function check($class, $method, $task_id)
{
if ($this->userSession->isLogged()) {
- $this->checkProjectPermission($class, $method, $this->taskFinderModel->getProjectId($category_id));
+ $this->checkProjectPermission($class, $method, $this->taskFinderModel->getProjectId($task_id));
}
}
}
diff --git a/app/Api/Middleware/AuthenticationMiddleware.php b/app/Api/Middleware/AuthenticationMiddleware.php
index 8e309593..174dc467 100644
--- a/app/Api/Middleware/AuthenticationMiddleware.php
+++ b/app/Api/Middleware/AuthenticationMiddleware.php
@@ -28,9 +28,10 @@ class AuthenticationMiddleware extends Base implements MiddlewareInterface
public function execute($username, $password, $procedureName)
{
$this->dispatcher->dispatch('app.bootstrap');
+ $this->sessionStorage->scope = 'API';
if ($this->isUserAuthenticated($username, $password)) {
- $this->userSession->initialize($this->userModel->getByUsername($username));
+ $this->userSession->initialize($this->userCacheDecorator->getByUsername($username));
} elseif (! $this->isAppAuthenticated($username, $password)) {
$this->logger->error('API authentication failure for '.$username);
throw new AuthenticationFailureException('Wrong credentials');
diff --git a/app/Api/Procedure/ActionProcedure.php b/app/Api/Procedure/ActionProcedure.php
index 4043dbb9..72fb9bbe 100644
--- a/app/Api/Procedure/ActionProcedure.php
+++ b/app/Api/Procedure/ActionProcedure.php
@@ -15,17 +15,17 @@ class ActionProcedure extends BaseProcedure
{
public function getAvailableActions()
{
- return $this->actionManager->getAvailableActions();
+ return (object) $this->actionManager->getAvailableActions();
}
public function getAvailableActionEvents()
{
- return $this->eventManager->getAll();
+ return (object) $this->eventManager->getAll();
}
public function getCompatibleActionEvents($action_name)
{
- return $this->actionManager->getCompatibleEvents($action_name);
+ return (object) $this->actionManager->getCompatibleEvents($action_name);
}
public function removeAction($action_id)
diff --git a/app/Api/Procedure/BoardProcedure.php b/app/Api/Procedure/BoardProcedure.php
index 674b5466..69daaf09 100644
--- a/app/Api/Procedure/BoardProcedure.php
+++ b/app/Api/Procedure/BoardProcedure.php
@@ -3,7 +3,6 @@
namespace Kanboard\Api\Procedure;
use Kanboard\Api\Authorization\ProjectAuthorization;
-use Kanboard\Formatter\BoardFormatter;
/**
* Board API controller
@@ -17,7 +16,7 @@ class BoardProcedure extends BaseProcedure
{
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getBoard', $project_id);
- return BoardFormatter::getInstance($this->container)
+ return $this->boardFormatter
->withProjectId($project_id)
->withQuery($this->taskFinderModel->getExtendedQuery())
->format();
diff --git a/app/Api/Procedure/MeProcedure.php b/app/Api/Procedure/MeProcedure.php
index e59e6522..71d5555b 100644
--- a/app/Api/Procedure/MeProcedure.php
+++ b/app/Api/Procedure/MeProcedure.php
@@ -54,7 +54,7 @@ class MeProcedure extends BaseProcedure
public function getMyProjectsList()
{
- return $this->projectUserRoleModel->getProjectsByUser($this->userSession->getId());
+ return (object) $this->projectUserRoleModel->getProjectsByUser($this->userSession->getId());
}
public function getMyOverdueTasks()
diff --git a/app/Api/Procedure/ProjectPermissionProcedure.php b/app/Api/Procedure/ProjectPermissionProcedure.php
index e22e1d62..1938a067 100644
--- a/app/Api/Procedure/ProjectPermissionProcedure.php
+++ b/app/Api/Procedure/ProjectPermissionProcedure.php
@@ -16,13 +16,13 @@ class ProjectPermissionProcedure extends BaseProcedure
public function getProjectUsers($project_id)
{
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getProjectUsers', $project_id);
- return $this->projectUserRoleModel->getAllUsers($project_id);
+ return (object) $this->projectUserRoleModel->getAllUsers($project_id);
}
public function getAssignableUsers($project_id, $prepend_unassigned = false)
{
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getAssignableUsers', $project_id);
- return $this->projectUserRoleModel->getAssignableUsersList($project_id, $prepend_unassigned);
+ return (object) $this->projectUserRoleModel->getAssignableUsersList($project_id, $prepend_unassigned);
}
public function addProjectUser($project_id, $user_id, $role = Role::PROJECT_MEMBER)
diff --git a/app/Api/Procedure/ProjectProcedure.php b/app/Api/Procedure/ProjectProcedure.php
index a580c8d9..e8a34cd3 100644
--- a/app/Api/Procedure/ProjectProcedure.php
+++ b/app/Api/Procedure/ProjectProcedure.php
@@ -32,6 +32,13 @@ class ProjectProcedure extends BaseProcedure
return $this->formatProject($project);
}
+ public function getProjectByEmail($email)
+ {
+ $project = $this->formatProject($this->projectModel->getByEmail($email));
+ ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getProjectByEmail', $project['id']);
+ return $this->formatProject($project);
+ }
+
public function getAllProjects()
{
return $this->formatProjects($this->projectModel->getAll());
diff --git a/app/Api/Procedure/TagProcedure.php b/app/Api/Procedure/TagProcedure.php
new file mode 100644
index 00000000..f1c06d01
--- /dev/null
+++ b/app/Api/Procedure/TagProcedure.php
@@ -0,0 +1,44 @@
+<?php
+
+namespace Kanboard\Api\Procedure;
+
+use Kanboard\Api\Authorization\ProjectAuthorization;
+use Kanboard\Api\Authorization\TagAuthorization;
+
+/**
+ * Class TagProcedure
+ *
+ * @package Kanboard\Api\Procedure
+ * @author Frederic Guillot
+ */
+class TagProcedure extends BaseProcedure
+{
+ public function getAllTags()
+ {
+ return $this->tagModel->getAll();
+ }
+
+ public function getTagsByProject($project_id)
+ {
+ ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getTagsByProject', $project_id);
+ return $this->tagModel->getAllByProject($project_id);
+ }
+
+ public function createTag($project_id, $tag)
+ {
+ ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'createTag', $project_id);
+ return $this->tagModel->findOrCreateTag($project_id, $tag);
+ }
+
+ public function updateTag($tag_id, $tag)
+ {
+ TagAuthorization::getInstance($this->container)->check($this->getClassName(), 'updateTag', $tag_id);
+ return $this->tagModel->update($tag_id, $tag);
+ }
+
+ public function removeTag($tag_id)
+ {
+ TagAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeTag', $tag_id);
+ return $this->tagModel->remove($tag_id);
+ }
+}
diff --git a/app/Api/Procedure/TaskMetadataProcedure.php b/app/Api/Procedure/TaskMetadataProcedure.php
index 169482f5..ab6c32d0 100644
--- a/app/Api/Procedure/TaskMetadataProcedure.php
+++ b/app/Api/Procedure/TaskMetadataProcedure.php
@@ -15,7 +15,7 @@ class TaskMetadataProcedure extends BaseProcedure
public function getTaskMetadata($task_id)
{
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'getTask', $task_id);
- return $this->taskMetadataModel->getAll($task_id);
+ return (object) $this->taskMetadataModel->getAll($task_id);
}
public function getTaskMetadataByName($task_id, $name)
diff --git a/app/Api/Procedure/TaskProcedure.php b/app/Api/Procedure/TaskProcedure.php
index ee9242d1..af67f3de 100644
--- a/app/Api/Procedure/TaskProcedure.php
+++ b/app/Api/Procedure/TaskProcedure.php
@@ -87,9 +87,9 @@ class TaskProcedure extends BaseProcedure
}
public function createTask($title, $project_id, $color_id = '', $column_id = 0, $owner_id = 0, $creator_id = 0,
- $date_due = '', $description = '', $category_id = 0, $score = 0, $swimlane_id = 0, $priority = 0,
- $recurrence_status = 0, $recurrence_trigger = 0, $recurrence_factor = 0, $recurrence_timeframe = 0,
- $recurrence_basedate = 0, $reference = '')
+ $date_due = '', $description = '', $category_id = 0, $score = 0, $swimlane_id = 0, $priority = 0,
+ $recurrence_status = 0, $recurrence_trigger = 0, $recurrence_factor = 0, $recurrence_timeframe = 0,
+ $recurrence_basedate = 0, $reference = '', array $tags = array())
{
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'createTask', $project_id);
@@ -120,6 +120,7 @@ class TaskProcedure extends BaseProcedure
'recurrence_basedate' => $recurrence_basedate,
'reference' => $reference,
'priority' => $priority,
+ 'tags' => $tags,
);
list($valid, ) = $this->taskValidator->validateCreation($values);
@@ -128,9 +129,9 @@ class TaskProcedure extends BaseProcedure
}
public function updateTask($id, $title = null, $color_id = null, $owner_id = null,
- $date_due = null, $description = null, $category_id = null, $score = null, $priority = null,
- $recurrence_status = null, $recurrence_trigger = null, $recurrence_factor = null,
- $recurrence_timeframe = null, $recurrence_basedate = null, $reference = null)
+ $date_due = null, $description = null, $category_id = null, $score = null, $priority = null,
+ $recurrence_status = null, $recurrence_trigger = null, $recurrence_factor = null,
+ $recurrence_timeframe = null, $recurrence_basedate = null, $reference = null, $tags = null)
{
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'updateTask', $id);
$project_id = $this->taskFinderModel->getProjectId($id);
@@ -159,6 +160,7 @@ class TaskProcedure extends BaseProcedure
'recurrence_basedate' => $recurrence_basedate,
'reference' => $reference,
'priority' => $priority,
+ 'tags' => $tags,
));
list($valid) = $this->taskValidator->validateApiModification($values);
diff --git a/app/Api/Procedure/TaskTagProcedure.php b/app/Api/Procedure/TaskTagProcedure.php
new file mode 100644
index 00000000..55dac8d4
--- /dev/null
+++ b/app/Api/Procedure/TaskTagProcedure.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace Kanboard\Api\Procedure;
+
+use Kanboard\Api\Authorization\TaskAuthorization;
+
+/**
+ * Class TaskTagProcedure
+ *
+ * @package Kanboard\Api\Procedure
+ * @author Frederic Guillot
+ */
+class TaskTagProcedure extends BaseProcedure
+{
+ public function setTaskTags($project_id, $task_id, array $tags)
+ {
+ TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'setTaskTags', $task_id);
+ return $this->taskTagModel->save($project_id, $task_id, $tags);
+ }
+
+ public function getTaskTags($task_id)
+ {
+ TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'getTaskTags', $task_id);
+ return (object) $this->taskTagModel->getList($task_id);
+ }
+}
diff --git a/app/Auth/ApiAccessTokenAuth.php b/app/Auth/ApiAccessTokenAuth.php
new file mode 100644
index 00000000..12ab21a7
--- /dev/null
+++ b/app/Auth/ApiAccessTokenAuth.php
@@ -0,0 +1,119 @@
+<?php
+
+namespace Kanboard\Auth;
+
+use Kanboard\Core\Base;
+use Kanboard\Core\Security\PasswordAuthenticationProviderInterface;
+use Kanboard\Model\UserModel;
+use Kanboard\User\DatabaseUserProvider;
+
+/**
+ * API Access Token Authentication Provider
+ *
+ * @package Kanboard\Auth
+ * @author Frederic Guillot
+ */
+class ApiAccessTokenAuth extends Base implements PasswordAuthenticationProviderInterface
+{
+ /**
+ * User properties
+ *
+ * @access protected
+ * @var array
+ */
+ protected $userInfo = array();
+
+ /**
+ * Username
+ *
+ * @access protected
+ * @var string
+ */
+ protected $username = '';
+
+ /**
+ * Password
+ *
+ * @access protected
+ * @var string
+ */
+ protected $password = '';
+
+ /**
+ * Get authentication provider name
+ *
+ * @access public
+ * @return string
+ */
+ public function getName()
+ {
+ return 'API Access Token';
+ }
+
+ /**
+ * Authenticate the user
+ *
+ * @access public
+ * @return boolean
+ */
+ public function authenticate()
+ {
+ if (! isset($this->sessionStorage->scope) || $this->sessionStorage->scope !== 'API') {
+ $this->logger->debug(__METHOD__.': Authentication provider skipped because invalid scope');
+ return false;
+ }
+
+ $user = $this->db
+ ->table(UserModel::TABLE)
+ ->columns('id', 'password')
+ ->eq('username', $this->username)
+ ->eq('api_access_token', $this->password)
+ ->notNull('api_access_token')
+ ->eq('is_active', 1)
+ ->findOne();
+
+ if (! empty($user)) {
+ $this->userInfo = $user;
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Get user object
+ *
+ * @access public
+ * @return \Kanboard\User\DatabaseUserProvider
+ */
+ public function getUser()
+ {
+ if (empty($this->userInfo)) {
+ return null;
+ }
+
+ return new DatabaseUserProvider($this->userInfo);
+ }
+
+ /**
+ * Set username
+ *
+ * @access public
+ * @param string $username
+ */
+ public function setUsername($username)
+ {
+ $this->username = $username;
+ }
+
+ /**
+ * Set password
+ *
+ * @access public
+ * @param string $password
+ */
+ public function setPassword($password)
+ {
+ $this->password = $password;
+ }
+}
diff --git a/app/Auth/DatabaseAuth.php b/app/Auth/DatabaseAuth.php
index ecb42c17..84a1e019 100644
--- a/app/Auth/DatabaseAuth.php
+++ b/app/Auth/DatabaseAuth.php
@@ -11,7 +11,7 @@ use Kanboard\User\DatabaseUserProvider;
/**
* Database Authentication Provider
*
- * @package auth
+ * @package Kanboard\Auth
* @author Frederic Guillot
*/
class DatabaseAuth extends Base implements PasswordAuthenticationProviderInterface, SessionCheckProviderInterface
diff --git a/app/Auth/LdapAuth.php b/app/Auth/LdapAuth.php
index a8dcfcb6..05ffbebf 100644
--- a/app/Auth/LdapAuth.php
+++ b/app/Auth/LdapAuth.php
@@ -12,7 +12,7 @@ use Kanboard\Core\Security\PasswordAuthenticationProviderInterface;
/**
* LDAP Authentication Provider
*
- * @package auth
+ * @package Kanboard\Auth
* @author Frederic Guillot
*/
class LdapAuth extends Base implements PasswordAuthenticationProviderInterface
diff --git a/app/Auth/RememberMeAuth.php b/app/Auth/RememberMeAuth.php
index 5d0a8b2e..e0f4ceb6 100644
--- a/app/Auth/RememberMeAuth.php
+++ b/app/Auth/RememberMeAuth.php
@@ -7,9 +7,9 @@ use Kanboard\Core\Security\PreAuthenticationProviderInterface;
use Kanboard\User\DatabaseUserProvider;
/**
- * Rember Me Cookie Authentication Provider
+ * RememberMe Cookie Authentication Provider
*
- * @package auth
+ * @package Kanboard\Auth
* @author Frederic Guillot
*/
class RememberMeAuth extends Base implements PreAuthenticationProviderInterface
diff --git a/app/Auth/ReverseProxyAuth.php b/app/Auth/ReverseProxyAuth.php
index fdf936b1..bf71e71e 100644
--- a/app/Auth/ReverseProxyAuth.php
+++ b/app/Auth/ReverseProxyAuth.php
@@ -10,7 +10,7 @@ use Kanboard\User\ReverseProxyUserProvider;
/**
* Reverse-Proxy Authentication Provider
*
- * @package auth
+ * @package Kanboard\Auth
* @author Frederic Guillot
*/
class ReverseProxyAuth extends Base implements PreAuthenticationProviderInterface, SessionCheckProviderInterface
@@ -45,7 +45,7 @@ class ReverseProxyAuth extends Base implements PreAuthenticationProviderInterfac
$username = $this->request->getRemoteUser();
if (! empty($username)) {
- $userProfile = $this->userModel->getByUsername($username);
+ $userProfile = $this->userCacheDecorator->getByUsername($username);
$this->userInfo = new ReverseProxyUserProvider($username, $userProfile ?: array());
return true;
}
diff --git a/app/Auth/TotpAuth.php b/app/Auth/TotpAuth.php
index 8e1ebe35..abfb2168 100644
--- a/app/Auth/TotpAuth.php
+++ b/app/Auth/TotpAuth.php
@@ -11,7 +11,7 @@ use Kanboard\Core\Security\PostAuthenticationProviderInterface;
/**
* TOTP Authentication Provider
*
- * @package auth
+ * @package Kanboard\Auth
* @author Frederic Guillot
*/
class TotpAuth extends Base implements PostAuthenticationProviderInterface
diff --git a/app/Console/DatabaseMigrationCommand.php b/app/Console/DatabaseMigrationCommand.php
new file mode 100644
index 00000000..252d4369
--- /dev/null
+++ b/app/Console/DatabaseMigrationCommand.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace Kanboard\Console;
+
+use Kanboard\ServiceProvider\DatabaseProvider;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class DatabaseMigrationCommand extends DatabaseVersionCommand
+{
+ protected function configure()
+ {
+ $this
+ ->setName('db:migrate')
+ ->setDescription('Execute SQL migrations');
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ parent::execute($input, $output);
+ DatabaseProvider::runMigrations($this->container['db']);
+ }
+}
diff --git a/app/Console/DatabaseVersionCommand.php b/app/Console/DatabaseVersionCommand.php
new file mode 100644
index 00000000..5b1f1ed1
--- /dev/null
+++ b/app/Console/DatabaseVersionCommand.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace Kanboard\Console;
+
+use Kanboard\ServiceProvider\DatabaseProvider;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class DatabaseVersionCommand extends BaseCommand
+{
+ protected function configure()
+ {
+ $this
+ ->setName('db:version')
+ ->setDescription('Show database schema version');
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $output->writeln('<info>Current version: '.DatabaseProvider::getSchemaVersion($this->container['db']).'</info>');
+ $output->writeln('<info>Last version: '.\Schema\VERSION.'</info>');
+ }
+}
diff --git a/app/Console/JobCommand.php b/app/Console/JobCommand.php
new file mode 100644
index 00000000..bdaae32f
--- /dev/null
+++ b/app/Console/JobCommand.php
@@ -0,0 +1,35 @@
+<?php
+
+namespace Kanboard\Console;
+
+use Kanboard\Core\Queue\JobHandler;
+use SimpleQueue\Job;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Class JobCommand
+ *
+ * @package Kanboard\Console
+ * @author Frederic Guillot
+ */
+class JobCommand extends BaseCommand
+{
+ protected function configure()
+ {
+ $this
+ ->setName('job')
+ ->setDescription('Execute individual job (read payload from stdin)')
+ ;
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $payload = fgets(STDIN);
+
+ $job = new Job();
+ $job->unserialize($payload);
+
+ JobHandler::getInstance($this->container)->executeJob($job);
+ }
+}
diff --git a/app/Controller/BoardAjaxController.php b/app/Controller/BoardAjaxController.php
index 484ef67d..ecb76e9c 100644
--- a/app/Controller/BoardAjaxController.php
+++ b/app/Controller/BoardAjaxController.php
@@ -3,7 +3,6 @@
namespace Kanboard\Controller;
use Kanboard\Core\Controller\AccessForbiddenException;
-use Kanboard\Formatter\BoardFormatter;
use Kanboard\Model\UserMetadataModel;
/**
@@ -139,7 +138,7 @@ class BoardAjaxController extends BaseController
'board_highlight_period' => $this->configModel->get('board_highlight_period'),
'swimlanes' => $this->taskLexer
->build($this->userSession->getFilters($project_id))
- ->format(BoardFormatter::getInstance($this->container)->withProjectId($project_id))
+ ->format($this->boardFormatter->withProjectId($project_id))
));
}
}
diff --git a/app/Controller/BoardViewController.php b/app/Controller/BoardViewController.php
index 10165908..9ef77e54 100644
--- a/app/Controller/BoardViewController.php
+++ b/app/Controller/BoardViewController.php
@@ -3,7 +3,6 @@
namespace Kanboard\Controller;
use Kanboard\Core\Controller\AccessForbiddenException;
-use Kanboard\Formatter\BoardFormatter;
use Kanboard\Model\TaskModel;
/**
@@ -35,7 +34,7 @@ class BoardViewController extends BaseController
$this->response->html($this->helper->layout->app('board/view_public', array(
'project' => $project,
- 'swimlanes' => BoardFormatter::getInstance($this->container)
+ 'swimlanes' => $this->boardFormatter
->withProjectId($project['id'])
->withQuery($query)
->format()
@@ -68,7 +67,7 @@ class BoardViewController extends BaseController
'board_highlight_period' => $this->configModel->get('board_highlight_period'),
'swimlanes' => $this->taskLexer
->build($search)
- ->format(BoardFormatter::getInstance($this->container)->withProjectId($project['id']))
+ ->format($this->boardFormatter->withProjectId($project['id']))
)));
}
}
diff --git a/app/Controller/CalendarController.php b/app/Controller/CalendarController.php
index e5114f02..5ad253e1 100644
--- a/app/Controller/CalendarController.php
+++ b/app/Controller/CalendarController.php
@@ -29,7 +29,6 @@ class CalendarController extends BaseController
'project' => $project,
'title' => $project['name'],
'description' => $this->helper->projectHeader->getDescription($project),
- 'check_interval' => $this->configModel->get('board_private_refresh_interval'),
)));
}
diff --git a/app/Controller/ColumnController.php b/app/Controller/ColumnController.php
index 8c366c6e..69167976 100644
--- a/app/Controller/ColumnController.php
+++ b/app/Controller/ColumnController.php
@@ -60,7 +60,7 @@ class ColumnController extends BaseController
public function save()
{
$project = $this->getProject();
- $values = $this->request->getValues();
+ $values = $this->request->getValues() + array('hide_in_dashboard' => 0);
list($valid, $errors) = $this->columnValidator->validateCreation($values);
@@ -70,18 +70,19 @@ class ColumnController extends BaseController
$values['title'],
$values['task_limit'],
$values['description'],
- isset($values['hide_in_dashboard']) ? $values['hide_in_dashboard'] : 0
+ $values['hide_in_dashboard']
);
if ($result !== false) {
$this->flash->success(t('Column created successfully.'));
- return $this->response->redirect($this->helper->url->to('ColumnController', 'index', array('project_id' => $project['id'])), true);
+ $this->response->redirect($this->helper->url->to('ColumnController', 'index', array('project_id' => $project['id'])), true);
+ return;
} else {
$errors['title'] = array(t('Another column with the same name exists in the project'));
}
}
- return $this->create($values, $errors);
+ $this->create($values, $errors);
}
/**
@@ -112,7 +113,7 @@ class ColumnController extends BaseController
public function update()
{
$project = $this->getProject();
- $values = $this->request->getValues();
+ $values = $this->request->getValues() + array('hide_in_dashboard' => 0);
list($valid, $errors) = $this->columnValidator->validateModification($values);
@@ -122,18 +123,19 @@ class ColumnController extends BaseController
$values['title'],
$values['task_limit'],
$values['description'],
- isset($values['hide_in_dashboard']) ? $values['hide_in_dashboard'] : 0
+ $values['hide_in_dashboard']
);
if ($result) {
$this->flash->success(t('Board updated successfully.'));
- return $this->response->redirect($this->helper->url->to('ColumnController', 'index', array('project_id' => $project['id'])));
+ $this->response->redirect($this->helper->url->to('ColumnController', 'index', array('project_id' => $project['id'])), true);
+ return;
} else {
$this->flash->failure(t('Unable to update this board.'));
}
}
- return $this->edit($values, $errors);
+ $this->edit($values, $errors);
}
/**
diff --git a/app/Controller/CommentController.php b/app/Controller/CommentController.php
index c61a0602..526bd2bf 100644
--- a/app/Controller/CommentController.php
+++ b/app/Controller/CommentController.php
@@ -48,6 +48,7 @@ class CommentController extends BaseController
*/
public function create(array $values = array(), array $errors = array())
{
+ $project = $this->getProject();
$task = $this->getTask();
if (empty($values)) {
@@ -57,10 +58,13 @@ class CommentController extends BaseController
);
}
- $this->response->html($this->template->render('comment/create', array(
+ $values['project_id'] = $task['project_id'];
+
+ $this->response->html($this->helper->layout->task('comment/create', array(
'values' => $values,
'errors' => $errors,
'task' => $task,
+ 'project' => $project,
)));
}
@@ -103,8 +107,14 @@ class CommentController extends BaseController
$task = $this->getTask();
$comment = $this->getComment();
+ if (empty($values)) {
+ $values = $comment;
+ }
+
+ $values['project_id'] = $task['project_id'];
+
$this->response->html($this->template->render('comment/edit', array(
- 'values' => empty($values) ? $comment : $values,
+ 'values' => $values,
'errors' => $errors,
'comment' => $comment,
'task' => $task,
diff --git a/app/Controller/ConfigController.php b/app/Controller/ConfigController.php
index 8285ee13..8572316e 100644
--- a/app/Controller/ConfigController.php
+++ b/app/Controller/ConfigController.php
@@ -76,7 +76,6 @@ class ConfigController extends BaseController
'languages' => $this->languageModel->getLanguages(),
'timezones' => $this->timezoneModel->getTimezones(),
'date_formats' => $this->dateParser->getAvailableFormats($this->dateParser->getDateFormats()),
- 'datetime_formats' => $this->dateParser->getAvailableFormats($this->dateParser->getDateTimeFormats()),
'time_formats' => $this->dateParser->getAvailableFormats($this->dateParser->getTimeFormats()),
'title' => t('Settings').' &gt; '.t('Application settings'),
)));
diff --git a/app/Controller/CurrencyController.php b/app/Controller/CurrencyController.php
index ad590035..155e229e 100644
--- a/app/Controller/CurrencyController.php
+++ b/app/Controller/CurrencyController.php
@@ -11,21 +11,33 @@ namespace Kanboard\Controller;
class CurrencyController extends BaseController
{
/**
- * Display all currency rates and form
+ * Display all currency rates
+ *
+ * @access public
+ */
+ public function show()
+ {
+ $this->response->html($this->helper->layout->config('currency/show', array(
+ 'application_currency' => $this->configModel->get('application_currency'),
+ 'rates' => $this->currencyModel->getAll(),
+ 'currencies' => $this->currencyModel->getCurrencies(),
+ 'title' => t('Settings') . ' &gt; ' . t('Currency rates'),
+ )));
+ }
+
+ /**
+ * Add or change currency rate
*
* @access public
* @param array $values
* @param array $errors
*/
- public function index(array $values = array(), array $errors = array())
+ public function create(array $values = array(), array $errors = array())
{
- $this->response->html($this->helper->layout->config('currency/index', array(
- 'config_values' => array('application_currency' => $this->configModel->get('application_currency')),
- 'values' => $values,
- 'errors' => $errors,
- 'rates' => $this->currencyModel->getAll(),
+ $this->response->html($this->template->render('currency/create', array(
+ 'values' => $values,
+ 'errors' => $errors,
'currencies' => $this->currencyModel->getCurrencies(),
- 'title' => t('Settings').' &gt; '.t('Currency rates'),
)));
}
@@ -34,7 +46,7 @@ class CurrencyController extends BaseController
*
* @access public
*/
- public function create()
+ public function save()
{
$values = $this->request->getValues();
list($valid, $errors) = $this->currencyValidator->validateCreation($values);
@@ -42,13 +54,34 @@ class CurrencyController extends BaseController
if ($valid) {
if ($this->currencyModel->create($values['currency'], $values['rate'])) {
$this->flash->success(t('The currency rate have been added successfully.'));
- return $this->response->redirect($this->helper->url->to('CurrencyController', 'index'));
+ $this->response->redirect($this->helper->url->to('CurrencyController', 'show'), true);
+ return;
} else {
$this->flash->failure(t('Unable to add this currency rate.'));
}
}
- return $this->index($values, $errors);
+ $this->create($values, $errors);
+ }
+
+ /**
+ * Change reference currency
+ *
+ * @access public
+ * @param array $values
+ * @param array $errors
+ */
+ public function change(array $values = array(), array $errors = array())
+ {
+ if (empty($values)) {
+ $values['application_currency'] = $this->configModel->get('application_currency');
+ }
+
+ $this->response->html($this->template->render('currency/change', array(
+ 'values' => $values,
+ 'errors' => $errors,
+ 'currencies' => $this->currencyModel->getCurrencies(),
+ )));
}
/**
@@ -56,7 +89,7 @@ class CurrencyController extends BaseController
*
* @access public
*/
- public function reference()
+ public function update()
{
$values = $this->request->getValues();
@@ -66,6 +99,6 @@ class CurrencyController extends BaseController
$this->flash->failure(t('Unable to save your settings.'));
}
- $this->response->redirect($this->helper->url->to('CurrencyController', 'index'));
+ $this->response->redirect($this->helper->url->to('CurrencyController', 'show'), true);
}
}
diff --git a/app/Controller/CustomFilterController.php b/app/Controller/CustomFilterController.php
index e5f674cd..dfe1ffc4 100644
--- a/app/Controller/CustomFilterController.php
+++ b/app/Controller/CustomFilterController.php
@@ -18,17 +18,13 @@ class CustomFilterController extends BaseController
* Display list of filters
*
* @access public
- * @param array $values
- * @param array $errors
* @throws \Kanboard\Core\Controller\PageNotFoundException
*/
- public function index(array $values = array(), array $errors = array())
+ public function index()
{
$project = $this->getProject();
$this->response->html($this->helper->layout->project('custom_filter/index', array(
- 'values' => $values + array('project_id' => $project['id']),
- 'errors' => $errors,
'project' => $project,
'custom_filters' => $this->customFilterModel->getAll($project['id'], $this->userSession->getId()),
'title' => t('Custom filters'),
@@ -36,6 +32,24 @@ class CustomFilterController extends BaseController
}
/**
+ * Show creation form for custom filters
+ *
+ * @access public
+ * @param array $values
+ * @param array $errors
+ */
+ public function create(array $values = array(), array $errors = array())
+ {
+ $project = $this->getProject();
+
+ $this->response->html($this->template->render('custom_filter/create', array(
+ 'values' => $values + array('project_id' => $project['id']),
+ 'errors' => $errors,
+ 'project' => $project,
+ )));
+ }
+
+ /**
* Save a new custom filter
*
* @access public
@@ -52,13 +66,14 @@ class CustomFilterController extends BaseController
if ($valid) {
if ($this->customFilterModel->create($values) !== false) {
$this->flash->success(t('Your custom filter have been created successfully.'));
- return $this->response->redirect($this->helper->url->to('CustomFilterController', 'index', array('project_id' => $project['id'])));
+ $this->response->redirect($this->helper->url->to('CustomFilterController', 'index', array('project_id' => $project['id'])), true);
+ return;
} else {
$this->flash->failure(t('Unable to create your custom filter.'));
}
}
- return $this->index($values, $errors);
+ $this->create($values, $errors);
}
/**
@@ -152,13 +167,14 @@ class CustomFilterController extends BaseController
if ($valid) {
if ($this->customFilterModel->update($values)) {
$this->flash->success(t('Your custom filter have been updated successfully.'));
- return $this->response->redirect($this->helper->url->to('CustomFilterController', 'index', array('project_id' => $project['id'])));
+ $this->response->redirect($this->helper->url->to('CustomFilterController', 'index', array('project_id' => $project['id'])), true);
+ return;
} else {
$this->flash->failure(t('Unable to update custom filter.'));
}
}
- return $this->edit($values, $errors);
+ $this->edit($values, $errors);
}
private function checkPermission(array $project, array $filter)
diff --git a/app/Controller/ExportController.php b/app/Controller/ExportController.php
index b7ac92aa..19f73a7c 100644
--- a/app/Controller/ExportController.php
+++ b/app/Controller/ExportController.php
@@ -24,27 +24,29 @@ class ExportController extends BaseController
private function common($model, $method, $filename, $action, $page_title)
{
$project = $this->getProject();
- $from = $this->request->getStringParam('from');
- $to = $this->request->getStringParam('to');
- if ($from && $to) {
- $data = $this->$model->$method($project['id'], $from, $to);
- $this->response->withFileDownload($filename.'.csv');
- $this->response->csv($data);
- } else {
+ if ($this->request->isPost()) {
+ $values = $this->request->getValues();
+ $from = empty($values['from']) ? '' : $values['from'];
+ $to = empty($values['to']) ? '' : $values['to'];
- $this->response->html($this->helper->layout->project('export/'.$action, array(
- 'values' => array(
- 'controller' => 'ExportController',
- 'action' => $action,
+ if ($from && $to) {
+ $data = $this->$model->$method($project['id'], $from, $to);
+ $this->response->withFileDownload($filename.'.csv');
+ $this->response->csv($data);
+ return;
+ }
+ } else {
+ $this->response->html($this->template->render('export/'.$action, array(
+ 'values' => array(
'project_id' => $project['id'],
- 'from' => $from,
- 'to' => $to,
+ 'from' => '',
+ 'to' => '',
),
- 'errors' => array(),
+ 'errors' => array(),
'project' => $project,
- 'title' => $page_title,
- ), 'export/sidebar'));
+ 'title' => $page_title,
+ )));
}
}
diff --git a/app/Controller/ExternalTaskCreationController.php b/app/Controller/ExternalTaskCreationController.php
new file mode 100644
index 00000000..a1985adb
--- /dev/null
+++ b/app/Controller/ExternalTaskCreationController.php
@@ -0,0 +1,97 @@
+<?php
+
+namespace Kanboard\Controller;
+
+use Kanboard\Core\ExternalTask\ExternalTaskException;
+
+/**
+ * External Task Creation Controller
+ *
+ * @package Kanboard\Controller
+ * @author Frederic Guillot
+ */
+class ExternalTaskCreationController extends BaseController
+{
+ public function step1(array $values = array(), $errorMessage = '')
+ {
+ $project = $this->getProject();
+ $providerName = $this->request->getStringParam('provider_name');
+ $taskProvider = $this->externalTaskManager->getProvider($providerName);
+
+ if (empty($values)) {
+ $values = array(
+ 'swimlane_id' => $this->request->getIntegerParam('swimlane_id'),
+ 'column_id' => $this->request->getIntegerParam('column_id'),
+ );
+ }
+
+ $this->response->html($this->template->render('external_task_creation/step1', array(
+ 'project' => $project,
+ 'values' => $values,
+ 'error_message' => $errorMessage,
+ 'provider_name' => $providerName,
+ 'template' => $taskProvider->getImportFormTemplate(),
+ )));
+ }
+
+ public function step2(array $values = array(), array $errors = array())
+ {
+ $project = $this->getProject();
+ $providerName = $this->request->getStringParam('provider_name');
+
+ try {
+ $taskProvider = $this->externalTaskManager->getProvider($providerName);
+
+ if (empty($values)) {
+ $values = $this->request->getValues();
+ $externalTask = $taskProvider->fetch($taskProvider->buildTaskUri($values));
+
+ $values = $externalTask->getFormValues() + array(
+ 'external_uri' => $externalTask->getUri(),
+ 'external_provider' => $providerName,
+ 'project_id' => $project['id'],
+ 'swimlane_id' => $values['swimlane_id'],
+ 'column_id' => $values['column_id'],
+ 'color_id' => $this->colorModel->getDefaultColor(),
+ 'owner_id' => $this->userSession->getId(),
+ );
+ } else {
+ $externalTask = $taskProvider->fetch($values['external_uri']);
+ }
+
+ $this->response->html($this->template->render('external_task_creation/step2', array(
+ 'project' => $project,
+ 'external_task' => $externalTask,
+ 'provider_name' => $providerName,
+ 'values' => $values,
+ 'errors' => $errors,
+ 'template' => $taskProvider->getCreationFormTemplate(),
+ 'columns_list' => $this->columnModel->getList($project['id']),
+ 'users_list' => $this->projectUserRoleModel->getAssignableUsersList($project['id'], true, false, true),
+ 'categories_list' => $this->categoryModel->getList($project['id']),
+ 'swimlanes_list' => $this->swimlaneModel->getList($project['id'], false, true),
+ )));
+ } catch (ExternalTaskException $e) {
+ $this->step1($values, $e->getMessage());
+ }
+ }
+
+ public function step3()
+ {
+ $project = $this->getProject();
+ $values = $this->request->getValues();
+
+ list($valid, $errors) = $this->taskValidator->validateCreation($values);
+
+ if (! $valid) {
+ $this->step2($values, $errors);
+ } else if (! $this->helper->projectRole->canCreateTaskInColumn($project['id'], $values['column_id'])) {
+ $this->flash->failure(t('You cannot create tasks in this column.'));
+ $this->response->redirect($this->helper->url->to('BoardViewController', 'show', array('project_id' => $project['id'])), true);
+ } else {
+ $taskId = $this->taskCreationModel->create($values);
+ $this->flash->success(t('Task created successfully.'));
+ $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('project_id' => $project['id'], 'task_id' => $taskId)), true);
+ }
+ }
+}
diff --git a/app/Controller/ExternalTaskViewController.php b/app/Controller/ExternalTaskViewController.php
new file mode 100644
index 00000000..18bc15c1
--- /dev/null
+++ b/app/Controller/ExternalTaskViewController.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace Kanboard\Controller;
+
+use Kanboard\Core\ExternalTask\ExternalTaskException;
+
+/**
+ * Class ExternalTaskViewController
+ *
+ * @package Kanboard\Controller
+ * @author Frederic Guillot
+ */
+class ExternalTaskViewController extends BaseController
+{
+ public function show()
+ {
+ try {
+ $task = $this->getTask();
+ $taskProvider = $this->externalTaskManager->getProvider($task['external_provider']);
+ $externalTask = $taskProvider->fetch($task['external_uri']);
+
+ $this->response->html($this->template->render($taskProvider->getViewTemplate(), array(
+ 'task' => $task,
+ 'external_task' => $externalTask,
+ )));
+ } catch (ExternalTaskException $e) {
+ $this->response->html('<div class="alert alert-error">'.$e->getMessage().'</div>');
+ }
+ }
+}
diff --git a/app/Controller/FileViewerController.php b/app/Controller/FileViewerController.php
index 518f5b0b..49568912 100644
--- a/app/Controller/FileViewerController.php
+++ b/app/Controller/FileViewerController.php
@@ -15,11 +15,11 @@ class FileViewerController extends BaseController
/**
* Get file content from object storage
*
- * @access private
+ * @access protected
* @param array $file
* @return string
*/
- private function getFileContent(array $file)
+ protected function getFileContent(array $file)
{
$content = '';
@@ -35,6 +35,30 @@ class FileViewerController extends BaseController
}
/**
+ * Output file with cache
+ *
+ * @param array $file
+ * @param $mimetype
+ */
+ protected function renderFileWithCache(array $file, $mimetype)
+ {
+ $etag = md5($file['path']);
+
+ if ($this->request->getHeader('If-None-Match') === '"'.$etag.'"') {
+ $this->response->status(304);
+ } else {
+ try {
+ $this->response->withContentType($mimetype);
+ $this->response->withCache(5 * 86400, $etag);
+ $this->response->send();
+ $this->objectStorage->output($file['path']);
+ } catch (ObjectStorageException $e) {
+ $this->logger->error($e->getMessage());
+ }
+ }
+ }
+
+ /**
* Show file content in a popover
*
* @access public
@@ -65,21 +89,18 @@ class FileViewerController extends BaseController
public function image()
{
$file = $this->getFile();
- $etag = md5($file['path']);
- $this->response->withContentType($this->helper->file->getImageMimeType($file['name']));
- $this->response->withCache(5 * 86400, $etag);
-
- if ($this->request->getHeader('If-None-Match') === '"'.$etag.'"') {
- $this->response->status(304);
- } else {
+ $this->renderFileWithCache($file, $this->helper->file->getImageMimeType($file['name']));
+ }
- try {
- $this->response->send();
- $this->objectStorage->output($file['path']);
- } catch (ObjectStorageException $e) {
- $this->logger->error($e->getMessage());
- }
- }
+ /**
+ * Display file in browser
+ *
+ * @access public
+ */
+ public function browser()
+ {
+ $file = $this->getFile();
+ $this->renderFileWithCache($file, $this->helper->file->getBrowserViewType($file['name']));
}
/**
diff --git a/app/Controller/GroupAjaxController.php b/app/Controller/GroupAjaxController.php
index 496e9ef2..308bba9e 100644
--- a/app/Controller/GroupAjaxController.php
+++ b/app/Controller/GroupAjaxController.php
@@ -2,8 +2,6 @@
namespace Kanboard\Controller;
-use Kanboard\Formatter\GroupAutoCompleteFormatter;
-
/**
* Group Ajax Controller
*
@@ -20,7 +18,7 @@ class GroupAjaxController extends BaseController
public function autocomplete()
{
$search = $this->request->getStringParam('term');
- $formatter = new GroupAutoCompleteFormatter($this->groupManager->find($search));
- $this->response->json($formatter->format());
+ $groups = $this->groupManager->find($search);
+ $this->response->json($this->groupAutoCompleteFormatter->withGroups($groups)->format());
}
}
diff --git a/app/Controller/ICalendarController.php b/app/Controller/ICalendarController.php
index e354c6f1..4fe8b78a 100644
--- a/app/Controller/ICalendarController.php
+++ b/app/Controller/ICalendarController.php
@@ -7,7 +7,6 @@ use Kanboard\Core\Filter\QueryBuilder;
use Kanboard\Filter\TaskAssigneeFilter;
use Kanboard\Filter\TaskProjectFilter;
use Kanboard\Filter\TaskStatusFilter;
-use Kanboard\Formatter\TaskICalFormatter;
use Kanboard\Model\TaskModel;
use Eluceo\iCal\Component\Calendar as iCalendar;
@@ -94,8 +93,6 @@ class ICalendarController extends BaseController
$end = $this->request->getStringParam('end', strtotime('+6 months'));
$this->helper->ical->addTaskDateDueEvents($queryBuilder, $calendar, $start, $end);
-
- $formatter = new TaskICalFormatter($this->container);
- $this->response->ical($formatter->setCalendar($calendar)->format());
+ $this->response->ical($this->taskICalFormatter->setCalendar($calendar)->format());
}
}
diff --git a/app/Controller/LinkController.php b/app/Controller/LinkController.php
index 477b25a4..2ad8a2b5 100644
--- a/app/Controller/LinkController.php
+++ b/app/Controller/LinkController.php
@@ -16,11 +16,11 @@ class LinkController extends BaseController
/**
* Get the current link
*
- * @access private
+ * @access protected
* @return array
* @throws PageNotFoundException
*/
- private function getLink()
+ protected function getLink()
{
$link = $this->linkModel->getById($this->request->getIntegerParam('link_id'));
@@ -32,19 +32,31 @@ class LinkController extends BaseController
}
/**
- * List of links
+ * List of labels
+ *
+ * @access public
+ */
+ public function show()
+ {
+ $this->response->html($this->helper->layout->config('link/show', array(
+ 'links' => $this->linkModel->getMergedList(),
+ 'title' => t('Settings').' &gt; '.t('Link labels'),
+ )));
+ }
+
+ /**
+ * Add new link label
*
* @access public
* @param array $values
* @param array $errors
*/
- public function index(array $values = array(), array $errors = array())
+ public function create(array $values = array(), array $errors = array())
{
- $this->response->html($this->helper->layout->config('link/index', array(
- 'links' => $this->linkModel->getMergedList(),
+ $this->response->html($this->template->render('link/create', array(
+ 'links' => $this->linkModel->getMergedList(),
'values' => $values,
'errors' => $errors,
- 'title' => t('Settings').' &gt; '.t('Task\'s links'),
)));
}
@@ -61,21 +73,22 @@ class LinkController extends BaseController
if ($valid) {
if ($this->linkModel->create($values['label'], $values['opposite_label']) !== false) {
$this->flash->success(t('Link added successfully.'));
- return $this->response->redirect($this->helper->url->to('LinkController', 'index'));
+ $this->response->redirect($this->helper->url->to('LinkController', 'show'), true);
+ return;
} else {
$this->flash->failure(t('Unable to create your link.'));
}
}
- return $this->index($values, $errors);
+ $this->create($values, $errors);
}
/**
* Edit form
*
* @access public
- * @param array $values
- * @param array $errors
+ * @param array $values
+ * @param array $errors
* @throws PageNotFoundException
*/
public function edit(array $values = array(), array $errors = array())
@@ -83,12 +96,11 @@ class LinkController extends BaseController
$link = $this->getLink();
$link['label'] = t($link['label']);
- $this->response->html($this->helper->layout->config('link/edit', array(
+ $this->response->html($this->template->render('link/edit', array(
'values' => $values ?: $link,
'errors' => $errors,
'labels' => $this->linkModel->getList($link['id']),
- 'link' => $link,
- 'title' => t('Link modification')
+ 'link' => $link,
)));
}
@@ -105,13 +117,14 @@ class LinkController extends BaseController
if ($valid) {
if ($this->linkModel->update($values)) {
$this->flash->success(t('Link updated successfully.'));
- return $this->response->redirect($this->helper->url->to('LinkController', 'index'));
+ $this->response->redirect($this->helper->url->to('LinkController', 'show'), true);
+ return;
} else {
$this->flash->failure(t('Unable to update your link.'));
}
}
- return $this->edit($values, $errors);
+ $this->edit($values, $errors);
}
/**
@@ -123,9 +136,8 @@ class LinkController extends BaseController
{
$link = $this->getLink();
- $this->response->html($this->helper->layout->config('link/remove', array(
+ $this->response->html($this->template->render('link/remove', array(
'link' => $link,
- 'title' => t('Remove a link')
)));
}
@@ -145,6 +157,6 @@ class LinkController extends BaseController
$this->flash->failure(t('Unable to remove this link.'));
}
- $this->response->redirect($this->helper->url->to('LinkController', 'index'));
+ $this->response->redirect($this->helper->url->to('LinkController', 'show'), true);
}
}
diff --git a/app/Controller/PasswordResetController.php b/app/Controller/PasswordResetController.php
index a1780ed9..cc0755ca 100644
--- a/app/Controller/PasswordResetController.php
+++ b/app/Controller/PasswordResetController.php
@@ -104,12 +104,12 @@ class PasswordResetController extends BaseController
*
* @param string $username
*/
- private function sendEmail($username)
+ protected function sendEmail($username)
{
$token = $this->passwordResetModel->create($username);
if ($token !== false) {
- $user = $this->userModel->getByUsername($username);
+ $user = $this->userCacheDecorator->getByUsername($username);
$this->emailClient->send(
$user['email'],
@@ -117,13 +117,17 @@ class PasswordResetController extends BaseController
t('Password Reset for Kanboard'),
$this->template->render('password_reset/email', array('token' => $token))
);
+
+ $this->flash->success(t('A link to reset your password has been sent by email.'));
+ } else {
+ $this->flash->failure(t('Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?'));
}
}
/**
* Check feature availability
*/
- private function checkActivation()
+ protected function checkActivation()
{
if ($this->configModel->get('password_reset', 0) == 0) {
throw AccessForbiddenException::getInstance()->withoutLayout();
diff --git a/app/Controller/PluginController.php b/app/Controller/PluginController.php
index 7b9d64d9..dbb739d6 100644
--- a/app/Controller/PluginController.php
+++ b/app/Controller/PluginController.php
@@ -23,6 +23,7 @@ class PluginController extends BaseController
{
$this->response->html($this->helper->layout->plugin('plugin/show', array(
'plugins' => $this->pluginLoader->getPlugins(),
+ 'incompatible_plugins' => $this->pluginLoader->getIncompatiblePlugins(),
'title' => t('Installed Plugins'),
'is_configured' => Installer::isConfigured(),
)));
diff --git a/app/Controller/ProjectEditController.php b/app/Controller/ProjectEditController.php
index 228d681c..ae39fdf3 100644
--- a/app/Controller/ProjectEditController.php
+++ b/app/Controller/ProjectEditController.php
@@ -11,51 +11,23 @@ namespace Kanboard\Controller;
class ProjectEditController extends BaseController
{
/**
- * General edition (most common operations)
+ * Edit project
*
* @access public
* @param array $values
* @param array $errors
*/
- public function edit(array $values = array(), array $errors = array())
+ public function show(array $values = array(), array $errors = array())
{
- $this->renderView('project_edit/general', $values, $errors);
- }
-
- /**
- * Change start and end dates
- *
- * @access public
- * @param array $values
- * @param array $errors
- */
- public function dates(array $values = array(), array $errors = array())
- {
- $this->renderView('project_edit/dates', $values, $errors);
- }
-
- /**
- * Change project description
- *
- * @access public
- * @param array $values
- * @param array $errors
- */
- public function description(array $values = array(), array $errors = array())
- {
- $this->renderView('project_edit/description', $values, $errors);
- }
+ $project = $this->getProject();
- /**
- * Change task priority
- *
- * @access public
- * @param array $values
- * @param array $errors
- */
- public function priority(array $values = array(), array $errors = array())
- {
- $this->renderView('project_edit/task_priority', $values, $errors);
+ $this->response->html($this->helper->layout->project('project_edit/show', array(
+ 'owners' => $this->projectUserRoleModel->getAssignableUsersList($project['id'], true),
+ 'values' => empty($values) ? $project : $values,
+ 'errors' => $errors,
+ 'project' => $project,
+ 'title' => t('Edit project')
+ )));
}
/**
@@ -67,67 +39,42 @@ class ProjectEditController extends BaseController
{
$project = $this->getProject();
$values = $this->request->getValues();
- $redirect = $this->request->getStringParam('redirect', 'edit');
- $values = $this->prepareValues($redirect, $project, $values);
+ $values = $this->prepareValues($project, $values);
list($valid, $errors) = $this->projectValidator->validateModification($values);
if ($valid) {
if ($this->projectModel->update($values)) {
$this->flash->success(t('Project updated successfully.'));
- return $this->response->redirect($this->helper->url->to('ProjectEditController', $redirect, array('project_id' => $project['id'])), true);
+ return $this->response->redirect($this->helper->url->to('ProjectEditController', 'show', array('project_id' => $project['id'])), true);
} else {
$this->flash->failure(t('Unable to update this project.'));
}
}
- return $this->$redirect($values, $errors);
+ return $this->show($values, $errors);
}
/**
* Prepare form values
*
* @access private
- * @param string $redirect
* @param array $project
* @param array $values
* @return array
*/
- private function prepareValues($redirect, array $project, array $values)
+ private function prepareValues(array $project, array $values)
{
- if ($redirect === 'edit') {
- if (isset($values['is_private'])) {
- if (! $this->helper->user->hasProjectAccess('ProjectCreationController', 'create', $project['id'])) {
- unset($values['is_private']);
- }
- } elseif ($project['is_private'] == 1 && ! isset($values['is_private'])) {
- if ($this->helper->user->hasProjectAccess('ProjectCreationController', 'create', $project['id'])) {
- $values += array('is_private' => 0);
- }
+ if (isset($values['is_private'])) {
+ if (! $this->helper->user->hasProjectAccess('ProjectCreationController', 'create', $project['id'])) {
+ unset($values['is_private']);
+ }
+ } elseif ($project['is_private'] == 1 && ! isset($values['is_private'])) {
+ if ($this->helper->user->hasProjectAccess('ProjectCreationController', 'create', $project['id'])) {
+ $values += array('is_private' => 0);
}
}
return $values;
}
-
- /**
- * Common method to render different views
- *
- * @access private
- * @param string $template
- * @param array $values
- * @param array $errors
- */
- private function renderView($template, array $values, array $errors)
- {
- $project = $this->getProject();
-
- $this->response->html($this->helper->layout->project($template, array(
- 'owners' => $this->projectUserRoleModel->getAssignableUsersList($project['id'], true),
- 'values' => empty($values) ? $project : $values,
- 'errors' => $errors,
- 'project' => $project,
- 'title' => t('Edit project')
- )));
- }
}
diff --git a/app/Controller/ProjectFileController.php b/app/Controller/ProjectFileController.php
index cbe48679..9c38f684 100644
--- a/app/Controller/ProjectFileController.php
+++ b/app/Controller/ProjectFileController.php
@@ -21,7 +21,7 @@ class ProjectFileController extends BaseController
$this->response->html($this->template->render('project_file/create', array(
'project' => $project,
- 'max_size' => $this->helper->text->phpToBytes(ini_get('upload_max_filesize')),
+ 'max_size' => $this->helper->text->phpToBytes(get_upload_max_size()),
)));
}
diff --git a/app/Controller/ProjectGanttController.php b/app/Controller/ProjectGanttController.php
index a70d9eee..8239005e 100644
--- a/app/Controller/ProjectGanttController.php
+++ b/app/Controller/ProjectGanttController.php
@@ -5,7 +5,6 @@ namespace Kanboard\Controller;
use Kanboard\Filter\ProjectIdsFilter;
use Kanboard\Filter\ProjectStatusFilter;
use Kanboard\Filter\ProjectTypeFilter;
-use Kanboard\Formatter\ProjectGanttFormatter;
use Kanboard\Model\ProjectModel;
/**
@@ -30,7 +29,7 @@ class ProjectGanttController extends BaseController
$filter->getQuery()->asc(ProjectModel::TABLE.'.start_date');
$this->response->html($this->helper->layout->app('project_gantt/show', array(
- 'projects' => $filter->format(new ProjectGanttFormatter($this->container)),
+ 'projects' => $filter->format($this->projectGanttFormatter),
'title' => t('Gantt chart for all projects'),
)));
}
diff --git a/app/Controller/ProjectPermissionController.php b/app/Controller/ProjectPermissionController.php
index 1aa59c6d..56777b25 100644
--- a/app/Controller/ProjectPermissionController.php
+++ b/app/Controller/ProjectPermissionController.php
@@ -132,7 +132,7 @@ class ProjectPermissionController extends BaseController
if (! empty($project) && ! empty($values) && $this->projectUserRoleModel->changeUserRole($project['id'], $values['id'], $values['role'])) {
$this->response->json(array('status' => 'ok'));
} else {
- $this->response->json(array('status' => 'error'));
+ $this->response->json(array('status' => 'error'), 500);
}
}
diff --git a/app/Controller/TaskAjaxController.php b/app/Controller/TaskAjaxController.php
index f9feff15..6d0b3fc2 100644
--- a/app/Controller/TaskAjaxController.php
+++ b/app/Controller/TaskAjaxController.php
@@ -5,8 +5,10 @@ namespace Kanboard\Controller;
use Kanboard\Filter\TaskIdExclusionFilter;
use Kanboard\Filter\TaskIdFilter;
use Kanboard\Filter\TaskProjectsFilter;
+use Kanboard\Filter\TaskStartsWithIdFilter;
+use Kanboard\Filter\TaskStatusFilter;
use Kanboard\Filter\TaskTitleFilter;
-use Kanboard\Formatter\TaskAutoCompleteFormatter;
+use Kanboard\Model\TaskModel;
/**
* Task Ajax Controller
@@ -19,7 +21,6 @@ class TaskAjaxController extends BaseController
/**
* Task auto-completion (Ajax)
*
- * @access public
*/
public function autocomplete()
{
@@ -43,7 +44,27 @@ class TaskAjaxController extends BaseController
$filter->withFilter(new TaskTitleFilter($search));
}
- $this->response->json($filter->format(new TaskAutoCompleteFormatter($this->container)));
+ $this->response->json($filter->format($this->taskAutoCompleteFormatter));
+ }
+ }
+
+ /**
+ * Task ID suggest menu
+ */
+ public function suggest()
+ {
+ $taskId = $this->request->getIntegerParam('search');
+ $projectIds = $this->projectPermissionModel->getActiveProjectIds($this->userSession->getId());
+
+ if (empty($projectIds)) {
+ $this->response->json(array());
+ } else {
+ $filter = $this->taskQuery
+ ->withFilter(new TaskProjectsFilter($projectIds))
+ ->withFilter(new TaskStatusFilter(TaskModel::STATUS_OPEN))
+ ->withFilter(new TaskStartsWithIdFilter($taskId));
+
+ $this->response->json($filter->format($this->taskSuggestMenuFormatter));
}
}
}
diff --git a/app/Controller/TaskBulkController.php b/app/Controller/TaskBulkController.php
index 4e06f636..4345a68f 100644
--- a/app/Controller/TaskBulkController.php
+++ b/app/Controller/TaskBulkController.php
@@ -32,7 +32,7 @@ class TaskBulkController extends BaseController
'project' => $project,
'values' => $values,
'errors' => $errors,
- 'users_list' => $this->projectUserRoleModel->getAssignableUsersList($project['id'], true, false, true),
+ 'users_list' => $this->projectUserRoleModel->getAssignableUsersList($project['id'], true, false, $project['is_private'] == 1),
'colors_list' => $this->colorModel->getList(),
'categories_list' => $this->categoryModel->getList($project['id']),
)));
diff --git a/app/Controller/TaskCreationController.php b/app/Controller/TaskCreationController.php
index ec53e211..faf2d250 100644
--- a/app/Controller/TaskCreationController.php
+++ b/app/Controller/TaskCreationController.php
@@ -23,11 +23,8 @@ class TaskCreationController extends BaseController
public function show(array $values = array(), array $errors = array())
{
$project = $this->getProject();
- $swimlanes_list = $this->swimlaneModel->getList($project['id'], false, true);
-
- if (empty($values)) {
- $values = $this->prepareValues($swimlanes_list);
- }
+ $swimlanesList = $this->swimlaneModel->getList($project['id'], false, true);
+ $values += $this->prepareValues($project['is_private'], $swimlanesList);
$values = $this->hook->merge('controller:task:form:default', $values, array('default_values' => $values));
$values = $this->hook->merge('controller:task-creation:form:default', $values, array('default_values' => $values));
@@ -37,9 +34,9 @@ class TaskCreationController extends BaseController
'errors' => $errors,
'values' => $values + array('project_id' => $project['id']),
'columns_list' => $this->columnModel->getList($project['id']),
- 'users_list' => $this->projectUserRoleModel->getAssignableUsersList($project['id'], true, false, true),
+ 'users_list' => $this->projectUserRoleModel->getAssignableUsersList($project['id'], true, false, $project['is_private'] == 1),
'categories_list' => $this->categoryModel->getList($project['id']),
- 'swimlanes_list' => $swimlanes_list,
+ 'swimlanes_list' => $swimlanesList,
)));
}
@@ -116,18 +113,22 @@ class TaskCreationController extends BaseController
* Prepare form values
*
* @access protected
- * @param array $swimlanes_list
+ * @param bool $isPrivateProject
+ * @param array $swimlanesList
* @return array
*/
- protected function prepareValues(array $swimlanes_list)
+ protected function prepareValues($isPrivateProject, array $swimlanesList)
{
$values = array(
- 'swimlane_id' => $this->request->getIntegerParam('swimlane_id', key($swimlanes_list)),
+ 'swimlane_id' => $this->request->getIntegerParam('swimlane_id', key($swimlanesList)),
'column_id' => $this->request->getIntegerParam('column_id'),
'color_id' => $this->colorModel->getDefaultColor(),
- 'owner_id' => $this->userSession->getId(),
);
+ if ($isPrivateProject) {
+ $values['owner_id'] = $this->userSession->getId();
+ }
+
return $values;
}
diff --git a/app/Controller/TaskExternalLinkController.php b/app/Controller/TaskExternalLinkController.php
index 9c04eb00..df23f87b 100644
--- a/app/Controller/TaskExternalLinkController.php
+++ b/app/Controller/TaskExternalLinkController.php
@@ -76,12 +76,23 @@ class TaskExternalLinkController extends BaseController
$values = $this->request->getValues();
list($valid, $errors) = $this->externalLinkValidator->validateCreation($values);
- if ($valid && $this->taskExternalLinkModel->create($values) !== false) {
- $this->flash->success(t('Link added successfully.'));
- return $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), true);
- }
+ if ($valid) {
+ if ($this->taskExternalLinkModel->create($values) !== false) {
+ $this->flash->success(t('Link added successfully.'));
+ } else {
+ $this->flash->success(t('Unable to create your link.'));
+ }
- return $this->edit($values, $errors);
+ $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), true);
+ } else {
+ $provider = $this->externalLinkManager->getProvider($values['link_type']);
+ $this->response->html($this->template->render('task_external_link/create', array(
+ 'values' => $values,
+ 'errors' => $errors,
+ 'dependencies' => $provider->getDependencies(),
+ 'task' => $task,
+ )));
+ }
}
/**
diff --git a/app/Controller/TaskFileController.php b/app/Controller/TaskFileController.php
index 77c0c026..8a0971e4 100644
--- a/app/Controller/TaskFileController.php
+++ b/app/Controller/TaskFileController.php
@@ -40,7 +40,7 @@ class TaskFileController extends BaseController
$this->response->html($this->template->render('task_file/create', array(
'task' => $task,
- 'max_size' => $this->helper->text->phpToBytes(ini_get('upload_max_filesize')),
+ 'max_size' => $this->helper->text->phpToBytes(get_upload_max_size()),
)));
}
diff --git a/app/Controller/TaskGanttController.php b/app/Controller/TaskGanttController.php
index 868368e1..b03b9d00 100644
--- a/app/Controller/TaskGanttController.php
+++ b/app/Controller/TaskGanttController.php
@@ -3,7 +3,6 @@
namespace Kanboard\Controller;
use Kanboard\Filter\TaskProjectFilter;
-use Kanboard\Formatter\TaskGanttFormatter;
use Kanboard\Model\TaskModel;
/**
@@ -35,7 +34,7 @@ class TaskGanttController extends BaseController
'title' => $project['name'],
'description' => $this->helper->projectHeader->getDescription($project),
'sorting' => $sorting,
- 'tasks' => $filter->format(new TaskGanttFormatter($this->container)),
+ 'tasks' => $filter->format($this->taskGanttFormatter),
)));
}
diff --git a/app/Controller/TaskGanttCreationController.php b/app/Controller/TaskGanttCreationController.php
deleted file mode 100644
index c5046f60..00000000
--- a/app/Controller/TaskGanttCreationController.php
+++ /dev/null
@@ -1,64 +0,0 @@
-<?php
-
-namespace Kanboard\Controller;
-
-/**
- * Class TaskGanttCreationController
- *
- * @package Kanboard\Controller
- * @author Frederic Guillot
- */
-class TaskGanttCreationController extends BaseController
-{
- /**
- * Simplified form to create a new task
- *
- * @access public
- * @param array $values
- * @param array $errors
- * @throws \Kanboard\Core\Controller\PageNotFoundException
- */
- public function show(array $values = array(), array $errors = array())
- {
- $project = $this->getProject();
-
- $values = $values + array(
- 'project_id' => $project['id'],
- 'column_id' => $this->columnModel->getFirstColumnId($project['id']),
- 'position' => 1
- );
-
- $values = $this->hook->merge('controller:task:form:default', $values, array('default_values' => $values));
- $values = $this->hook->merge('controller:gantt:task:form:default', $values, array('default_values' => $values));
-
- $this->response->html($this->template->render('task_gantt_creation/show', array(
- 'project' => $project,
- 'errors' => $errors,
- 'values' => $values,
- 'users_list' => $this->projectUserRoleModel->getAssignableUsersList($project['id'], true, false, true),
- 'categories_list' => $this->categoryModel->getList($project['id']),
- 'swimlanes_list' => $this->swimlaneModel->getList($project['id'], false, true),
- )));
- }
-
- /**
- * Validate and save a new task
- *
- * @access public
- */
- public function save()
- {
- $project = $this->getProject();
- $values = $this->request->getValues();
-
- list($valid, $errors) = $this->taskValidator->validateCreation($values);
-
- if ($valid && $this->taskCreationModel->create($values)) {
- $this->flash->success(t('Task created successfully.'));
- $this->response->redirect($this->helper->url->to('TaskGanttController', 'show', array('project_id' => $project['id'])));
- } else {
- $this->flash->failure(t('Unable to create your task.'));
- $this->show($values, $errors);
- }
- }
-}
diff --git a/app/Controller/TaskImportController.php b/app/Controller/TaskImportController.php
index aff2d390..2e323979 100644
--- a/app/Controller/TaskImportController.php
+++ b/app/Controller/TaskImportController.php
@@ -23,15 +23,14 @@ class TaskImportController extends BaseController
{
$project = $this->getProject();
- $this->response->html($this->helper->layout->project('task_import/show', array(
+ $this->response->html($this->template->render('task_import/show', array(
'project' => $project,
'values' => $values,
'errors' => $errors,
- 'max_size' => ini_get('upload_max_filesize'),
+ 'max_size' => get_upload_max_size(),
'delimiters' => Csv::getDelimiters(),
'enclosures' => Csv::getEnclosures(),
- 'title' => t('Import tasks from CSV file'),
- ), 'task_import/sidebar'));
+ )));
}
/**
@@ -58,7 +57,7 @@ class TaskImportController extends BaseController
$this->flash->failure(t('Nothing have been imported!'));
}
- $this->response->redirect($this->helper->url->to('TaskImportController', 'show', array('project_id' => $project['id'])));
+ $this->response->redirect($this->helper->url->to('TaskImportController', 'show', array('project_id' => $project['id'])), true);
}
}
diff --git a/app/Controller/TaskModificationController.php b/app/Controller/TaskModificationController.php
index f628e923..520bf70e 100644
--- a/app/Controller/TaskModificationController.php
+++ b/app/Controller/TaskModificationController.php
@@ -2,6 +2,10 @@
namespace Kanboard\Controller;
+use Kanboard\Core\Controller\AccessForbiddenException;
+use Kanboard\Core\ExternalTask\AccessForbiddenException as ExternalTaskAccessForbiddenException;
+use Kanboard\Core\ExternalTask\ExternalTaskException;
+
/**
* Task Modification controller
*
@@ -43,7 +47,7 @@ class TaskModificationController extends BaseController
$values = $this->hook->merge('controller:task:form:default', $values, array('default_values' => $values));
$values = $this->hook->merge('controller:task-modification:form:default', $values, array('default_values' => $values));
- $this->response->html($this->template->render('task_modification/show', array(
+ $params = array(
'project' => $project,
'values' => $values,
'errors' => $errors,
@@ -51,7 +55,29 @@ class TaskModificationController extends BaseController
'tags' => $this->taskTagModel->getList($task['id']),
'users_list' => $this->projectUserRoleModel->getAssignableUsersList($task['project_id']),
'categories_list' => $this->categoryModel->getList($task['project_id']),
- )));
+ );
+
+ $this->renderTemplate($task, $params);
+ }
+
+ protected function renderTemplate(array &$task, array &$params)
+ {
+ if (empty($task['external_uri'])) {
+ $this->response->html($this->template->render('task_modification/show', $params));
+ } else {
+
+ try {
+ $taskProvider = $this->externalTaskManager->getProvider($task['external_provider']);
+ $params['template'] = $taskProvider->getModificationFormTemplate();
+ $params['external_task'] = $taskProvider->fetch($task['external_uri']);
+ } catch (ExternalTaskAccessForbiddenException $e) {
+ throw new AccessForbiddenException($e->getMessage());
+ } catch (ExternalTaskException $e) {
+ $params['error_message'] = $e->getMessage();
+ }
+
+ $this->response->html($this->template->render('external_task_modification/show', $params));
+ }
}
/**
@@ -66,7 +92,7 @@ class TaskModificationController extends BaseController
list($valid, $errors) = $this->taskValidator->validateModification($values);
- if ($valid && $this->taskModificationModel->update($values)) {
+ if ($valid && $this->updateTask($task, $values, $errors)) {
$this->flash->success(t('Task updated successfully.'));
$this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id'])), true);
} else {
@@ -74,4 +100,23 @@ class TaskModificationController extends BaseController
$this->edit($values, $errors);
}
}
+
+ protected function updateTask(array &$task, array &$values, array &$errors)
+ {
+ $result = $this->taskModificationModel->update($values);
+
+ if ($result && ! empty($task['external_uri'])) {
+ try {
+ $taskProvider = $this->externalTaskManager->getProvider($task['external_provider']);
+ $result = $taskProvider->save($task['external_uri'], $values, $errors);
+ } catch (ExternalTaskAccessForbiddenException $e) {
+ throw new AccessForbiddenException($e->getMessage());
+ } catch (ExternalTaskException $e) {
+ $this->logger->error($e->getMessage());
+ $result = false;
+ }
+ }
+
+ return $result;
+ }
}
diff --git a/app/Controller/TaskMovePositionController.php b/app/Controller/TaskMovePositionController.php
index a655ca0a..39687b79 100644
--- a/app/Controller/TaskMovePositionController.php
+++ b/app/Controller/TaskMovePositionController.php
@@ -3,7 +3,6 @@
namespace Kanboard\Controller;
use Kanboard\Core\Controller\AccessForbiddenException;
-use Kanboard\Formatter\BoardFormatter;
use Kanboard\Model\TaskModel;
/**
@@ -20,7 +19,7 @@ class TaskMovePositionController extends BaseController
$this->response->html($this->template->render('task_move_position/show', array(
'task' => $task,
- 'board' => BoardFormatter::getInstance($this->container)
+ 'board' => $this->boardFormatter
->withProjectId($task['project_id'])
->withQuery($this->taskFinderModel->getExtendedQuery()
->eq(TaskModel::TABLE.'.is_active', TaskModel::STATUS_OPEN)
@@ -36,10 +35,10 @@ class TaskMovePositionController extends BaseController
$values = $this->request->getJson();
if (! $this->helper->projectRole->canMoveTask($task['project_id'], $task['column_id'], $values['column_id'])) {
- throw new AccessForbiddenException(e("You don't have the permission to move this task"));
+ throw new AccessForbiddenException(e('You are not allowed to move this task.'));
}
- $result = $this->taskPositionModel->movePosition(
+ $this->taskPositionModel->movePosition(
$task['project_id'],
$task['id'],
$values['column_id'],
@@ -47,6 +46,6 @@ class TaskMovePositionController extends BaseController
$values['swimlane_id']
);
- $this->response->json(array('result' => $result));
+ $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])));
}
}
diff --git a/app/Controller/TaskStatusController.php b/app/Controller/TaskStatusController.php
index 82b4f9c4..56d38400 100644
--- a/app/Controller/TaskStatusController.php
+++ b/app/Controller/TaskStatusController.php
@@ -52,11 +52,11 @@ class TaskStatusController extends BaseController
$this->flash->failure($failure_message);
}
- return $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), true);
+ $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), true);
+ } else {
+ $this->response->html($this->template->render($template, array(
+ 'task' => $task,
+ )));
}
-
- return $this->response->html($this->template->render($template, array(
- 'task' => $task,
- )));
}
}
diff --git a/app/Controller/UserAjaxController.php b/app/Controller/UserAjaxController.php
index ed180471..17567a00 100644
--- a/app/Controller/UserAjaxController.php
+++ b/app/Controller/UserAjaxController.php
@@ -3,7 +3,6 @@
namespace Kanboard\Controller;
use Kanboard\Filter\UserNameFilter;
-use Kanboard\Formatter\UserAutoCompleteFormatter;
use Kanboard\Model\UserModel;
/**
@@ -24,7 +23,7 @@ class UserAjaxController extends BaseController
$search = $this->request->getStringParam('term');
$filter = $this->userQuery->withFilter(new UserNameFilter($search));
$filter->getQuery()->asc(UserModel::TABLE.'.name')->asc(UserModel::TABLE.'.username');
- $this->response->json($filter->format(new UserAutoCompleteFormatter($this->container)));
+ $this->response->json($filter->format($this->userAutoCompleteFormatter));
}
/**
@@ -35,9 +34,10 @@ class UserAjaxController extends BaseController
public function mention()
{
$project_id = $this->request->getStringParam('project_id');
- $query = $this->request->getStringParam('q');
+ $query = $this->request->getStringParam('search');
$users = $this->projectPermissionModel->findUsernames($project_id, $query);
- $this->response->json($users);
+
+ $this->response->json($this->userMentionFormatter->withUsers($users)->format());
}
/**
diff --git a/app/Controller/UserApiAccessController.php b/app/Controller/UserApiAccessController.php
new file mode 100644
index 00000000..e03514d5
--- /dev/null
+++ b/app/Controller/UserApiAccessController.php
@@ -0,0 +1,50 @@
+<?php
+
+namespace Kanboard\Controller;
+
+use Kanboard\Core\Security\Token;
+
+/**
+ * Class UserApiAccessController
+ *
+ * @package Kanboard\Controller
+ * @author Frederic Guillot
+ */
+class UserApiAccessController extends BaseController
+{
+ public function show()
+ {
+ $user = $this->getUser();
+
+ return $this->response->html($this->helper->layout->user('user_api_access/show', array(
+ 'user' => $user,
+ 'title' => t('API User Access'),
+ )));
+ }
+
+ public function generate()
+ {
+ $user = $this->getUser();
+ $this->checkCSRFParam();
+
+ $this->userModel->update(array(
+ 'id' => $user['id'],
+ 'api_access_token' => Token::getToken(),
+ ));
+
+ $this->response->redirect($this->helper->url->to('UserApiAccessController', 'show', array('user_id' => $user['id'])));
+ }
+
+ public function remove()
+ {
+ $user = $this->getUser();
+ $this->checkCSRFParam();
+
+ $this->userModel->update(array(
+ 'id' => $user['id'],
+ 'api_access_token' => null,
+ ));
+
+ $this->response->redirect($this->helper->url->to('UserApiAccessController', 'show', array('user_id' => $user['id'])));
+ }
+} \ No newline at end of file
diff --git a/app/Controller/UserCreationController.php b/app/Controller/UserCreationController.php
index 9c873f85..27f1687b 100644
--- a/app/Controller/UserCreationController.php
+++ b/app/Controller/UserCreationController.php
@@ -22,10 +22,7 @@ class UserCreationController extends BaseController
*/
public function show(array $values = array(), array $errors = array())
{
- $isRemote = $this->request->getIntegerParam('remote') == 1 || (isset($values['is_ldap_user']) && $values['is_ldap_user'] == 1);
- $template = $isRemote ? 'user_creation/remote' : 'user_creation/local';
-
- $this->response->html($this->template->render($template, array(
+ $this->response->html($this->template->render('user_creation/show', array(
'timezones' => $this->timezoneModel->getTimezones(true),
'languages' => $this->languageModel->getLanguages(true),
'roles' => $this->role->getApplicationRoles(),
@@ -57,7 +54,7 @@ class UserCreationController extends BaseController
*
* @param array $values
*/
- private function createUser(array $values)
+ protected function createUser(array $values)
{
$project_id = empty($values['project_id']) ? 0 : $values['project_id'];
unset($values['project_id']);
diff --git a/app/Controller/UserImportController.php b/app/Controller/UserImportController.php
index fec9a31d..6a9d5992 100644
--- a/app/Controller/UserImportController.php
+++ b/app/Controller/UserImportController.php
@@ -23,7 +23,7 @@ class UserImportController extends BaseController
$this->response->html($this->template->render('user_import/show', array(
'values' => $values,
'errors' => $errors,
- 'max_size' => ini_get('upload_max_filesize'),
+ 'max_size' => get_upload_max_size(),
'delimiters' => Csv::getDelimiters(),
'enclosures' => Csv::getEnclosures(),
)));
diff --git a/app/Controller/UserInviteController.php b/app/Controller/UserInviteController.php
new file mode 100644
index 00000000..8c77940c
--- /dev/null
+++ b/app/Controller/UserInviteController.php
@@ -0,0 +1,107 @@
+<?php
+
+namespace Kanboard\Controller;
+
+use Kanboard\Core\Controller\PageNotFoundException;
+use Kanboard\Core\Security\Role;
+use Kanboard\Notification\MailNotification;
+
+/**
+ * Class UserInviteController
+ *
+ * @package Kanboard\Controller
+ * @author Frederic Guillot
+ */
+class UserInviteController extends BaseController
+{
+ public function show(array $values = array(), array $errors = array())
+ {
+ $this->response->html($this->template->render('user_invite/show', array(
+ 'projects' => $this->projectModel->getList(),
+ 'errors' => $errors,
+ 'values' => $values,
+ )));
+ }
+
+ public function save()
+ {
+ $values = $this->request->getValues();
+
+ if (! empty($values['emails']) && isset($values['project_id'])) {
+ $emails = explode("\r\n", trim($values['emails']));
+ $nb = $this->inviteModel->createInvites($emails, $values['project_id']);
+ $this->flash->success($nb > 1 ? t('%d invitations were sent.', $nb) : t('%d invitation was sent.', $nb));
+ }
+
+ $this->response->redirect($this->helper->url->to('UserListController', 'show'));
+ }
+
+ public function signup(array $values = array(), array $errors = array())
+ {
+ $invite = $this->getInvite();
+
+ $this->response->html($this->helper->layout->app('user_invite/signup', array(
+ 'no_layout' => true,
+ 'not_editable' => true,
+ 'token' => $invite['token'],
+ 'errors' => $errors,
+ 'values' => $values + array('email' => $invite['email']),
+ 'timezones' => $this->timezoneModel->getTimezones(true),
+ 'languages' => $this->languageModel->getLanguages(true),
+ )));
+ }
+
+ public function register()
+ {
+ $invite = $this->getInvite();
+
+ $values = $this->request->getValues();
+ list($valid, $errors) = $this->userValidator->validateCreation($values);
+
+ if ($valid) {
+ $this->createUser($invite, $values);
+ } else {
+ $this->signup($values, $errors);
+ }
+ }
+
+ protected function getInvite()
+ {
+ $token = $this->request->getStringParam('token');
+
+ if (empty($token)) {
+ throw PageNotFoundException::getInstance()->withoutLayout();
+ }
+
+ $invite = $this->inviteModel->getByToken($token);
+
+ if (empty($invite)) {
+ throw PageNotFoundException::getInstance()->withoutLayout();
+ }
+
+ return $invite;
+ }
+
+ protected function createUser(array $invite, array $values)
+ {
+ $user_id = $this->userModel->create($values);
+
+ if ($user_id !== false) {
+ if ($invite['project_id'] != 0) {
+ $this->projectUserRoleModel->addUser($invite['project_id'], $user_id, Role::PROJECT_MEMBER);
+ }
+
+ if (! empty($values['notifications_enabled'])) {
+ $this->userNotificationTypeModel->saveSelectedTypes($user_id, array(MailNotification::TYPE));
+ }
+
+ $this->inviteModel->remove($invite['email']);
+
+ $this->flash->success(t('User created successfully.'));
+ $this->response->redirect($this->helper->url->to('AuthController', 'login'));
+ } else {
+ $this->flash->failure(t('Unable to create this user.'));
+ $this->response->redirect($this->helper->url->to('UserInviteController', 'signup'));
+ }
+ }
+}
diff --git a/app/Core/Base.php b/app/Core/Base.php
index 44dfaa39..17ed5b33 100644
--- a/app/Core/Base.php
+++ b/app/Core/Base.php
@@ -17,6 +17,7 @@ use Pimple\Container;
* @property \Kanboard\Analytic\AverageTimeSpentColumnAnalytic $averageTimeSpentColumnAnalytic
* @property \Kanboard\Core\Action\ActionManager $actionManager
* @property \Kanboard\Core\ExternalLink\ExternalLinkManager $externalLinkManager
+ * @property \Kanboard\Core\ExternalTask\ExternalTaskManager $externalTaskManager
* @property \Kanboard\Core\Cache\MemoryCache $memoryCache
* @property \Kanboard\Core\Cache\BaseCache $cacheDriver
* @property \Kanboard\Core\Event\EventManager $eventManager
@@ -57,9 +58,25 @@ use Pimple\Container;
* @property \Kanboard\Core\Paginator $paginator
* @property \Kanboard\Core\Template $template
* @property \Kanboard\Decorator\MetadataCacheDecorator $userMetadataCacheDecorator
- * @property \Kanboard\Decorator\columnRestrictionCacheDecorator $columnRestrictionCacheDecorator
+ * @property \Kanboard\Decorator\UserCacheDecorator $userCacheDecorator
+ * @property \Kanboard\Decorator\ColumnRestrictionCacheDecorator $columnRestrictionCacheDecorator
* @property \Kanboard\Decorator\ColumnMoveRestrictionCacheDecorator $columnMoveRestrictionCacheDecorator
* @property \Kanboard\Decorator\ProjectRoleRestrictionCacheDecorator $projectRoleRestrictionCacheDecorator
+ * @property \Kanboard\Formatter\BoardColumnFormatter $boardColumnFormatter
+ * @property \Kanboard\Formatter\BoardFormatter $boardFormatter
+ * @property \Kanboard\Formatter\BoardSwimlaneFormatter $boardSwimlaneFormatter
+ * @property \Kanboard\Formatter\BoardTaskFormatter $boardTaskFormatter
+ * @property \Kanboard\Formatter\GroupAutoCompleteFormatter $groupAutoCompleteFormatter
+ * @property \Kanboard\Formatter\ProjectActivityEventFormatter $projectActivityEventFormatter
+ * @property \Kanboard\Formatter\ProjectGanttFormatter $projectGanttFormatter
+ * @property \Kanboard\Formatter\SubtaskTimeTrackingCalendarFormatter $subtaskTimeTrackingCalendarFormatter
+ * @property \Kanboard\Formatter\TaskAutoCompleteFormatter $taskAutoCompleteFormatter
+ * @property \Kanboard\Formatter\TaskCalendarFormatter $taskCalendarFormatter
+ * @property \Kanboard\Formatter\TaskGanttFormatter $taskGanttFormatter
+ * @property \Kanboard\Formatter\TaskICalFormatter $taskICalFormatter
+ * @property \Kanboard\Formatter\TaskSuggestMenuFormatter $taskSuggestMenuFormatter
+ * @property \Kanboard\Formatter\UserAutoCompleteFormatter $userAutoCompleteFormatter
+ * @property \Kanboard\Formatter\UserMentionFormatter $userMentionFormatter
* @property \Kanboard\Model\ActionModel $actionModel
* @property \Kanboard\Model\ActionParameterModel $actionParameterModel
* @property \Kanboard\Model\AvatarFileModel $avatarFileModel
@@ -77,6 +94,7 @@ use Pimple\Container;
* @property \Kanboard\Model\ProjectFileModel $projectFileModel
* @property \Kanboard\Model\GroupModel $groupModel
* @property \Kanboard\Model\GroupMemberModel $groupMemberModel
+ * @property \Kanboard\Model\InviteModel $inviteModel
* @property \Kanboard\Model\LanguageModel $languageModel
* @property \Kanboard\Model\LastLoginModel $lastLoginModel
* @property \Kanboard\Model\LinkModel $linkModel
@@ -125,7 +143,6 @@ use Pimple\Container;
* @property \Kanboard\Model\TransitionModel $transitionModel
* @property \Kanboard\Model\UserModel $userModel
* @property \Kanboard\Model\UserLockingModel $userLockingModel
- * @property \Kanboard\Model\UserMentionModel $userMentionModel
* @property \Kanboard\Model\UserNotificationModel $userNotificationModel
* @property \Kanboard\Model\UserNotificationTypeModel $userNotificationTypeModel
* @property \Kanboard\Model\UserNotificationFilterModel $userNotificationFilterModel
@@ -177,6 +194,7 @@ use Pimple\Container;
* @property \Kanboard\Job\ProjectFileEventJob $projectFileEventJob
* @property \Kanboard\Job\NotificationJob $notificationJob
* @property \Kanboard\Job\ProjectMetricJob $projectMetricJob
+ * @property \Kanboard\Job\UserMentionJob $userMentionJob
* @property \Psr\Log\LoggerInterface $logger
* @property \PicoDb\Database $db
* @property \Symfony\Component\EventDispatcher\EventDispatcher $dispatcher
diff --git a/app/Core/DateParser.php b/app/Core/DateParser.php
index b9aa9230..9d012d12 100644
--- a/app/Core/DateParser.php
+++ b/app/Core/DateParser.php
@@ -13,7 +13,6 @@ use DateTime;
class DateParser extends Base
{
const DATE_FORMAT = 'm/d/Y';
- const DATE_TIME_FORMAT = 'm/d/Y H:i';
const TIME_FORMAT = 'H:i';
/**
@@ -35,7 +34,7 @@ class DateParser extends Base
*/
public function getUserDateTimeFormat()
{
- return $this->configModel->get('application_datetime_format', DateParser::DATE_TIME_FORMAT);
+ return $this->getUserDateFormat().' '.$this->getUserTimeFormat();
}
/**
@@ -292,11 +291,9 @@ class DateParser extends Base
{
foreach ($fields as $field) {
if (! empty($values[$field])) {
- if (! ctype_digit($values[$field])) {
- $values[$field] = strtotime($values[$field]);
+ if (ctype_digit($values[$field])) {
+ $values[$field] = date($format, $values[$field]);
}
-
- $values[$field] = date($format, $values[$field]);
} else {
$values[$field] = '';
}
diff --git a/app/Core/ExternalTask/AccessForbiddenException.php b/app/Core/ExternalTask/AccessForbiddenException.php
new file mode 100644
index 00000000..2b5ebd33
--- /dev/null
+++ b/app/Core/ExternalTask/AccessForbiddenException.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace Kanboard\Core\ExternalTask;
+
+/**
+ * Class AccessForbiddenException
+ *
+ * @package Kanboard\Core\ExternalTask
+ * @author Frederic Guillot
+ */
+class AccessForbiddenException extends ExternalTaskException
+{
+}
diff --git a/app/Core/ExternalTask/ExternalTaskException.php b/app/Core/ExternalTask/ExternalTaskException.php
new file mode 100644
index 00000000..07e5665d
--- /dev/null
+++ b/app/Core/ExternalTask/ExternalTaskException.php
@@ -0,0 +1,15 @@
+<?php
+
+namespace Kanboard\Core\ExternalTask;
+
+use Exception;
+
+/**
+ * Class NotFoundException
+ *
+ * @package Kanboard\Core\ExternalTask
+ * @author Frederic Guillot
+ */
+class ExternalTaskException extends Exception
+{
+}
diff --git a/app/Core/ExternalTask/ExternalTaskInterface.php b/app/Core/ExternalTask/ExternalTaskInterface.php
new file mode 100644
index 00000000..084af509
--- /dev/null
+++ b/app/Core/ExternalTask/ExternalTaskInterface.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace Kanboard\Core\ExternalTask;
+
+/**
+ * Interface ExternalTaskInterface
+ *
+ * @package Kanboard\Core\ExternalTask
+ * @author Frederic Guillot
+ */
+interface ExternalTaskInterface
+{
+ /**
+ * Return Uniform Resource Identifier for the task
+ *
+ * @return string
+ */
+ public function getUri();
+
+ /**
+ * Return a dict to populate the task form
+ *
+ * @return array
+ */
+ public function getFormValues();
+}
diff --git a/app/Core/ExternalTask/ExternalTaskManager.php b/app/Core/ExternalTask/ExternalTaskManager.php
new file mode 100644
index 00000000..102ec459
--- /dev/null
+++ b/app/Core/ExternalTask/ExternalTaskManager.php
@@ -0,0 +1,58 @@
+<?php
+
+namespace Kanboard\Core\ExternalTask;
+
+/**
+ * Class ExternalTaskManager
+ *
+ * @package Kanboard\Core\ExternalTask
+ * @author Frederic Guillot
+ */
+class ExternalTaskManager
+{
+ protected $providers = array();
+
+ /**
+ * Register a new task provider
+ *
+ * @param ExternalTaskProviderInterface $externalTaskProvider
+ * @return $this
+ */
+ public function register(ExternalTaskProviderInterface $externalTaskProvider)
+ {
+ $this->providers[$externalTaskProvider->getName()] = $externalTaskProvider;
+ return $this;
+ }
+
+ /**
+ * Get task provider
+ *
+ * @param string $name
+ * @return ExternalTaskProviderInterface|null
+ * @throws ProviderNotFoundException
+ */
+ public function getProvider($name)
+ {
+ if (isset($this->providers[$name])) {
+ return $this->providers[$name];
+ }
+
+ throw new ProviderNotFoundException('Unable to load this provider: '.$name);
+ }
+
+ /**
+ * Get list of task providers
+ *
+ * @return array
+ */
+ public function getProvidersList()
+ {
+ $providers = array_keys($this->providers);
+
+ if (count($providers)) {
+ return array_combine($providers, $providers);
+ }
+
+ return array();
+ }
+}
diff --git a/app/Core/ExternalTask/ExternalTaskProviderInterface.php b/app/Core/ExternalTask/ExternalTaskProviderInterface.php
new file mode 100644
index 00000000..f67f7552
--- /dev/null
+++ b/app/Core/ExternalTask/ExternalTaskProviderInterface.php
@@ -0,0 +1,77 @@
+<?php
+
+namespace Kanboard\Core\ExternalTask;
+
+/**
+ * Interface ExternalTaskProviderInterface
+ *
+ * @package Kanboard\Core\ExternalTask
+ * @author Frederic Guillot
+ */
+interface ExternalTaskProviderInterface
+{
+ /**
+ * Get provider name (visible in the user interface)
+ *
+ * @access public
+ * @return string
+ */
+ public function getName();
+
+ /**
+ * Retrieve task from external system or cache
+ *
+ * @access public
+ * @throws \Kanboard\Core\ExternalTask\ExternalTaskException
+ * @param string $uri
+ * @return ExternalTaskInterface
+ */
+ public function fetch($uri);
+
+ /**
+ * Save external task to another system
+ *
+ * @throws \Kanboard\Core\ExternalTask\ExternalTaskException
+ * @param string $uri
+ * @param array $formValues
+ * @param array $formErrors
+ * @return bool
+ */
+ public function save($uri, array $formValues, array &$formErrors);
+
+ /**
+ * Get task import template name
+ *
+ * @return string
+ */
+ public function getImportFormTemplate();
+
+ /**
+ * Get creation form template
+ *
+ * @return string
+ */
+ public function getCreationFormTemplate();
+
+ /**
+ * Get modification form template
+ *
+ * @return string
+ */
+ public function getModificationFormTemplate();
+
+ /**
+ * Get task view template name
+ *
+ * @return string
+ */
+ public function getViewTemplate();
+
+ /**
+ * Build external task URI based on import form values
+ *
+ * @param array $formValues
+ * @return string
+ */
+ public function buildTaskUri(array $formValues);
+}
diff --git a/app/Core/ExternalTask/NotFoundException.php b/app/Core/ExternalTask/NotFoundException.php
new file mode 100644
index 00000000..34eff8ea
--- /dev/null
+++ b/app/Core/ExternalTask/NotFoundException.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace Kanboard\Core\ExternalTask;
+
+/**
+ * Class NotFoundException
+ *
+ * @package Kanboard\Core\ExternalTask
+ * @author Frederic Guillot
+ */
+class NotFoundException extends ExternalTaskException
+{
+}
diff --git a/app/Core/ExternalTask/ProviderNotFoundException.php b/app/Core/ExternalTask/ProviderNotFoundException.php
new file mode 100644
index 00000000..6ad1fae1
--- /dev/null
+++ b/app/Core/ExternalTask/ProviderNotFoundException.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace Kanboard\Core\ExternalTask;
+
+/**
+ * Class ProviderNotFoundException
+ *
+ * @package Kanboard\Core\ExternalTask
+ * @author Frederic Guillot
+ */
+class ProviderNotFoundException extends ExternalTaskException
+{
+}
diff --git a/app/Core/Filter/FormatterInterface.php b/app/Core/Filter/FormatterInterface.php
index b7c04c51..0ff84976 100644
--- a/app/Core/Filter/FormatterInterface.php
+++ b/app/Core/Filter/FormatterInterface.php
@@ -17,7 +17,7 @@ interface FormatterInterface
*
* @access public
* @param Table $query
- * @return FormatterInterface
+ * @return $this
*/
public function withQuery(Table $query);
diff --git a/app/Core/Helper.php b/app/Core/Helper.php
index b5c560af..ab7c3b7b 100644
--- a/app/Core/Helper.php
+++ b/app/Core/Helper.php
@@ -12,6 +12,7 @@ use Pimple\Container;
*
* @property \Kanboard\Helper\AppHelper $app
* @property \Kanboard\Helper\AssetHelper $asset
+ * @property \Kanboard\Helper\AvatarHelper $avatar
* @property \Kanboard\Helper\BoardHelper $board
* @property \Kanboard\Helper\CalendarHelper $calendar
* @property \Kanboard\Helper\DateHelper $dt
@@ -19,6 +20,7 @@ use Pimple\Container;
* @property \Kanboard\Helper\FormHelper $form
* @property \Kanboard\Helper\HookHelper $hook
* @property \Kanboard\Helper\ICalHelper $ical
+ * @property \Kanboard\Helper\ModalHelper $modal
* @property \Kanboard\Helper\ModelHelper $model
* @property \Kanboard\Helper\SubtaskHelper $subtask
* @property \Kanboard\Helper\TaskHelper $task
diff --git a/app/Core/Http/Request.php b/app/Core/Http/Request.php
index 2e84958d..44bfdbe6 100644
--- a/app/Core/Http/Request.php
+++ b/app/Core/Http/Request.php
@@ -105,7 +105,7 @@ class Request extends Base
{
if (! empty($this->post) && ! empty($this->post['csrf_token']) && $this->token->validateCSRFToken($this->post['csrf_token'])) {
unset($this->post['csrf_token']);
- return $this->post;
+ return $this->filterValues($this->post);
}
return array();
@@ -344,4 +344,17 @@ class Request extends Base
{
return isset($this->server[$variable]) ? $this->server[$variable] : '';
}
+
+ protected function filterValues(array $values)
+ {
+ foreach ($values as $key => $value) {
+
+ // IE11 Workaround when submitting multipart/form-data
+ if (strpos($key, '-----------------------------') === 0) {
+ unset($values[$key]);
+ }
+ }
+
+ return $values;
+ }
}
diff --git a/app/Core/Http/Response.php b/app/Core/Http/Response.php
index 0f16fb65..0af763a6 100644
--- a/app/Core/Http/Response.php
+++ b/app/Core/Http/Response.php
@@ -129,6 +129,18 @@ class Response extends Base
}
/**
+ * Add P3P headers for Internet Explorer
+ *
+ * @access public
+ * @return $this
+ */
+ public function withP3P()
+ {
+ $this->withHeader('P3P', 'CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"');
+ return $this;
+ }
+
+ /**
* Set HTTP response body
*
* @access public
diff --git a/app/Core/Mail/Transport/Mail.php b/app/Core/Mail/Transport/Mail.php
index d27925f0..c99cc8ba 100644
--- a/app/Core/Mail/Transport/Mail.php
+++ b/app/Core/Mail/Transport/Mail.php
@@ -33,8 +33,8 @@ class Mail extends Base implements ClientInterface
$message = Swift_Message::newInstance()
->setSubject($subject)
->setFrom(array($this->helper->mail->getMailSenderAddress() => $author))
- ->setBody($html, 'text/html')
- ->setTo(array($email => $name));
+ ->setTo(array($email => $name))
+ ->setBody($html, 'text/html');
Swift_Mailer::newInstance($this->getTransport())->send($message);
} catch (Swift_TransportException $e) {
diff --git a/app/Core/Mail/Transport/Smtp.php b/app/Core/Mail/Transport/Smtp.php
index 1f4e54ce..815dde5d 100644
--- a/app/Core/Mail/Transport/Smtp.php
+++ b/app/Core/Mail/Transport/Smtp.php
@@ -24,6 +24,7 @@ class Smtp extends Mail
$transport->setUsername(MAIL_SMTP_USERNAME);
$transport->setPassword(MAIL_SMTP_PASSWORD);
$transport->setEncryption(MAIL_SMTP_ENCRYPTION);
+
if (HTTP_VERIFY_SSL_CERTIFICATE === false) {
$transport->setStreamOptions(array(
'ssl' => array(
diff --git a/app/Core/Markdown.php b/app/Core/Markdown.php
index b5abe5ed..4487bf2a 100644
--- a/app/Core/Markdown.php
+++ b/app/Core/Markdown.php
@@ -86,18 +86,23 @@ class Markdown extends Parsedown
*/
protected function inlineUserLink(array $Excerpt)
{
- if (! $this->isPublicLink && preg_match('/^@([^\s]+)/', $Excerpt['text'], $matches)) {
- $user_id = $this->container['userModel']->getIdByUsername($matches[1]);
+ if (! $this->isPublicLink && preg_match('/^@([^\s,!:?]+)/', $Excerpt['text'], $matches)) {
+ $username = rtrim($matches[1], '.');
+ $user = $this->container['userCacheDecorator']->getByUsername($username);
- if (! empty($user_id)) {
- $url = $this->container['helper']->url->href('UserViewController', 'profile', array('user_id' => $user_id));
+ if (! empty($user)) {
+ $url = $this->container['helper']->url->href('UserViewController', 'profile', array('user_id' => $user['id']));
return array(
- 'extent' => strlen($matches[0]),
+ 'extent' => strlen($username) + 1,
'element' => array(
- 'name' => 'a',
- 'text' => $matches[0],
- 'attributes' => array('href' => $url, 'class' => 'user-mention-link'),
+ 'name' => 'a',
+ 'text' => '@' . $username,
+ 'attributes' => array(
+ 'href' => $url,
+ 'class' => 'user-mention-link',
+ 'title' => $user['name'] ?: $user['username'],
+ ),
),
);
}
@@ -125,7 +130,10 @@ class Markdown extends Parsedown
array(
'token' => $token,
'task_id' => $task_id,
- )
+ ),
+ false,
+ '',
+ true
);
}
diff --git a/app/Core/Paginator.php b/app/Core/Paginator.php
index cfe89938..9075a713 100644
--- a/app/Core/Paginator.php
+++ b/app/Core/Paginator.php
@@ -232,6 +232,17 @@ class Paginator
}
/**
+ * Get the number of current page
+ *
+ * @access public
+ * @return integer
+ */
+ public function getPage()
+ {
+ return $this->page;
+ }
+
+ /**
* Set the default column order
*
* @access public
@@ -271,6 +282,16 @@ class Paginator
}
/**
+ * Get the maximum number of items per page.
+ *
+ * @return int
+ */
+ public function getMax()
+ {
+ return $this->limit;
+ }
+
+ /**
* Return true if the collection is empty
*
* @access public
@@ -353,7 +374,9 @@ class Paginator
'&larr; '.t('Previous'),
$this->controller,
$this->action,
- $this->getUrlParams($this->page - 1, $this->order, $this->direction)
+ $this->getUrlParams($this->page - 1, $this->order, $this->direction),
+ false,
+ 'js-modal-replace'
);
} else {
$html .= '&larr; '.t('Previous');
@@ -379,7 +402,9 @@ class Paginator
t('Next').' &rarr;',
$this->controller,
$this->action,
- $this->getUrlParams($this->page + 1, $this->order, $this->direction)
+ $this->getUrlParams($this->page + 1, $this->order, $this->direction),
+ false,
+ 'js-modal-replace'
);
} else {
$html .= t('Next').' &rarr;';
@@ -391,6 +416,17 @@ class Paginator
}
/**
+ * Generate the page showing.
+ *
+ * @access public
+ * @return string
+ */
+ public function generatPageShowing()
+ {
+ return '<span class="pagination-showing">'.t('Showing %d-%d of %d', (($this->getPage() - 1) * $this->getMax() + 1), min($this->getTotal(), $this->getPage() * $this->getMax()), $this->getTotal()).'</span>';
+ }
+
+ /**
* Return true if there is no pagination to show
*
* @access public
@@ -413,6 +449,7 @@ class Paginator
if (! $this->hasNothingtoShow()) {
$html .= '<div class="pagination">';
+ $html .= $this->generatPageShowing();
$html .= $this->generatePreviousLink();
$html .= $this->generateNextLink();
$html .= '</div>';
@@ -453,7 +490,9 @@ class Paginator
$label,
$this->controller,
$this->action,
- $this->getUrlParams($this->page, $column, $direction)
+ $this->getUrlParams($this->page, $column, $direction),
+ false,
+ 'js-modal-replace'
);
}
}
diff --git a/app/Core/Plugin/Base.php b/app/Core/Plugin/Base.php
index 9d8167a9..e0b5954a 100644
--- a/app/Core/Plugin/Base.php
+++ b/app/Core/Plugin/Base.php
@@ -131,4 +131,17 @@ abstract class Base extends \Kanboard\Core\Base
{
return '';
}
+
+ /**
+ * Get application compatibility version
+ *
+ * Examples: >=1.0.36, 1.0.37, APP_VERSION
+ *
+ * @access public
+ * @return string
+ */
+ public function getCompatibleVersion()
+ {
+ return APP_VERSION;
+ }
}
diff --git a/app/Core/Plugin/Directory.php b/app/Core/Plugin/Directory.php
index 27c3514e..dc32e655 100644
--- a/app/Core/Plugin/Directory.php
+++ b/app/Core/Plugin/Directory.php
@@ -36,18 +36,7 @@ class Directory extends BaseCore
*/
public function isCompatible(array $plugin, $appVersion = APP_VERSION)
{
- if (strpos($appVersion, 'master') !== false) {
- return true;
- }
-
- foreach (array('>=', '>') as $operator) {
- if (strpos($plugin['compatible_version'], $operator) === 0) {
- $pluginVersion = substr($plugin['compatible_version'], strlen($operator));
- return version_compare($appVersion, $pluginVersion, $operator);
- }
- }
-
- return $plugin['compatible_version'] === $appVersion;
+ return Version::isCompatible($plugin['compatible_version'], $appVersion);
}
/**
diff --git a/app/Core/Plugin/Loader.php b/app/Core/Plugin/Loader.php
index f2f6add7..38f41d39 100644
--- a/app/Core/Plugin/Loader.php
+++ b/app/Core/Plugin/Loader.php
@@ -4,6 +4,7 @@ namespace Kanboard\Core\Plugin;
use Composer\Autoload\ClassLoader;
use DirectoryIterator;
+use Exception;
use LogicException;
use Kanboard\Core\Tool;
@@ -22,6 +23,7 @@ class Loader extends \Kanboard\Core\Base
* @var array
*/
protected $plugins = array();
+ protected $incompatiblePlugins = array();
/**
* Get list of loaded plugins
@@ -35,6 +37,17 @@ class Loader extends \Kanboard\Core\Base
}
/**
+ * Get list of not compatible plugins
+ *
+ * @access public
+ * @return Base[]
+ */
+ public function getIncompatiblePlugins()
+ {
+ return $this->incompatiblePlugins;
+ }
+
+ /**
* Scan plugin folder and load plugins
*
* @access public
@@ -51,8 +64,7 @@ class Loader extends \Kanboard\Core\Base
foreach ($dir as $fileInfo) {
if ($fileInfo->isDir() && substr($fileInfo->getFilename(), 0, 1) !== '.') {
$pluginName = $fileInfo->getFilename();
- $this->loadSchema($pluginName);
- $this->initializePlugin($pluginName, $this->loadPlugin($pluginName));
+ $this->initializePlugin($pluginName);
}
}
}
@@ -85,7 +97,7 @@ class Loader extends \Kanboard\Core\Base
$className = '\Kanboard\Plugin\\'.$pluginName.'\\Plugin';
if (! class_exists($className)) {
- throw new LogicException('Unable to load this plugin class '.$className);
+ throw new LogicException('Unable to load this plugin class: '.$className);
}
return new $className($this->container);
@@ -96,18 +108,30 @@ class Loader extends \Kanboard\Core\Base
*
* @access public
* @param string $pluginName
- * @param Base $plugin
*/
- public function initializePlugin($pluginName, Base $plugin)
+ public function initializePlugin($pluginName)
{
- if (method_exists($plugin, 'onStartup')) {
- $this->dispatcher->addListener('app.bootstrap', array($plugin, 'onStartup'));
- }
+ try {
+ $plugin = $this->loadPlugin($pluginName);
- Tool::buildDIC($this->container, $plugin->getClasses());
- Tool::buildDICHelpers($this->container, $plugin->getHelpers());
+ if (Version::isCompatible($plugin->getCompatibleVersion(), APP_VERSION)) {
+ $this->loadSchema($pluginName);
+
+ if (method_exists($plugin, 'onStartup')) {
+ $this->dispatcher->addListener('app.bootstrap', array($plugin, 'onStartup'));
+ }
- $plugin->initialize();
- $this->plugins[$pluginName] = $plugin;
+ Tool::buildDIC($this->container, $plugin->getClasses());
+ Tool::buildDICHelpers($this->container, $plugin->getHelpers());
+
+ $plugin->initialize();
+ $this->plugins[$pluginName] = $plugin;
+ } else {
+ $this->incompatiblePlugins[$pluginName] = $plugin;
+ $this->logger->error($pluginName.' is not compatible with this version');
+ }
+ } catch (Exception $e) {
+ $this->logger->critical($pluginName.': '.$e->getMessage());
+ }
}
}
diff --git a/app/Core/Plugin/PluginException.php b/app/Core/Plugin/PluginException.php
new file mode 100644
index 00000000..fae7de35
--- /dev/null
+++ b/app/Core/Plugin/PluginException.php
@@ -0,0 +1,15 @@
+<?php
+
+namespace Kanboard\Core\Plugin;
+
+use Exception;
+
+/**
+ * Class PluginException
+ *
+ * @package Kanboard\Core\Plugin
+ * @author Frederic Guillot
+ */
+class PluginException extends Exception
+{
+}
diff --git a/app/Core/Plugin/PluginInstallerException.php b/app/Core/Plugin/PluginInstallerException.php
index 7d356c9b..31745f22 100644
--- a/app/Core/Plugin/PluginInstallerException.php
+++ b/app/Core/Plugin/PluginInstallerException.php
@@ -2,14 +2,12 @@
namespace Kanboard\Core\Plugin;
-use Exception;
-
/**
* Class PluginInstallerException
*
* @package Kanboard\Core\Plugin
* @author Frederic Guillot
*/
-class PluginInstallerException extends Exception
+class PluginInstallerException extends PluginException
{
}
diff --git a/app/Core/Plugin/Version.php b/app/Core/Plugin/Version.php
new file mode 100644
index 00000000..ba5e0443
--- /dev/null
+++ b/app/Core/Plugin/Version.php
@@ -0,0 +1,38 @@
+<?php
+
+namespace Kanboard\Core\Plugin;
+
+/**
+ * Class Version
+ *
+ * @package Kanboard\Core\Plugin
+ * @author Frederic Guillot
+ */
+class Version
+{
+ /**
+ * Check plugin version compatibility with application version
+ *
+ * @param string $pluginCompatibleVersion
+ * @param string $appVersion
+ * @return bool
+ */
+ public static function isCompatible($pluginCompatibleVersion, $appVersion = APP_VERSION)
+ {
+ if (strpos($appVersion, 'master') !== false) {
+ return true;
+ }
+
+ $appVersion = str_replace('v', '', $appVersion);
+ $pluginCompatibleVersion = str_replace('v', '', $pluginCompatibleVersion);
+
+ foreach (array('>=', '>', '<=', '<') as $operator) {
+ if (strpos($pluginCompatibleVersion, $operator) === 0) {
+ $pluginVersion = substr($pluginCompatibleVersion, strlen($operator));
+ return version_compare($appVersion, $pluginVersion, $operator);
+ }
+ }
+
+ return $pluginCompatibleVersion === $appVersion;
+ }
+}
diff --git a/app/Core/Queue/QueueManager.php b/app/Core/Queue/QueueManager.php
index dcf0ebf5..1d7c2d1e 100644
--- a/app/Core/Queue/QueueManager.php
+++ b/app/Core/Queue/QueueManager.php
@@ -64,7 +64,7 @@ class QueueManager extends Base
public function listen()
{
if ($this->queue === null) {
- throw new LogicException('No queue driver defined!');
+ throw new LogicException('No queue driver defined or unable to connect to broker!');
}
while ($job = $this->queue->pull()) {
diff --git a/app/Core/Session/SessionStorage.php b/app/Core/Session/SessionStorage.php
index 9e93602c..e6478d8d 100644
--- a/app/Core/Session/SessionStorage.php
+++ b/app/Core/Session/SessionStorage.php
@@ -19,6 +19,7 @@ namespace Kanboard\Core\Session;
* @property bool $hasSubtaskInProgress
* @property bool $hasRememberMe
* @property bool $boardCollapsed
+ * @property string $scope
* @property bool $twoFactorBeforeCodeCalled
* @property string $twoFactorSecret
* @property string $oauthState
diff --git a/app/Core/Tool.php b/app/Core/Tool.php
index 9b8820eb..6e457641 100644
--- a/app/Core/Tool.php
+++ b/app/Core/Tool.php
@@ -41,7 +41,7 @@ class Tool
}
/**
- * Build dependency injection container from an array
+ * Build dependency injection containers from an array
*
* @static
* @access public
@@ -64,6 +64,29 @@ class Tool
}
/**
+ * Build dependency injection container from an array
+ *
+ * @static
+ * @access public
+ * @param Container $container
+ * @param array $namespaces
+ * @return Container
+ */
+ public static function buildFactories(Container $container, array $namespaces)
+ {
+ foreach ($namespaces as $namespace => $classes) {
+ foreach ($classes as $name) {
+ $class = '\\Kanboard\\'.$namespace.'\\'.$name;
+ $container[lcfirst($name)] = $container->factory(function ($c) use ($class) {
+ return new $class($c);
+ });
+ }
+ }
+
+ return $container;
+ }
+
+ /**
* Build dependency injection container for custom helpers from an array
*
* @static
diff --git a/app/Core/Translator.php b/app/Core/Translator.php
index 113c0dc6..ac2e2aae 100644
--- a/app/Core/Translator.php
+++ b/app/Core/Translator.php
@@ -11,13 +11,6 @@ namespace Kanboard\Core;
class Translator
{
/**
- * Locale path
- *
- * @var string
- */
- const PATH = 'app/Locale';
-
- /**
* Locale
*
* @static
@@ -171,9 +164,13 @@ class Translator
* @param string $language Locale code: fr_FR
* @param string $path Locale folder
*/
- public static function load($language, $path = self::PATH)
+ public static function load($language, $path = '')
{
- $filename = $path.DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.'translations.php';
+ if ($path === '') {
+ $path = self::getDefaultFolder();
+ }
+
+ $filename = implode(DIRECTORY_SEPARATOR, array($path, $language, 'translations.php'));
if (file_exists($filename)) {
self::$locales = array_merge(self::$locales, require($filename));
@@ -190,4 +187,15 @@ class Translator
{
self::$locales = array();
}
+
+ /**
+ * Get default locales folder
+ *
+ * @access public
+ * @return string
+ */
+ public static function getDefaultFolder()
+ {
+ return implode(DIRECTORY_SEPARATOR, array(__DIR__, '..', 'Locale'));
+ }
}
diff --git a/app/Decorator/UserCacheDecorator.php b/app/Decorator/UserCacheDecorator.php
new file mode 100644
index 00000000..1cfe31c9
--- /dev/null
+++ b/app/Decorator/UserCacheDecorator.php
@@ -0,0 +1,59 @@
+<?php
+
+namespace Kanboard\Decorator;
+
+use Kanboard\Core\Cache\CacheInterface;
+use Kanboard\Model\UserModel;
+
+/**
+ * Class UserCacheDecorator
+ *
+ * @package Kanboard\Decorator
+ * @author Frederic Guillot
+ */
+class UserCacheDecorator
+{
+ protected $cachePrefix = 'user_model:';
+
+ /**
+ * @var CacheInterface
+ */
+ protected $cache;
+
+ /**
+ * @var UserModel
+ */
+ private $userModel;
+
+ /**
+ * UserCacheDecorator constructor.
+ *
+ * @param CacheInterface $cache
+ * @param UserModel $userModel
+ */
+ public function __construct(CacheInterface $cache, UserModel $userModel)
+ {
+ $this->cache = $cache;
+ $this->userModel = $userModel;
+ }
+
+ /**
+ * Get a specific user by the username
+ *
+ * @access public
+ * @param string $username Username
+ * @return array
+ */
+ public function getByUsername($username)
+ {
+ $key = $this->cachePrefix.$username;
+ $user = $this->cache->get($key);
+
+ if ($user === null) {
+ $user = $this->userModel->getByUsername($username);
+ $this->cache->set($key, $user);
+ }
+
+ return $user;
+ }
+}
diff --git a/app/Event/GenericEvent.php b/app/Event/GenericEvent.php
index 94a51479..e87d9481 100644
--- a/app/Event/GenericEvent.php
+++ b/app/Event/GenericEvent.php
@@ -14,6 +14,28 @@ class GenericEvent extends BaseEvent implements ArrayAccess
$this->container = $values;
}
+ public function getTaskId()
+ {
+ if (isset($this->container['task']['id'])) {
+ return $this->container['task']['id'];
+ }
+
+ if (isset($this->container['task_id'])) {
+ return $this->container['task_id'];
+ }
+
+ return null;
+ }
+
+ public function getProjectId()
+ {
+ if (isset($this->container['task']['project_id'])) {
+ return $this->container['task']['project_id'];
+ }
+
+ return null;
+ }
+
public function getAll()
{
return $this->container;
diff --git a/app/Event/ProjectFileEvent.php b/app/Event/ProjectFileEvent.php
index 5d57e463..e1d29c48 100644
--- a/app/Event/ProjectFileEvent.php
+++ b/app/Event/ProjectFileEvent.php
@@ -4,4 +4,12 @@ namespace Kanboard\Event;
class ProjectFileEvent extends GenericEvent
{
+ public function getProjectId()
+ {
+ if (isset($this->container['file']['project_id'])) {
+ return $this->container['file']['project_id'];
+ }
+
+ return null;
+ }
}
diff --git a/app/Filter/TaskStartsWithIdFilter.php b/app/Filter/TaskStartsWithIdFilter.php
new file mode 100644
index 00000000..8b7cc678
--- /dev/null
+++ b/app/Filter/TaskStartsWithIdFilter.php
@@ -0,0 +1,38 @@
+<?php
+
+namespace Kanboard\Filter;
+
+use Kanboard\Core\Filter\FilterInterface;
+use Kanboard\Model\TaskModel;
+
+/**
+ * Class TaskIdSearchFilter
+ *
+ * @package Kanboard\Filter
+ * @author Frederic Guillot
+ */
+class TaskStartsWithIdFilter extends BaseFilter implements FilterInterface
+{
+ /**
+ * Get search attribute
+ *
+ * @access public
+ * @return string[]
+ */
+ public function getAttributes()
+ {
+ return array('starts_with_id');
+ }
+
+ /**
+ * Apply filter
+ *
+ * @access public
+ * @return FilterInterface
+ */
+ public function apply()
+ {
+ $this->query->ilike('CAST('.TaskModel::TABLE.'.id AS CHAR(8))', $this->value.'%');
+ return $this;
+ }
+}
diff --git a/app/Formatter/BaseFormatter.php b/app/Formatter/BaseFormatter.php
index 89c48437..0d62628e 100644
--- a/app/Formatter/BaseFormatter.php
+++ b/app/Formatter/BaseFormatter.php
@@ -4,7 +4,6 @@ namespace Kanboard\Formatter;
use Kanboard\Core\Base;
use PicoDb\Table;
-use Pimple\Container;
/**
* Class BaseFormatter
@@ -23,19 +22,6 @@ abstract class BaseFormatter extends Base
protected $query;
/**
- * Get object instance
- *
- * @static
- * @access public
- * @param Container $container
- * @return static
- */
- public static function getInstance(Container $container)
- {
- return new static($container);
- }
-
- /**
* Set query
*
* @access public
diff --git a/app/Formatter/BaseTaskCalendarFormatter.php b/app/Formatter/BaseTaskCalendarFormatter.php
index 8fab3e9a..3d9ead4d 100644
--- a/app/Formatter/BaseTaskCalendarFormatter.php
+++ b/app/Formatter/BaseTaskCalendarFormatter.php
@@ -2,8 +2,6 @@
namespace Kanboard\Formatter;
-use Kanboard\Core\Filter\FormatterInterface;
-
/**
* Common class to handle calendar events
*
@@ -34,7 +32,7 @@ abstract class BaseTaskCalendarFormatter extends BaseFormatter
* @access public
* @param string $start_column Column name for the start date
* @param string $end_column Column name for the end date
- * @return FormatterInterface
+ * @return $this
*/
public function setColumns($start_column, $end_column = '')
{
diff --git a/app/Formatter/BoardColumnFormatter.php b/app/Formatter/BoardColumnFormatter.php
index 85d31b5c..0d59f54e 100644
--- a/app/Formatter/BoardColumnFormatter.php
+++ b/app/Formatter/BoardColumnFormatter.php
@@ -79,7 +79,7 @@ class BoardColumnFormatter extends BaseFormatter implements FormatterInterface
{
foreach ($this->columns as &$column) {
$column['id'] = (int) $column['id'];
- $column['tasks'] = BoardTaskFormatter::getInstance($this->container)
+ $column['tasks'] = $this->boardTaskFormatter
->withTasks($this->tasks)
->withTags($this->tags)
->withSwimlaneId($this->swimlaneId)
diff --git a/app/Formatter/BoardFormatter.php b/app/Formatter/BoardFormatter.php
index df443a52..3f47bfa9 100644
--- a/app/Formatter/BoardFormatter.php
+++ b/app/Formatter/BoardFormatter.php
@@ -59,7 +59,7 @@ class BoardFormatter extends BaseFormatter implements FormatterInterface
$task_ids = array_column($tasks, 'id');
$tags = $this->taskTagModel->getTagsByTasks($task_ids);
- return BoardSwimlaneFormatter::getInstance($this->container)
+ return $this->boardSwimlaneFormatter
->withSwimlanes($swimlanes)
->withColumns($columns)
->withTasks($tasks)
diff --git a/app/Formatter/BoardSwimlaneFormatter.php b/app/Formatter/BoardSwimlaneFormatter.php
index ce67c8a8..18db259d 100644
--- a/app/Formatter/BoardSwimlaneFormatter.php
+++ b/app/Formatter/BoardSwimlaneFormatter.php
@@ -82,7 +82,7 @@ class BoardSwimlaneFormatter extends BaseFormatter implements FormatterInterface
foreach ($this->swimlanes as &$swimlane) {
$swimlane['id'] = (int) $swimlane['id'];
- $swimlane['columns'] = BoardColumnFormatter::getInstance($this->container)
+ $swimlane['columns'] = $this->boardColumnFormatter
->withSwimlaneId($swimlane['id'])
->withColumns($this->columns)
->withTasks($this->tasks)
diff --git a/app/Formatter/GroupAutoCompleteFormatter.php b/app/Formatter/GroupAutoCompleteFormatter.php
index 4d552886..d811de7f 100644
--- a/app/Formatter/GroupAutoCompleteFormatter.php
+++ b/app/Formatter/GroupAutoCompleteFormatter.php
@@ -12,36 +12,26 @@ use PicoDb\Table;
* @package formatter
* @author Frederic Guillot
*/
-class GroupAutoCompleteFormatter implements FormatterInterface
+class GroupAutoCompleteFormatter extends BaseFormatter implements FormatterInterface
{
/**
* Groups found
*
- * @access private
+ * @access protected
* @var GroupProviderInterface[]
*/
- private $groups;
+ protected $groups;
/**
- * Format groups for the ajax auto-completion
+ * Set groups
*
* @access public
* @param GroupProviderInterface[] $groups
+ * @return $this
*/
- public function __construct(array $groups)
+ public function withGroups(array $groups)
{
$this->groups = $groups;
- }
-
- /**
- * Set query
- *
- * @access public
- * @param Table $query
- * @return FormatterInterface
- */
- public function withQuery(Table $query)
- {
return $this;
}
diff --git a/app/Formatter/TaskAutoCompleteFormatter.php b/app/Formatter/TaskAutoCompleteFormatter.php
index 2d9f7341..3a4f1e1a 100644
--- a/app/Formatter/TaskAutoCompleteFormatter.php
+++ b/app/Formatter/TaskAutoCompleteFormatter.php
@@ -14,6 +14,20 @@ use Kanboard\Model\TaskModel;
*/
class TaskAutoCompleteFormatter extends BaseFormatter implements FormatterInterface
{
+ protected $limit = 25;
+
+ /**
+ * Limit number of results
+ *
+ * @param $limit
+ * @return $this
+ */
+ public function withLimit($limit)
+ {
+ $this->limit = $limit;
+ return $this;
+ }
+
/**
* Apply formatter
*
@@ -22,11 +36,15 @@ class TaskAutoCompleteFormatter extends BaseFormatter implements FormatterInterf
*/
public function format()
{
- $tasks = $this->query->columns(
- TaskModel::TABLE.'.id',
- TaskModel::TABLE.'.title',
- ProjectModel::TABLE.'.name AS project_name'
- )->asc(TaskModel::TABLE.'.id')->findAll();
+ $tasks = $this->query
+ ->columns(
+ TaskModel::TABLE.'.id',
+ TaskModel::TABLE.'.title',
+ ProjectModel::TABLE.'.name AS project_name'
+ )
+ ->asc(TaskModel::TABLE.'.id')
+ ->limit($this->limit)
+ ->findAll();
foreach ($tasks as &$task) {
$task['value'] = $task['title'];
diff --git a/app/Formatter/TaskSuggestMenuFormatter.php b/app/Formatter/TaskSuggestMenuFormatter.php
new file mode 100644
index 00000000..518f99e6
--- /dev/null
+++ b/app/Formatter/TaskSuggestMenuFormatter.php
@@ -0,0 +1,63 @@
+<?php
+
+namespace Kanboard\Formatter;
+
+use Kanboard\Core\Filter\FormatterInterface;
+use Kanboard\Model\ProjectModel;
+use Kanboard\Model\TaskModel;
+
+/**
+ * Class TaskSuggestMenuFormatter
+ *
+ * @package Kanboard\Formatter
+ * @author Frederic Guillot
+ */
+class TaskSuggestMenuFormatter extends BaseFormatter implements FormatterInterface
+{
+ protected $limit = 25;
+
+ /**
+ * Limit number of results
+ *
+ * @param $limit
+ * @return $this
+ */
+ public function withLimit($limit)
+ {
+ $this->limit = $limit;
+ return $this;
+ }
+
+ /**
+ * Apply formatter
+ *
+ * @access public
+ * @return mixed
+ */
+ public function format()
+ {
+ $result = array();
+ $tasks = $this->query
+ ->columns(
+ TaskModel::TABLE.'.id',
+ TaskModel::TABLE.'.title',
+ ProjectModel::TABLE.'.name AS project_name'
+ )
+ ->asc(TaskModel::TABLE.'.id')
+ ->limit($this->limit)
+ ->findAll();
+
+ foreach ($tasks as $task) {
+ $html = '#'.$task['id'].' ';
+ $html .= $this->helper->text->e($task['title']).' ';
+ $html .= '<small>'.$this->helper->text->e($task['project_name']).'</small>';
+
+ $result[] = array(
+ 'value' => (string) $task['id'],
+ 'html' => $html,
+ );
+ }
+
+ return $result;
+ }
+}
diff --git a/app/Formatter/UserAutoCompleteFormatter.php b/app/Formatter/UserAutoCompleteFormatter.php
index cd23a2a4..c81af00a 100644
--- a/app/Formatter/UserAutoCompleteFormatter.php
+++ b/app/Formatter/UserAutoCompleteFormatter.php
@@ -14,7 +14,7 @@ use Kanboard\Core\Filter\FormatterInterface;
class UserAutoCompleteFormatter extends BaseFormatter implements FormatterInterface
{
/**
- * Format the tasks for the ajax autocompletion
+ * Format the tasks for the ajax auto-completion
*
* @access public
* @return array
@@ -24,11 +24,11 @@ class UserAutoCompleteFormatter extends BaseFormatter implements FormatterInterf
$users = $this->query->columns(UserModel::TABLE.'.id', UserModel::TABLE.'.username', UserModel::TABLE.'.name')->findAll();
foreach ($users as &$user) {
- $user['value'] = $user['username'].' (#'.$user['id'].')';
-
if (empty($user['name'])) {
+ $user['value'] = $user['username'].' (#'.$user['id'].')';
$user['label'] = $user['username'];
} else {
+ $user['value'] = $user['name'].' (#'.$user['id'].')';
$user['label'] = $user['name'].' ('.$user['username'].')';
}
}
diff --git a/app/Formatter/UserMentionFormatter.php b/app/Formatter/UserMentionFormatter.php
new file mode 100644
index 00000000..395fc463
--- /dev/null
+++ b/app/Formatter/UserMentionFormatter.php
@@ -0,0 +1,60 @@
+<?php
+
+namespace Kanboard\Formatter;
+
+/**
+ * Class UserMentionFormatter
+ *
+ * @package Kanboard\Formatter
+ * @author Frederic Guillot
+ */
+class UserMentionFormatter extends BaseFormatter
+{
+ protected $users = array();
+
+ /**
+ * Set users
+ *
+ * @param array $users
+ * @return $this
+ */
+ public function withUsers(array $users) {
+ $this->users = $users;
+ return $this;
+ }
+
+ /**
+ * Apply formatter
+ *
+ * @access public
+ * @return array
+ */
+ public function format()
+ {
+ $result = array();
+
+ foreach ($this->users as $user) {
+ $html = $this->helper->avatar->small(
+ $user['id'],
+ $user['username'],
+ $user['name'],
+ $user['email'],
+ $user['avatar_path'],
+ 'avatar-inline'
+ );
+
+ $html .= ' '.$this->helper->text->e($user['username']);
+
+ if (! empty($user['name'])) {
+ $html .= ' <small>'.$this->helper->text->e($user['name']).'</small>';
+ }
+
+ $result[] = array(
+ 'value' => $user['username'],
+ 'html' => $html,
+ );
+ }
+
+ return $result;
+ }
+} \ No newline at end of file
diff --git a/app/Helper/AppHelper.php b/app/Helper/AppHelper.php
index 09f280cb..3cefd1c5 100644
--- a/app/Helper/AppHelper.php
+++ b/app/Helper/AppHelper.php
@@ -12,17 +12,34 @@ use Kanboard\Core\Base;
*/
class AppHelper extends Base
{
+ public function isAjax()
+ {
+ return $this->request->isAjax();
+ }
+
+ /**
+ * Render Javascript component
+ *
+ * @param string $name
+ * @param array $params
+ * @return string
+ */
+ public function component($name, array $params = array())
+ {
+ return '<div class="js-'.$name.'" data-params=\''.json_encode($params, JSON_HEX_APOS).'\'></div>';
+ }
+
/**
* Get config variable
*
* @access public
* @param string $param
- * @param mixed $default_value
+ * @param mixed $default
* @return mixed
*/
- public function config($param, $default_value = '')
+ public function config($param, $default = '')
{
- return $this->configModel->get($param, $default_value);
+ return $this->configModel->get($param, $default);
}
/**
diff --git a/app/Helper/CalendarHelper.php b/app/Helper/CalendarHelper.php
index b35c40f7..0942177d 100644
--- a/app/Helper/CalendarHelper.php
+++ b/app/Helper/CalendarHelper.php
@@ -5,8 +5,6 @@ namespace Kanboard\Helper;
use Kanboard\Core\Base;
use Kanboard\Core\Filter\QueryBuilder;
use Kanboard\Filter\TaskDueDateRangeFilter;
-use Kanboard\Formatter\SubtaskTimeTrackingCalendarFormatter;
-use Kanboard\Formatter\TaskCalendarFormatter;
/**
* Calendar Helper
@@ -17,6 +15,23 @@ use Kanboard\Formatter\TaskCalendarFormatter;
class CalendarHelper extends Base
{
/**
+ * Render calendar component
+ *
+ * @param string $checkUrl
+ * @param string $saveUrl
+ * @return string
+ */
+ public function render($checkUrl, $saveUrl)
+ {
+ $params = array(
+ 'checkUrl' => $checkUrl,
+ 'saveUrl' => $saveUrl,
+ );
+
+ return '<div class="js-calendar" data-params=\''.json_encode($params, JSON_HEX_APOS).'\'></div>';
+ }
+
+ /**
* Get formatted calendar task due events
*
* @access public
@@ -27,7 +42,7 @@ class CalendarHelper extends Base
*/
public function getTaskDateDueEvents(QueryBuilder $queryBuilder, $start, $end)
{
- $formatter = new TaskCalendarFormatter($this->container);
+ $formatter = $this->taskCalendarFormatter;
$formatter->setFullDay();
$formatter->setColumns('date_due');
@@ -56,7 +71,7 @@ class CalendarHelper extends Base
'date_due'
));
- $formatter = new TaskCalendarFormatter($this->container);
+ $formatter = $this->taskCalendarFormatter;
$formatter->setColumns($startColumn, 'date_due');
return $queryBuilder->format($formatter);
@@ -73,8 +88,7 @@ class CalendarHelper extends Base
*/
public function getSubtaskTimeTrackingEvents($user_id, $start, $end)
{
- $formatter = new SubtaskTimeTrackingCalendarFormatter($this->container);
- return $formatter
+ return $this->subtaskTimeTrackingCalendarFormatter
->withQuery($this->subtaskTimeTrackingModel->getUserQuery($user_id)
->addCondition($this->getCalendarCondition(
$this->dateParser->getTimestampFromIsoFormat($start),
diff --git a/app/Helper/DateHelper.php b/app/Helper/DateHelper.php
index 7e2ec79c..3bc85b76 100644
--- a/app/Helper/DateHelper.php
+++ b/app/Helper/DateHelper.php
@@ -54,7 +54,7 @@ class DateHelper extends Base
*/
public function datetime($value)
{
- return date($this->configModel->get('application_datetime_format', 'm/d/Y H:i'), $value);
+ return date($this->dateParser->getUserDateTimeFormat(), $value);
}
/**
diff --git a/app/Helper/FileHelper.php b/app/Helper/FileHelper.php
index cabf371c..06589124 100644
--- a/app/Helper/FileHelper.php
+++ b/app/Helper/FileHelper.php
@@ -21,9 +21,7 @@ class FileHelper extends Base
*/
public function icon($filename)
{
- $extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
-
- switch ($extension) {
+ switch (get_file_extension($filename)) {
case 'jpeg':
case 'jpg':
case 'png':
@@ -70,9 +68,7 @@ class FileHelper extends Base
*/
public function getImageMimeType($filename)
{
- $extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
-
- switch ($extension) {
+ switch (get_file_extension($filename)) {
case 'jpeg':
case 'jpg':
return 'image/jpeg';
@@ -94,9 +90,7 @@ class FileHelper extends Base
*/
public function getPreviewType($filename)
{
- $extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
-
- switch ($extension) {
+ switch (get_file_extension($filename)) {
case 'md':
case 'markdown':
return 'markdown';
@@ -106,4 +100,21 @@ class FileHelper extends Base
return null;
}
+
+ /**
+ * Return the browser view mime-type based on the file extension.
+ *
+ * @access public
+ * @param $filename
+ * @return string
+ */
+ public function getBrowserViewType($filename)
+ {
+ switch (get_file_extension($filename)) {
+ case 'pdf':
+ return 'application/pdf';
+ }
+
+ return null;
+ }
}
diff --git a/app/Helper/FormHelper.php b/app/Helper/FormHelper.php
index eca1f317..9eabd724 100644
--- a/app/Helper/FormHelper.php
+++ b/app/Helper/FormHelper.php
@@ -131,16 +131,34 @@ class FormHelper extends Base
* Display a checkbox field
*
* @access public
- * @param string $name Field name
- * @param string $label Form label
- * @param string $value Form value
- * @param boolean $checked Field selected or not
- * @param string $class CSS class
+ * @param string $name Field name
+ * @param string $label Form label
+ * @param string $value Form value
+ * @param boolean $checked Field selected or not
+ * @param string $class CSS class
+ * @param array $attributes
* @return string
*/
- public function checkbox($name, $label, $value, $checked = false, $class = '')
+ public function checkbox($name, $label, $value, $checked = false, $class = '', array $attributes = array())
{
- return '<label><input type="checkbox" name="'.$name.'" class="'.$class.'" value="'.$this->helper->text->e($value).'" '.($checked ? 'checked="checked"' : '').'>&nbsp;'.$this->helper->text->e($label).'</label>';
+ $htmlAttributes = '';
+
+ if ($checked) {
+ $attributes['checked'] = 'checked';
+ }
+
+ foreach ($attributes as $attribute => $attributeValue) {
+ $htmlAttributes .= sprintf('%s="%s"', $attribute, $this->helper->text->e($attributeValue));
+ }
+
+ return sprintf(
+ '<label><input type="checkbox" name="%s" class="%s" value="%s" %s>&nbsp;%s</label>',
+ $name,
+ $class,
+ $this->helper->text->e($value),
+ $htmlAttributes,
+ $this->helper->text->e($label)
+ );
}
/**
@@ -182,6 +200,45 @@ class FormHelper extends Base
}
/**
+ * Display a markdown editor
+ *
+ * @access public
+ * @param string $name Field name
+ * @param array $values Form values
+ * @param array $errors Form errors
+ * @param array $attributes
+ * @return string
+ */
+ public function textEditor($name, $values = array(), array $errors = array(), array $attributes = array())
+ {
+ $params = array(
+ 'name' => $name,
+ 'text' => isset($values[$name]) ? $values[$name] : '',
+ 'css' => $this->errorClass($errors, $name),
+ 'required' => isset($attributes['required']) && $attributes['required'],
+ 'tabindex' => isset($attributes['tabindex']) ? $attributes['tabindex'] : '-1',
+ 'labelPreview' => t('Preview'),
+ 'labelWrite' => t('Write'),
+ 'placeholder' => t('Write your text in Markdown'),
+ 'autofocus' => isset($attributes['autofocus']) && $attributes['autofocus'],
+ 'suggestOptions' => array(
+ 'triggers' => array(
+ '#' => $this->helper->url->to('TaskAjaxController', 'suggest', array('search' => 'SEARCH_TERM')),
+ )
+ ),
+ );
+
+ if (isset($values['project_id'])) {
+ $params['suggestOptions']['triggers']['@'] = $this->helper->url->to('UserAjaxController', 'mention', array('project_id' => $values['project_id'], 'search' => 'SEARCH_TERM'));
+ }
+
+ $html = '<div class="js-text-editor" data-params=\''.json_encode($params, JSON_HEX_APOS).'\'></div>';
+ $html .= $this->errorList($errors, $name);
+
+ return $html;
+ }
+
+ /**
* Display file field
*
* @access public
diff --git a/app/Helper/ICalHelper.php b/app/Helper/ICalHelper.php
index dc399bf8..95723417 100644
--- a/app/Helper/ICalHelper.php
+++ b/app/Helper/ICalHelper.php
@@ -5,7 +5,6 @@ namespace Kanboard\Helper;
use Kanboard\Core\Base;
use Kanboard\Core\Filter\QueryBuilder;
use Kanboard\Filter\TaskDueDateRangeFilter;
-use Kanboard\Formatter\TaskICalFormatter;
use Eluceo\iCal\Component\Calendar as iCalendar;
/**
@@ -29,10 +28,10 @@ class ICalHelper extends Base
{
$queryBuilder->withFilter(new TaskDueDateRangeFilter(array($start, $end)));
- $formatter = new TaskICalFormatter($this->container);
- $formatter->setColumns('date_due');
- $formatter->setCalendar($calendar);
- $formatter->withQuery($queryBuilder->getQuery());
- $formatter->addFullDayEvents();
+ $this->taskICalFormatter
+ ->setColumns('date_due')
+ ->setCalendar($calendar)
+ ->withQuery($queryBuilder->getQuery())
+ ->addFullDayEvents();
}
}
diff --git a/app/Helper/LayoutHelper.php b/app/Helper/LayoutHelper.php
index 8d2e7e00..91745f58 100644
--- a/app/Helper/LayoutHelper.php
+++ b/app/Helper/LayoutHelper.php
@@ -22,12 +22,19 @@ class LayoutHelper extends Base
*/
public function app($template, array $params = array())
{
- if ($this->request->isAjax()) {
+ $isAjax = $this->request->isAjax();
+ $params['is_ajax'] = $isAjax;
+
+ if ($isAjax) {
return $this->template->render($template, $params);
}
if (! isset($params['no_layout']) && ! isset($params['board_selector'])) {
$params['board_selector'] = $this->projectUserRoleModel->getActiveProjectsByUser($this->userSession->getId());
+
+ if (isset($params['project']['id'])) {
+ unset($params['board_selector'][$params['project']['id']]);
+ }
}
return $this->pageLayout($template, $params);
@@ -160,7 +167,7 @@ class LayoutHelper extends Base
$params['title'] = $params['project']['name'].' &gt; '.$params['title'];
}
- return $this->subLayout('analytic/layout', 'analytic/sidebar', $template, $params);
+ return $this->subLayout('analytic/layout', 'analytic/sidebar', $template, $params, true);
}
/**
@@ -188,13 +195,16 @@ class LayoutHelper extends Base
* @param string $sidebar
* @param string $template
* @param array $params
+ * @param bool $ignoreAjax
* @return string
*/
- public function subLayout($sublayout, $sidebar, $template, array $params = array())
+ public function subLayout($sublayout, $sidebar, $template, array $params = array(), $ignoreAjax = false)
{
+ $isAjax = $this->request->isAjax();
+ $params['is_ajax'] = $isAjax;
$content = $this->template->render($template, $params);
- if ($this->request->isAjax()) {
+ if (!$ignoreAjax && $isAjax) {
return $content;
}
diff --git a/app/Helper/MailHelper.php b/app/Helper/MailHelper.php
index 3b1c9e41..cb16d6f8 100644
--- a/app/Helper/MailHelper.php
+++ b/app/Helper/MailHelper.php
@@ -40,8 +40,9 @@ class MailHelper extends Base
*/
public function filterSubject($subject)
{
- $subject = str_replace('RE: ', '', $subject);
- $subject = str_replace('FW: ', '', $subject);
+ $subject = str_ireplace('RE: ', '', $subject);
+ $subject = str_ireplace('FW: ', '', $subject);
+ $subject = str_ireplace('Fwd: ', '', $subject);
return $subject;
}
@@ -54,27 +55,31 @@ class MailHelper extends Base
*/
public function getMailSenderAddress()
{
- $email = $this->configModel->get('mail_sender_address');
+ if (MAIL_CONFIGURATION) {
+ $email = $this->configModel->get('mail_sender_address');
- if (!empty($email)) {
- return $email;
+ if (! empty($email)) {
+ return $email;
+ }
}
return MAIL_FROM;
}
/**
- * Get mail sender address
+ * Get mail transport
*
* @access public
* @return string
*/
public function getMailTransport()
{
- $transport = $this->configModel->get('mail_transport');
+ if (MAIL_CONFIGURATION) {
+ $transport = $this->configModel->get('mail_transport');
- if (!empty($transport)) {
- return $transport;
+ if (! empty($transport)) {
+ return $transport;
+ }
}
return MAIL_TRANSPORT;
diff --git a/app/Helper/ModalHelper.php b/app/Helper/ModalHelper.php
new file mode 100644
index 00000000..efbe2c4d
--- /dev/null
+++ b/app/Helper/ModalHelper.php
@@ -0,0 +1,83 @@
+<?php
+
+namespace Kanboard\Helper;
+
+use Kanboard\Core\Base;
+
+/**
+ * Class ModalHelper
+ *
+ * @package Kanboard\Helper
+ * @author Frederic Guillot
+ */
+class ModalHelper extends Base
+{
+ public function submitButtons(array $params = array())
+ {
+ return $this->helper->app->component('submit-buttons', array(
+ 'submitLabel' => isset($params['submitLabel']) ? $params['submitLabel'] : t('Save'),
+ 'orLabel' => t('or'),
+ 'cancelLabel' => t('cancel'),
+ 'color' => isset($params['color']) ? $params['color'] : 'blue',
+ 'tabindex' => isset($params['tabindex']) ? $params['tabindex'] : null,
+ 'disabled' => isset($params['disabled']) ? true : false,
+ ));
+ }
+
+ public function confirmButtons($controller, $action, array $params = array(), $submitLabel = '', $tabindex = null)
+ {
+ return $this->helper->app->component('confirm-buttons', array(
+ 'url' => $this->helper->url->href($controller, $action, $params, true),
+ 'submitLabel' => $submitLabel ?: t('Yes'),
+ 'orLabel' => t('or'),
+ 'cancelLabel' => t('cancel'),
+ 'tabindex' => $tabindex,
+ ));
+ }
+
+ public function largeIcon($icon, $label, $controller, $action, array $params = array())
+ {
+ $html = '<i class="fa fa-'.$icon.' fa-fw js-modal-large" aria-hidden="true"></i>';
+ return $this->helper->url->link($html, $controller, $action, $params, false, 'js-modal-large', $label);
+ }
+
+ public function large($icon, $label, $controller, $action, array $params = array())
+ {
+ $html = '<i class="fa fa-'.$icon.' fa-fw js-modal-large" aria-hidden="true"></i>'.$label;
+ return $this->helper->url->link($html, $controller, $action, $params, false, 'js-modal-large');
+ }
+
+ public function medium($icon, $label, $controller, $action, array $params = array())
+ {
+ $html = '<i class="fa fa-'.$icon.' fa-fw js-modal-medium" aria-hidden="true"></i>'.$label;
+ return $this->helper->url->link($html, $controller, $action, $params, false, 'js-modal-medium');
+ }
+
+ public function small($icon, $label, $controller, $action, array $params = array())
+ {
+ $html = '<i class="fa fa-'.$icon.' fa-fw js-modal-small" aria-hidden="true"></i>'.$label;
+ return $this->helper->url->link($html, $controller, $action, $params, false, 'js-modal-small');
+ }
+
+ public function mediumButton($icon, $label, $controller, $action, array $params = array())
+ {
+ $html = '<i class="fa fa-'.$icon.' fa-fw js-modal-medium" aria-hidden="true"></i>'.$label;
+ return $this->helper->url->link($html, $controller, $action, $params, false, 'js-modal-medium btn');
+ }
+
+ public function confirm($icon, $label, $controller, $action, array $params = array())
+ {
+ $html = '<i class="fa fa-'.$icon.' fa-fw js-modal-confirm" aria-hidden="true"></i>'.$label;
+ return $this->helper->url->link($html, $controller, $action, $params, false, 'js-modal-confirm');
+ }
+
+ public function confirmLink($label, $controller, $action, array $params = array())
+ {
+ return $this->helper->url->link($label, $controller, $action, $params, false, 'js-modal-confirm');
+ }
+
+ public function replaceLink($label, $controller, $action, array $params = array())
+ {
+ return $this->helper->url->link($label, $controller, $action, $params, false, 'js-modal-replace');
+ }
+}
diff --git a/app/Helper/ProjectActivityHelper.php b/app/Helper/ProjectActivityHelper.php
index 704cd4fe..480db3d5 100644
--- a/app/Helper/ProjectActivityHelper.php
+++ b/app/Helper/ProjectActivityHelper.php
@@ -6,7 +6,6 @@ use Kanboard\Core\Base;
use Kanboard\Filter\ProjectActivityProjectIdFilter;
use Kanboard\Filter\ProjectActivityProjectIdsFilter;
use Kanboard\Filter\ProjectActivityTaskIdFilter;
-use Kanboard\Formatter\ProjectActivityEventFormatter;
use Kanboard\Model\ProjectActivityModel;
/**
@@ -38,7 +37,7 @@ class ProjectActivityHelper extends Base
->limit(500)
;
- $events = $queryBuilder->format(new ProjectActivityEventFormatter($this->container));
+ $events = $queryBuilder->format($this->projectActivityEventFormatter);
}
return $events;
@@ -62,7 +61,7 @@ class ProjectActivityHelper extends Base
->limit($limit)
;
- return $queryBuilder->format(new ProjectActivityEventFormatter($this->container));
+ return $queryBuilder->format($this->projectActivityEventFormatter);
}
/**
@@ -83,7 +82,7 @@ class ProjectActivityHelper extends Base
->limit($limit)
;
- return $queryBuilder->format(new ProjectActivityEventFormatter($this->container));
+ return $queryBuilder->format($this->projectActivityEventFormatter);
}
/**
@@ -100,6 +99,6 @@ class ProjectActivityHelper extends Base
$queryBuilder->getQuery()->desc(ProjectActivityModel::TABLE.'.id');
- return $queryBuilder->format(new ProjectActivityEventFormatter($this->container));
+ return $queryBuilder->format($this->projectActivityEventFormatter);
}
}
diff --git a/app/Helper/ProjectRoleHelper.php b/app/Helper/ProjectRoleHelper.php
index 5c80d42b..6f9cf10c 100644
--- a/app/Helper/ProjectRoleHelper.php
+++ b/app/Helper/ProjectRoleHelper.php
@@ -35,7 +35,7 @@ class ProjectRoleHelper extends Base
*/
public function isDraggable(array &$task)
{
- if ($task['is_active'] == 1 && $this->helper->user->hasProjectAccess('BoardViewController', 'save', $task['project_id'])) {
+ if ($task['is_active'] == 1 && $this->helper->user->hasProjectAccess('BoardAjaxController', 'save', $task['project_id'])) {
return $this->isSortableColumn($task['project_id'], $task['column_id']);
}
diff --git a/app/Helper/SubtaskHelper.php b/app/Helper/SubtaskHelper.php
index 833544a7..8e090f17 100644
--- a/app/Helper/SubtaskHelper.php
+++ b/app/Helper/SubtaskHelper.php
@@ -50,7 +50,7 @@ class SubtaskHelper extends Base
return $this->helper->url->link($this->getTitle($subtask), 'SubtaskStatusController', 'change', $params, false, $class);
}
- public function selectTitle(array $values, array $errors = array(), array $attributes = array())
+ public function renderTitleField(array $values, array $errors = array(), array $attributes = array())
{
$attributes = array_merge(array('tabindex="1"', 'required', 'maxlength="255"'), $attributes);
@@ -60,7 +60,7 @@ class SubtaskHelper extends Base
return $html;
}
- public function selectAssignee(array $users, array $values, array $errors = array(), array $attributes = array())
+ public function renderAssigneeField(array $users, array $values, array $errors = array(), array $attributes = array())
{
$attributes = array_merge(array('tabindex="2"'), $attributes);
@@ -74,7 +74,7 @@ class SubtaskHelper extends Base
return $html;
}
- public function selectTimeEstimated(array $values, array $errors = array(), array $attributes = array())
+ public function renderTimeEstimatedField(array $values, array $errors = array(), array $attributes = array())
{
$attributes = array_merge(array('tabindex="3"'), $attributes);
@@ -85,7 +85,7 @@ class SubtaskHelper extends Base
return $html;
}
- public function selectTimeSpent(array $values, array $errors = array(), array $attributes = array())
+ public function renderTimeSpentField(array $values, array $errors = array(), array $attributes = array())
{
$attributes = array_merge(array('tabindex="4"'), $attributes);
diff --git a/app/Helper/TaskHelper.php b/app/Helper/TaskHelper.php
index 678b4bed..71596b60 100644
--- a/app/Helper/TaskHelper.php
+++ b/app/Helper/TaskHelper.php
@@ -40,34 +40,28 @@ class TaskHelper extends Base
return $this->taskRecurrenceModel->getRecurrenceBasedateList();
}
- public function selectTitle(array $values, array $errors)
+ public function renderTitleField(array $values, array $errors)
{
- $html = $this->helper->form->label(t('Title'), 'title');
- $html .= $this->helper->form->text('title', $values, $errors, array('autofocus', 'required', 'maxlength="200"', 'tabindex="1"'), 'form-input-large');
- return $html;
- }
-
- public function selectDescription(array $values, array $errors)
- {
- $html = $this->helper->form->label(t('Description'), 'description');
- $html .= '<div class="markdown-editor-container">';
- $html .= $this->helper->form->textarea(
- 'description',
+ return $this->helper->form->text(
+ 'title',
$values,
$errors,
array(
- 'placeholder="'.t('Leave a description').'"',
- 'tabindex="2"',
- 'data-mention-search-url="'.$this->helper->url->href('UserAjaxController', 'mention', array('project_id' => $values['project_id'])).'"'
- ),
- 'markdown-editor'
+ 'autofocus',
+ 'required',
+ 'maxlength="200"',
+ 'tabindex="1"',
+ 'placeholder="'.t('Title').'"'
+ )
);
+ }
- $html .= '</div>';
- return $html;
+ public function renderDescriptionField(array $values, array $errors)
+ {
+ return $this->helper->form->textEditor('description', $values, $errors, array('tabindex' => 2));
}
- public function selectTags(array $project, array $tags = array())
+ public function renderTagField(array $project, array $tags = array())
{
$options = $this->tagModel->getAssignableList($project['id']);
@@ -89,7 +83,7 @@ class TaskHelper extends Base
return $html;
}
- public function selectColor(array $values)
+ public function renderColorField(array $values)
{
$colors = $this->colorModel->getList();
$html = $this->helper->form->label(t('Color'), 'color_id');
@@ -97,7 +91,7 @@ class TaskHelper extends Base
return $html;
}
- public function selectAssignee(array $users, array $values, array $errors = array(), array $attributes = array())
+ public function renderAssigneeField(array $users, array $values, array $errors = array(), array $attributes = array())
{
$attributes = array_merge(array('tabindex="3"'), $attributes);
@@ -111,7 +105,7 @@ class TaskHelper extends Base
return $html;
}
- public function selectCategory(array $categories, array $values, array $errors = array(), array $attributes = array(), $allow_one_item = false)
+ public function renderCategoryField(array $categories, array $values, array $errors = array(), array $attributes = array(), $allow_one_item = false)
{
$attributes = array_merge(array('tabindex="4"'), $attributes);
$html = '';
@@ -124,7 +118,7 @@ class TaskHelper extends Base
return $html;
}
- public function selectSwimlane(array $swimlanes, array $values, array $errors = array(), array $attributes = array())
+ public function renderSwimlaneField(array $swimlanes, array $values, array $errors = array(), array $attributes = array())
{
$attributes = array_merge(array('tabindex="5"'), $attributes);
$html = '';
@@ -137,7 +131,7 @@ class TaskHelper extends Base
return $html;
}
- public function selectColumn(array $columns, array $values, array $errors = array(), array $attributes = array())
+ public function renderColumnField(array $columns, array $values, array $errors = array(), array $attributes = array())
{
$attributes = array_merge(array('tabindex="6"'), $attributes);
@@ -147,7 +141,7 @@ class TaskHelper extends Base
return $html;
}
- public function selectPriority(array $project, array $values)
+ public function renderPriorityField(array $project, array $values)
{
$html = '';
@@ -163,9 +157,9 @@ class TaskHelper extends Base
return $html;
}
- public function selectScore(array $values, array $errors = array(), array $attributes = array())
+ public function renderScoreField(array $values, array $errors = array(), array $attributes = array())
{
- $attributes = array_merge(array('tabindex="8"'), $attributes);
+ $attributes = array_merge(array('tabindex="13"'), $attributes);
$html = $this->helper->form->label(t('Complexity'), 'score');
$html .= $this->helper->form->number('score', $values, $errors, $attributes);
@@ -173,9 +167,9 @@ class TaskHelper extends Base
return $html;
}
- public function selectReference(array $values, array $errors = array(), array $attributes = array())
+ public function renderReferenceField(array $values, array $errors = array(), array $attributes = array())
{
- $attributes = array_merge(array('tabindex="9"'), $attributes);
+ $attributes = array_merge(array('tabindex="14"'), $attributes);
$html = $this->helper->form->label(t('Reference'), 'reference');
$html .= $this->helper->form->text('reference', $values, $errors, $attributes, 'form-input-small');
@@ -183,9 +177,9 @@ class TaskHelper extends Base
return $html;
}
- public function selectTimeEstimated(array $values, array $errors = array(), array $attributes = array())
+ public function renderTimeEstimatedField(array $values, array $errors = array(), array $attributes = array())
{
- $attributes = array_merge(array('tabindex="10"'), $attributes);
+ $attributes = array_merge(array('tabindex="11"'), $attributes);
$html = $this->helper->form->label(t('Original estimate'), 'time_estimated');
$html .= $this->helper->form->numeric('time_estimated', $values, $errors, $attributes);
@@ -194,9 +188,9 @@ class TaskHelper extends Base
return $html;
}
- public function selectTimeSpent(array $values, array $errors = array(), array $attributes = array())
+ public function renderTimeSpentField(array $values, array $errors = array(), array $attributes = array())
{
- $attributes = array_merge(array('tabindex="11"'), $attributes);
+ $attributes = array_merge(array('tabindex="12"'), $attributes);
$html = $this->helper->form->label(t('Time spent'), 'time_spent');
$html .= $this->helper->form->numeric('time_spent', $values, $errors, $attributes);
@@ -205,15 +199,15 @@ class TaskHelper extends Base
return $html;
}
- public function selectStartDate(array $values, array $errors = array(), array $attributes = array())
+ public function renderStartDateField(array $values, array $errors = array(), array $attributes = array())
{
- $attributes = array_merge(array('tabindex="12"'), $attributes);
+ $attributes = array_merge(array('tabindex="10"'), $attributes);
return $this->helper->form->datetime(t('Start Date'), 'date_started', $values, $errors, $attributes);
}
- public function selectDueDate(array $values, array $errors = array(), array $attributes = array())
+ public function renderDueDateField(array $values, array $errors = array(), array $attributes = array())
{
- $attributes = array_merge(array('tabindex="13"'), $attributes);
+ $attributes = array_merge(array('tabindex="9"'), $attributes);
return $this->helper->form->date(t('Due Date'), 'date_due', $values, $errors, $attributes);
}
@@ -238,4 +232,32 @@ class TaskHelper extends Base
return $this->taskModel->getProgress($task, $this->columns[$task['project_id']]);
}
+
+ public function getNewTaskDropdown($projectId, $swimlaneId, $columnId)
+ {
+ $providers = $this->externalTaskManager->getProvidersList();
+
+ if (empty($providers)) {
+ return '';
+ }
+
+ $html = '<small class="pull-right"><div class="dropdown">';
+ $html .= '<a href="#" class="dropdown-menu"><i class="fa fa-cloud-download" aria-hidden="true"></i> <i class="fa fa-caret-down"></i></a><ul>';
+
+ foreach ($providers as $providerName) {
+ $link = $this->helper->url->link(
+ t('New External Task: %s', $providerName),
+ 'ExternalTaskCreationController',
+ 'step1',
+ array('project_id' => $projectId, 'swimlane_id' => $swimlaneId, 'column_id' => $columnId, 'provider_name' => $providerName),
+ false,
+ 'js-modal-replace'
+ );
+
+ $html .= '<li><i class="fa fa-fw fa-plus-square" aria-hidden="true"></i> '.$link.'</li>';
+ }
+
+ $html .= '</ul></div></small>';
+ return $html;
+ }
}
diff --git a/app/Helper/TextHelper.php b/app/Helper/TextHelper.php
index 654eb171..66583cd1 100644
--- a/app/Helper/TextHelper.php
+++ b/app/Helper/TextHelper.php
@@ -59,6 +59,10 @@ class TextHelper extends Base
*/
public function bytes($size, $precision = 2)
{
+ if ($size == 0) {
+ return 0;
+ }
+
$base = log($size) / log(1024);
$suffixes = array('', 'k', 'M', 'G', 'T');
diff --git a/app/Helper/UrlHelper.php b/app/Helper/UrlHelper.php
index 93177ed5..94412cf5 100644
--- a/app/Helper/UrlHelper.php
+++ b/app/Helper/UrlHelper.php
@@ -42,9 +42,32 @@ class UrlHelper extends Base
*/
public function button($icon, $label, $controller, $action, array $params = array(), $class = '')
{
- $icon = '<i class="fa '.$icon.' fa-fw"></i> ';
+ $html = '<i class="fa fa-'.$icon.' fa-fw"></i> '.$label;
$class = 'btn '.$class;
- return $this->link($icon.$label, $controller, $action, $params, false, $class);
+ return $this->link($html, $controller, $action, $params, false, $class);
+ }
+
+ /**
+ * Link element with icon
+ *
+ * @access public
+ * @param string $icon Icon name
+ * @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 Link title
+ * @param boolean $newTab Open the link in a new tab
+ * @param string $anchor Link Anchor
+ * @param bool $absolute
+ * @return string
+ */
+ public function icon($icon, $label, $controller, $action, array $params = array(), $csrf = false, $class = '', $title = '', $newTab = false, $anchor = '', $absolute = false)
+ {
+ $html = '<i class="fa fa-fw fa-'.$icon.'" aria-hidden="true"></i>'.$label;
+ return $this->helper->url->link($html, $controller, $action, $params, $csrf, $class, $title, $newTab, $anchor, $absolute);
}
/**
@@ -58,14 +81,14 @@ class UrlHelper extends Base
* @param boolean $csrf Add a CSRF token
* @param string $class CSS class attribute
* @param string $title Link title
- * @param boolean $new_tab Open the link in a new tab
+ * @param boolean $newTab Open the link in a new tab
* @param string $anchor Link Anchor
* @param bool $absolute
* @return string
*/
- public function link($label, $controller, $action, array $params = array(), $csrf = false, $class = '', $title = '', $new_tab = false, $anchor = '', $absolute = false)
+ public function link($label, $controller, $action, array $params = array(), $csrf = false, $class = '', $title = '', $newTab = false, $anchor = '', $absolute = false)
{
- return '<a href="'.$this->href($controller, $action, $params, $csrf, $anchor, $absolute).'" class="'.$class.'" title=\''.$title.'\' '.($new_tab ? 'target="_blank"' : '').'>'.$label.'</a>';
+ return '<a href="'.$this->href($controller, $action, $params, $csrf, $anchor, $absolute).'" class="'.$class.'" title=\''.$title.'\' '.($newTab ? 'target="_blank"' : '').'>'.$label.'</a>';
}
/**
diff --git a/app/Job/CommentEventJob.php b/app/Job/CommentEventJob.php
index 47cf8020..62fae40a 100644
--- a/app/Job/CommentEventJob.php
+++ b/app/Job/CommentEventJob.php
@@ -31,7 +31,6 @@ class CommentEventJob extends BaseJob
*
* @param int $commentId
* @param string $eventName
- * @return $this
*/
public function execute($commentId, $eventName)
{
@@ -43,7 +42,8 @@ class CommentEventJob extends BaseJob
$this->dispatcher->dispatch($eventName, $event);
if ($eventName === CommentModel::EVENT_CREATE) {
- $this->userMentionModel->fireEvents($event['comment']['comment'], CommentModel::EVENT_USER_MENTION, $event);
+ $userMentionJob = $this->userMentionJob->withParams($event['comment']['comment'], CommentModel::EVENT_USER_MENTION, $event);
+ $this->queueManager->push($userMentionJob);
}
}
}
diff --git a/app/Job/TaskEventJob.php b/app/Job/TaskEventJob.php
index 7d026a68..acc7fca3 100644
--- a/app/Job/TaskEventJob.php
+++ b/app/Job/TaskEventJob.php
@@ -69,7 +69,8 @@ class TaskEventJob extends BaseJob
$this->dispatcher->dispatch($eventName, $event);
if ($eventName === TaskModel::EVENT_CREATE) {
- $this->userMentionModel->fireEvents($event['task']['description'], TaskModel::EVENT_USER_MENTION, $event);
+ $userMentionJob = $this->userMentionJob->withParams($event['task']['description'], TaskModel::EVENT_USER_MENTION, $event);
+ $this->queueManager->push($userMentionJob);
}
}
}
diff --git a/app/Job/UserMentionJob.php b/app/Job/UserMentionJob.php
new file mode 100644
index 00000000..355095bb
--- /dev/null
+++ b/app/Job/UserMentionJob.php
@@ -0,0 +1,73 @@
+<?php
+
+namespace Kanboard\Job;
+
+use Kanboard\Event\GenericEvent;
+use Kanboard\Model\UserModel;
+
+/**
+ * Class UserMentionJob
+ *
+ * @package Kanboard\Job
+ * @author Frederic Guillot
+ */
+class UserMentionJob extends BaseJob
+{
+ /**
+ * Set job parameters
+ *
+ * @param string $text
+ * @param string $eventName
+ * @param GenericEvent $event
+ * @return $this
+ */
+ public function withParams($text, $eventName, GenericEvent $event)
+ {
+ $this->jobParams = array($text, $eventName, $event->getAll());
+ return $this;
+ }
+
+ /**
+ * Execute job
+ *
+ * @param string $text
+ * @param string $eventName
+ * @param array $eventData
+ */
+ public function execute($text, $eventName, array $eventData)
+ {
+ $event = new GenericEvent($eventData);
+ $users = $this->getMentionedUsers($text);
+
+ foreach ($users as $user) {
+ if ($this->projectPermissionModel->isMember($event->getProjectId(), $user['id'])) {
+ $event['mention'] = $user;
+ $this->dispatcher->dispatch($eventName, $event);
+ }
+ }
+ }
+
+ /**
+ * Get list of mentioned users
+ *
+ * @access public
+ * @param string $text
+ * @return array
+ */
+ public function getMentionedUsers($text)
+ {
+ $users = array();
+
+ if (preg_match_all('/@([^\s,!:?]+)/', $text, $matches)) {
+ array_walk($matches[1], function (&$username) { $username = rtrim($username, '.'); });
+ $users = $this->db->table(UserModel::TABLE)
+ ->columns('id', 'username', 'name', 'email', 'language')
+ ->eq('notifications_enabled', 1)
+ ->neq('id', $this->userSession->getId())
+ ->in('username', array_unique($matches[1]))
+ ->findAll();
+ }
+
+ return $users;
+ }
+}
diff --git a/app/Locale/bs_BA/translations.php b/app/Locale/bs_BA/translations.php
index f4f457a1..a168f6df 100644
--- a/app/Locale/bs_BA/translations.php
+++ b/app/Locale/bs_BA/translations.php
@@ -61,7 +61,6 @@ return array(
'%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 ploču.',
- 'Edit board' => 'Izmijeni ploču',
'Disable' => 'Onemogući',
'Enable' => 'Omogući',
'New project' => 'Novi projekat',
@@ -72,7 +71,6 @@ return array(
'Title' => 'Naslov',
'Assigned to %s' => 'Dodijeljen korisniku %s',
'Remove a column' => 'Ukloni kolonu',
- 'Remove a column from a board' => 'Ukloni kolonu sa table',
'Unable to remove this column.' => 'Nemoguće uklanjanje kolone.',
'Do you really want to remove this column: "%s"?' => 'Da li zaista želiš da ukoniš ovu kolonu: "%s"?',
'This action will REMOVE ALL TASKS associated to this column!' => 'Ova akcija BRIŠE SVE ZADATKE vezane za ovu kolonu!',
@@ -160,9 +158,7 @@ return array(
'Task count' => 'Broj zadataka',
'User' => 'Korisnik',
'Comments' => 'Komentari',
- 'Leave a comment' => 'Ostavi komentar',
'Comment is required' => 'Komentar je obavezan',
- 'Leave a description' => 'Dodaj opis',
'Comment added successfully.' => 'Komentar uspješno dodan',
'Unable to create your comment.' => 'Nemoguće kreiranje komentara',
'Due Date' => 'Treba biti gotovo do dana',
@@ -224,7 +220,6 @@ return array(
'Search' => 'Pretraga',
'Nothing found.' => 'Ništa nije pronađeno',
'Due date' => 'Treba biti gotovo do dana',
- 'Others formats accepted: %s and %s' => 'Ostali podržani formati: %s i %s',
'Description' => 'Opis',
'%d comments' => '%d Komentara',
'%d comment' => '%d Komentar',
@@ -298,7 +293,6 @@ return array(
'Created by %s' => 'Kreirao %s',
'Tasks Export' => 'Izvoz zadataka',
'Start Date' => 'Početni datum',
- 'End Date' => 'Datum završetka',
'Execute' => 'Izvrši',
'Task Id' => 'Identifikator zadatka',
'Creator' => 'Autor',
@@ -342,8 +336,8 @@ return array(
'Remote' => 'Udaljeno',
'Enabled' => 'Omogućeno',
'Disabled' => 'Onemogućeno',
- 'Username:' => 'Korisničko ime:',
- 'Name:' => 'Ime i Prezime',
+ 'Login:' => 'Korisničko ime:',
+ 'Full Name:' => 'Ime i Prezime',
'Email:' => 'Email: ',
'Notifications:' => 'Obavještenja: ',
'Notifications' => 'Obavještenja',
@@ -516,10 +510,8 @@ return array(
'Link labels' => 'Veza s etiketama',
'Link modification' => 'Veza modifikacija',
'Links' => 'Veze',
- 'Link settings' => 'Postavke veza',
'Opposite label' => 'Suprotna etiketa',
'Remove a link' => 'Ukloni vezu',
- 'Task\'s links' => 'Veze zadatka',
'The labels must be different' => 'Etikete moraju biti različite',
'There is no link.' => 'Ovdje nema veza',
'This label must be unique' => 'Ova etiketa mora biti jedinstvena',
@@ -552,7 +544,6 @@ return array(
'Compact view' => 'Kompaktan pregled',
'Horizontal scrolling' => 'Horizontalno listanje',
'Compact/wide view' => 'Skupi/raširi pregled',
- 'No results match:' => 'Nema rezultata:',
'Currency' => 'Valuta',
'Private project' => 'Privatni projekat',
'AUD - Australian Dollar' => 'AUD - Australijski dolar',
@@ -566,6 +557,7 @@ return array(
'JPY - Japanese Yen' => 'JPY - Japanski jen',
'NZD - New Zealand Dollar' => 'NZD - Novozelandski dolar',
'RSD - Serbian dinar' => 'RSD - Srpski dinar',
+ // 'CNY - Chinese Yuan' => '',
'USD - US Dollar' => 'USD - Američki dolar',
'Destination column' => 'Odredišna kolona',
'Move the task to another column when assigned to a user' => 'Premjesti zadatak u neku drugu kolonu kada se dodijeli izvršiocu',
@@ -580,7 +572,6 @@ return array(
'Currency rates' => 'Stopa valute',
'Rate' => 'Stopa',
'Change reference currency' => 'Promijeni referencu valute',
- 'Add a new currency rate' => 'Dodaj novu stopu 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.',
@@ -702,7 +693,6 @@ return array(
'<30m' => '<30m',
'Stop timer' => 'Zaustavi tajmer',
'Start timer' => 'Pokreni tajmer',
- 'Add project member' => 'Dodaj člana projekta',
'My activity stream' => 'Tok mojih aktivnosti',
'My calendar' => 'Moj kalendar',
'Search tasks' => 'Pretraga zadataka',
@@ -757,8 +747,6 @@ return array(
'Remote user' => 'Vanjski korisnik',
'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => 'Vanjski korisnik ne čuva šifru u Kanboard bazi, npr: LDAP, Google i Github korisnički računi.',
'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => 'Ako ste označili kvadratić "Zabrani prijavnu formu", unos pristupnih podataka u prijavnoj formi će biti ignorisan.',
- 'New remote user' => 'Novi vanjski korisnik',
- 'New local user' => 'Novi lokalni korisnik',
'Default task color' => 'Podrazumijevana boja zadatka',
'This feature does not work with all browsers.' => 'Ovaj funkcionalnost ne radi na svim internet pretraživačima.',
'There is no destination project available.' => 'Nema definisanog odredišta za projekat.',
@@ -852,7 +840,6 @@ return array(
'Owner' => 'Vlasnik',
'Unread notifications' => 'Nepročitana obavještenja',
'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',
'%d task(s) have been imported successfully.' => '%d zadataka uspješno uvezeno.',
'Nothing have been imported!' => 'Ništa nije uvezeno!',
@@ -980,7 +967,6 @@ return array(
'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',
@@ -1037,7 +1023,6 @@ return array(
'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:',
@@ -1051,9 +1036,7 @@ return array(
'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',
@@ -1163,7 +1146,6 @@ return array(
// 'Email sender address' => '',
// 'Email transport' => '',
// 'Webhook token' => '',
- // 'Imports' => '',
// 'Project tags management' => '',
// 'Tag created successfully.' => '',
// 'Unable to create this tag.' => '',
@@ -1210,8 +1192,6 @@ return array(
// 'Activity stream for %s' => '',
// 'Calendar for %s' => '',
// 'Notifications for %s' => '',
- // 'Subtasks export' => '',
- // 'Tasks exportation' => '',
// 'Assign a color when the task is moved to a specific swimlane' => '',
// 'Assign a priority when the task is moved to a specific swimlane' => '',
// 'User unlocked successfully.' => '',
@@ -1277,4 +1257,61 @@ return array(
// 'This field is required' => '',
// 'Moving a task is not permitted' => '',
// 'This value must be in the range %d to %d' => '',
+ // 'You are not allowed to move this task.' => '',
+ // 'API User Access' => '',
+ // 'Preview' => '',
+ // 'Write' => '',
+ // 'Write your text in Markdown' => '',
+ // 'New External Task: %s' => '',
+ // 'No personal API access token registered.' => '',
+ // 'Your personal API access token is "%s"' => '',
+ // 'Remove your token' => '',
+ // 'Generate a new token' => '',
+ // 'Showing %d-%d of %d' => '',
+ // 'Outgoing Emails' => '',
+ // 'Add or change currency rate' => '',
+ // 'Reference currency: %s' => '',
+ // 'Add custom filters' => '',
+ // 'Export' => '',
+ // 'Add link label' => '',
+ // 'Incompatible Plugins' => '',
+ // 'Compatibility' => '',
+ // 'Permissions and ownership' => '',
+ // 'Priorities' => '',
+ // 'Close this window' => '',
+ // 'Unable to upload this file.' => '',
+ // 'Import tasks' => '',
+ // 'Choose a project' => '',
+ // 'Profile' => '',
+ // 'Application role' => '',
+ // '%d invitations were sent.' => '',
+ // '%d invitation was sent.' => '',
+ // 'Unable to create this user.' => '',
+ // 'Kanboard Invitation' => '',
+ // 'Visible on dashboard' => '',
+ // 'Created at:' => '',
+ // 'Updated at:' => '',
+ // 'There is no custom filter.' => '',
+ // 'New User' => '',
+ // 'Authentication' => '',
+ // 'If checked, this user will use a third-party system for authentication.' => '',
+ // 'The password is necessary only for local users.' => '',
+ // 'You have been invited to register on Kanboard.' => '',
+ // 'Click here to join your team' => '',
+ // 'Invite people' => '',
+ // 'Emails' => '',
+ // 'Enter one email address by line.' => '',
+ // 'Add these people to this project' => '',
+ // 'Add this person to this project' => '',
+ // 'Sign-up' => '',
+ // 'Credentials' => '',
+ // 'New user' => '',
+ // 'This username is already taken' => '',
+ // 'A link to reset your password has been sent by email.' => '',
+ // 'Your profile must have a valid email address.' => '',
+ // 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
+ // 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
+ // 'The email configuration has been disabled by the administrator.' => '',
);
diff --git a/app/Locale/cs_CZ/translations.php b/app/Locale/cs_CZ/translations.php
index 8dd5fb20..96b50af3 100644
--- a/app/Locale/cs_CZ/translations.php
+++ b/app/Locale/cs_CZ/translations.php
@@ -61,7 +61,6 @@ return array(
'%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',
- 'Edit board' => 'Editace nástěnky',
'Disable' => 'Zakázat projekt',
'Enable' => 'Povolit projekt',
'New project' => 'Nový projekt',
@@ -72,7 +71,6 @@ return array(
'Title' => 'Název',
'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',
'Unable to remove this column.' => 'Tento sloupec nelze odstranit',
'Do you really want to remove this column: "%s"?' => 'Opravdu chcete vyjmout tento sloupec: "%s"?',
'This action will REMOVE ALL TASKS associated to this column!' => 'Tato akce vyjme všechny úkoly přiřazený k tomuto sloupci!',
@@ -160,9 +158,7 @@ return array(
'Task count' => 'Počet úkolů',
'User' => 'Uživatel',
'Comments' => 'Komentáře',
- 'Leave a comment' => 'Zanechte komentář',
'Comment is required' => 'Komentář je vyžadován',
- 'Leave a description' => 'Vložte popis',
'Comment added successfully.' => 'Komentář byl úspěšně přidán.',
'Unable to create your comment.' => 'Komentář nelze vytvořit.',
'Due Date' => 'Datum splnění',
@@ -224,7 +220,6 @@ return array(
'Search' => 'Vyhledat',
'Nothing found.' => 'Nenalezena žádná položka.',
'Due date' => 'Plánovaný termín',
- 'Others formats accepted: %s and %s' => 'Akceptovány jiné formáty: %s und %s',
'Description' => 'Podrobný popis',
'%d comments' => '%d komentářů',
'%d comment' => '%d komentář',
@@ -298,7 +293,6 @@ return array(
'Created by %s' => 'Vytvořeno uživatelem %s',
'Tasks Export' => 'Export úkolů',
'Start Date' => 'Počáteční datum',
- 'End Date' => 'Konečné datum',
'Execute' => 'Spustit',
'Task Id' => 'Úkol ID',
'Creator' => 'Vlastník',
@@ -342,8 +336,8 @@ return array(
'Remote' => 'Vzdálený',
'Enabled' => 'Povoleno',
'Disabled' => 'Zakázáno',
- 'Username:' => 'Uživatelské jméno:',
- 'Name:' => 'Jméno:',
+ 'Login:' => 'Uživatelské jméno:',
+ 'Full Name:' => 'Jméno:',
'Email:' => 'e-mail',
'Notifications:' => 'Upozornění:',
'Notifications' => 'Upozornění',
@@ -516,10 +510,8 @@ return array(
'Link labels' => 'Seznam odkazů',
'Link modification' => 'Úpravy odkazů',
'Links' => 'Odkazy',
- 'Link settings' => 'Nastavení odkazů',
'Opposite label' => 'Opačný text',
'Remove a link' => 'Odstranit odkaz',
- 'Task\'s links' => 'Související odkazy',
'The labels must be different' => 'názvy musí být odlišné',
'There is no link.' => 'Nejsou zde žádné odkazy',
'This label must be unique' => 'Tento název musí být jedinečný',
@@ -552,7 +544,6 @@ return array(
'Compact view' => 'Kompaktní zobrazení',
'Horizontal scrolling' => 'Horizontální rolování',
'Compact/wide view' => 'Kompaktní/plné zobrazení',
- 'No results match:' => 'Žádná shoda:',
'Currency' => 'Měna',
'Private project' => 'Soukromý projekt',
// 'AUD - Australian Dollar' => '',
@@ -566,6 +557,7 @@ return array(
'JPY - Japanese Yen' => 'JPY - Japanischer Yen',
'NZD - New Zealand Dollar' => 'NZD - Neuseeland-Dollar',
'RSD - Serbian dinar' => 'RSD - Serbische Dinar',
+ // 'CNY - Chinese Yuan' => '',
'USD - US Dollar' => 'USD - US Dollar',
'Destination column' => 'Cílový sloupec',
'Move the task to another column when assigned to a user' => 'Přesunout úkol do jiného sloupce, když je úkol přiřazen uživateli.',
@@ -580,7 +572,6 @@ return array(
'Currency rates' => 'Aktuální kurzy',
'Rate' => 'Kurz',
'Change reference currency' => 'Změnit referenční měnu',
- 'Add a new currency rate' => 'Přidat nový směnný kurz',
'Reference currency' => 'Referenční měna',
'The currency rate have been added successfully.' => 'Směnný kurz byl úspěšně přidán.',
'Unable to add this currency rate.' => 'Nelze přidat tento směnný kurz',
@@ -702,7 +693,6 @@ return array(
'<30m' => '<30min.',
'Stop timer' => 'Zastavit časovač',
'Start timer' => 'Spustit časovač',
- 'Add project member' => 'Přidat člena projektu',
'My activity stream' => 'Přehled mých aktivit',
'My calendar' => 'Můj kalendář',
'Search tasks' => 'Hledání úkolů',
@@ -757,8 +747,6 @@ return array(
'Remote user' => 'Vzdálený uživatel',
'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => 'Hesla vzdáleným uživatelům se neukládají do databáze Kanboard. Naříklad: LDAP, Google a Github účty.',
'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => 'Pokud zaškrtnete políčko "Zakázat přihlašovací formulář", budou pověření zadané do přihlašovacího formuláře ignorovány.',
- 'New remote user' => 'Nový vzdálený uživatel',
- 'New local user' => 'Nový lokální uživatel',
'Default task color' => 'Výchozí barva úkolu',
'This feature does not work with all browsers.' => 'Tato funkcionalita nefunguje ve všech prohlížečích.',
'There is no destination project available.' => 'Není dostupný žádný cílový projekt.',
@@ -852,7 +840,6 @@ return array(
// '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!' => '',
@@ -980,7 +967,6 @@ return array(
// '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' => '',
@@ -1037,7 +1023,6 @@ return array(
// 'Started:' => '',
// 'Moved:' => '',
// 'Task #%d' => '',
- // 'Date and time format' => '',
// 'Time format' => '',
// 'Start date: ' => '',
// 'End date: ' => '',
@@ -1051,9 +1036,7 @@ return array(
// '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' => '',
@@ -1163,7 +1146,6 @@ return array(
// 'Email sender address' => '',
// 'Email transport' => '',
// 'Webhook token' => '',
- // 'Imports' => '',
// 'Project tags management' => '',
// 'Tag created successfully.' => '',
// 'Unable to create this tag.' => '',
@@ -1210,8 +1192,6 @@ return array(
// 'Activity stream for %s' => '',
// 'Calendar for %s' => '',
// 'Notifications for %s' => '',
- // 'Subtasks export' => '',
- // 'Tasks exportation' => '',
// 'Assign a color when the task is moved to a specific swimlane' => '',
// 'Assign a priority when the task is moved to a specific swimlane' => '',
// 'User unlocked successfully.' => '',
@@ -1277,4 +1257,61 @@ return array(
// 'This field is required' => '',
// 'Moving a task is not permitted' => '',
// 'This value must be in the range %d to %d' => '',
+ // 'You are not allowed to move this task.' => '',
+ // 'API User Access' => '',
+ // 'Preview' => '',
+ // 'Write' => '',
+ // 'Write your text in Markdown' => '',
+ // 'New External Task: %s' => '',
+ // 'No personal API access token registered.' => '',
+ // 'Your personal API access token is "%s"' => '',
+ // 'Remove your token' => '',
+ // 'Generate a new token' => '',
+ // 'Showing %d-%d of %d' => '',
+ // 'Outgoing Emails' => '',
+ // 'Add or change currency rate' => '',
+ // 'Reference currency: %s' => '',
+ // 'Add custom filters' => '',
+ // 'Export' => '',
+ // 'Add link label' => '',
+ // 'Incompatible Plugins' => '',
+ // 'Compatibility' => '',
+ // 'Permissions and ownership' => '',
+ // 'Priorities' => '',
+ // 'Close this window' => '',
+ // 'Unable to upload this file.' => '',
+ // 'Import tasks' => '',
+ // 'Choose a project' => '',
+ // 'Profile' => '',
+ // 'Application role' => '',
+ // '%d invitations were sent.' => '',
+ // '%d invitation was sent.' => '',
+ // 'Unable to create this user.' => '',
+ // 'Kanboard Invitation' => '',
+ // 'Visible on dashboard' => '',
+ // 'Created at:' => '',
+ // 'Updated at:' => '',
+ // 'There is no custom filter.' => '',
+ // 'New User' => '',
+ // 'Authentication' => '',
+ // 'If checked, this user will use a third-party system for authentication.' => '',
+ // 'The password is necessary only for local users.' => '',
+ // 'You have been invited to register on Kanboard.' => '',
+ // 'Click here to join your team' => '',
+ // 'Invite people' => '',
+ // 'Emails' => '',
+ // 'Enter one email address by line.' => '',
+ // 'Add these people to this project' => '',
+ // 'Add this person to this project' => '',
+ // 'Sign-up' => '',
+ // 'Credentials' => '',
+ // 'New user' => '',
+ // 'This username is already taken' => '',
+ // 'A link to reset your password has been sent by email.' => '',
+ // 'Your profile must have a valid email address.' => '',
+ // 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
+ // 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
+ // 'The email configuration has been disabled by the administrator.' => '',
);
diff --git a/app/Locale/da_DK/translations.php b/app/Locale/da_DK/translations.php
index fa756b7f..5d61581c 100644
--- a/app/Locale/da_DK/translations.php
+++ b/app/Locale/da_DK/translations.php
@@ -61,7 +61,6 @@ return array(
'%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',
- 'Edit board' => 'Rediger board',
'Disable' => 'Deaktiver',
'Enable' => 'Aktiver',
'New project' => 'Nyt projekt',
@@ -72,7 +71,6 @@ return array(
'Title' => 'Titel',
'Assigned to %s' => 'Ansvarlig: %s',
'Remove a column' => 'Fjern en kolonne',
- 'Remove a column from a board' => 'Fjern en kolonne fra et board',
'Unable to remove this column.' => 'Ikke muligt at fjerne denne kolonne',
'Do you really want to remove this column: "%s"?' => 'Vil du virkelig fjerne denne kolonne: "%s"?',
'This action will REMOVE ALL TASKS associated to this column!' => 'Denne handling vil SLETTE ALLE OPGAVER tilknyttet denne kolonne',
@@ -160,9 +158,7 @@ return array(
// 'Task count' => '',
'User' => 'Bruger',
'Comments' => 'Kommentarer',
- 'Leave a comment' => 'Efterlad en kommentar',
'Comment is required' => 'Kommentar er krævet',
- 'Leave a description' => 'Efterlad en beskrivelse...',
'Comment added successfully.' => 'Kommentaren er tilføjet.',
'Unable to create your comment.' => 'Din kommentar kunne ikke oprettes.',
'Due Date' => 'Forfaldsdato',
@@ -224,7 +220,6 @@ return array(
'Search' => 'Søg',
'Nothing found.' => 'Intet fundet.',
'Due date' => 'Forfaldsdato',
- 'Others formats accepted: %s and %s' => 'Andre acceptable formater: %s und %s',
'Description' => 'Beskrivelse',
'%d comments' => '%d kommentarer',
'%d comment' => '%d kommentar',
@@ -298,7 +293,6 @@ return array(
'Created by %s' => 'Oprettet af %s',
'Tasks Export' => 'Opgave eksport',
'Start Date' => 'Start-dato',
- 'End Date' => 'Slut-dato',
'Execute' => 'Udfør',
'Task Id' => 'Opgave ID',
'Creator' => 'Skaber',
@@ -342,8 +336,8 @@ return array(
'Remote' => 'Remote',
'Enabled' => 'Aktiv',
'Disabled' => 'Deaktiveret',
- 'Username:' => 'Brugernavn',
- 'Name:' => 'Navn:',
+ 'Login:' => 'Brugernavn',
+ 'Full Name:' => 'Navn:',
'Email:' => 'Email:',
'Notifications:' => 'Notifikationer:',
'Notifications' => 'Notifikationer',
@@ -516,10 +510,8 @@ return array(
// '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' => '',
@@ -552,7 +544,6 @@ return array(
// 'Compact view' => '',
// 'Horizontal scrolling' => '',
// 'Compact/wide view' => '',
- // 'No results match:' => '',
// 'Currency' => '',
// 'Private project' => '',
// 'AUD - Australian Dollar' => '',
@@ -566,6 +557,7 @@ return array(
// 'JPY - Japanese Yen' => '',
// 'NZD - New Zealand Dollar' => '',
// 'RSD - Serbian dinar' => '',
+ // 'CNY - Chinese Yuan' => '',
// 'USD - US Dollar' => '',
// 'Destination column' => '',
// 'Move the task to another column when assigned to a user' => '',
@@ -580,7 +572,6 @@ return array(
// '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.' => '',
@@ -702,7 +693,6 @@ return array(
// '<30m' => '',
// 'Stop timer' => '',
// 'Start timer' => '',
- // 'Add project member' => '',
// 'My activity stream' => '',
// 'My calendar' => '',
// 'Search tasks' => '',
@@ -757,8 +747,6 @@ return array(
// '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.' => '',
@@ -852,7 +840,6 @@ return array(
// '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!' => '',
@@ -980,7 +967,6 @@ return array(
// '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' => '',
@@ -1037,7 +1023,6 @@ return array(
// 'Started:' => '',
// 'Moved:' => '',
// 'Task #%d' => '',
- // 'Date and time format' => '',
// 'Time format' => '',
// 'Start date: ' => '',
// 'End date: ' => '',
@@ -1051,9 +1036,7 @@ return array(
// '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' => '',
@@ -1163,7 +1146,6 @@ return array(
// 'Email sender address' => '',
// 'Email transport' => '',
// 'Webhook token' => '',
- // 'Imports' => '',
// 'Project tags management' => '',
// 'Tag created successfully.' => '',
// 'Unable to create this tag.' => '',
@@ -1210,8 +1192,6 @@ return array(
// 'Activity stream for %s' => '',
// 'Calendar for %s' => '',
// 'Notifications for %s' => '',
- // 'Subtasks export' => '',
- // 'Tasks exportation' => '',
// 'Assign a color when the task is moved to a specific swimlane' => '',
// 'Assign a priority when the task is moved to a specific swimlane' => '',
// 'User unlocked successfully.' => '',
@@ -1277,4 +1257,61 @@ return array(
// 'This field is required' => '',
// 'Moving a task is not permitted' => '',
// 'This value must be in the range %d to %d' => '',
+ // 'You are not allowed to move this task.' => '',
+ // 'API User Access' => '',
+ // 'Preview' => '',
+ // 'Write' => '',
+ // 'Write your text in Markdown' => '',
+ // 'New External Task: %s' => '',
+ // 'No personal API access token registered.' => '',
+ // 'Your personal API access token is "%s"' => '',
+ // 'Remove your token' => '',
+ // 'Generate a new token' => '',
+ // 'Showing %d-%d of %d' => '',
+ // 'Outgoing Emails' => '',
+ // 'Add or change currency rate' => '',
+ // 'Reference currency: %s' => '',
+ // 'Add custom filters' => '',
+ // 'Export' => '',
+ // 'Add link label' => '',
+ // 'Incompatible Plugins' => '',
+ // 'Compatibility' => '',
+ // 'Permissions and ownership' => '',
+ // 'Priorities' => '',
+ // 'Close this window' => '',
+ // 'Unable to upload this file.' => '',
+ // 'Import tasks' => '',
+ // 'Choose a project' => '',
+ // 'Profile' => '',
+ // 'Application role' => '',
+ // '%d invitations were sent.' => '',
+ // '%d invitation was sent.' => '',
+ // 'Unable to create this user.' => '',
+ // 'Kanboard Invitation' => '',
+ // 'Visible on dashboard' => '',
+ // 'Created at:' => '',
+ // 'Updated at:' => '',
+ // 'There is no custom filter.' => '',
+ // 'New User' => '',
+ // 'Authentication' => '',
+ // 'If checked, this user will use a third-party system for authentication.' => '',
+ // 'The password is necessary only for local users.' => '',
+ // 'You have been invited to register on Kanboard.' => '',
+ // 'Click here to join your team' => '',
+ // 'Invite people' => '',
+ // 'Emails' => '',
+ // 'Enter one email address by line.' => '',
+ // 'Add these people to this project' => '',
+ // 'Add this person to this project' => '',
+ // 'Sign-up' => '',
+ // 'Credentials' => '',
+ // 'New user' => '',
+ // 'This username is already taken' => '',
+ // 'A link to reset your password has been sent by email.' => '',
+ // 'Your profile must have a valid email address.' => '',
+ // 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
+ // 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
+ // 'The email configuration has been disabled by the administrator.' => '',
);
diff --git a/app/Locale/de_DE/translations.php b/app/Locale/de_DE/translations.php
index fb6967c4..61175e33 100644
--- a/app/Locale/de_DE/translations.php
+++ b/app/Locale/de_DE/translations.php
@@ -61,7 +61,6 @@ return array(
'%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.',
- 'Edit board' => 'Pinnwand bearbeiten',
'Disable' => 'Deaktivieren',
'Enable' => 'Aktivieren',
'New project' => 'Neues Projekt',
@@ -72,7 +71,6 @@ return array(
'Title' => 'Titel',
'Assigned to %s' => 'Zuständig: %s',
'Remove a column' => 'Spalte löschen',
- 'Remove a column from a board' => 'Spalte einer Pinnwand löschen',
'Unable to remove this column.' => 'Löschen dieser Spalte nicht möglich.',
'Do you really want to remove this column: "%s"?' => 'Soll diese Spalte wirklich gelöscht werden: "%s"?',
'This action will REMOVE ALL TASKS associated to this column!' => 'ALLE AUFGABEN dieser Spalte werden GELÖSCHT!',
@@ -160,9 +158,7 @@ return array(
'Task count' => 'Aufgabenanzahl',
'User' => 'Benutzer',
'Comments' => 'Kommentare',
- 'Leave a comment' => 'Kommentar eingeben',
'Comment is required' => 'Ein Kommentar wird benötigt',
- 'Leave a description' => 'Beschreibung eingeben',
'Comment added successfully.' => 'Kommentar erfolgreich hinzugefügt.',
'Unable to create your comment.' => 'Hinzufügen eines Kommentars nicht möglich.',
'Due Date' => 'Fällig am',
@@ -224,7 +220,6 @@ return array(
'Search' => 'Suchen',
'Nothing found.' => 'Nichts gefunden.',
'Due date' => 'Fälligkeitsdatum',
- 'Others formats accepted: %s and %s' => 'Andere akzeptierte Formate: %s und %s',
'Description' => 'Beschreibung',
'%d comments' => '%d Kommentare',
'%d comment' => '%d Kommentar',
@@ -298,7 +293,6 @@ return array(
'Created by %s' => 'Erstellt durch %s',
'Tasks Export' => 'Aufgaben exportieren',
'Start Date' => 'Anfangsdatum',
- 'End Date' => 'Enddatum',
'Execute' => 'Ausführen',
'Task Id' => 'Aufgaben ID',
'Creator' => 'Erstellt von',
@@ -342,8 +336,8 @@ return array(
'Remote' => 'Remote',
'Enabled' => 'angeschaltet',
'Disabled' => 'abgeschaltet',
- 'Username:' => 'Benutzername:',
- 'Name:' => 'Name:',
+ 'Login:' => 'Benutzername:',
+ 'Full Name:' => 'Vollständiger Name:',
'Email:' => 'E-Mail:',
'Notifications:' => 'Benachrichtigungen:',
'Notifications' => 'Benachrichtigungen',
@@ -516,10 +510,8 @@ return array(
'Link labels' => 'Verbindungsbeschriftung',
'Link modification' => 'Verbindung ändern',
'Links' => 'Verbindungen',
- 'Link settings' => 'Verbindungseinstellungen',
'Opposite label' => 'Gegenteil',
'Remove a link' => 'Verbindung entfernen',
- 'Task\'s links' => 'Aufgaben-Verbindungen',
'The labels must be different' => 'Die Beschriftung muss unterschiedlich sein',
'There is no link.' => 'Es gibt keine Verbindung',
'This label must be unique' => 'Die Beschriftung muss einzigartig sein',
@@ -552,7 +544,6 @@ return array(
'Compact view' => 'Kompaktansicht',
'Horizontal scrolling' => 'Horizontales Scrollen',
'Compact/wide view' => 'Kompakt/Breite-Ansicht',
- 'No results match:' => 'Keine Ergebnisse:',
'Currency' => 'Währung',
'Private project' => 'privates Projekt',
'AUD - Australian Dollar' => 'AUD - Australische Dollar',
@@ -566,6 +557,7 @@ return array(
'JPY - Japanese Yen' => 'JPY - Japanische Yen',
'NZD - New Zealand Dollar' => 'NZD - Neuseeland-Dollar',
'RSD - Serbian dinar' => 'RSD - Serbische Dinar',
+ // 'CNY - Chinese Yuan' => '',
'USD - US Dollar' => 'USD - US-Dollar',
'Destination column' => 'Zielspalte',
'Move the task to another column when assigned to a user' => 'Aufgabe in eine andere Spalte verschieben, wenn ein User zugeordnet wurde.',
@@ -580,7 +572,6 @@ return array(
'Currency rates' => 'Währungskurse',
'Rate' => 'Kurse',
'Change reference currency' => 'Referenzwährung ändern',
- 'Add a new currency rate' => 'Neuen Währungskurs hinzufügen',
'Reference currency' => 'Referenzwährung',
'The currency rate have been added successfully.' => 'Der Währungskurs wurde erfolgreich hinzugefügt.',
'Unable to add this currency rate.' => 'Währungskurs konnte nicht hinzugefügt werden',
@@ -632,11 +623,11 @@ return array(
'Factor to calculate new due date: ' => 'Faktor zur Berechnung für neues Ablaufdatum: ',
'Month(s)' => 'Monat(e)',
'Recurrence' => 'Wiederholung',
- 'This task has been created by: ' => 'DIese Aufgabe wurde erstellt von: ',
+ 'This task has been created by: ' => 'Diese Aufgabe wurde erstellt von: ',
'Recurrent task has been generated:' => 'Wiederkehrende Aufgabe wurde erstellt:',
'Timeframe to calculate new due date: ' => 'Zeitfenster zur Berechnung für neues Ablaufdatum: ',
'Trigger to generate recurrent task: ' => 'Auslöser für wiederkehrende Aufgabe: ',
- 'When task is closed' => 'Wenn Aufgabe geshlossen wird',
+ 'When task is closed' => 'Wenn Aufgabe geschlossen wird',
'When task is moved from first column' => 'Wenn Aufgabe von erster Spalte verschoben wird',
'When task is moved to last column' => 'Wenn Aufgabe in letzte Spalte verschoben wird',
'Year(s)' => 'Jahr(e)',
@@ -702,7 +693,6 @@ return array(
'<30m' => '<30min',
'Stop timer' => 'Stoppe Timer',
'Start timer' => 'Starte Timer',
- 'Add project member' => 'Projektmitglied hinzufügen',
'My activity stream' => 'Aktivitätsstream',
'My calendar' => 'Mein Kalender',
'Search tasks' => 'Suche nach Aufgaben',
@@ -757,8 +747,6 @@ return array(
'Remote user' => 'Remote-Benutzer',
'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => 'Remote-Benutzer haben kein Passwort in der Kanboard Datenbank, Beispiel: LDAP, Google und Github Accounts',
'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => 'Wenn die Box "Verbiete Login-Formular" angeschaltet ist, werden Eingaben in das Login Formular ignoriert.',
- 'New remote user' => 'Neuer Remote-Benutzer',
- 'New local user' => 'Neuer lokaler Benutzer',
'Default task color' => 'Voreingestellte Aufgabenfarbe',
'This feature does not work with all browsers.' => 'Diese Funktion funktioniert nicht mit allen Browsern',
'There is no destination project available.' => 'Es ist kein Zielprojekt vorhanden.',
@@ -852,7 +840,6 @@ return array(
'Owner' => 'Eigentümer',
'Unread notifications' => 'Ungelesene Benachrichtigungen',
'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',
'%d task(s) have been imported successfully.' => '%d Aufgabe(n) wurde(n) erfolgreich importiert',
'Nothing have been imported!' => 'Es wurde nichts importiert!',
@@ -980,7 +967,6 @@ return array(
'Project owner: ' => 'Projekt-Besitzer: ',
'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => 'Die Projekt-Kennung ist optional und muss alphanumerisch sein, beispielsweise: MYPROJECT.',
'Project owner' => 'Projekt-Besitzer',
- 'Those dates are useful for the project Gantt chart.' => 'Diese Daten sind nützlich für das Gantt-Diagramm.',
'Private projects do not have users and groups management.' => 'Private Projekte haben kein Benutzer- und Gruppen-Management.',
'There is no project member.' => 'Es gibt kein Projekt-Mitglied.',
'Priority' => 'Priorität',
@@ -1009,7 +995,7 @@ return array(
'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...',
+ 'Copy and paste your link here...' => 'Kopieren Sie Ihren Link hierher...',
'URL' => 'URL',
'Internal links' => 'Interne Verbindungen',
'Assign to me' => 'Mir zuweisen',
@@ -1037,7 +1023,6 @@ return array(
'Started:' => 'Gestarted:',
'Moved:' => 'Verschoben:',
'Task #%d' => 'Aufgabe #%d',
- 'Date and time format' => 'Datums- und Zeitformat',
'Time format' => 'Zeitformat',
'Start date: ' => 'Anfangsdatum: ',
'End date: ' => 'Enddatum: ',
@@ -1051,9 +1036,7 @@ return array(
'User disabled successfully.' => 'Benutzer erfolgreich deaktiviert.',
'Unable to disable this user.' => 'Dieser Benutzer kann nicht deaktiviert werden.',
'All files have been uploaded successfully.' => 'Alle Dateien wurden erfolgreich hochgeladen.',
- 'View uploaded files' => 'Hochgeladene Dateien ansehen',
'The maximum allowed file size is %sB.' => 'Die maximal erlaubte Dateigröße ist %sB.',
- 'Choose files again' => 'Wählen Sie erneut Dateien aus',
'Drag and drop your files here' => 'Ziehen Sie Ihre Dateien hier hin',
'choose files' => 'Dateien auswählen',
'View profile' => 'Profil ansehen',
@@ -1163,7 +1146,6 @@ return array(
'Email sender address' => 'E-Mail Absender Adresse',
'Email transport' => 'E-Mail Verkehr',
'Webhook token' => 'Webhook Token',
- 'Imports' => 'Importe',
'Project tags management' => 'Projektbezogenes Schlagwort-Management',
'Tag created successfully.' => 'Schlagwort erfolgreich erstellt.',
'Unable to create this tag.' => 'Das Schlagwort kann nicht erstellt werden.',
@@ -1210,8 +1192,6 @@ return array(
'Activity stream for %s' => 'Aktivitätenstrom für %s',
'Calendar for %s' => 'Kalender für %s',
'Notifications for %s' => 'Benachrichtigungen für %s',
- 'Subtasks export' => 'Teilaufgaben Export',
- 'Tasks exportation' => 'Aufgaben Export',
'Assign a color when the task is moved to a specific swimlane' => 'Einer Aufgabe eine Farbe zuweisen, wenn diese in eine bestimmte Swimlane verschoben wird',
'Assign a priority when the task is moved to a specific swimlane' => 'Einer Aufgabe eine Priorität zuweisen, wenn diese in eine bestimmte Swimlane verschoben wird',
'User unlocked successfully.' => 'Benutzer erfolgreich entsperrt.',
@@ -1224,57 +1204,114 @@ return array(
'Insert before this task' => 'Vor dieser Aufgabe einfügen',
'Insert after this task' => 'Nach dieser Aufgabe einfügen',
'Unlock this user' => 'Diesen Benutzer entsperren',
- // 'Custom Project Roles' => '',
- // 'Add a new custom role' => '',
- // 'Restrictions for the role "%s"' => '',
- // 'Add a new project restriction' => '',
- // 'Add a new drag and drop restriction' => '',
- // 'Add a new column restriction' => '',
- // 'Edit this role' => '',
- // 'Remove this role' => '',
- // 'There is no restriction for this role.' => '',
- // 'Only moving task between those columns is permitted' => '',
- // 'Close a task in a specific column when not moved during a given period' => '',
- // 'Edit columns' => '',
- // 'The column restriction has been created successfully.' => '',
- // 'Unable to create this column restriction.' => '',
- // 'Column restriction removed successfully.' => '',
- // 'Unable to remove this restriction.' => '',
- // 'Your custom project role has been created successfully.' => '',
- // 'Unable to create custom project role.' => '',
- // 'Your custom project role has been updated successfully.' => '',
- // 'Unable to update custom project role.' => '',
- // 'Custom project role removed successfully.' => '',
- // 'Unable to remove this project role.' => '',
- // 'The project restriction has been created successfully.' => '',
- // 'Unable to create this project restriction.' => '',
- // 'Project restriction removed successfully.' => '',
- // 'You cannot create tasks in this column.' => '',
- // 'Task creation is permitted for this column' => '',
- // 'Closing or opening a task is permitted for this column' => '',
- // 'Task creation is blocked for this column' => '',
- // 'Closing or opening a task is blocked for this column' => '',
- // 'Task creation is not permitted' => '',
- // 'Closing or opening a task is not permitted' => '',
- // 'New drag and drop restriction for the role "%s"' => '',
- // 'People belonging to this role will be able to move tasks only between the source and the destination column.' => '',
- // 'Remove a column restriction' => '',
- // 'Do you really want to remove this column restriction: "%s" to "%s"?' => '',
- // 'New column restriction for the role "%s"' => '',
- // 'Rule' => '',
- // 'Do you really want to remove this column restriction?' => '',
- // 'Custom roles' => '',
- // 'New custom project role' => '',
- // 'Edit custom project role' => '',
- // 'Remove a custom role' => '',
- // 'Do you really want to remove this custom role: "%s"? All people assigned to this role will become project member.' => '',
- // 'There is no custom role for this project.' => '',
- // 'New project restriction for the role "%s"' => '',
- // 'Restriction' => '',
- // 'Remove a project restriction' => '',
- // 'Do you really want to remove this project restriction: "%s"?' => '',
- // 'Duplicate to multiple projects' => '',
- // 'This field is required' => '',
- // 'Moving a task is not permitted' => '',
- // 'This value must be in the range %d to %d' => '',
+ 'Custom Project Roles' => 'Benutzerdefinierte Projekt Rollen',
+ 'Add a new custom role' => 'Neue benutzerdefinierte Rolle erstellen',
+ 'Restrictions for the role "%s"' => 'Einschränkungen für Rolle "%s"',
+ 'Add a new project restriction' => 'Neue projektbezogene Einschränkung erstellen',
+ 'Add a new drag and drop restriction' => 'Neue drag and drop Einschränkung erstellen',
+ 'Add a new column restriction' => 'Neue spaltenbezogene Einschränkung erstellen',
+ 'Edit this role' => 'Diese Rolle bearbeiten',
+ 'Remove this role' => 'Diese Rolle entfernen',
+ 'There is no restriction for this role.' => 'Für diese Rolle gibt es keine Einschränkungen.',
+ 'Only moving task between those columns is permitted' => 'Verschieben von Aufgaben ist nur zwischen diesen Spalten erlaubt',
+ 'Close a task in a specific column when not moved during a given period' => 'Aufgabe in einer bestimmten Spalte schliessen, wenn sie im angegebenen Zeitraum nicht verschoben wurde',
+ 'Edit columns' => 'Spalten bearbeiten',
+ 'The column restriction has been created successfully.' => 'Die spaltenbezogene Einschränkung wurde erfolgreich erstellt.',
+ 'Unable to create this column restriction.' => 'Erstellen der spaltenbezogenen Einschränkung fehlgeschlagen.',
+ 'Column restriction removed successfully.' => 'Spaltenbezogene Einschränkung erfolgreich entfernt.',
+ 'Unable to remove this restriction.' => 'Entfernen der spaltenbezogenen Einschränkung fehlgeschlagen.',
+ 'Your custom project role has been created successfully.' => 'Benutzerdefinierte Projekt Rolle erfolgreich erstellt.',
+ 'Unable to create custom project role.' => 'Erstellen der benutzerdefinierten Projekt Rolle fehlgeschlagen.',
+ 'Your custom project role has been updated successfully.' => 'Benutzerdefinierte Projekt Rolle wurde erfolgreich geändert.',
+ 'Unable to update custom project role.' => 'Ändern der benutzerdefinierten Projekt Rolle fehlgeschlagen.',
+ 'Custom project role removed successfully.' => 'Benutzerdefinierte Projekt Rolle erfolgreich entfernt.',
+ 'Unable to remove this project role.' => 'Entfernen der benutzerdefinierten Projekt Rolle fehlgeschlagen.',
+ 'The project restriction has been created successfully.' => 'Projektbezogene Einschränkung erfolgreich erstellt.',
+ 'Unable to create this project restriction.' => 'Erstellen der projektbezogenen Einschränkung fehlgeschlagen.',
+ 'Project restriction removed successfully.' => 'Projektbezogene Einschränkung erfolgreich entfernt.',
+ 'You cannot create tasks in this column.' => 'Sie können in dieser spalte keine Aufgaben erzeugen.',
+ 'Task creation is permitted for this column' => 'Erzeugen von Aufgaben ist für diese Spalte erlaubt.',
+ 'Closing or opening a task is permitted for this column' => 'Öffnen und Schliessen von Aufgaben ist für diese Spalte erlaubt.',
+ 'Task creation is blocked for this column' => 'Erzeugen von Aufgaben ist für diese Spalte blockiert.',
+ 'Closing or opening a task is blocked for this column' => 'Öffnen und Schliessen von Aufgaben ist für diese Spalte blockiert.',
+ 'Task creation is not permitted' => 'Erzeugen von Aufgaben ist nicht erlaubt.',
+ 'Closing or opening a task is not permitted' => 'Öffnen und Schliessen von Aufgaben ist nicht erlaubt.',
+ 'New drag and drop restriction for the role "%s"' => 'Neue drag and drop Einschränkung für Rolle "%s"',
+ 'People belonging to this role will be able to move tasks only between the source and the destination column.' => 'Benutzer mit dieser Rolle können Aufgaben nur zwischen Quell- und Zielspalte verschieben.',
+ 'Remove a column restriction' => 'Spaltenbezogene Einschränkung entfernen',
+ 'Do you really want to remove this column restriction: "%s" to "%s"?' => 'Wollen Sie diese spaltenbezogene Einschränkung wirklich löschen: "%s" nach "%s"?',
+ 'New column restriction for the role "%s"' => 'Neue spaltenbezogene Einschränkung für Rolle "%s"',
+ 'Rule' => 'Regel',
+ 'Do you really want to remove this column restriction?' => 'Wollen Sie diese spaltenbezogene Einschränkung wirklich entfernen?',
+ 'Custom roles' => 'Benutzerdefinierte Rollen',
+ 'New custom project role' => 'Neue benutzerdefinierte Projekt Rolle',
+ 'Edit custom project role' => 'Benutzerdefinierte Projekt Rolle bearbeiten',
+ 'Remove a custom role' => 'Benutzerdefinierte Projekt Rolle entfernen',
+ 'Do you really want to remove this custom role: "%s"? All people assigned to this role will become project member.' => 'Wollen sie diese benutzerdefinierte Rolle wirklich entfernen: "%s"? Alle Benutzer mit dieser Rolle werden zu Projekt-Mitgliedern.',
+ 'There is no custom role for this project.' => 'Für dieses Projekt gibt es keine benutzerdefinierten Rollen.',
+ 'New project restriction for the role "%s"' => 'Neue projektbezogene Einschränkung für Rolle "%s"',
+ 'Restriction' => 'Einschränkung',
+ 'Remove a project restriction' => 'Projektbezogene Einschränkung entfernen',
+ 'Do you really want to remove this project restriction: "%s"?' => 'Wollen Sie diese projektbezogene Einschränkung wirklich entfernen: "%s"?',
+ 'Duplicate to multiple projects' => 'In mehrere Projekte duplizieren',
+ 'This field is required' => 'Dies ist ein Pflichtfeld',
+ 'Moving a task is not permitted' => 'Verschieben einer Aufgabe ist nicht erlaubt',
+ 'This value must be in the range %d to %d' => 'Dieser Wert muss im Bereich %d bis %d sein',
+ 'You are not allowed to move this task.' => 'Sie haben nicht die Berechtigung, diese Aufgabe zu verschieben.',
+ 'API User Access' => 'API Benutzerzugriff',
+ 'Preview' => 'Vorschau',
+ 'Write' => 'Schreiben',
+ 'Write your text in Markdown' => 'Schreiben Sie iHren Text in Markdown',
+ 'New External Task: %s' => 'Neue externe Aufgabe: %s',
+ 'No personal API access token registered.' => 'Keine persönlichen API-Zugriffsinformationen registriert',
+ 'Your personal API access token is "%s"' => 'Ihre persönlichen API-Zugriffsinformationen: "%s"',
+ 'Remove your token' => 'Ihre Zugriffsinformationen entfernen',
+ 'Generate a new token' => 'Neue Zugriffsinformationen generieren',
+ 'Showing %d-%d of %d' => 'Zeige %d-%d of %d',
+ 'Outgoing Emails' => 'Ausgehende E-Mails',
+ 'Add or change currency rate' => 'Wechselkurs hinzufügen oder ändern',
+ 'Reference currency: %s' => 'Referenzwährung: %s',
+ 'Add custom filters' => 'Benutzerdefinierten Filter hinzufügen',
+ 'Export' => 'Exportieren',
+ 'Add link label' => 'Linkbeschreibung hinzufügen',
+ 'Incompatible Plugins' => 'Nicht-kompatible Plugins',
+ 'Compatibility' => 'Kompatibilität',
+ 'Permissions and ownership' => 'Berechtigungen und Besitz',
+ 'Priorities' => 'Prioritäten',
+ 'Close this window' => 'Dieses Fenster schließen',
+ 'Unable to upload this file.' => 'Diese Datei kann nicht hochgeladen werden',
+ 'Import tasks' => 'Aufgaben importieren',
+ 'Choose a project' => 'Wählen Sie ein Projekt',
+ 'Profile' => 'Profil',
+ 'Application role' => 'Anwendungsrolle',
+ '%d invitations were sent.' => '%d Einladungen wurden gesendet.',
+ '%d invitation was sent.' => '%d Einladung wurde gesendet.',
+ 'Unable to create this user.' => 'Dieser Benutzer kann nicht erstellt werden.',
+ 'Kanboard Invitation' => 'Kanboard Einladung',
+ 'Visible on dashboard' => 'Sichtbar auf dem Dashboard',
+ 'Created at:' => 'Erstellt am:',
+ 'Updated at:' => 'Aktualisiert am:',
+ 'There is no custom filter.' => 'Es gibt keinen benutzerdefinierten Filter.',
+ 'New User' => 'Neuer Benutzer',
+ 'Authentication' => 'Authentifizierung',
+ 'If checked, this user will use a third-party system for authentication.' => 'Wenn aktiviert, verwendet dieser Benutzer ein Drittanbieter-System für die Authentifizierung.',
+ 'The password is necessary only for local users.' => 'Das Passwort ist nur für lokale Benutzer erforderlich.',
+ 'You have been invited to register on Kanboard.' => 'Sie wurden eingeladen, sich auf Kanboard zu registrieren.',
+ 'Click here to join your team' => 'Klicken Sie hier, um Ihrem Team beizutreten',
+ 'Invite people' => 'Leute einladen',
+ 'Emails' => 'E-Mail',
+ 'Enter one email address by line.' => 'Geben Sie eine E-Mail-Adresse pro Zeile ein.',
+ 'Add these people to this project' => 'Füge diese Personen diesem Projekt hinzu',
+ 'Add this person to this project' => 'Füge diese Persone diesem Projekt hinzu',
+ 'Sign-up' => 'Anmelden',
+ 'Credentials' => 'Anmeldeinformationen',
+ 'New user' => 'Neuer Benutzer',
+ 'This username is already taken' => 'Dieser Benutzername ist bereits vergeben',
+ // 'A link to reset your password has been sent by email.' => '',
+ // 'Your profile must have a valid email address.' => '',
+ // 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
+ // 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
+ // 'The email configuration has been disabled by the administrator.' => '',
);
diff --git a/app/Locale/el_GR/translations.php b/app/Locale/el_GR/translations.php
index 44f5e0df..5e99a225 100644
--- a/app/Locale/el_GR/translations.php
+++ b/app/Locale/el_GR/translations.php
@@ -61,7 +61,6 @@ return array(
'%d tasks on the board' => '%d εργασίες στον κεντρικό πίνακα έργου',
'%d tasks in total' => '%d εργασιών στο σύνολο',
'Unable to update this board.' => 'Αδύνατη η ενημέρωση αυτού του πίνακα',
- 'Edit board' => 'Ενημέρωση πίνακα',
'Disable' => 'Απενεργοποίηση',
'Enable' => 'Ενεργοποίηση',
'New project' => 'Νέο έργο',
@@ -72,7 +71,6 @@ return array(
'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"?' => 'Θέλετε να αφαιρέσετε τη στήλη: « %s » ?',
'This action will REMOVE ALL TASKS associated to this column!' => 'Αυτή η ενέργεια θα ΑΦΑΙΡΕΣΕΙ ΟΛΕΣ ΤΙΣ ΕΡΓΑΣΙΕΣ που είναι σχετικές με τη στήλη!!',
@@ -160,9 +158,7 @@ return array(
'Task count' => 'Αρίθμηση εργασιών',
'User' => 'Χρήστης',
'Comments' => 'Σχόλια',
- 'Leave a comment' => 'Αφήστε ένα σχόλιο',
'Comment is required' => 'Το σχόλιο απαιτείται',
- 'Leave a description' => 'Αφήστε μια περιγραφή',
'Comment added successfully.' => 'Το σχόλιο σας προστέθηκε με επιτυχία.',
'Unable to create your comment.' => 'Δεν είναι δυνατή η προσθήκη του σχολίου σας.',
'Due Date' => 'Μέχρι την ημερομηνία',
@@ -224,7 +220,6 @@ return array(
'Search' => 'Αναζήτηση',
'Nothing found.' => 'Δεν βρέθηκε.',
'Due date' => 'Μέχρι την ημερομηνία',
- 'Others formats accepted: %s and %s' => 'Άλλες δεκτές μορφοποιήσεις: %s και %s',
'Description' => 'Περιγραφή',
'%d comments' => '%d σχόλια',
'%d comment' => '%d σχόλιο',
@@ -298,7 +293,6 @@ return array(
'Created by %s' => 'Δημιουργήθηκε από %s',
'Tasks Export' => 'Εξαγωγή εργασιών',
'Start Date' => 'Ημερομηνία έναρξης',
- 'End Date' => 'ημερομηνία λήξης',
'Execute' => 'Εκτέλεση',
'Task Id' => 'Task Id',
'Creator' => 'Δημιουργός',
@@ -342,8 +336,8 @@ return array(
'Remote' => 'Απομακρυσμένη',
'Enabled' => 'Ενεργή',
'Disabled' => 'Απενεργοποιημένη',
- 'Username:' => 'Username:',
- 'Name:' => 'Όνομα:',
+ 'Login:' => 'Login:',
+ 'Full Name:' => 'Όνομα:',
'Email:' => 'Email:',
'Notifications:' => 'Ειδοποιήσεις:',
'Notifications' => 'Ειδοποιήσεις',
@@ -516,10 +510,8 @@ return array(
'Link labels' => 'Link labels',
'Link modification' => 'Τροποποίηση Link ',
'Links' => 'Links',
- 'Link settings' => 'Ρυθμίσεις συνδέσμων',
'Opposite label' => 'Αντίθετο label',
'Remove a link' => 'Αφαίρεση ενός link',
- 'Task\'s links' => 'Σύνδεσμοι εργασιών',
'The labels must be different' => 'Τα label πρέπει να είναι διαφορετικά',
'There is no link.' => 'Δεν υπάρχει σύνδεσμος.',
'This label must be unique' => 'Το label πρέπει να είναι μοναδικό',
@@ -552,7 +544,6 @@ return array(
'Compact view' => 'Συμπυκνωμένη προβολή',
'Horizontal scrolling' => 'Οριζόντια ολίσθηση',
'Compact/wide view' => 'Συμπυκνωμένη/Ευρεία Προβολή',
- 'No results match:' => 'Δεν ταιριάζει κανένα αποτέλεσμα:',
'Currency' => 'Νόμισμα',
'Private project' => 'Ιδιωτικό έργο',
'AUD - Australian Dollar' => 'AUD - Australian Dollar',
@@ -566,6 +557,7 @@ return array(
'JPY - Japanese Yen' => 'JPY - Japanese Yen',
'NZD - New Zealand Dollar' => 'NZD - New Zealand Dollar',
'RSD - Serbian dinar' => 'RSD - Serbian dinar',
+ // 'CNY - Chinese Yuan' => '',
'USD - US Dollar' => 'USD - US Dollar',
'Destination column' => 'Στήλη προορισμού',
'Move the task to another column when assigned to a user' => 'Μετακινήστε την εργασία σε άλλη στήλη όταν ανατεθεί σε ένα χρήστη',
@@ -580,7 +572,6 @@ return array(
'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.' => 'Αδύνατο να προστεθεί αυτή η ισοτιμία.',
@@ -702,7 +693,6 @@ return array(
'<30m' => '<30m',
'Stop timer' => 'Διακοπή ρολογιού',
'Start timer' => 'Έναρξη ρολογιού',
- 'Add project member' => 'Προσθήκη νέου μέλους έργου',
'My activity stream' => 'Η ροή δραστηριοτήτων μου',
'My calendar' => 'Το ημερολόγιο μου',
'Search tasks' => 'Αναζήτηση εργασιών',
@@ -757,8 +747,6 @@ return array(
'Remote user' => 'Απομακρυσμένος χρήστης',
'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => 'Στους απομακρυσμένους χρήστες δεν αποθηκεύονται οι κωδικοί πρόσβασης εντός της βάσης δεδομένων της τρέχουσας εφαρμογής, Παραδείγματα: 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.' => 'Αυτή η δυνατότητα δεν δουλεύει σε όλους τους browsers',
'There is no destination project available.' => 'Δεν υπάρχει διαθέσιμο κανένα έργο προορισμού.',
@@ -852,7 +840,6 @@ return array(
'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!' => 'Τίποτα δεν εισήχθη',
@@ -980,7 +967,6 @@ return array(
'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' => 'Προτεραιότητα',
@@ -1037,7 +1023,6 @@ return array(
'Started:' => 'Ξεκίνησε:',
'Moved:' => 'Μετακινήθηκε:',
'Task #%d' => 'Εργασία #%d',
- 'Date and time format' => 'Μορφή ημερομηνίας και ώρας',
'Time format' => 'Μορφή ώρας',
'Start date: ' => 'Ημερομηνία έναρξης: ',
'End date: ' => 'Ημερομηνία λήξης: ',
@@ -1051,9 +1036,7 @@ return array(
'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' => 'Προβολή προφίλ',
@@ -1163,7 +1146,6 @@ return array(
// 'Email sender address' => '',
// 'Email transport' => '',
// 'Webhook token' => '',
- // 'Imports' => '',
// 'Project tags management' => '',
// 'Tag created successfully.' => '',
// 'Unable to create this tag.' => '',
@@ -1210,8 +1192,6 @@ return array(
// 'Activity stream for %s' => '',
// 'Calendar for %s' => '',
// 'Notifications for %s' => '',
- // 'Subtasks export' => '',
- // 'Tasks exportation' => '',
// 'Assign a color when the task is moved to a specific swimlane' => '',
// 'Assign a priority when the task is moved to a specific swimlane' => '',
// 'User unlocked successfully.' => '',
@@ -1277,4 +1257,61 @@ return array(
// 'This field is required' => '',
// 'Moving a task is not permitted' => '',
// 'This value must be in the range %d to %d' => '',
+ // 'You are not allowed to move this task.' => '',
+ // 'API User Access' => '',
+ // 'Preview' => '',
+ // 'Write' => '',
+ // 'Write your text in Markdown' => '',
+ // 'New External Task: %s' => '',
+ // 'No personal API access token registered.' => '',
+ // 'Your personal API access token is "%s"' => '',
+ // 'Remove your token' => '',
+ // 'Generate a new token' => '',
+ // 'Showing %d-%d of %d' => '',
+ // 'Outgoing Emails' => '',
+ // 'Add or change currency rate' => '',
+ // 'Reference currency: %s' => '',
+ // 'Add custom filters' => '',
+ // 'Export' => '',
+ // 'Add link label' => '',
+ // 'Incompatible Plugins' => '',
+ // 'Compatibility' => '',
+ // 'Permissions and ownership' => '',
+ // 'Priorities' => '',
+ // 'Close this window' => '',
+ // 'Unable to upload this file.' => '',
+ // 'Import tasks' => '',
+ // 'Choose a project' => '',
+ // 'Profile' => '',
+ // 'Application role' => '',
+ // '%d invitations were sent.' => '',
+ // '%d invitation was sent.' => '',
+ // 'Unable to create this user.' => '',
+ // 'Kanboard Invitation' => '',
+ // 'Visible on dashboard' => '',
+ // 'Created at:' => '',
+ // 'Updated at:' => '',
+ // 'There is no custom filter.' => '',
+ // 'New User' => '',
+ // 'Authentication' => '',
+ // 'If checked, this user will use a third-party system for authentication.' => '',
+ // 'The password is necessary only for local users.' => '',
+ // 'You have been invited to register on Kanboard.' => '',
+ // 'Click here to join your team' => '',
+ // 'Invite people' => '',
+ // 'Emails' => '',
+ // 'Enter one email address by line.' => '',
+ // 'Add these people to this project' => '',
+ // 'Add this person to this project' => '',
+ // 'Sign-up' => '',
+ // 'Credentials' => '',
+ // 'New user' => '',
+ // 'This username is already taken' => '',
+ // 'A link to reset your password has been sent by email.' => '',
+ // 'Your profile must have a valid email address.' => '',
+ // 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
+ // 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
+ // 'The email configuration has been disabled by the administrator.' => '',
);
diff --git a/app/Locale/es_ES/translations.php b/app/Locale/es_ES/translations.php
index cdd6c278..2e3f4215 100644
--- a/app/Locale/es_ES/translations.php
+++ b/app/Locale/es_ES/translations.php
@@ -61,7 +61,6 @@ return array(
'%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.',
- 'Edit board' => 'Modificar este tablero',
'Disable' => 'Desactivar',
'Enable' => 'Activar',
'New project' => 'Nuevo proyecto',
@@ -72,7 +71,6 @@ return array(
'Title' => 'Título',
'Assigned to %s' => 'Asignada a %s',
'Remove a column' => 'Eliminar esta columna',
- 'Remove a column from a board' => 'Eliminar una columna de un tablero',
'Unable to remove this column.' => 'No se puede eliminar esta columna.',
'Do you really want to remove this column: "%s"?' => '¿De vedad que desea eliminar esta columna: «%s»?',
'This action will REMOVE ALL TASKS associated to this column!' => '¡Esta acción ELIMINARÁ TODAS LAS TAREAS asociadas a esta columna!',
@@ -160,9 +158,7 @@ return array(
'Task count' => 'Contador de tareas',
'User' => 'Usuario',
'Comments' => 'Comentarios',
- 'Leave a comment' => 'Dejar un comentario',
'Comment is required' => 'El comentario es obligatorio',
- 'Leave a description' => 'Dejar una descripción',
'Comment added successfully.' => 'El comentario ha sido añadido correctamente.',
'Unable to create your comment.' => 'No se puede crear este comentario.',
'Due Date' => 'Fecha límite',
@@ -224,7 +220,6 @@ return array(
'Search' => 'Buscar',
'Nothing found.' => 'No se ha encontrado nada.',
'Due date' => 'Fecha límite',
- 'Others formats accepted: %s and %s' => 'Otros formatos aceptados: %s y %s',
'Description' => 'Descripción',
'%d comments' => '%d comentarios',
'%d comment' => '%d comentario',
@@ -298,7 +293,6 @@ return array(
'Created by %s' => 'Creado por %s',
'Tasks Export' => 'Exportar tareas',
'Start Date' => 'Fecha de inicio',
- 'End Date' => 'Fecha final',
'Execute' => 'Ejecutar',
'Task Id' => 'Identificador de tarea',
'Creator' => 'Creador',
@@ -342,8 +336,8 @@ return array(
'Remote' => 'Remota',
'Enabled' => 'Activada',
'Disabled' => 'Desactivada',
- 'Username:' => 'Nombre de usuario:',
- 'Name:' => 'Nombre:',
+ 'Login:' => 'Nombre de usuario:',
+ 'Full Name:' => 'Nombre:',
'Email:' => 'Correo electrónico:',
'Notifications:' => 'Notificaciones:',
'Notifications' => 'Notificaciones',
@@ -516,10 +510,8 @@ return array(
'Link labels' => 'Etiquetas de enlace',
'Link modification' => 'Modificación del enlace',
'Links' => 'Enlaces',
- 'Link settings' => 'Preferencias de enlace',
'Opposite label' => 'Etiqueta opuesta',
'Remove a link' => 'Eliminar un enlace',
- 'Task\'s links' => 'Enlaces de tareas',
'The labels must be different' => 'Las etiquetas han de ser diferentes',
'There is no link.' => 'No hay enlace.',
'This label must be unique' => 'Esta etiqueta debe ser única',
@@ -552,7 +544,6 @@ return array(
'Compact view' => 'Compactar vista',
'Horizontal scrolling' => 'Desplazamiento horizontal',
'Compact/wide view' => 'Vista compacta/amplia',
- 'No results match:' => 'No hay resultados coincidentes:',
'Currency' => 'Moneda',
'Private project' => 'Proyecto privado',
'AUD - Australian Dollar' => 'AUD - Dólar australiano',
@@ -566,6 +557,7 @@ return array(
'JPY - Japanese Yen' => 'JPY - Yen japonés',
'NZD - New Zealand Dollar' => 'NZD - Dóloar neocelandés',
'RSD - Serbian dinar' => 'RSD - Dinar serbio',
+ // 'CNY - Chinese Yuan' => '',
'USD - US Dollar' => 'USD - Dólar estadounidense',
'Destination column' => 'Columna destino',
'Move the task to another column when assigned to a user' => 'Mover la tarea a otra columna al asignarse a un usuario',
@@ -580,7 +572,6 @@ return array(
'Currency rates' => 'Cambio de monedas',
'Rate' => 'Cambio',
'Change reference currency' => 'Cambiar moneda de referencia',
- 'Add a new currency rate' => 'Añadir nuevo cambio de moneda',
'Reference currency' => 'Moneda de referencia',
'The currency rate have been added successfully.' => 'El cambio de moneda se ha añadido correctamente.',
'Unable to add this currency rate.' => 'No se puede añadir este cambio de moneda.',
@@ -702,7 +693,6 @@ return array(
'<30m' => '<30m',
'Stop timer' => 'Parar temporizador',
'Start timer' => 'Iniciar temporizador',
- 'Add project member' => 'Añadir miembro al proyecto',
'My activity stream' => 'Mi flujo de actividad',
'My calendar' => 'Mi calendario',
'Search tasks' => 'Buscar tareas',
@@ -757,8 +747,6 @@ return array(
'Remote user' => 'Usuario remoto',
'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => 'Los usuarios remotos no almacenan sus contraseñas en la base de datos Kanboard, por ejemplo: cuentas de LDAP, Google y Github.',
'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => 'Si marcas la opción "Desactivar formulario de ingreso", se ignoran las credenciales introducidas en el formulario de ingreso.',
- 'New remote user' => 'Nuevo usuario remoto',
- 'New local user' => 'Nuevo usuario local',
'Default task color' => 'Color de la tarea por defecto',
'This feature does not work with all browsers.' => 'Esta característica no funciona en todos los navegadores.',
'There is no destination project available.' => 'No está disponible proyecto de destino.',
@@ -852,7 +840,6 @@ return array(
'Owner' => 'Propietario',
'Unread notifications' => 'Notificaciones sin leer',
'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',
'%d task(s) have been imported successfully.' => '%d tarea(s) han sido importadas correctamente.',
'Nothing have been imported!' => '¡No se ha importado nada!',
@@ -980,7 +967,6 @@ return array(
'Project owner: ' => 'Propietario del proyecto: ',
'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => 'El identificador del proyecto es opcional y debe ser alfanumérico. Ejemplo: MIPROYECTO',
'Project owner' => 'Propietario del proyecto',
- 'Those dates are useful for the project Gantt chart.' => 'Esas fechas son útiles para el diagrama de Gantt.',
'Private projects do not have users and groups management.' => 'Los proyectos privados no cuentan con gestión de usuarios y grupos.',
'There is no project member.' => 'No existe miembro del proyecto.',
'Priority' => 'Prioridad',
@@ -1037,7 +1023,6 @@ return array(
'Started:' => 'Iniciado:',
'Moved:' => 'Movido:',
'Task #%d' => 'Tarea #%d',
- 'Date and time format' => 'Formato de fecha y hora',
'Time format' => 'Formato de hora',
'Start date: ' => 'Fecha de inicio: ',
'End date: ' => 'Fecha de finalización: ',
@@ -1051,9 +1036,7 @@ return array(
'User disabled successfully.' => 'Usuario deshabilitado correctamente.',
'Unable to disable this user.' => 'No es posible deshabilitar este usuario.',
'All files have been uploaded successfully.' => 'Todos los archivos han sido cargados correctamente.',
- 'View uploaded files' => 'Ver archivos cargados',
'The maximum allowed file size is %sB.' => 'El tamaño máximo de archivo es %sB.',
- 'Choose files again' => 'Elegir archivos de nuevo',
'Drag and drop your files here' => 'Arrastra y suelta tus archivos aquí',
'choose files' => 'elegir archivos',
'View profile' => 'Ver perfil',
@@ -1163,7 +1146,6 @@ return array(
'Email sender address' => 'Dirección del remitente del correo electrónico',
'Email transport' => 'Transporte de correo electrónico',
'Webhook token' => 'Token del disparador web (webhook)',
- 'Imports' => 'Importaciones',
// 'Project tags management' => '',
// 'Tag created successfully.' => '',
// 'Unable to create this tag.' => '',
@@ -1210,8 +1192,6 @@ return array(
// 'Activity stream for %s' => '',
// 'Calendar for %s' => '',
// 'Notifications for %s' => '',
- // 'Subtasks export' => '',
- // 'Tasks exportation' => '',
// 'Assign a color when the task is moved to a specific swimlane' => '',
// 'Assign a priority when the task is moved to a specific swimlane' => '',
// 'User unlocked successfully.' => '',
@@ -1277,4 +1257,61 @@ return array(
// 'This field is required' => '',
// 'Moving a task is not permitted' => '',
// 'This value must be in the range %d to %d' => '',
+ // 'You are not allowed to move this task.' => '',
+ // 'API User Access' => '',
+ // 'Preview' => '',
+ // 'Write' => '',
+ // 'Write your text in Markdown' => '',
+ // 'New External Task: %s' => '',
+ // 'No personal API access token registered.' => '',
+ // 'Your personal API access token is "%s"' => '',
+ // 'Remove your token' => '',
+ // 'Generate a new token' => '',
+ // 'Showing %d-%d of %d' => '',
+ // 'Outgoing Emails' => '',
+ // 'Add or change currency rate' => '',
+ // 'Reference currency: %s' => '',
+ // 'Add custom filters' => '',
+ // 'Export' => '',
+ // 'Add link label' => '',
+ // 'Incompatible Plugins' => '',
+ // 'Compatibility' => '',
+ // 'Permissions and ownership' => '',
+ // 'Priorities' => '',
+ // 'Close this window' => '',
+ // 'Unable to upload this file.' => '',
+ // 'Import tasks' => '',
+ // 'Choose a project' => '',
+ // 'Profile' => '',
+ // 'Application role' => '',
+ // '%d invitations were sent.' => '',
+ // '%d invitation was sent.' => '',
+ // 'Unable to create this user.' => '',
+ // 'Kanboard Invitation' => '',
+ // 'Visible on dashboard' => '',
+ // 'Created at:' => '',
+ // 'Updated at:' => '',
+ // 'There is no custom filter.' => '',
+ // 'New User' => '',
+ // 'Authentication' => '',
+ // 'If checked, this user will use a third-party system for authentication.' => '',
+ // 'The password is necessary only for local users.' => '',
+ // 'You have been invited to register on Kanboard.' => '',
+ // 'Click here to join your team' => '',
+ // 'Invite people' => '',
+ // 'Emails' => '',
+ // 'Enter one email address by line.' => '',
+ // 'Add these people to this project' => '',
+ // 'Add this person to this project' => '',
+ // 'Sign-up' => '',
+ // 'Credentials' => '',
+ // 'New user' => '',
+ // 'This username is already taken' => '',
+ // 'A link to reset your password has been sent by email.' => '',
+ // 'Your profile must have a valid email address.' => '',
+ // 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
+ // 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
+ // 'The email configuration has been disabled by the administrator.' => '',
);
diff --git a/app/Locale/fi_FI/translations.php b/app/Locale/fi_FI/translations.php
index 4f74cbf8..84ddf1ce 100644
--- a/app/Locale/fi_FI/translations.php
+++ b/app/Locale/fi_FI/translations.php
@@ -61,7 +61,6 @@ return array(
'%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.',
- 'Edit board' => 'Muuta taulua',
'Disable' => 'Disabloi',
'Enable' => 'Aktivoi',
'New project' => 'Uusi projekti',
@@ -72,7 +71,6 @@ return array(
'Title' => 'Nimi',
'Assigned to %s' => 'Tekijä: %s',
'Remove a column' => 'Poista sarake',
- 'Remove a column from a board' => 'Poista sarake taulusta',
'Unable to remove this column.' => 'Sarakkeen poistaminen ei onnistunut.',
'Do you really want to remove this column: "%s"?' => 'Haluatko varmasti poistaa sarakkeen "%s"?',
'This action will REMOVE ALL TASKS associated to this column!' => 'Tämä toiminto POISTAA KAIKKI TEHTÄVÄT tästä sarakkeesta!',
@@ -160,9 +158,7 @@ return array(
'Task count' => 'Tehtävien määrä',
'User' => 'Käyttäjät',
'Comments' => 'Kommentit',
- 'Leave a comment' => 'Lisää kommentti',
'Comment is required' => 'Kommentti vaaditaan',
- 'Leave a description' => 'Lisää kuvaus',
'Comment added successfully.' => 'Kommentti lisättiin onnistuneesti.',
'Unable to create your comment.' => 'Kommentin lisäys epäonnistui.',
'Due Date' => 'Deadline',
@@ -224,7 +220,6 @@ return array(
'Search' => 'Etsi',
'Nothing found.' => 'Ei löytynyt.',
'Due date' => 'Deadline',
- 'Others formats accepted: %s and %s' => 'Muut hyväksytyt muodot: %s ja %s',
'Description' => 'Kuvaus',
'%d comments' => '%d kommenttia',
'%d comment' => '%d kommentti',
@@ -298,7 +293,6 @@ return array(
'Created by %s' => 'Luonut: %s',
'Tasks Export' => 'Tehtävien vienti',
'Start Date' => 'Aloituspäivä',
- 'End Date' => 'Lopetuspäivä',
'Execute' => 'Suorita',
'Task Id' => 'Tehtävän ID',
'Creator' => 'Luonut',
@@ -342,8 +336,8 @@ return array(
'Remote' => 'Etä',
'Enabled' => 'Käytössä',
'Disabled' => 'Pois käytöstä',
- 'Username:' => 'Käyttäjänimi:',
- 'Name:' => 'Nimi:',
+ 'Login:' => 'Käyttäjänimi:',
+ 'Full Name:' => 'Nimi:',
'Email:' => 'Sähköpostiosoite:',
'Notifications:' => 'Ilmoitukset:',
'Notifications' => 'Ilmoitukset',
@@ -516,10 +510,8 @@ return array(
// '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' => '',
@@ -552,7 +544,6 @@ return array(
// 'Compact view' => '',
// 'Horizontal scrolling' => '',
// 'Compact/wide view' => '',
- // 'No results match:' => '',
// 'Currency' => '',
// 'Private project' => '',
// 'AUD - Australian Dollar' => '',
@@ -566,6 +557,7 @@ return array(
// 'JPY - Japanese Yen' => '',
// 'NZD - New Zealand Dollar' => '',
// 'RSD - Serbian dinar' => '',
+ // 'CNY - Chinese Yuan' => '',
// 'USD - US Dollar' => '',
// 'Destination column' => '',
// 'Move the task to another column when assigned to a user' => '',
@@ -580,7 +572,6 @@ return array(
// '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.' => '',
@@ -702,7 +693,6 @@ return array(
// '<30m' => '',
// 'Stop timer' => '',
// 'Start timer' => '',
- // 'Add project member' => '',
// 'My activity stream' => '',
// 'My calendar' => '',
// 'Search tasks' => '',
@@ -757,8 +747,6 @@ return array(
// '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.' => '',
@@ -852,7 +840,6 @@ return array(
// '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!' => '',
@@ -980,7 +967,6 @@ return array(
// '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' => '',
@@ -1037,7 +1023,6 @@ return array(
// 'Started:' => '',
// 'Moved:' => '',
// 'Task #%d' => '',
- // 'Date and time format' => '',
// 'Time format' => '',
// 'Start date: ' => '',
// 'End date: ' => '',
@@ -1051,9 +1036,7 @@ return array(
// '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' => '',
@@ -1163,7 +1146,6 @@ return array(
// 'Email sender address' => '',
// 'Email transport' => '',
// 'Webhook token' => '',
- // 'Imports' => '',
// 'Project tags management' => '',
// 'Tag created successfully.' => '',
// 'Unable to create this tag.' => '',
@@ -1210,8 +1192,6 @@ return array(
// 'Activity stream for %s' => '',
// 'Calendar for %s' => '',
// 'Notifications for %s' => '',
- // 'Subtasks export' => '',
- // 'Tasks exportation' => '',
// 'Assign a color when the task is moved to a specific swimlane' => '',
// 'Assign a priority when the task is moved to a specific swimlane' => '',
// 'User unlocked successfully.' => '',
@@ -1277,4 +1257,61 @@ return array(
// 'This field is required' => '',
// 'Moving a task is not permitted' => '',
// 'This value must be in the range %d to %d' => '',
+ // 'You are not allowed to move this task.' => '',
+ // 'API User Access' => '',
+ // 'Preview' => '',
+ // 'Write' => '',
+ // 'Write your text in Markdown' => '',
+ // 'New External Task: %s' => '',
+ // 'No personal API access token registered.' => '',
+ // 'Your personal API access token is "%s"' => '',
+ // 'Remove your token' => '',
+ // 'Generate a new token' => '',
+ // 'Showing %d-%d of %d' => '',
+ // 'Outgoing Emails' => '',
+ // 'Add or change currency rate' => '',
+ // 'Reference currency: %s' => '',
+ // 'Add custom filters' => '',
+ // 'Export' => '',
+ // 'Add link label' => '',
+ // 'Incompatible Plugins' => '',
+ // 'Compatibility' => '',
+ // 'Permissions and ownership' => '',
+ // 'Priorities' => '',
+ // 'Close this window' => '',
+ // 'Unable to upload this file.' => '',
+ // 'Import tasks' => '',
+ // 'Choose a project' => '',
+ // 'Profile' => '',
+ // 'Application role' => '',
+ // '%d invitations were sent.' => '',
+ // '%d invitation was sent.' => '',
+ // 'Unable to create this user.' => '',
+ // 'Kanboard Invitation' => '',
+ // 'Visible on dashboard' => '',
+ // 'Created at:' => '',
+ // 'Updated at:' => '',
+ // 'There is no custom filter.' => '',
+ // 'New User' => '',
+ // 'Authentication' => '',
+ // 'If checked, this user will use a third-party system for authentication.' => '',
+ // 'The password is necessary only for local users.' => '',
+ // 'You have been invited to register on Kanboard.' => '',
+ // 'Click here to join your team' => '',
+ // 'Invite people' => '',
+ // 'Emails' => '',
+ // 'Enter one email address by line.' => '',
+ // 'Add these people to this project' => '',
+ // 'Add this person to this project' => '',
+ // 'Sign-up' => '',
+ // 'Credentials' => '',
+ // 'New user' => '',
+ // 'This username is already taken' => '',
+ // 'A link to reset your password has been sent by email.' => '',
+ // 'Your profile must have a valid email address.' => '',
+ // 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
+ // 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
+ // 'The email configuration has been disabled by the administrator.' => '',
);
diff --git a/app/Locale/fr_FR/translations.php b/app/Locale/fr_FR/translations.php
index 89f46181..8e062c45 100644
--- a/app/Locale/fr_FR/translations.php
+++ b/app/Locale/fr_FR/translations.php
@@ -36,7 +36,7 @@ return array(
'Remove user' => 'Supprimer un utilisateur',
'Do you really want to remove this user: "%s"?' => 'Voulez-vous vraiment supprimer cet utilisateur : « %s » ?',
'All users' => 'Tous les utilisateurs',
- 'Username' => 'Nom d\'utilisateur',
+ 'Username' => 'Identifiant',
'Password' => 'Mot de passe',
'Administrator' => 'Administrateur',
'Sign in' => 'Connexion',
@@ -61,7 +61,6 @@ return array(
'%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.',
- 'Edit board' => 'Modifier le tableau',
'Disable' => 'Désactiver',
'Enable' => 'Activer',
'New project' => 'Nouveau projet',
@@ -72,7 +71,6 @@ return array(
'Title' => 'Titre',
'Assigned to %s' => 'Assigné à %s',
'Remove a column' => 'Supprimer une colonne',
- 'Remove a column from a board' => 'Supprimer une colonne d\'un tableau',
'Unable to remove this column.' => 'Impossible de supprimer cette colonne.',
'Do you really want to remove this column: "%s"?' => 'Voulez vraiment supprimer cette colonne : « %s » ?',
'This action will REMOVE ALL TASKS associated to this column!' => 'Cette action va supprimer toutes les tâches associées à cette colonne !',
@@ -160,9 +158,7 @@ return array(
'Task count' => 'Nombre de tâches',
'User' => 'Utilisateur',
'Comments' => 'Commentaires',
- 'Leave a comment' => 'Laissez un commentaire',
'Comment is required' => 'Le commentaire est obligatoire',
- 'Leave a description' => 'Laissez une description',
'Comment added successfully.' => 'Commentaire ajouté avec succès.',
'Unable to create your comment.' => 'Impossible de sauvegarder votre commentaire.',
'Due Date' => 'Date d\'échéance',
@@ -224,7 +220,6 @@ return array(
'Search' => 'Rechercher',
'Nothing found.' => 'Rien trouvé.',
'Due date' => 'Date d\'échéance',
- 'Others formats accepted: %s and %s' => 'Autres formats acceptés : %s et %s',
'Description' => 'Description',
'%d comments' => '%d commentaires',
'%d comment' => '%d commentaire',
@@ -298,7 +293,6 @@ return array(
'Created by %s' => 'Créé par %s',
'Tasks Export' => 'Exportation des tâches',
'Start Date' => 'Date de début',
- 'End Date' => 'Date de fin',
'Execute' => 'Exécuter',
'Task Id' => 'Identifiant de la tâche',
'Creator' => 'Créateur',
@@ -342,8 +336,8 @@ return array(
'Remote' => 'Distant',
'Enabled' => 'Activé',
'Disabled' => 'Désactivé',
- 'Username:' => 'Nom d\'utilisateur :',
- 'Name:' => 'Nom :',
+ 'Login:' => 'Nom d\'utilisateur :',
+ 'Full Name:' => 'Nom :',
'Email:' => 'Email :',
'Notifications:' => 'Notifications :',
'Notifications' => 'Notifications',
@@ -516,10 +510,8 @@ return array(
'Link labels' => 'Libellé des liens',
'Link modification' => 'Modification d\'un lien',
'Links' => 'Liens',
- 'Link settings' => 'Paramètres des liens',
'Opposite label' => 'Nom du libellé opposé',
'Remove a link' => 'Supprimer un lien',
- 'Task\'s links' => 'Liens des tâches',
'The labels must be different' => 'Les libellés doivent être différents',
'There is no link.' => 'Il n\'y a aucun lien.',
'This label must be unique' => 'Ce libellé doit être unique',
@@ -552,7 +544,6 @@ return array(
'Compact view' => 'Vue compacte',
'Horizontal scrolling' => 'Défilement horizontal',
'Compact/wide view' => 'Basculer entre la vue compacte et étendue',
- 'No results match:' => 'Aucun résultat :',
'Currency' => 'Devise',
'Private project' => 'Projet privé',
'AUD - Australian Dollar' => 'AUD - Dollar australien',
@@ -566,6 +557,7 @@ return array(
'JPY - Japanese Yen' => 'JPY - Yen',
'NZD - New Zealand Dollar' => 'NZD - Dollar néo-zélandais',
'RSD - Serbian dinar' => 'RSD - Dinar serbe',
+ 'CNY - Chinese Yuan' => 'CNY - Yuan (Chine)',
'USD - US Dollar' => 'USD - Dollar américain',
'Destination column' => 'Colonne de destination',
'Move the task to another column when assigned to a user' => 'Déplacer la tâche dans une autre colonne lorsque celle-ci est assignée à quelqu\'un',
@@ -580,7 +572,6 @@ return array(
'Currency rates' => 'Taux de change des devises',
'Rate' => 'Taux',
'Change reference currency' => 'Changer la monnaie de référence',
- 'Add a new currency rate' => 'Ajouter un nouveau taux pour une devise',
'Reference currency' => 'Devise de référence',
'The currency rate have been added successfully.' => 'Le taux de change a été ajouté avec succès.',
'Unable to add this currency rate.' => 'Impossible d\'ajouter ce taux de change',
@@ -675,7 +666,6 @@ return array(
'view the board on Kanboard' => 'voir le tableau sur Kanboard',
'The task have been moved to the first swimlane' => 'La tâche a été déplacée dans la première swimlane',
'The task have been moved to another swimlane:' => 'La tâche a été déplacée dans une autre swimlane :',
- // 'Overdue tasks for the project(s) "%s"' => 'Tâches en retard pour le projet « %s »',
'New title: %s' => 'Nouveau titre : %s',
'The task is not assigned anymore' => 'La tâche n\'est plus assignée maintenant',
'New assignee: %s' => 'Nouvel assigné : %s',
@@ -703,7 +693,6 @@ return array(
'<30m' => '<30m',
'Stop timer' => 'Stopper le chrono',
'Start timer' => 'Démarrer le chrono',
- 'Add project member' => 'Ajouter un membre au projet',
'My activity stream' => 'Mon flux d\'activité',
'My calendar' => 'Mon agenda',
'Search tasks' => 'Rechercher des tâches',
@@ -758,8 +747,6 @@ return array(
'Remote user' => 'Utilisateur distant',
'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => 'Les utilisateurs distants ne stockent pas leur mot de passe dans la base de données de Kanboard, exemples : comptes LDAP, Github ou Google.',
'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => 'Si vous cochez la case « Interdire le formulaire d\'authentification », les identifiants entrés dans le formulaire d\'authentification seront ignorés.',
- 'New remote user' => 'Créer un utilisateur distant',
- 'New local user' => 'Créer un utilisateur local',
'Default task color' => 'Couleur par défaut des tâches',
'This feature does not work with all browsers.' => 'Cette fonctionnalité n\'est pas compatible avec tous les navigateurs',
'There is no destination project available.' => 'Il n\'y a pas de projet de destination disponible.',
@@ -840,7 +827,7 @@ return array(
'Swimlane changed for task #%d' => 'Changement de swimlane pour la tâche n°%d',
'Assignee changed on task #%d' => 'Changement de l\'assigné pour la tâche n°%d',
'%d overdue tasks' => '%d tâches en retard',
- 'Task #%d is overdue' => 'La tâche n°%d est retard',
+ 'Task #%d is overdue' => 'La tâche n°%d est en retard',
'No new notifications.' => 'Aucune notification.',
'Mark all as read' => 'Tout marquer comme lu',
'Mark as read' => 'Marquer comme lu',
@@ -853,7 +840,6 @@ return array(
'Owner' => 'Propriétaire',
'Unread notifications' => 'Notifications non lus',
'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',
'%d task(s) have been imported successfully.' => '%d tâche(s) ont été importées avec succès.',
'Nothing have been imported!' => 'Rien n\'a été importé',
@@ -975,13 +961,12 @@ return array(
'Do you really want to close all tasks of this column?' => 'Voulez-vous vraiment fermer toutes les tâches de cette colonne ?',
'%d task(s) in the column "%s" and the swimlane "%s" will be closed.' => '%d tâche(s) dans la colonne « %s » et la swimlane « %s » seront fermées.',
'Close all tasks of this column' => 'Fermer toutes les tâches de cette colonne',
- 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => 'Aucun plugin n\'a enregistré une méthode de notification de projet. Vous pouvez toujours configurer les notifications individuelles dans votre profil d\'utilisateur.',
+ 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => 'Aucun plugin n\'a enregistré une méthode de notification de projet. Vous pouvez toujours configurer les notifications individuelles dans votre profil utilisateur.',
'My dashboard' => 'Mon tableau de bord',
'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',
- 'Those dates are useful for the project Gantt chart.' => 'Ces dates sont utiles pour le diagramme de Gantt des projets.',
'Private projects do not have users and groups management.' => 'Les projets privés n\'ont pas de gestion d\'utilisateurs et de groupes.',
'There is no project member.' => 'Il n\'y a aucun membre du projet.',
'Priority' => 'Priorité',
@@ -1038,7 +1023,6 @@ return array(
'Started:' => 'Commençé le :',
'Moved:' => 'Déplacé le : ',
'Task #%d' => 'Tâche n°%d',
- 'Date and time format' => 'Format de la date et de l\'heure',
'Time format' => 'Format de l\'heure',
'Start date: ' => 'Date de début : ',
'End date: ' => 'Date de fin : ',
@@ -1052,9 +1036,7 @@ return array(
'User disabled successfully.' => 'Utilisateur désactivé avec succès.',
'Unable to disable this user.' => 'Impossible de désactiver cet utilisateur.',
'All files have been uploaded successfully.' => 'Tous les fichiers ont été uploadés avec succès.',
- 'View uploaded files' => 'Voir les fichiers uploadés',
'The maximum allowed file size is %sB.' => 'La taille maximale autorisée pour les fichiers est de %so.',
- '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 profil',
@@ -1164,7 +1146,6 @@ return array(
'Email sender address' => 'Adresse email de l\'expéditeur',
'Email transport' => 'Transport des emails',
'Webhook token' => 'Jeton de sécurité des webhooks',
- 'Imports' => 'Importations',
'Project tags management' => 'Gestion des libellés pour le projet',
'Tag created successfully.' => 'Libellé créé avec succès.',
'Unable to create this tag.' => 'Imposssible de créer ce libellé.',
@@ -1211,8 +1192,6 @@ return array(
'Activity stream for %s' => 'Flux d\'activité pour %s',
'Calendar for %s' => 'Calendrier pour %s',
'Notifications for %s' => 'Notifications pour %s',
- 'Subtasks export' => 'Export des sous-tâches',
- 'Tasks exportation' => 'Export des tâches',
'Assign a color when the task is moved to a specific swimlane' => 'Assigner une couleur lorsque une tâche est déplaçée dans une swimlane spécifique',
'Assign a priority when the task is moved to a specific swimlane' => 'Assigner une priorité lorsque une tâche est déplaçée dans une swimlane spécifique',
'User unlocked successfully.' => 'Utilisateur débloqué avec succès.',
@@ -1278,4 +1257,61 @@ return array(
'This field is required' => 'Ce champ est requis',
'Moving a task is not permitted' => 'Déplaçer une tâche n\'est pas autorisé',
'This value must be in the range %d to %d' => 'Cette valeur doit être définie entre %d et %d',
+ 'You are not allowed to move this task.' => 'Vous n\'êtes pas autorisé à déplacer cette tâche.',
+ 'API User Access' => 'Accès utilisateur de l\'API',
+ 'Preview' => 'Aperçu',
+ 'Write' => 'Écrire',
+ 'Write your text in Markdown' => 'Écrivez votre texte en Markdown',
+ 'New External Task: %s' => 'Nouvelle tâche externe : %s',
+ 'No personal API access token registered.' => 'Aucun jeton d\'accès personnel à l\'API enregistré.',
+ 'Your personal API access token is "%s"' => 'Votre jeton d\'accès personnel à l\'API est « %s »',
+ 'Remove your token' => 'Supprimer votre jeton',
+ 'Generate a new token' => 'Générer un nouveau jeton',
+ 'Showing %d-%d of %d' => 'Éléments %d à %d sur %d',
+ 'Outgoing Emails' => 'Emails sortants',
+ 'Add or change currency rate' => 'Ajouter ou changer le taux de change',
+ 'Reference currency: %s' => 'Monnaie de référence : %s',
+ 'Add custom filters' => 'Ajouter un filtre personnalisé',
+ 'Export' => 'Exporter',
+ 'Add link label' => 'Ajouter un libellé de lien',
+ 'Incompatible Plugins' => 'Extensions incompatibles',
+ 'Compatibility' => 'Compatibilité',
+ 'Permissions and ownership' => 'Permissions et propriétaire',
+ 'Priorities' => 'Priorités',
+ 'Close this window' => 'Fermer cette fenêtre',
+ 'Unable to upload this file.' => 'Impossible de téléverser ce fichier.',
+ 'Import tasks' => 'Importer des tâches',
+ 'Choose a project' => 'Choisir un projet',
+ 'Profile' => 'Profil',
+ 'Application role' => 'Rôle dans l\'application',
+ '%d invitations were sent.' => '%d invitations ont été envoyées.',
+ '%d invitation was sent.' => '%d invitation a été envoyée.',
+ 'Unable to create this user.' => 'Impossible de créer cet utilisateur.',
+ 'Kanboard Invitation' => 'Invitation pour Kanboard',
+ 'Visible on dashboard' => 'Visible sur le tableau de bord',
+ 'Created at:' => 'Créé le :',
+ 'Updated at:' => 'Mis à jour le :',
+ 'There is no custom filter.' => 'Il n\'y a aucun filtre personnalisé.',
+ 'New User' => 'Nouvel utilisateur',
+ 'Authentication' => 'Authentification',
+ 'If checked, this user will use a third-party system for authentication.' => 'Si coché, cet utilisateur va utiliser un système externe pour s\'authentifier.',
+ 'The password is necessary only for local users.' => 'Le mot de passe est nécessaire uniquement pour les utilisateurs locaux.',
+ 'You have been invited to register on Kanboard.' => 'Vous avez été invité à vous inscrire sur Kanboard.',
+ 'Click here to join your team' => 'Cliquez ici pour rejoindre votre équipe',
+ 'Invite people' => 'Inviter des gens',
+ 'Emails' => 'Emails',
+ 'Enter one email address by line.' => 'Entrez une adresse électronique par ligne.',
+ 'Add these people to this project' => 'Ajouter ces personnes à ce projet',
+ 'Add this person to this project' => 'Ajouter cet utilisateur à ce projet',
+ 'Sign-up' => 'Inscription',
+ 'Credentials' => 'Informations d\'identification',
+ 'New user' => 'Nouvel utilisateur',
+ 'This username is already taken' => 'Ce nom d\'utilisateur est déjà pris',
+ 'A link to reset your password has been sent by email.' => 'Un lien pour réinitialiser votre mot de passe a été envoyé par email.',
+ 'Your profile must have a valid email address.' => 'Votre profil doit avoir une adresse e-mail valide.',
+ 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => 'Malheureusement, nous ne pouvons pas réinitialiser votre mot de passe. Avez-vous saisi un nom d\'utilisateur valide ? Avez-vous une adresse e-mail dans votre profil ?',
+ 'TRL - Turkish Lira' => 'TRL - Livre turque',
+ 'The project email is optional and could be used by several plugins.' => 'L\'adresse email d\'un projet est optionnel et pourrait être utilisé par plusieurs extensions.',
+ 'The email project must be unique across all projects' => 'L\'adresse email d\'un projet doit être unique pour tous les projets',
+ 'The email configuration has been disabled by the administrator.' => 'La configuration des emails a été désactivée par l\'administrateur.',
);
diff --git a/app/Locale/hu_HU/translations.php b/app/Locale/hu_HU/translations.php
index 7123d461..0d4beb00 100644
--- a/app/Locale/hu_HU/translations.php
+++ b/app/Locale/hu_HU/translations.php
@@ -61,7 +61,6 @@ return array(
'%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.',
- 'Edit board' => 'Tábla szerkesztése',
'Disable' => 'Letiltás',
'Enable' => 'Engedélyezés',
'New project' => 'Új projekt',
@@ -72,7 +71,6 @@ return array(
'Title' => 'Cím',
'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',
'Unable to remove this column.' => 'Az oszlop törlése nem lehetséges.',
'Do you really want to remove this column: "%s"?' => 'Valóban törölni akarja ezt az oszlopot: "%s"?',
'This action will REMOVE ALL TASKS associated to this column!' => 'Az oszlophoz rendelt ÖSSZES FELADAT TÖRLŐDNI FOG!',
@@ -160,9 +158,7 @@ return array(
'Task count' => 'Feladatok száma',
'User' => 'Felhasználó',
'Comments' => 'Hozzászólások',
- '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 ...',
'Comment added successfully.' => 'Hozzászólás sikeresen elküldve.',
'Unable to create your comment.' => 'Hozzászólás létrehozása nem lehetséges.',
'Due Date' => 'Határidő',
@@ -224,7 +220,6 @@ return array(
'Search' => 'Keresés',
'Nothing found.' => 'Nincs találat.',
'Due date' => 'Határidő',
- 'Others formats accepted: %s and %s' => 'Egyéb érvényes formátumok: "%s" és "%s"',
'Description' => 'Leírás',
'%d comments' => '%d megjegyzés',
'%d comment' => '%d megjegyzés',
@@ -298,7 +293,6 @@ return array(
'Created by %s' => 'Készítette: %s',
'Tasks Export' => 'Feladatok exportálása',
'Start Date' => 'Kezdés dátuma',
- 'End Date' => 'Befejezés dátuma',
'Execute' => 'Végrehajt',
'Task Id' => 'Feladat ID',
'Creator' => 'Készítette',
@@ -342,8 +336,8 @@ return array(
'Remote' => 'Távoli',
'Enabled' => 'Engedélyezve',
'Disabled' => 'Letiltva',
- 'Username:' => 'Felhasználónév:',
- 'Name:' => 'Név:',
+ 'Login:' => 'Felhasználónév:',
+ 'Full Name:' => 'Név:',
'Email:' => 'E-mail:',
'Notifications:' => 'Értesítések:',
'Notifications' => 'Értesítések',
@@ -516,10 +510,8 @@ return array(
'Link labels' => 'Hivatkozás címkék',
'Link modification' => 'Hivatkozás módosítás',
'Links' => 'Hivatkozások',
- 'Link settings' => 'Hivatkozás beállítasok',
'Opposite label' => 'Ellenkező címke',
'Remove a link' => 'Hivatkozás törlése',
- 'Task\'s links' => 'Feladat hivatkozások',
'The labels must be different' => 'A címkék nem lehetnek azonosak',
'There is no link.' => 'Nincs hivatkozás.',
'This label must be unique' => 'A címkének egyedinek kell lennie.',
@@ -552,7 +544,6 @@ return array(
'Compact view' => 'Kompakt nézet',
'Horizontal scrolling' => 'Vízszintes görgetés',
'Compact/wide view' => 'Kompakt/széles nézet',
- 'No results match:' => 'Nincs találat:',
'Currency' => 'Pénznem',
'Private project' => 'Privát projekt',
'AUD - Australian Dollar' => 'AUD - Ausztrál dollár',
@@ -566,6 +557,7 @@ return array(
'JPY - Japanese Yen' => 'JPY - Japán Yen',
'NZD - New Zealand Dollar' => 'NZD - Új-Zélandi dollár',
'RSD - Serbian dinar' => 'RSD - Szerb dínár',
+ // 'CNY - Chinese Yuan' => '',
'USD - US Dollar' => 'USD - Amerikai dollár',
'Destination column' => 'Cél oszlop',
'Move the task to another column when assigned to a user' => 'Feladat másik oszlopba helyezése felhasználóhoz rendélés után',
@@ -580,7 +572,6 @@ return array(
'Currency rates' => 'Árfolyamok',
'Rate' => 'Árfolyam',
'Change reference currency' => 'A bázis pénznem megváltoztatása',
- 'Add a new currency rate' => 'Új átváltási árfolyam megadása',
'Reference currency' => 'Bázis pénznem',
'The currency rate have been added successfully.' => 'Az átváltási árfolyammal történő bővítés sikerült',
'Unable to add this currency rate.' => 'Nem sikerült az átváltási árfolyam felvétele',
@@ -702,7 +693,6 @@ return array(
'<30m' => '30p',
'Stop timer' => 'Időmérő leállítása',
'Start timer' => 'Időmérő elindítása',
- 'Add project member' => 'Projekt tag hozzáadása',
'My activity stream' => 'Tevékenységem',
'My calendar' => 'Naptáram',
'Search tasks' => 'Feladatok közötti keresés',
@@ -757,8 +747,6 @@ return array(
'Remote user' => 'Távoli felhasználó',
'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => 'A távoli felhasználók jelszava nem a Kanboard adatbázisban van tárolva. Példák: LDAP, Google és GitHub számlák.',
'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => 'Ha bekattintja a "Bejelentkezési ablak tiltása" jelölőnégyzetet, akkor a login ablakban megadott jelszó nem lesz figyelembe véve.',
- 'New remote user' => 'Új távoli felhasználó',
- 'New local user' => 'Új helyi felhasználó',
'Default task color' => 'A feladathoz rendelt alapszín',
'This feature does not work with all browsers.' => 'Ez a jellemző nem minden böngészőben működik.',
'There is no destination project available.' => 'Nincs ilyen cél projekt.',
@@ -852,7 +840,6 @@ return array(
'Owner' => 'Tulajdonos',
'Unread notifications' => 'Olvasatlan értesítések',
'Notification methods:' => 'Értesítési módszerek:',
- 'Import tasks from CSV file' => 'Feladatok beolvasása CSV fájlból',
'Unable to read your file' => 'A fájl nem olvasható',
'%d task(s) have been imported successfully.' => '%d feladat sikeresen feldolgozva.',
'Nothing have been imported!' => 'Nem történt beolvasás!',
@@ -980,7 +967,6 @@ return array(
'Project owner: ' => 'A projekt tulajdonosa: ',
'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => 'A projekt azonosító opcionális, és kötelezően alfanumerikus karakterekből áll, pl: MYPROJECT.',
'Project owner' => 'Projekt tulajdonos',
- 'Those dates are useful for the project Gantt chart.' => 'Ezek a dátumok a projekt Gantt diagramjához hasznosak.',
'Private projects do not have users and groups management.' => 'A privát projektekhez nem tartozik felhasználó kezelés és csoport kezelés.',
'There is no project member.' => 'A projektnek nincs tagja.',
'Priority' => 'Prioritás',
@@ -1037,7 +1023,6 @@ return array(
'Started:' => 'Elindult:',
'Moved:' => 'Elmozgatva:',
'Task #%d' => '#%d. feladat',
- 'Date and time format' => 'Dátum és idő formátum',
'Time format' => 'Idő formátum',
'Start date: ' => 'Kezdő datum: ',
'End date: ' => 'Vég dátum: ',
@@ -1051,9 +1036,7 @@ return array(
'User disabled successfully.' => 'A felhaszáló sikeresen le lett tiltva.',
'Unable to disable this user.' => 'Nem sikerült a felhasználó letiltása.',
'All files have been uploaded successfully.' => 'Az összes fájl sikeresen feltöltődött.',
- 'View uploaded files' => 'A feltöltött fájlok megtekintése',
'The maximum allowed file size is %sB.' => 'A fájl max. megengedett mérete %s bájt',
- 'Choose files again' => 'Válasszon újból fájlt',
'Drag and drop your files here' => 'Fogdd-és-vidd módszerrel dobja ide a fájlt',
'choose files' => 'válasszon fájlt',
'View profile' => 'Profil megtekintés',
@@ -1163,7 +1146,6 @@ return array(
// 'Email sender address' => '',
// 'Email transport' => '',
// 'Webhook token' => '',
- // 'Imports' => '',
// 'Project tags management' => '',
// 'Tag created successfully.' => '',
// 'Unable to create this tag.' => '',
@@ -1210,8 +1192,6 @@ return array(
// 'Activity stream for %s' => '',
// 'Calendar for %s' => '',
// 'Notifications for %s' => '',
- // 'Subtasks export' => '',
- // 'Tasks exportation' => '',
// 'Assign a color when the task is moved to a specific swimlane' => '',
// 'Assign a priority when the task is moved to a specific swimlane' => '',
// 'User unlocked successfully.' => '',
@@ -1277,4 +1257,61 @@ return array(
// 'This field is required' => '',
// 'Moving a task is not permitted' => '',
// 'This value must be in the range %d to %d' => '',
+ // 'You are not allowed to move this task.' => '',
+ // 'API User Access' => '',
+ // 'Preview' => '',
+ // 'Write' => '',
+ // 'Write your text in Markdown' => '',
+ // 'New External Task: %s' => '',
+ // 'No personal API access token registered.' => '',
+ // 'Your personal API access token is "%s"' => '',
+ // 'Remove your token' => '',
+ // 'Generate a new token' => '',
+ // 'Showing %d-%d of %d' => '',
+ // 'Outgoing Emails' => '',
+ // 'Add or change currency rate' => '',
+ // 'Reference currency: %s' => '',
+ // 'Add custom filters' => '',
+ // 'Export' => '',
+ // 'Add link label' => '',
+ // 'Incompatible Plugins' => '',
+ // 'Compatibility' => '',
+ // 'Permissions and ownership' => '',
+ // 'Priorities' => '',
+ // 'Close this window' => '',
+ // 'Unable to upload this file.' => '',
+ // 'Import tasks' => '',
+ // 'Choose a project' => '',
+ // 'Profile' => '',
+ // 'Application role' => '',
+ // '%d invitations were sent.' => '',
+ // '%d invitation was sent.' => '',
+ // 'Unable to create this user.' => '',
+ // 'Kanboard Invitation' => '',
+ // 'Visible on dashboard' => '',
+ // 'Created at:' => '',
+ // 'Updated at:' => '',
+ // 'There is no custom filter.' => '',
+ // 'New User' => '',
+ // 'Authentication' => '',
+ // 'If checked, this user will use a third-party system for authentication.' => '',
+ // 'The password is necessary only for local users.' => '',
+ // 'You have been invited to register on Kanboard.' => '',
+ // 'Click here to join your team' => '',
+ // 'Invite people' => '',
+ // 'Emails' => '',
+ // 'Enter one email address by line.' => '',
+ // 'Add these people to this project' => '',
+ // 'Add this person to this project' => '',
+ // 'Sign-up' => '',
+ // 'Credentials' => '',
+ // 'New user' => '',
+ // 'This username is already taken' => '',
+ // 'A link to reset your password has been sent by email.' => '',
+ // 'Your profile must have a valid email address.' => '',
+ // 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
+ // 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
+ // 'The email configuration has been disabled by the administrator.' => '',
);
diff --git a/app/Locale/id_ID/translations.php b/app/Locale/id_ID/translations.php
index ce52d328..78b15e98 100644
--- a/app/Locale/id_ID/translations.php
+++ b/app/Locale/id_ID/translations.php
@@ -5,7 +5,7 @@ return array(
'number.thousands_separator' => ' ',
'None' => 'Tidak satupun',
'edit' => 'modifikasi',
- 'Edit' => 'Modifikasi',
+ 'Edit' => 'Edit',
'remove' => 'hapus',
'Remove' => 'Hapus',
'Yes' => 'Ya',
@@ -30,11 +30,11 @@ return array(
'Amber' => 'Amber',
'Save' => 'Simpan',
'Login' => 'Masuk',
- 'Official website:' => 'Situs resmi :',
+ 'Official website:' => 'Situs resmi:',
'Unassigned' => 'Belum ditugaskan',
'View this task' => 'Lihat tugas ini',
'Remove user' => 'Hapus pengguna',
- 'Do you really want to remove this user: "%s"?' => 'Anda yakin akan menghapus pengguna ini : « %s » ?',
+ 'Do you really want to remove this user: "%s"?' => 'Anda yakin mau menghapus pengguna ini: "%s"?',
'All users' => 'Semua pengguna',
'Username' => 'Nama pengguna',
'Password' => 'Kata sandi',
@@ -44,10 +44,10 @@ return array(
'No user' => 'Tidak ada pengguna',
'Forbidden' => 'Terlarang',
'Access Forbidden' => 'Akses Dilarang',
- 'Edit user' => 'Rubah Pengguna',
+ 'Edit user' => 'Edit pengguna',
'Logout' => 'Keluar',
- 'Bad username or password' => 'Nama pengguna atau kata sandri buruk',
- 'Edit project' => 'Rubah proyek',
+ 'Bad username or password' => 'Nama pengguna atau password salah',
+ 'Edit project' => 'Edit proyek',
'Name' => 'Nama',
'Projects' => 'Proyek',
'No project' => 'Tidak ada proyek',
@@ -60,31 +60,29 @@ return array(
'Active' => 'Aktif',
'%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',
- 'Edit board' => 'Rubah papan',
+ 'Unable to update this board.' => 'Tidak dapat memperbarui papan ini',
'Disable' => 'Nonaktifkan',
'Enable' => 'Aktifkan',
- 'New project' => 'Proyek Baru',
- 'Do you really want to remove this project: "%s"?' => 'Apakah anda yakin akan menghapus proyek ini : « %s » ?',
+ 'New project' => 'Proyek baru',
+ 'Do you really want to remove this project: "%s"?' => 'Apakah Anda yakin mau menghapus proyek ini: "%s"?',
'Remove project' => 'Hapus proyek',
- 'Edit the board for "%s"' => 'Rubah papan untuk « %s »',
+ 'Edit the board for "%s"' => 'Edit papan untuk "%s"',
'Add a new column' => 'Tambah kolom baru',
'Title' => 'Judul',
- 'Assigned to %s' => 'Ditugaskan ke %s',
+ 'Assigned to %s' => 'Ditugaskan kepada %s',
'Remove a column' => 'Hapus kolom',
- 'Remove a column from a board' => 'Hapus kolom dari papan',
'Unable to remove this column.' => 'Tidak dapat menghapus kolom ini.',
- 'Do you really want to remove this column: "%s"?' => 'Apakah anda yakin akan menghapus kolom ini : « %s » ?',
- 'This action will REMOVE ALL TASKS associated to this column!' => 'tindakan ini akan MENGHAPUS SEMUA TUGAS yang terkait dengan kolom ini!',
+ 'Do you really want to remove this column: "%s"?' => 'Apakah Anda yakin mau menghapus kolom ini: "%s"?',
+ 'This action will REMOVE ALL TASKS associated to this column!' => 'Tindakan ini akan MENGHAPUS SEMUA TUGAS yang berkaitan dengan kolom ini!',
'Settings' => 'Pengaturan',
'Application settings' => 'Pengaturan aplikasi',
'Language' => 'Bahasa',
- 'Webhook token:' => 'Token webhook :',
- 'API token:' => 'Token API :',
- 'Database size:' => 'Ukuran basis data :',
- 'Download the database' => 'Unduh basis data',
- 'Optimize the database' => 'Optimasi basis data',
- '(VACUUM command)' => '(perintah VACUUM)',
+ 'Webhook token:' => 'Token Webhook:',
+ 'API token:' => 'Token API:',
+ 'Database size:' => 'Ukuran database:',
+ 'Download the database' => 'Unduh database',
+ 'Optimize the database' => 'Optimasi database',
+ '(VACUUM command)' => '(Perintah VACUUM)',
'(Gzip compressed Sqlite file)' => '(File Sqlite yang terkompress Gzip)',
'Close a task' => 'Tutup tugas',
'Column' => 'Kolom',
@@ -93,38 +91,38 @@ return array(
'Create another task' => 'Buat tugas lain',
'New task' => 'Tugas baru',
'Open a task' => 'Buka tugas',
- 'Do you really want to open this task: "%s"?' => 'Apakah anda yakin akan membuka tugas ini : « %s » ?',
+ 'Do you really want to open this task: "%s"?' => 'Apakah Anda yakin mau membuka tugas ini: "%s"?',
'Back to the board' => 'Kembali ke papan',
'There is nobody assigned' => 'Tidak ada orang yand ditugaskan',
- 'Column on the board:' => 'Kolom di dalam papan : ',
+ 'Column on the board:' => 'Kolom di dalam papan:',
'Close this task' => 'Tutup tugas ini',
'Open this task' => 'Buka tugas ini',
'There is no description.' => 'Tidak ada deskripsi.',
'Add a new task' => 'Tambah tugas baru',
- 'The username is required' => 'nama pengguna diperlukan',
+ 'The username is required' => 'Nama pengguna dibutuhkan',
'The maximum length is %d characters' => 'Panjang maksimum adalah %d karakter',
'The minimum length is %d characters' => 'Panjang minimum adalah %d karakter',
- 'The password is required' => 'Kata sandi diperlukan',
+ 'The password is required' => 'Password dibutuhkan',
'This value must be an integer' => 'Nilai ini harus integer',
'The username must be unique' => 'Nama pengguna harus unik',
- 'The user id is required' => 'Id Pengguna diperlukan',
- 'Passwords don\'t match' => 'Kata sandi tidak cocok',
+ 'The user id is required' => 'ID pengguna diperlukan',
+ 'Passwords don\'t match' => 'Password tidak cocok',
'The confirmation is required' => 'Konfirmasi diperlukan',
'The project is required' => 'Proyek diperlukan',
- 'The id is required' => 'Id diperlukan',
- 'The project id is required' => 'Id proyek diperlukan',
+ 'The id is required' => 'ID diperlukan',
+ 'The project id is required' => 'ID proyek diperlukan',
'The project name is required' => 'Nama proyek diperlukan',
'The title is required' => 'Judul diperlukan',
'Settings saved successfully.' => 'Pengaturan berhasil disimpan.',
'Unable to save your settings.' => 'Tidak dapat menyimpan pengaturan anda.',
- 'Database optimization done.' => 'Optimasi basis data selesai.',
+ 'Database optimization done.' => 'Optimasi database selesai.',
'Your project have been created successfully.' => 'Proyek anda berhasil dibuat.',
'Unable to create your project.' => 'Tidak dapat membuat proyek anda.',
- 'Project updated successfully.' => 'Proyek berhasil diperbaharui.',
- 'Unable to update this project.' => 'Tidak dapat memperbaharui proyek ini.',
+ 'Project updated successfully.' => 'Proyek berhasil diperbarui.',
+ 'Unable to update this project.' => 'Tidak dapat memperbarui proyek ini.',
'Unable to remove this project.' => 'Tidak dapat menghapus proyek ini.',
'Project removed successfully.' => 'Proyek berhasil dihapus.',
- 'Project activated successfully.' => 'Proyek berhasil diaktivasi.',
+ 'Project activated successfully.' => 'Proyek berhasil diaktifkan.',
'Unable to activate this project.' => 'Tidak dapat mengaktifkan proyek ini.',
'Project disabled successfully.' => 'Proyek berhasil dinonaktifkan.',
'Unable to disable this project.' => 'Tidak dapat menonaktifkan proyek ini.',
@@ -132,61 +130,59 @@ return array(
'Task opened successfully.' => 'Tugas berhasil dibuka.',
'Unable to close this task.' => 'Tidak dapat menutup tugas ini.',
'Task closed successfully.' => 'Tugas berhasil ditutup.',
- 'Unable to update your task.' => 'Tidak dapat memperbaharui tugas ini.',
- 'Task updated successfully.' => 'Tugas berhasil diperbaharui.',
+ 'Unable to update your task.' => 'Tidak dapat memperbarui tugas ini.',
+ 'Task updated successfully.' => 'Tugas berhasil diperbarui.',
'Unable to create your task.' => 'Tidak dapat membuat tugas anda.',
'Task created successfully.' => 'Tugas berhasil dibuat.',
'User created successfully.' => 'Pengguna berhasil dibuat.',
- 'Unable to create your user.' => 'Tidak dapat membuat pengguna anda.',
- 'User updated successfully.' => 'Pengguna berhasil diperbaharui.',
- 'Unable to update your user.' => 'Tidak dapat memperbaharui pengguna anda.',
- 'User removed successfully.' => 'pengguna berhasil dihapus.',
+ 'Unable to create your user.' => 'Tidak dapat membuat pengguna Anda.',
+ 'User updated successfully.' => 'Pengguna berhasil diperbarui.',
+ 'Unable to update your user.' => 'Tidak dapat memperbarui pengguna anda.',
+ 'User removed successfully.' => 'Pengguna berhasil dihapus.',
'Unable to remove this user.' => 'Tidak dapat menghapus pengguna ini.',
'Board updated successfully.' => 'Papan berhasil diperbaharui.',
'Ready' => 'Siap',
'Backlog' => 'Tertunda',
'Work in progress' => 'Sedang dalam pengerjaan',
'Done' => 'Selesai',
- 'Application version:' => 'Versi aplikasi :',
- 'Id' => 'Id.',
+ 'Application version:' => 'Versi aplikasi:',
+ 'Id' => 'ID',
'%d closed tasks' => '%d tugas yang ditutup',
'No task for this project' => 'Tidak ada tugas dalam proyek ini',
'Public link' => 'Tautan publik',
'Timezone' => 'Zona waktu',
- 'Sorry, I didn\'t find this information in my database!' => 'Maaf, saya tidak menemukan informasi ini dalam basis data saya !',
+ 'Sorry, I didn\'t find this information in my database!' => 'Maaf, saya tidak dapat menemukan informasi ini dalam database saya!',
'Page not found' => 'Halaman tidak ditemukan',
'Complexity' => 'Kompleksitas',
- 'Task limit' => 'Batas tugas.',
+ 'Task limit' => 'Batas tugas',
'Task count' => 'Jumlah tugas',
'User' => 'Pengguna',
'Comments' => 'Komentar',
- 'Leave a comment' => 'Tinggalkan komentar',
- 'Comment is required' => 'Komentar diperlukan',
- 'Leave a description' => 'Tinggalkan deskripsi',
+ 'Comment is required' => 'Komentar dibutuhkan',
'Comment added successfully.' => 'Komentar berhasil ditambahkan.',
- 'Unable to create your comment.' => 'Tidak dapat menambahkan komentar anda.',
+ 'Unable to create your comment.' => 'Tidak dapat menambahkan komentar Anda.',
'Due Date' => 'Batas Tanggal Terakhir',
- 'Invalid date' => 'Tanggal tidak valid',
+ 'Invalid date' => 'Tanggal tidak sesuai',
'Automatic actions' => 'Tindakan otomatis',
- 'Your automatic action have been created successfully.' => 'Tindakan otomatis anda berhasil dibuat.',
- 'Unable to create your automatic action.' => 'Tidak dapat membuat tindakan otomatis anda.',
+ 'Your automatic action have been created successfully.' => 'Tindakan otomatis Anda berhasil dibuat.',
+ 'Unable to create your automatic action.' => 'Tidak dapat membuat tindakan otomatis Anda.',
'Remove an action' => 'Hapus tindakan',
- 'Unable to remove this action.' => 'Tidak dapat menghapus tindakan ini',
+ '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 »',
+ 'Automatic actions for the project "%s"' => 'Tindakan otomatis untuk proyek ini "%s"',
'Add an action' => 'Tambah tindakan',
'Event name' => 'Nama acara',
'Action name' => 'Nama tindakan',
'Action parameters' => 'Parameter tindakan',
'Action' => 'Tindakan',
'Event' => 'Acara',
- 'When the selected event occurs execute the corresponding action.' => 'Ketika acara yang dipilih terjadi, melakukan tindakan yang sesuai.',
+ 'When the selected event occurs execute the corresponding action.' => 'Ketika acara yang dipilih terjadi, tindakan yang berhubungan dengan acara akan dieksekusi.',
'Next step' => 'Langkah selanjutnya',
'Define action parameters' => 'Definisi parameter tindakan',
- 'Do you really want to remove this action: "%s"?' => 'Apakah anda yakin akan menghapus tindakan ini « %s » ?',
+ 'Do you really want to remove this action: "%s"?' => 'Apakah Anda yakin mau menghapus tindakan ini: "%s"?',
'Remove an automatic action' => 'Hapus tindakan otomatis',
- 'Assign the task to a specific user' => 'Menetapkan tugas untuk pengguna tertentu',
- 'Assign the task to the person who does the action' => 'Memberikan tugas untuk orang yang melakukan tindakan',
+ 'Assign the task to a specific user' => 'Berikan tugas pada pengguna tertentu',
+ 'Assign the task to the person who does the action' => 'Berikan tugas pada orang yang melakukan tindakan',
'Duplicate the task to another project' => 'Duplikasi tugas ke proyek lain',
'Move a task to another column' => 'Pindahkan tugas ke kolom lain',
'Task modification' => 'Modifikasi tugas',
@@ -196,65 +192,64 @@ return array(
'Column title' => 'Judul kolom',
'Position' => 'Posisi',
'Duplicate to another project' => 'Duplikasi ke proyek lain',
- 'Duplicate' => 'Duplikasi',
+ 'Duplicate' => 'Duplikat',
'link' => 'tautan',
- 'Comment updated successfully.' => 'Komentar berhasil diperbaharui.',
- 'Unable to update your comment.' => 'Tidak dapat memperbaharui komentar anda.',
+ 'Comment updated successfully.' => 'Komentar berhasil diperbarui.',
+ 'Unable to update your comment.' => 'Tidak dapat memperbarui komentar Anda.',
'Remove a comment' => 'Hapus komentar',
'Comment removed successfully.' => 'Komentar berhasil dihapus.',
'Unable to remove this comment.' => 'Tidak dapat menghapus komentar ini.',
- 'Do you really want to remove this comment?' => 'Apakah anda yakin akan menghapus komentar ini ?',
- 'Current password for the user "%s"' => 'Kata sandi saat ini untuk pengguna « %s »',
- 'The current password is required' => 'Kata sandi saat ini diperlukan',
- 'Wrong password' => 'Kata sandi salah',
+ 'Do you really want to remove this comment?' => 'Apakah Anda yakin mau menghapus komentar ini?',
+ 'Current password for the user "%s"' => 'Password saat ini untuk pengguna "%s"',
+ 'The current password is required' => 'Password saat ini diperlukan',
+ 'Wrong password' => 'Password salah',
'Unknown' => 'Tidak diketahui',
'Last logins' => 'Masuk terakhir',
'Login date' => 'Tanggal masuk',
'Authentication method' => 'Metode otentifikasi',
'IP address' => 'Alamat IP',
- 'User agent' => 'Agen Pengguna',
- 'Persistent connections' => 'Koneksi persisten',
+ 'User agent' => 'Agen pengguna',
+ 'Persistent connections' => 'Koneksi tetap',
'No session.' => 'Tidak ada sesi.',
'Expiration date' => 'Tanggal kadaluarsa',
'Remember Me' => 'Ingat Saya',
- 'Creation date' => 'Tanggal dibuat',
+ 'Creation date' => 'Tanggal pembuatan',
'Everybody' => 'Semua orang',
'Open' => 'Terbuka',
'Closed' => 'Ditutup',
'Search' => 'Cari',
'Nothing found.' => 'Tidak ditemukan.',
'Due date' => 'Batas tanggal terakhir',
- 'Others formats accepted: %s and %s' => 'Format lain yang didukung : %s et %s',
'Description' => 'Deskripsi',
'%d comments' => '%d komentar',
'%d comment' => '%d komentar',
- 'Email address invalid' => 'Alamat email tidak valid',
- 'Your external account is not linked anymore to your profile.' => 'Akun eksternal anda tidak lagi terhubung ke profil anda.',
- 'Unable to unlink your external account.' => 'Tidak dapat memutuskan akun eksternal anda.',
+ 'Email address invalid' => 'Alamat email tidak sesuai',
+ 'Your external account is not linked anymore to your profile.' => 'Akun eksternal Anda tidak lagi terhubung ke profil anda.',
+ 'Unable to unlink your external account.' => 'Tidak dapat memutuskan akun eksternal Anda.',
'External authentication failed' => 'Otentifikasi eksternal gagal',
- 'Your external account is linked to your profile successfully.' => 'Akun eksternal anda berhasil dihubungkan ke profil anda.',
+ 'Your external account is linked to your profile successfully.' => 'Akun eksternal Anda berhasil dihubungkan ke profil anda.',
'Email' => 'Email',
'Task removed successfully.' => 'Tugas berhasil dihapus.',
'Unable to remove this task.' => 'Tidak dapat menghapus tugas ini.',
'Remove a task' => 'Hapus tugas',
- 'Do you really want to remove this task: "%s"?' => 'Apakah anda yakin akan menghapus tugas ini « %s » ?',
+ 'Do you really want to remove this task: "%s"?' => 'Apakah Anda yakin mau menghapus tugas ini: "%s"?',
'Assign automatically a color based on a category' => 'Otomatis menetapkan warna berdasarkan kategori',
'Assign automatically a category based on a color' => 'Otomatis menetapkan kategori berdasarkan warna',
- 'Task creation or modification' => 'Tugas dibuat atau di mofifikasi',
+ 'Task creation or modification' => 'Tugas dibuat atau di modifikasi',
'Category' => 'Kategori',
- 'Category:' => 'Kategori :',
+ 'Category:' => 'Kategori:',
'Categories' => 'Kategori',
- 'Your category have been created successfully.' => 'Kategori anda berhasil dibuat.',
- 'Unable to create your category.' => 'Tidak dapat membuat kategori anda.',
- 'Your category have been updated successfully.' => 'Kategori anda berhasil diperbaharui.',
- 'Unable to update your category.' => 'Tidak dapat memperbaharui kategori anda.',
+ 'Your category have been created successfully.' => 'Kategori Anda berhasil dibuat.',
+ 'Unable to create your category.' => 'Tidak dapat membuat kategori Anda.',
+ 'Your category have been updated successfully.' => 'Kategori Anda berhasil diperbarui.',
+ 'Unable to update your category.' => 'Tidak dapat memperbarui kategori Anda.',
'Remove a category' => 'Hapus kategori',
'Category removed successfully.' => 'Kategori berhasil dihapus.',
'Unable to remove this category.' => 'Tidak dapat menghapus kategori ini.',
- 'Category modification for the project "%s"' => 'Modifikasi kategori untuk proyek « %s »',
+ 'Category modification for the project "%s"' => 'Modifikasi kategori untuk proyek "%s"',
'Category Name' => 'Nama Kategori',
'Add a new category' => 'Tambah kategori baru',
- 'Do you really want to remove this category: "%s"?' => 'Apakah anda yakin akan menghapus kategori ini « %s » ?',
+ 'Do you really want to remove this category: "%s"?' => 'Apakah Anda yakin mau menghapus kategori ini: "%s"?',
'All categories' => 'Semua kategori',
'No category' => 'Tidak ada kategori',
'The name is required' => 'Nama diperlukan',
@@ -262,35 +257,35 @@ return array(
'Unable to remove this file.' => 'Tidak dapat menghapus berkas ini.',
'File removed successfully.' => 'Berkas berhasil dihapus.',
'Attach a document' => 'Lampirkan dokumen',
- 'Do you really want to remove this file: "%s"?' => 'Apakah anda yakin akan menghapus berkas ini « %s » ?',
+ 'Do you really want to remove this file: "%s"?' => 'Apakah Anda yakin akan menghapus berkas ini: "%s"?',
'Attachments' => 'Lampiran',
- 'Edit the task' => 'Modifikasi tugas',
+ 'Edit the task' => 'Edit tugas',
'Add a comment' => 'Tambahkan komentar',
- 'Edit a comment' => 'Modifikasi komentar',
+ 'Edit a comment' => 'Edit komentar',
'Summary' => 'Ringkasan',
'Time tracking' => 'Pelacakan waktu',
- 'Estimate:' => 'Estimasi :',
+ 'Estimate:' => 'Estimasi:',
'Spent:' => 'Menghabiskan:',
- 'Do you really want to remove this sub-task?' => 'Apakah anda yakin akan menghapus sub-tugas ini ?',
+ 'Do you really want to remove this sub-task?' => 'Apakah Anda yakin mau menghapus sub-tugas ini?',
'Remaining:' => 'Tersisa:',
'hours' => 'jam',
- 'spent' => 'menghabiskan',
+ 'spent' => 'dihabiskan',
'estimated' => 'perkiraan',
'Sub-Tasks' => 'Sub-tugas',
'Add a sub-task' => 'Tambahkan sub-tugas',
'Original estimate' => 'Perkiraan semula',
'Create another sub-task' => 'Tambahkan sub-tugas lainnya',
'Time spent' => 'Waktu yang dihabiskan',
- 'Edit a sub-task' => 'Modifikasi sub-tugas',
+ 'Edit a sub-task' => 'Edit sub-tugas',
'Remove a sub-task' => 'Hapus sub-tugas',
- 'The time must be a numeric value' => 'Waktu harus berisikan numerik',
+ 'The time must be a numeric value' => 'Waktu harus berupa angka',
'Todo' => 'Yang harus dilakukan',
- 'In progress' => 'Sedang proses',
+ 'In progress' => 'Dalam proses',
'Sub-task removed successfully.' => 'Sub-tugas berhasil dihapus.',
'Unable to remove this sub-task.' => 'Tidak dapat menghapus sub-tugas.',
- 'Sub-task updated successfully.' => 'Sub-tugas berhasil diperbaharui.',
- 'Unable to update your sub-task.' => 'Tidak dapat memperbaharui sub-tugas anda.',
- 'Unable to create your sub-task.' => 'Tidak dapat membuat sub-tugas anda.',
+ 'Sub-task updated successfully.' => 'Sub-tugas berhasil diperbarui.',
+ 'Unable to update your sub-task.' => 'Tidak dapat memperbarui sub-tugas Anda.',
+ 'Unable to create your sub-task.' => 'Tidak dapat membuat sub-tugas Anda.',
'Sub-task added successfully.' => 'Sub-tugas berhasil dibuat.',
'Maximum size: ' => 'Ukuran maksimum: ',
'Unable to upload the file.' => 'Tidak dapat mengunggah berkas.',
@@ -298,9 +293,8 @@ return array(
'Created by %s' => 'Dibuat oleh %s',
'Tasks Export' => 'Ekspor Tugas',
'Start Date' => 'Tanggal Mulai',
- 'End Date' => 'Tanggal Berakhir',
'Execute' => 'Eksekusi',
- 'Task Id' => 'Id Tugas',
+ 'Task Id' => 'ID Tugas',
'Creator' => 'Pembuat',
'Modification date' => 'Tanggal modifikasi',
'Completion date' => 'Tanggal penyelesaian',
@@ -308,19 +302,19 @@ return array(
'Project cloned successfully.' => 'Kloning proyek berhasil.',
'Unable to clone this project.' => 'Tidak dapat mengkloning proyek.',
'Enable email notifications' => 'Aktifkan pemberitahuan dari email',
- 'Task position:' => 'Posisi tugas :',
+ 'Task position:' => 'Posisi tugas:',
'The task #%d have been opened.' => 'Tugas #%d telah dibuka.',
'The task #%d have been closed.' => 'Tugas #%d telah ditutup.',
- 'Sub-task updated' => 'Sub-tugas diperbaharui',
- 'Title:' => 'Judul :',
- 'Status:' => 'Status :',
- 'Assignee:' => 'Ditugaskan ke :',
- 'Time tracking:' => 'Pelacakan waktu :',
+ 'Sub-task updated' => 'Sub-tugas diperbarui',
+ 'Title:' => 'Judul:',
+ 'Status:' => 'Status:',
+ 'Assignee:' => 'Ditugaskan ke:',
+ 'Time tracking:' => 'Pelacakan waktu:',
'New sub-task' => 'Sub-tugas baru',
- 'New attachment added "%s"' => 'Lampiran baru ditambahkan « %s »',
- 'New comment posted by %s' => 'Komentar baru ditambahkan oleh « %s »',
+ 'New attachment added "%s"' => 'Lampiran baru ditambahkan "%s"',
+ 'New comment posted by %s' => 'Komentar baru ditambahkan oleh %s',
'New comment' => 'Komentar baru',
- 'Comment updated' => 'Komentar diperbaharui',
+ 'Comment updated' => 'Komentar diperbarui',
'New subtask' => 'Sub-tugas baru',
'I want to receive notifications only for those projects:' => 'Saya ingin menerima pemberitahuan hanya untuk proyek-proyek yang dipilih :',
'view the task on Kanboard' => 'lihat tugas di Kanboard',
@@ -329,125 +323,125 @@ return array(
'Disable public access' => 'Nonaktifkan akses publik',
'Enable public access' => 'Aktifkan akses publik',
'Public access disabled' => 'Akses publik dinonaktifkan',
- 'Do you really want to disable this project: "%s"?' => 'Apakah anda yakin akan menonaktifkan proyek ini : « %s » ?',
- 'Do you really want to enable this project: "%s"?' => 'Apakah anda yakin akan mengaktifkan proyek ini : « %s » ?',
+ 'Do you really want to disable this project: "%s"?' => 'Apakah Anda yakin mau menonaktifkan proyek ini: "%s"?',
+ 'Do you really want to enable this project: "%s"?' => 'Apakah Anda yakin mau mengaktifkan proyek ini: "%s"?',
'Project activation' => 'Aktivasi proyek',
'Move the task to another project' => 'Pindahkan tugas ke proyek lain',
'Move to another project' => 'Pindahkan ke proyek lain',
- 'Do you really want to duplicate this task?' => 'Apakah anda yakin akan menduplikasi tugas ini ?',
+ 'Do you really want to duplicate this task?' => 'Apakah Anda yakin mau menduplikasi tugas ini?',
'Duplicate a task' => 'Duplikasi tugas',
'External accounts' => 'Akun eksternal',
'Account type' => 'Tipe akun',
'Local' => 'Lokal',
- 'Remote' => 'Jauh',
+ 'Remote' => 'Jarak Jauh',
'Enabled' => 'Aktif',
'Disabled' => 'Nonaktif',
- 'Username:' => 'Nama pengguna :',
- 'Name:' => 'Nama :',
- 'Email:' => 'Email :',
- 'Notifications:' => 'Pemberitahuan :',
+ // 'Login:' => '',
+ // 'Full Name:' => '',
+ 'Email:' => 'Email:',
+ 'Notifications:' => 'Pemberitahuan:',
'Notifications' => 'Pemberitahuan',
- 'Account type:' => 'Tipe akun :',
- 'Edit profile' => 'Modifikasi profil',
- 'Change password' => 'Rubah kata sandri',
- 'Password modification' => 'Modifikasi kata sandi',
+ 'Account type:' => 'Tipe akun:',
+ 'Edit profile' => 'Edit profil',
+ 'Change password' => 'Ganti password',
+ 'Password modification' => 'Modifikasi password',
'External authentications' => 'Otentifikasi eksternal',
'Never connected.' => 'Tidak pernah terhubung.',
'No external authentication enabled.' => 'Tidak ada otentifikasi eksternal yang aktif.',
- 'Password modified successfully.' => 'Kata sandi berhasil dimodifikasi.',
- 'Unable to change the password.' => 'Tidak dapat merubah kata sandir.',
- 'Change category' => 'Rubah kategori',
- '%s updated the task %s' => '%s memperbaharui tugas %s',
+ 'Password modified successfully.' => 'Password berhasil dimodifikasi.',
+ 'Unable to change the password.' => 'Tidak dapat mengganti kata sandi.',
+ 'Change category' => 'Ganti kategori',
+ '%s updated the task %s' => '%s memperbarui tugas %s',
'%s opened the task %s' => '%s membuka tugas %s',
- '%s moved the task %s to the position #%d in the column "%s"' => '%s memindahkan tugas %s ke posisi n°%d dalam kolom « %s »',
- '%s moved the task %s to the column "%s"' => '%s memindahkan tugas %s ke kolom « %s »',
+ '%s moved the task %s to the position #%d in the column "%s"' => '%s memindahkan tugas %s ke posisi #%d dalam kolom "%s"',
+ '%s moved the task %s to the column "%s"' => '%s memindahkan tugas %s ke kolom "%s"',
'%s created the task %s' => '%s membuat tugas %s',
'%s closed the task %s' => '%s menutup tugas %s',
- '%s created a subtask for the task %s' => '%s membuat subtugas untuk tugas %s',
- '%s updated a subtask for the task %s' => '%s memperbaharui subtugas untuk tugas %s',
- 'Assigned to %s with an estimate of %s/%sh' => 'Ditugaskan untuk %s dengan perkiraan %s/%sh',
+ '%s created a subtask for the task %s' => '%s membuat sub-tugas untuk tugas %s',
+ '%s updated a subtask for the task %s' => '%s memperbarui sub-tugas untuk tugas %s',
+ 'Assigned to %s with an estimate of %s/%sh' => 'Ditugaskan pada %s dengan perkiraan %s/%sh',
'Not assigned, estimate of %sh' => 'Tidak ada yang ditugaskan, perkiraan %sh',
- '%s updated a comment on the task %s' => '%s memperbaharui komentar pada tugas %s',
+ '%s updated a comment on the task %s' => '%s memperbarui komentar pada tugas %s',
'%s commented the task %s' => '%s memberikan komentar pada tugas %s',
'%s\'s activity' => 'Aktifitas dari %s',
- 'RSS feed' => 'RSS feed',
- '%s updated a comment on the task #%d' => '%s memperbaharui komentar pada tugas n°%d',
- '%s commented on the task #%d' => '%s memberikan komentar pada tugas n°%d',
- '%s updated a subtask for the task #%d' => '%s memperbaharui subtugas untuk tugas n°%d',
- '%s created a subtask for the task #%d' => '%s membuat subtugas untuk tugas n°%d',
- '%s updated the task #%d' => '%s memperbaharui tugas n°%d',
- '%s created the task #%d' => '%s membuat tugas n°%d',
- '%s closed the task #%d' => '%s menutup tugas n°%d',
- '%s opened the task #%d' => '%s membuka tugas n°%d',
+ 'RSS feed' => 'Umpan RSS',
+ '%s updated a comment on the task #%d' => '%s memperbarui komentar pada tugas #%d',
+ '%s commented on the task #%d' => '%s memberikan komentar pada tugas #%d',
+ '%s updated a subtask for the task #%d' => '%s memperbarui sub-tugas untuk tugas #%d',
+ '%s created a subtask for the task #%d' => '%s membuat sub-tugas untuk tugas #%d',
+ '%s updated the task #%d' => '%s memperbarui tugas #%d',
+ '%s created the task #%d' => '%s membuat tugas #%d',
+ '%s closed the task #%d' => '%s menutup tugas #%d',
+ '%s opened the task #%d' => '%s membuka tugas #%d',
'Activity' => 'Aktifitas',
- 'Default values are "%s"' => 'Standar nilai adalah« %s »',
+ 'Default values are "%s"' => 'Nilai default adalah "%s"',
'Default columns for new projects (Comma-separated)' => 'Kolom default untuk proyek baru (dipisahkan dengan koma)',
- 'Task assignee change' => 'Mengubah orang ditugaskan untuk tugas',
- '%s changed the assignee of the task #%d to %s' => '%s rubah orang yang ditugaskan dari tugas n%d ke %s',
- '%s changed the assignee of the task %s to %s' => '%s mengubah orang yang ditugaskan dari tugas %s ke %s',
- 'New password for the user "%s"' => 'Kata sandi baru untuk pengguna « %s »',
+ 'Task assignee change' => 'Ganti orang yang ditugaskan',
+ '%s changed the assignee of the task #%d to %s' => '%s mengganti orang yang ditugaskan dari tugas #%d ke %s',
+ '%s changed the assignee of the task %s to %s' => '%s mengganti orang yang ditugaskan dari tugas %s ke %s',
+ 'New password for the user "%s"' => 'Password baru untuk pengguna "%s"',
'Choose an event' => 'Pilih acara',
- 'Create a task from an external provider' => 'Buat tugas dari pemasok eksternal',
- 'Change the assignee based on an external username' => 'Rubah penugasan berdasarkan nama pengguna eksternal',
- 'Change the category based on an external label' => 'Rubah kategori berdasarkan label eksternal',
+ 'Create a task from an external provider' => 'Buat tugas dari penyedia eksternal',
+ 'Change the assignee based on an external username' => 'Ganti penugasan berdasarkan nama pengguna eksternal',
+ 'Change the category based on an external label' => 'Ganti kategori berdasarkan label eksternal',
'Reference' => 'Referensi',
'Label' => 'Label',
- 'Database' => 'Basis data',
+ 'Database' => 'Database',
'About' => 'Tentang',
- 'Database driver:' => 'Driver basis data :',
+ 'Database driver:' => 'Driver database:',
'Board settings' => 'Pengaturan papan',
- 'Webhook settings' => 'Pengaturan webhook',
- 'Reset token' => 'Mereset token',
+ 'Webhook settings' => 'Pengaturan Webhook',
+ 'Reset token' => 'Reset token',
'API endpoint:' => 'API endpoint :',
'Refresh interval for private board' => 'Interval pembaruan untuk papan pribadi',
'Refresh interval for public board' => 'Interval pembaruan untuk papan publik',
- 'Task highlight period' => 'Periode puncak tugas',
- 'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => 'Periode (dalam detik) untuk mempertimbangkan tugas yang baru dimodifikasi (0 untuk menonaktifkan, standar 2 hari)',
- 'Frequency in second (60 seconds by default)' => 'Frequensi dalam detik (standar 60 detik)',
- 'Frequency in second (0 to disable this feature, 10 seconds by default)' => 'Frequensi dalam detik (0 untuk menonaktifkan fitur ini, standar 10 detik)',
+ 'Task highlight period' => 'Periode penyorotan tugas',
+ 'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => 'Periode (dalam detik) untuk mempertimbangkan tugas yang baru dimodifikasi (0 untuk menonaktifkan, default 2 hari)',
+ 'Frequency in second (60 seconds by default)' => 'Frekuensi dalam detik (default 60 detik)',
+ 'Frequency in second (0 to disable this feature, 10 seconds by default)' => 'Frekuensi dalam detik (0 untuk menonaktifkan fitur ini, default 10 detik)',
'Application URL' => 'URL Aplikasi',
'Token regenerated.' => 'Token diregenerasi.',
'Date format' => 'Format tanggal',
- 'ISO format is always accepted, example: "%s" and "%s"' => 'Format ISO selalu diterima, contoh : « %s » et « %s »',
+ 'ISO format is always accepted, example: "%s" and "%s"' => 'Format ISO selalu diterima, contoh: "%s" dan "%s"',
'New private project' => 'Proyek pribadi baru',
- 'This project is private' => 'Proyek ini adalah pribadi',
+ 'This project is private' => 'Proyek ini pribadi',
'Add' => 'Tambah',
'Start date' => 'Tanggal mulai',
'Time estimated' => 'Perkiraan waktu',
- 'There is nothing assigned to you.' => 'Tidak ada yang diberikan kepada anda.',
+ 'There is nothing assigned to you.' => 'Tidak ada tugas yang diberikan pada Anda.',
'My tasks' => 'Tugas saya',
'Activity stream' => 'Arus aktifitas',
'Dashboard' => 'Dasbor',
'Confirmation' => 'Konfirmasi',
- 'Allow everybody to access to this project' => 'Memungkinkan semua orang untuk mengakses proyek ini',
+ 'Allow everybody to access to this project' => 'Izinkan semua orang untuk mengakses proyek ini',
'Everybody have access to this project.' => 'Semua orang mendapat akses untuk proyek ini.',
'Webhooks' => 'Webhooks',
'API' => 'API',
- 'Create a comment from an external provider' => 'Buat komentar dari pemasok eksternal',
+ 'Create a comment from an external provider' => 'Buat komentar dari penyedia eksternal',
'Project management' => 'Manajemen proyek',
'My projects' => 'Proyek saya',
'Columns' => 'Kolom',
'Task' => 'Tugas',
- 'Your are not member of any project.' => 'Anda bukan anggota dari setiap proyek.',
+ 'Your are not member of any project.' => 'Anda bukan anggota dari proyek apapun.',
'Percentage' => 'Persentasi',
'Number of tasks' => 'Jumlah dari tugas',
'Task distribution' => 'Pembagian tugas',
- 'Analytics' => 'Analitis',
- 'Subtask' => 'Subtugas',
- 'My subtasks' => 'Subtugas saya',
+ 'Analytics' => 'Analitik',
+ 'Subtask' => 'Sub-tugas',
+ 'My subtasks' => 'Sub-tugas saya',
'User repartition' => 'Partisi ulang pengguna',
- 'Clone this project' => 'Gandakan proyek ini',
+ 'Clone this project' => 'Klon proyek ini',
'Column removed successfully.' => 'Kolom berhasil dihapus.',
'Not enough data to show the graph.' => 'Tidak cukup data untuk menampilkan grafik.',
'Previous' => 'Sebelumnya',
- 'The id must be an integer' => 'Id harus integer',
- 'The project id must be an integer' => 'Id proyek harus integer',
+ 'The id must be an integer' => 'ID harus integer',
+ 'The project id must be an integer' => 'ID proyek harus integer',
'The status must be an integer' => 'Status harus integer',
- 'The subtask id is required' => 'Id subtugas diperlukan',
- 'The subtask id must be an integer' => 'Id subtugas harus integer',
- 'The task id is required' => 'Id tugas diperlukan',
- 'The task id must be an integer' => 'Id tugas harus integer',
- 'The user id must be an integer' => 'Id user harus integer',
+ 'The subtask id is required' => 'ID sub-tugas diperlukan',
+ 'The subtask id must be an integer' => 'ID sub-tugas harus integer',
+ 'The task id is required' => 'ID tugas diperlukan',
+ 'The task id must be an integer' => 'ID tugas harus integer',
+ 'The user id must be an integer' => 'ID user harus integer',
'This value is required' => 'Nilai ini diperlukan',
'This value must be numeric' => 'Nilai ini harus angka',
'Unable to create this task.' => 'Tidak dapat membuat tugas ini',
@@ -455,121 +449,119 @@ return array(
'Daily project summary' => 'Ringkasan proyek harian',
'Daily project summary export' => 'Ekspor ringkasan proyek harian',
'Exports' => 'Ekspor',
- 'This export contains the number of tasks per column grouped per day.' => 'Ekspor ini berisi jumlah dari tugas per kolom dikelompokan perhari.',
+ 'This export contains the number of tasks per column grouped per day.' => 'Ekspor ini berisi jumlah dari tugas per kolom yang dikelompokan per hari.',
'Active swimlanes' => 'Swimlanes aktif',
'Add a new swimlane' => 'Tambah swimlane baru',
- 'Change default swimlane' => 'Modifikasi standar swimlane',
- 'Default swimlane' => 'Standar swimlane',
- 'Do you really want to remove this swimlane: "%s"?' => 'Apakah anda yakin akan menghapus swimlane ini : « %s » ?',
+ 'Change default swimlane' => 'Ganti swimlane default',
+ 'Default swimlane' => 'Swimlane default',
+ 'Do you really want to remove this swimlane: "%s"?' => 'Apakah Anda yakin mau menghapus swimlane ini: "%s"?',
'Inactive swimlanes' => 'Swimlanes tidak aktif',
- 'Remove a swimlane' => 'Supprimer une swimlane',
- 'Show default swimlane' => 'Perlihatkan standar swimlane',
- 'Swimlane modification for the project "%s"' => 'Modifikasi swimlane untuk proyek « %s »',
+ 'Remove a swimlane' => 'Hapus swimlane',
+ 'Show default swimlane' => 'Lihat swimlane default',
+ 'Swimlane modification for the project "%s"' => 'Modifikasi swimlane untuk proyek "%s"',
'Swimlane removed successfully.' => 'Swimlane berhasil dihapus.',
'Swimlanes' => 'Swimlanes',
- 'Swimlane updated successfully.' => 'Swimlane berhasil diperbaharui.',
- 'The default swimlane have been updated successfully.' => 'Standar swimlane berhasil diperbaharui.',
+ 'Swimlane updated successfully.' => 'Swimlane berhasil diperbarui.',
+ 'The default swimlane have been updated successfully.' => 'Swimlane default berhasil diperbarui.',
'Unable to remove this swimlane.' => 'Tidak dapat menghapus swimlane ini.',
- 'Unable to update this swimlane.' => 'Tidak dapat memperbaharui swimlane ini.',
- 'Your swimlane have been created successfully.' => 'Swimlane anda berhasil dibuat.',
- 'Example: "Bug, Feature Request, Improvement"' => 'Contoh: « Insiden, Permintaan Fitur, Perbaikan »',
- 'Default categories for new projects (Comma-separated)' => 'Standar kategori untuk proyek baru (dipisahkan dengan koma)',
+ 'Unable to update this swimlane.' => 'Tidak dapat memperbarui swimlane ini.',
+ 'Your swimlane have been created successfully.' => 'Swimlane Anda berhasil dibuat.',
+ 'Example: "Bug, Feature Request, Improvement"' => 'Contoh: "Bug, Permintaan Fitur, Peningkatan"',
+ 'Default categories for new projects (Comma-separated)' => 'Kategori default untuk proyek baru (dipisahkan dengan koma)',
'Integrations' => 'Integrasi',
'Integration with third-party services' => 'Integrasi dengan layanan pihak ketiga',
- 'Subtask Id' => 'Id Subtugas',
- 'Subtasks' => 'Subtugas',
- 'Subtasks Export' => 'Ekspor Subtugas',
+ 'Subtask Id' => 'ID Sub-tugas',
+ 'Subtasks' => 'Sub-tugas',
+ 'Subtasks Export' => 'Ekspor Sub-tugas',
'Task Title' => 'Judul Tugas',
- 'Untitled' => 'Tanpa nama',
- 'Application default' => 'Aplikasi standar',
- 'Language:' => 'Bahasa :',
- 'Timezone:' => 'Zona waktu :',
+ 'Untitled' => 'Tanpa Nama',
+ 'Application default' => 'Default aplikasi',
+ 'Language:' => 'Bahasa:',
+ 'Timezone:' => 'Zona waktu:',
'All columns' => 'Semua kolom',
'Calendar' => 'Kalender',
'Next' => 'Selanjutnya',
- '#%d' => 'n˚%d',
+ '#%d' => '#%d',
'All swimlanes' => 'Semua swimlane',
'All colors' => 'Semua warna',
'Moved to column %s' => 'Pindah ke kolom %s',
'User dashboard' => 'Dasbor pengguna',
- 'Allow only one subtask in progress at the same time for a user' => 'Izinkan hanya satu subtugas dalam proses secara bersamaan untuk satu pengguna',
- 'Edit column "%s"' => 'Modifikasi kolom « %s »',
- 'Select the new status of the subtask: "%s"' => 'Pilih status baru untuk subtugas : « %s »',
- 'Subtask timesheet' => 'Subtugas absen',
- 'There is nothing to show.' => 'Tidak ada yang dapat diperlihatkan.',
- 'Time Tracking' => 'Pelacakan waktu',
- 'You already have one subtask in progress' => 'Anda sudah ada satu subtugas dalam proses',
- 'Which parts of the project do you want to duplicate?' => 'Bagian dalam proyek mana yang ingin anda duplikasi?',
+ 'Allow only one subtask in progress at the same time for a user' => 'Izinkan hanya satu sub-tugas dalam proses secara bersamaan untuk satu pengguna',
+ 'Edit column "%s"' => 'Edit kolom "%s"',
+ 'Select the new status of the subtask: "%s"' => 'Pilih status baru untuk sub-tugas: "%s"',
+ 'Subtask timesheet' => 'Absen sub-tugas',
+ 'There is nothing to show.' => 'Tidak ada yang bisa diperlihatkan.',
+ 'Time Tracking' => 'Pelacakan Waktu',
+ 'You already have one subtask in progress' => 'Anda sudah memiliki satu sub-tugas dalam proses',
+ 'Which parts of the project do you want to duplicate?' => 'Bagian proyek mana yang ingin Anda duplikasi?',
'Disallow login form' => 'Larang formulir masuk',
'Start' => 'Mulai',
'End' => 'Selesai',
'Task age in days' => 'Usia tugas dalam hari',
'Days in this column' => 'Hari dalam kolom ini',
- '%dd' => '%dj',
+ '%dd' => '%dd',
'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 ?',
- 'Field required' => 'Field diperlukan',
+ 'Do you really want to remove this link: "%s"?' => 'Apakah Anda yakin mau menghapus tautan ini: "%s"?',
+ 'Do you really want to remove this link with task #%d?' => 'Apakah Anda yakin mau menghapus tautan ini dengan tugas #%d ?',
+ 'Field required' => 'Bidang dibutuhkan',
'Link added successfully.' => 'Tautan berhasil ditambahkan.',
- 'Link updated successfully.' => 'Tautan berhasil diperbaharui.',
+ 'Link updated successfully.' => 'Tautan berhasil diperbarui.',
'Link removed successfully.' => 'Tautan berhasil dihapus.',
'Link labels' => 'Label tautan',
'Link modification' => 'Modifikasi tautan',
'Links' => 'Tautan',
- 'Link settings' => 'Pengaturan tautan',
'Opposite label' => 'Label berlawanan',
'Remove a link' => 'Hapus tautan',
- 'Task\'s links' => 'Tautan tugas',
'The labels must be different' => 'Label harus berbeda',
'There is no link.' => 'Tidak ada tautan.',
'This label must be unique' => 'Label ini harus unik',
- 'Unable to create your link.' => 'Tidak dapat membuat tautan anda.',
- 'Unable to update your link.' => 'Tidak dapat memperbaharui tautan anda.',
+ 'Unable to create your link.' => 'Tidak dapat membuat tautan Anda.',
+ 'Unable to update your link.' => 'Tidak dapat memperbarui tautan Anda.',
'Unable to remove this link.' => 'Tidak dapat menghapus tautan ini.',
'relates to' => 'berhubungan dengan',
- 'blocks' => 'blok',
+ 'blocks' => 'blokir',
'is blocked by' => 'diblokir oleh',
'duplicates' => 'duplikat',
'is duplicated by' => 'diduplikasi oleh',
'is a child of' => 'anak dari',
- 'is a parent of' => 'orant tua dari',
- 'targets milestone' => 'milestone target',
- 'is a milestone of' => 'adalah milestone dari',
+ 'is a parent of' => 'induk dari',
+ 'targets milestone' => 'target batu pijakan',
+ 'is a milestone of' => 'adalah batu pijakan dari',
'fixes' => 'perbaikan',
'is fixed by' => 'diperbaiki oleh',
'This task' => 'Tugas ini',
'<1h' => '<1h',
'%dh' => '%dh',
'Expand tasks' => 'Perluas tugas',
- 'Collapse tasks' => 'Lipat tugas',
- 'Expand/collapse tasks' => 'Perluas/lipat tugas',
+ 'Collapse tasks' => 'Tutup tugas',
+ 'Expand/collapse tasks' => 'Perluas/tutup tugas',
'Close dialog box' => 'Tutup kotak dialog',
- 'Submit a form' => 'Submit formulir',
- 'Board view' => 'Table halaman',
- 'Keyboard shortcuts' => 'pintas keyboard',
- 'Open board switcher' => 'Buka table switcher',
+ 'Submit a form' => 'Kirim formulir',
+ 'Board view' => 'Tampilan papan',
+ 'Keyboard shortcuts' => 'Pintasan keyboard',
+ 'Open board switcher' => 'Buka switcher papan',
'Application' => 'Aplikasi',
'Compact view' => 'Tampilan kompak',
- 'Horizontal scrolling' => 'Horisontal bergulir',
- 'Compact/wide view' => 'Beralih antara tampilan kompak dan diperluas',
- 'No results match:' => 'Tidak ada hasil :',
+ 'Horizontal scrolling' => 'Gulir horizontal',
+ 'Compact/wide view' => 'Tampilan kompak/lebar',
'Currency' => 'Mata uang',
'Private project' => 'Proyek pribadi',
- 'AUD - Australian Dollar' => 'AUD - Dollar Australia',
- 'CAD - Canadian Dollar' => 'CAD - Dollar Kanada',
- 'CHF - Swiss Francs' => 'CHF - Swiss Prancis',
- 'Custom Stylesheet' => 'Kustomisasi Stylesheet',
+ 'AUD - Australian Dollar' => 'AUD - Dolar Australia',
+ 'CAD - Canadian Dollar' => 'CAD - Dolar Kanada',
+ 'CHF - Swiss Francs' => 'CHF - Francs Swiss',
+ 'Custom Stylesheet' => 'Kustomisasi CSS',
'download' => 'unduh',
'EUR - Euro' => 'EUR - Euro',
- 'GBP - British Pound' => 'GBP - Poundsterling inggris',
+ 'GBP - British Pound' => 'GBP - Poundsterling Inggris',
'INR - Indian Rupee' => 'INR - Rupe India',
'JPY - Japanese Yen' => 'JPY - Yen Jepang',
- 'NZD - New Zealand Dollar' => 'NZD - Dollar Selandia baru',
+ 'NZD - New Zealand Dollar' => 'NZD - Dolar Selandia baru',
'RSD - Serbian dinar' => 'RSD - Dinar Serbia',
- 'USD - US Dollar' => 'USD - Dollar Amerika',
+ // 'CNY - Chinese Yuan' => '',
+ 'USD - US Dollar' => 'USD - Dolar Amerika',
'Destination column' => 'Kolom tujuan',
- 'Move the task to another column when assigned to a user' => 'Pindahkan tugas ke kolom lain ketika ditugaskan ke pengguna',
- 'Move the task to another column when assignee is cleared' => 'Pindahkan tugas ke kolom lain ketika orang yang ditugaskan dibersihkan',
+ 'Move the task to another column when assigned to a user' => 'Pindahkan tugas ke kolom lain saat ditugaskan ke pengguna',
+ 'Move the task to another column when assignee is cleared' => 'Pindahkan tugas ke kolom lain saat orang yang ditugaskan kosong',
'Source column' => 'Sumber kolom',
'Transitions' => 'Transisi',
'Executer' => 'Eksekusi',
@@ -579,77 +571,76 @@ return array(
'This report contains all column moves for each task with the date, the user and the time spent for each transition.' => 'Laporan ini berisi semua kolom yang pindah untuk setiap tugas dengan tanggal, pengguna dan waktu yang dihabiskan untuk setiap transisi.',
'Currency rates' => 'Nilai tukar mata uang',
'Rate' => 'Tarif',
- 'Change reference currency' => 'Mengubah referensi mata uang',
- 'Add a new currency rate' => 'Tambahkan nilai tukar mata uang baru',
+ 'Change reference currency' => 'Ganti referensi mata uang',
'Reference currency' => 'Referensi mata uang',
'The currency rate have been added successfully.' => 'Nilai tukar mata uang berhasil ditambahkan.',
'Unable to add this currency rate.' => 'Tidak dapat menambahkan nilai tukar mata uang',
- 'Webhook URL' => 'URL webhook',
+ 'Webhook URL' => 'URL Webhook',
'%s removed the assignee of the task %s' => '%s menghapus penugasan dari tugas %s',
- 'Enable Gravatar images' => 'Mengaktifkan gambar Gravatar',
+ 'Enable Gravatar images' => 'Aktifkan gambar Gravatar',
'Information' => 'Informasi',
'Check two factor authentication code' => 'Cek dua faktor kode otentifikasi',
- 'The two factor authentication code is not valid.' => 'Kode dua faktor kode otentifikasi tidak valid.',
- 'The two factor authentication code is valid.' => 'Kode dua faktor kode otentifikasi valid.',
+ 'The two factor authentication code is not valid.' => 'Kode dua faktor kode otentifikasi tidak sesuai.',
+ 'The two factor authentication code is valid.' => 'Kode dua faktor kode otentifikasi sesuai.',
'Code' => 'Kode',
'Two factor authentication' => 'Dua faktor otentifikasi',
- 'This QR code contains the key URI: ' => 'kode QR ini mengandung kunci URI : ',
- 'Check my code' => 'Memeriksa kode saya',
- 'Secret key: ' => 'Kunci rahasia : ',
- 'Test your device' => 'Menguji perangkat anda',
- 'Assign a color when the task is moved to a specific column' => 'Menetapkan warna ketika tugas tersebut dipindahkan ke kolom tertentu',
+ 'This QR code contains the key URI: ' => 'Kode QR ini mengandung kunci URI: ',
+ 'Check my code' => 'Periksa kode saya',
+ 'Secret key: ' => 'Kunci rahasia: ',
+ 'Test your device' => 'Uji perangkat Anda',
+ 'Assign a color when the task is moved to a specific column' => 'Tetapkan warna ketika tugas tersebut dipindahkan ke kolom tertentu',
'%s via Kanboard' => '%s via Kanboard',
'Burndown chart' => 'Grafik Burndown',
'This chart show the task complexity over the time (Work Remaining).' => 'Grafik ini menunjukkan kompleksitas tugas dari waktu ke waktu (Sisa Pekerjaan).',
'Screenshot taken %s' => 'Screenshot diambil %s',
'Add a screenshot' => 'Tambah screenshot',
- 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => 'Mengambil screenshot dan tekan CTRL + V atau ⌘ + V untuk paste di sini.',
+ 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => 'Ambil screenshot dan tekan CTRL+V atau ⌘+V untuk ditempel di sini.',
'Screenshot uploaded successfully.' => 'Screenshot berhasil diunggah.',
'SEK - Swedish Krona' => 'SEK - Krona Swedia',
'Identifier' => 'Identifier',
'Disable two factor authentication' => 'Matikan dua faktor otentifikasi',
- 'Do you really want to disable the two factor authentication for this user: "%s"?' => 'Apakah anda yakin akan mematikan dua faktor otentifikasi untuk pengguna ini : « %s » ?',
- 'Edit link' => 'Modifikasi tautan',
+ 'Do you really want to disable the two factor authentication for this user: "%s"?' => 'Apakah Anda yakin mau mematikan dua faktor otentifikasi untuk pengguna ini: "%s"?',
+ 'Edit link' => 'Edit tautan',
'Start to type task title...' => 'Mulai mengetik judul tugas...',
- 'A task cannot be linked to itself' => 'Sebuah tugas tidak dapat dikaitkan dengan dirinya sendiri',
+ 'A task cannot be linked to itself' => 'Tugas tidak dapat dikaitkan dengan dirinya sendiri',
'The exact same link already exists' => 'Tautan yang sama persis sudah ada',
- 'Recurrent task is scheduled to be generated' => 'Tugas berulang dijadwalkan akan dihasilkan',
+ 'Recurrent task is scheduled to be generated' => 'Tugas berulang dijadwalkan untuk di generate',
'Score' => 'Skor',
'The identifier must be unique' => 'Identifier harus unik',
- 'This linked task id doesn\'t exists' => 'Id tugas terkait tidak ada',
+ 'This linked task id doesn\'t exists' => 'ID tugas terkait tidak ada',
'This value must be alphanumeric' => 'Nilai harus alfanumerik',
- 'Edit recurrence' => 'Modifikasi pengulangan',
- 'Generate recurrent task' => 'Menghasilkan tugas berulang',
- 'Trigger to generate recurrent task' => 'Memicu untuk menghasilkan tugas berulang',
+ 'Edit recurrence' => 'Edit pengulangan',
+ 'Generate recurrent task' => 'Generate tugas berulang',
+ 'Trigger to generate recurrent task' => 'Pemicu untuk menghasilkan tugas berulang',
'Factor to calculate new due date' => 'Faktor untuk menghitung tanggal jatuh tempo baru',
'Timeframe to calculate new due date' => 'Jangka waktu untuk menghitung tanggal jatuh tempo baru',
'Base date to calculate new due date' => 'Tanggal dasar untuk menghitung tanggal jatuh tempo baru',
'Action date' => 'Tanggal aksi',
'Base date to calculate new due date: ' => 'Tanggal dasar untuk menghitung tanggal jatuh tempo baru: ',
- 'This task has created this child task: ' => 'Tugas ini telah menciptakan tugas anak ini: ',
+ 'This task has created this child task: ' => 'Tugas ini telah membuat tugas anak ini: ',
'Day(s)' => 'Hari',
'Existing due date' => 'Batas waktu yang ada',
'Factor to calculate new due date: ' => 'Faktor untuk menghitung tanggal jatuh tempo baru: ',
'Month(s)' => 'Bulan',
'Recurrence' => 'Pengulangan',
- 'This task has been created by: ' => 'Tugas ini telah dibuat oleh:',
- 'Recurrent task has been generated:' => 'Tugas berulang telah dihasilkan:',
+ 'This task has been created by: ' => 'Tugas ini telah dibuat oleh: ',
+ 'Recurrent task has been generated:' => 'Tugas berulang telah di generate:',
'Timeframe to calculate new due date: ' => 'Jangka waktu untuk menghitung tanggal jatuh tempo baru: ',
'Trigger to generate recurrent task: ' => 'Pemicu untuk menghasilkan tugas berulang: ',
- 'When task is closed' => 'Ketika tugas ditutup',
- 'When task is moved from first column' => 'Ketika tugas dipindahkan dari kolom pertama',
- 'When task is moved to last column' => 'Ketika tugas dipindahkan ke kolom terakhir',
+ 'When task is closed' => 'Saat tugas ditutup',
+ 'When task is moved from first column' => 'Saat tugas dipindahkan dari kolom pertama',
+ 'When task is moved to last column' => 'Saat tugas dipindahkan ke kolom terakhir',
'Year(s)' => 'Tahun',
'Calendar settings' => 'Pengaturan kalender',
'Project calendar view' => 'Tampilan kalender proyek',
'Project settings' => 'Pengaturan proyek',
- 'Show subtasks based on the time tracking' => 'Tampilkan subtugas berdasarkan pelacakan waktu',
+ 'Show subtasks based on the time tracking' => 'Tampilkan sub-tugas berdasarkan pelacakan waktu',
'Show tasks based on the creation date' => 'Tampilkan tugas berdasarkan tanggal pembuatan',
'Show tasks based on the start date' => 'Tampilkan tugas berdasarkan tanggal mulai',
- 'Subtasks time tracking' => 'Pelacakan waktu subtgas',
- 'User calendar view' => 'Pengguna tampilan kalender',
- 'Automatically update the start date' => 'Memperbarui tanggal mulai otomatis',
- 'iCal feed' => 'iCal feed',
+ 'Subtasks time tracking' => 'Pelacakan waktu sub-tugas',
+ 'User calendar view' => 'Tampilan kalender pengguna',
+ 'Automatically update the start date' => 'Otomatis memperbarui tanggal permulaan',
+ 'iCal feed' => 'Umpan iCal',
'Preferences' => 'Preferensi',
'Security' => 'Keamanan',
'Two factor authentication disabled' => 'Otentifikasi dua faktor dimatikan',
@@ -657,40 +648,40 @@ return array(
'Unable to update this user.' => 'Tidak dapat memperbarui pengguna ini.',
'There is no user management for private projects.' => 'Tidak ada manajemen pengguna untuk proyek-proyek pribadi.',
'User that will receive the email' => 'Pengguna yang akan menerima email',
- 'Email subject' => 'Subjek Email',
+ 'Email subject' => 'Subyek Email',
'Date' => 'Tanggal',
'Add a comment log when moving the task between columns' => 'Menambahkan log komentar ketika memindahkan tugas antara kolom',
'Move the task to another column when the category is changed' => 'Pindahkan tugas ke kolom lain ketika kategori berubah',
'Send a task by email to someone' => 'Kirim tugas melalui email ke seseorang',
- 'Reopen a task' => 'Membuka kembali tugas',
+ 'Reopen a task' => 'Buka kembali tugas',
'Notification' => 'Pemberitahuan',
- '%s moved the task #%d to the first swimlane' => '%s memindahkan tugas n°%d ke swimlane pertama',
+ '%s moved the task #%d to the first swimlane' => '%s memindahkan tugas #%d ke swimlane pertama',
'Swimlane' => 'Swimlane',
'Gravatar' => 'Gravatar',
'%s moved the task %s to the first swimlane' => '%s memindahkan tugas %s ke swimlane pertama',
- '%s moved the task %s to the swimlane "%s"' => '%s memindahkan tugas %s ke swimlane « %s »',
- 'This report contains all subtasks information for the given date range.' => 'Laporan ini berisi semua informasi subtugas untuk rentang tanggal tertentu.',
+ '%s moved the task %s to the swimlane "%s"' => '%s memindahkan tugas %s ke swimlane "%s"',
+ 'This report contains all subtasks information for the given date range.' => 'Laporan ini berisi semua informasi sub-tugas untuk rentang tanggal tertentu.',
'This report contains all tasks information for the given date range.' => 'Laporan ini berisi semua informasi tugas untuk rentang tanggal tertentu.',
- 'Project activities for %s' => 'Aktifitas proyek untuk « %s »',
+ 'Project activities for %s' => 'Aktifitas proyek untuk "%s"',
'view the board on Kanboard' => 'lihat papan di Kanboard',
'The task have been moved to the first swimlane' => 'Tugas telah dipindahkan ke swimlane pertama',
'The task have been moved to another swimlane:' => 'Tugas telah dipindahkan ke swimlane lain:',
- 'New title: %s' => 'Judul baru : %s',
+ 'New title: %s' => 'Judul baru: %s',
'The task is not assigned anymore' => 'Tugas tidak ditugaskan lagi',
- 'New assignee: %s' => 'Penerima baru : %s',
- 'There is no category now' => 'Tidak ada kategori untuk sekarang',
- 'New category: %s' => 'Kategori baru : %s',
- 'New color: %s' => 'Warna baru : %s',
- 'New complexity: %d' => 'Kompleksitas baru : %d',
+ 'New assignee: %s' => 'Penerima baru: %s',
+ 'There is no category now' => 'Tidak ada kategori untuk saat ini',
+ 'New category: %s' => 'Kategori baru: %s',
+ 'New color: %s' => 'Warna baru: %s',
+ 'New complexity: %d' => 'Kompleksitas baru: %d',
'The due date have been removed' => 'Tanggal jatuh tempo telah dihapus',
'There is no description anymore' => 'Tidak ada deskripsi lagi',
'Recurrence settings have been modified' => 'Pengaturan pengulangan telah dimodifikasi',
- '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',
+ 'Time spent changed: %sh' => 'Waktu yang dihabiskan telah diganti: %sh',
+ 'Time estimated changed: %sh' => 'Perkiraan waktu telah diganti: %sh',
+ 'The field "%s" have been updated' => 'Bidang "%s" telah diperbarui',
'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 :',
+ 'Do you really want to close the task "%s" as well as all subtasks?' => 'Apakah Anda yakin mau menutup tugas "%s" beserta semua sub-tugasnya?',
+ 'I want to receive notifications for:' => 'Saya ingin menerima pemberitahuan untuk:',
'All tasks' => 'Semua tugas',
'Only for tasks assigned to me' => 'Hanya untuk tugas yang ditugaskan ke saya',
'Only for tasks created by me' => 'Hanya untuk tugas yang dibuat oleh saya',
@@ -702,84 +693,81 @@ return array(
'<30m' => '<30m',
'Stop timer' => 'Hentikan timer',
'Start timer' => 'Mulai timer',
- 'Add project member' => 'Tambahkan anggota proyek',
'My activity stream' => 'Aliran kegiatan saya',
'My calendar' => 'Kalender saya',
'Search tasks' => 'Cari tugas',
- 'Reset filters' => 'Reset ulang filter',
+ 'Reset filters' => 'Reset saringan',
'My tasks due tomorrow' => 'Tugas saya yang berakhir besok',
'Tasks due today' => 'Tugas yang berakhir hari ini',
'Tasks due tomorrow' => 'Tugas yang berakhir besok',
'Tasks due yesterday' => 'Tugas yang berakhir kemarin',
'Closed tasks' => 'Tugas yang ditutup',
- 'Open tasks' => 'Buka Tugas',
+ 'Open tasks' => 'Tugas terbuka',
'Not assigned' => 'Tidak ditugaskan',
'View advanced search syntax' => 'Lihat sintaks pencarian lanjutan',
- 'Overview' => 'Ikhtisar',
+ 'Overview' => 'Ringkasan',
'Board/Calendar/List view' => 'Tampilan Papan/Kalender/Daftar',
'Switch to the board view' => 'Beralih ke tampilan papan',
'Switch to the calendar view' => 'Beralih ke tampilan kalender',
'Switch to the list view' => 'Beralih ke tampilan daftar',
- 'Go to the search/filter box' => 'Pergi ke kotak pencarian/filter',
- 'There is no activity yet.' => 'Tidak ada aktifitas saat ini.',
+ 'Go to the search/filter box' => 'Pergi ke kotak pencarian/saringan',
+ 'There is no activity yet.' => 'Belum ada aktifitas.',
'No tasks found.' => 'Tidak ada tugas yang ditemukan.',
- 'Keyboard shortcut: "%s"' => 'Keyboard shortcut : « %s »',
+ 'Keyboard shortcut: "%s"' => 'Pintasan keyboard: "%s"',
'List' => 'Daftar',
- 'Filter' => 'Filter',
+ 'Filter' => 'Saringan',
'Advanced search' => 'Pencarian lanjutan',
'Example of query: ' => 'Contoh dari query : ',
- 'Search by project: ' => 'Pencarian berdasarkan proyek : ',
- 'Search by column: ' => 'Pencarian berdasarkan kolom : ',
- 'Search by assignee: ' => 'Pencarian berdasarkan penerima : ',
- 'Search by color: ' => 'Pencarian berdasarkan warna : ',
- 'Search by category: ' => 'Pencarian berdasarkan kategori : ',
- 'Search by description: ' => 'Pencarian berdasarkan deskripsi : ',
- 'Search by due date: ' => 'Pencarian berdasarkan tanggal jatuh tempo : ',
+ 'Search by project: ' => 'Cari berdasarkan proyek: ',
+ 'Search by column: ' => 'Cari berdasarkan kolom: ',
+ 'Search by assignee: ' => 'Cari berdasarkan penerima tugas: ',
+ 'Search by color: ' => 'Cari berdasarkan warna: ',
+ 'Search by category: ' => 'Cari berdasarkan kategori: ',
+ 'Search by description: ' => 'Cari berdasarkan deskripsi: ',
+ 'Search by due date: ' => 'Cari berdasarkan tanggal jatuh tempo: ',
'Average time spent into each column' => 'Rata-rata waktu yang dihabiskan dalam setiap kolom',
'Average time spent' => 'Rata-rata waktu yang dihabiskan',
- 'This chart show the average time spent into each column for the last %d tasks.' => 'Grafik ini menunjukkan rata-rata waktu yang dihabiskan dalam setiap kolom untuk %d tugas.',
- 'Average Lead and Cycle time' => 'Rata-rata Memimpin dan Siklus waktu',
- 'Average lead time: ' => 'Rata-rata waktu pimpinan : ',
- 'Average cycle time: ' => 'Rata-rata siklus waktu : ',
- 'Cycle Time' => 'Siklus Waktu',
+ 'This chart show the average time spent into each column for the last %d tasks.' => 'Grafik ini menunjukkan rata-rata waktu yang dihabiskan dalam setiap kolom untuk %d tugas terakhir.',
+ 'Average Lead and Cycle time' => 'Rata-rata Lead dan Cycle time',
+ 'Average lead time: ' => 'Rata-rata lead time: ',
+ 'Average cycle time: ' => 'Rata-rata 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.' => 'Grafik ini menunjukkan memimpin rata-rata dan waktu siklus untuk %d tugas terakhir dari waktu ke waktu.',
+ 'This chart show the average lead and cycle time for the last %d tasks over the time.' => 'Grafik ini menunjukkan rata-rata waktu lead dan cycle time untuk %d tugas terakhir dari waktu ke waktu.',
'Average time into each column' => 'Rata-rata waktu ke setiap kolom',
- 'Lead and cycle time' => 'Lead dan siklus waktu',
- 'Lead time: ' => 'Lead time : ',
- 'Cycle time: ' => 'Siklus waktu : ',
+ 'Lead and cycle time' => 'Lead dan cycle time',
+ 'Lead time: ' => 'Lead time: ',
+ 'Cycle time: ' => 'Cycle time: ',
'Time spent into each column' => 'Waktu yang dihabiskan di setiap kolom',
'The lead time is the duration between the task creation and the completion.' => 'Lead time adalah durasi antara pembuatan tugas dan penyelesaian.',
- 'The cycle time is the duration between the start date and the completion.' => 'Siklus waktu adalah durasi antara tanggal mulai dan tanggal penyelesaian.',
- 'If the task is not closed the current time is used instead of the completion date.' => 'Jika tugas tidak ditutup waktu saat ini yang digunakan sebagai pengganti tanggal penyelesaian.',
+ 'The cycle time is the duration between the start date and the completion.' => 'Cycle time adalah durasi antara tanggal mulai dan tanggal penyelesaian.',
+ 'If the task is not closed the current time is used instead of the completion date.' => 'Jika tugas tidak ditutup, waktu saat ini akan digunakan sebagai pengganti tanggal penyelesaian.',
'Set automatically the start date' => 'Secara otomatis mengatur tanggal mulai',
- 'Edit Authentication' => 'Modifikasi Otentifikasi',
+ 'Edit Authentication' => 'Edit Otentifikasi',
'Remote user' => 'Pengguna jauh',
'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => 'Pengguna jauh tidak menyimpan kata sandi mereka dalam basis data Kanboard, contoh: akun LDAP, Google dan Github.',
'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => 'Jika anda mencentang kotak "Larang formulir login", kredensial masuk ke formulis login akan diabaikan.',
- 'New remote user' => 'Pengguna baru jauh',
- 'New local user' => 'Pengguna baru lokal',
- 'Default task color' => 'Standar warna tugas',
- 'This feature does not work with all browsers.' => 'Fitur ini tidak dapat digunakan di semua browsers',
- 'There is no destination project available.' => 'Tidak ada destinasi proyek yang tersedia.',
- 'Trigger automatically subtask time tracking' => 'Otomatis memicu pelacakan untuk subtugas',
- 'Include closed tasks in the cumulative flow diagram' => 'Termasuk tugas yang ditutup pada diagram aliran kumulatif',
- 'Current swimlane: %s' => 'Swimlane saat ini : %s',
- 'Current column: %s' => 'Kolom saat ini : %s',
- 'Current category: %s' => 'Kategori saat ini : %s',
+ 'Default task color' => 'Warna tugas default',
+ 'This feature does not work with all browsers.' => 'Fitur ini tidak dapat digunakan di semua peramban',
+ 'There is no destination project available.' => 'Tidak ada tujuan proyek yang tersedia.',
+ 'Trigger automatically subtask time tracking' => 'Otomatis memicu pelacakan waktu untuk sub-tugas',
+ 'Include closed tasks in the cumulative flow diagram' => 'Sertakan tugas yang ditutup dalam diagram alir kumulatif',
+ 'Current swimlane: %s' => 'Swimlane saat ini: %s',
+ 'Current column: %s' => 'Kolom saat ini: %s',
+ 'Current category: %s' => 'Kategori saat ini: %s',
'no category' => 'tidak ada kategori',
- 'Current assignee: %s' => 'Saat ini ditugaskan : %s',
- 'not assigned' => 'Belum ditugaskan',
- 'Author:' => 'Penulis :',
+ 'Current assignee: %s' => 'Orang yang ditugaskan saat ini: %s',
+ 'not assigned' => 'belum ditugaskan',
+ 'Author:' => 'Penulis:',
'contributors' => 'kontributor',
- 'License:' => 'Lisensi :',
+ 'License:' => 'Lisensi:',
'License' => 'Lisensi',
'Enter the text below' => 'Masukkan teks di bawah',
'Sort by position' => 'Urutkan berdasarkan posisi',
'Sort by date' => 'Urutkan berdasarkan tanggal',
'Add task' => 'Tambah tugas',
- 'Start date:' => 'Tanggal mulai :',
- 'Due date:' => 'Batas waktu :',
+ 'Start date:' => 'Tanggal mulai:',
+ 'Due date:' => 'Batas waktu:',
'There is no start date or due date for this task.' => 'Tidak ada tanggal mulai dan batas waktu untuk tugas ini.',
'Moving or resizing a task will change the start and due date of the task.' => 'Memindahkan atau mengubah ukuran tugas anda akan mengubah tanggal mulai dan batas waktu dari tugas ini.',
'There is no task in your project.' => 'Tidak ada tugas didalam proyek anda.',
@@ -791,7 +779,7 @@ return array(
'Hide this column' => 'Sembunyikan kolom ini',
'open file' => 'buka berkas',
'End date' => 'Waktu berakhir',
- 'Users overview' => 'Ikhtisar pengguna',
+ 'Users overview' => 'Ringkasan pengguna',
'Members' => 'Anggota',
'Shared project' => 'Proyek bersama',
'Project managers' => 'Manajer proyek',
@@ -799,15 +787,15 @@ return array(
'Projects list' => 'Daftar proyek',
'Gantt chart for this project' => 'Grafik Gantt untuk proyek ini',
'Project board' => 'Papan proyek',
- 'End date:' => 'Waktu berakhir :',
+ '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',
- 'Change task color when using a specific task link' => 'Rubah warna tugas ketika menggunakan tautan tugas yang spesifik',
+ 'Projects Gantt chart' => 'Grafik Gantt proyek',
+ 'Change task color when using a specific task link' => 'Ganti warna tugas ketika menggunakan tautan tugas yang spesifik',
'Task link creation or modification' => 'Tautan pembuatan atau modifikasi tugas ',
'Milestone' => 'Milestone',
- 'Documentation: %s' => 'Dokumentasi : %s',
+ 'Documentation: %s' => 'Dokumentasi: %s',
'Switch to the Gantt chart view' => 'Beralih ke tampilan grafik Gantt',
- 'Reset the search/filter box' => 'Atur ulang pencarian/kotak filter',
+ 'Reset the search/filter box' => 'Reset kotak pencarian/saringan',
'Documentation' => 'Dokumentasi',
'Table of contents' => 'Daftar isi',
'Gantt' => 'Gantt',
@@ -816,44 +804,43 @@ return array(
'Plugins' => 'Plugin',
'There is no plugin loaded.' => 'Tidak ada plugin yang dimuat',
'My notifications' => 'Notifikasi saya',
- 'Custom filters' => 'Filter kustom',
- 'Your custom filter have been created successfully.' => 'Filter kustom anda telah berhasil dibuat',
- 'Unable to create your custom filter.' => 'Tidak dapat membuat filter kustom',
- 'Custom filter removed successfully.' => 'Filter kustom berhail dihapus',
- 'Unable to remove this custom filter.' => 'Tidak dapat menghapus filter kustom',
- 'Edit custom filter' => 'Modifikasi filter kustom',
- 'Your custom filter have been updated successfully.' => 'Filter kustom anda telah berhasil diperbaharui',
- 'Unable to update custom filter.' => 'Tidak dapat memperbaharui filter kustom',
+ 'Custom filters' => 'Saringan kustom',
+ 'Your custom filter have been created successfully.' => 'Saringan kustom Anda berhasil dibuat',
+ 'Unable to create your custom filter.' => 'Tidak dapat membuat saringan kustom',
+ 'Custom filter removed successfully.' => 'Saringan kustom berhasil dihapus',
+ 'Unable to remove this custom filter.' => 'Tidak dapat menghapus saringan kustom',
+ 'Edit custom filter' => 'Edit saringan kustom',
+ 'Your custom filter have been updated successfully.' => 'Saringan kustom Anda berhasil diperbarui',
+ 'Unable to update custom filter.' => 'Tidak dapat memperbarui saringan kustom',
'Web' => 'Web',
'New attachment on task #%d: %s' => 'Lampiran baru pada tugas #%d: %s',
'New comment on task #%d' => 'Komentar baru pada tugas #%d',
- 'Comment updated on task #%d' => 'Komentar diperbaharui pada tugas #%d',
- 'New subtask on task #%d' => 'Subtask baru pada tugas #%d',
- 'Subtask updated on task #%d' => 'Subtask diperbaharui pada tugas #%d',
+ 'Comment updated on task #%d' => 'Komentar diperbarui pada tugas #%d',
+ 'New subtask on task #%d' => 'Sub-tugas baru pada tugas #%d',
+ 'Subtask updated on task #%d' => 'Sub-tugas diperbarui pada tugas #%d',
'New task #%d: %s' => 'Tugas baru #%d: %s',
- 'Task updated #%d' => 'Tugas diperbaharui #%d',
+ 'Task updated #%d' => 'Tugas diperbarui #%d',
'Task #%d closed' => 'Tugas #%d ditutup',
'Task #%d opened' => 'Tugas #%d dibuka',
- 'Column changed for task #%d' => 'Kolom berubah untuk tugas #%d',
+ 'Column changed for task #%d' => 'Kolom diganti untuk tugas #%d',
'New position for task #%d' => 'Posisi baru untuk tugas #%d',
- 'Swimlane changed for task #%d' => 'Swimlane berubah untuk tugas #%d',
- 'Assignee changed on task #%d' => 'Orang yang ditugaskan berubah pada tugas #%d',
- '%d overdue tasks' => '%d tugas terlambat',
- 'Task #%d is overdue' => 'Tugas #%d terlambat',
+ 'Swimlane changed for task #%d' => 'Swimlane diganti untuk tugas #%d',
+ 'Assignee changed on task #%d' => 'Orang yang ditugaskan diganti pada tugas #%d',
+ '%d overdue tasks' => '%d tugas kadaluarsa',
+ 'Task #%d is overdue' => 'Tugas #%d sudah kadaluarsa',
'No new notifications.' => 'Tidak ada notifikasi baru',
'Mark all as read' => 'Tandai semua sebagai sudah dibaca',
'Mark as read' => 'Tandai sebagai sudah dibaca',
- 'Total number of tasks in this column across all swimlanes' => 'Total jumlah tugas di kolom ini di semua swimlanes',
- 'Collapse swimlane' => 'Lipat swimlane',
+ 'Total number of tasks in this column across all swimlanes' => 'Total tugas di kolom ini untuk semua swimlane',
+ 'Collapse swimlane' => 'Tutup swimlane',
'Expand swimlane' => 'Perluas swimlane',
- 'Add a new filter' => 'Tambah filter baru',
- 'Share with all project members' => 'Bagikan dengan semua member proyek',
+ 'Add a new filter' => 'Tambah saringan baru',
+ 'Share with all project members' => 'Bagikan dengan semua anggota proyek',
'Shared' => 'Dibagikan',
'Owner' => 'Pemilik',
'Unread notifications' => 'Notifikasi belum terbaca',
'Notification methods:' => 'Metode pemberitahuan',
- 'Import tasks from CSV file' => 'Impor tugas dari berkas CSV',
- 'Unable to read your file' => 'Tidak dapat membaca berkas anda',
+ 'Unable to read your file' => 'Tidak dapat membaca berkas Anda',
'%d task(s) have been imported successfully.' => '%d tugas telah berhasil di impor',
'Nothing have been imported!' => 'Tidak ada yang dapat di impor',
'Import users from CSV file' => 'Impor pengguna dari berkas CSV',
@@ -865,14 +852,14 @@ return array(
'Double Quote' => 'Kutip Ganda',
'Single Quote' => 'Kutip Satu',
'%s attached a file to the task #%d' => '%s berkas dilampirkan untuk tugas #%d',
- 'There is no column or swimlane activated in your project!' => 'Tidak ada kolom atau swimlane aktif untuk proyek anda',
- 'Append filter (instead of replacement)' => 'Tambahkan filter (bukan pengganti)',
+ 'There is no column or swimlane activated in your project!' => 'Tidak ada kolom atau swimlane aktif untuk proyek Anda',
+ 'Append filter (instead of replacement)' => 'Tambahkan saringan (ketimbang pengganti)',
'Append/Replace' => 'Tambah/Ganti',
'Append' => 'Tambahkan',
'Replace' => 'Ganti',
'Import' => 'Impor',
- 'change sorting' => 'rubah sortir',
- 'Tasks Importation' => 'Tugas Impor',
+ 'change sorting' => 'ubah pengurutan',
+ 'Tasks Importation' => 'Importasi Tugas',
'Delimiter' => 'Pembatas',
'Enclosure' => 'Lampiran',
'CSV File' => 'Berkas CSV',
@@ -880,33 +867,33 @@ return array(
'Your file must use the predefined CSV format' => 'Berkas Anda harus menggunakan format CSV yang telah ditetapkan',
'Your file must be encoded in UTF-8' => 'Berkas anda harus di kodekan dalam bentuk UTF-8',
'The first row must be the header' => 'Baris pertama harus header',
- 'Duplicates are not verified for you' => 'Duplikasi tidak diverifikasi untuk anda',
+ 'Duplicates are not verified for you' => 'Duplikasi tidak diverifikasikan untuk Anda',
'The due date must use the ISO format: YYYY-MM-DD' => 'Tanggal jatuh tempo harus menggunakan format ISO: YYYY-MM-DD',
'Download CSV template' => 'Unduh template CSV',
- 'No external integration registered.' => 'Tidak ada integrasi eksternal terdaftar',
+ 'No external integration registered.' => 'Tidak ada integrasi eksternal yang terdaftar',
'Duplicates are not imported' => 'Duplikasi tidak diimpor',
- 'Usernames must be lowercase and unique' => 'Username harus huruf kecil dan unik',
+ 'Usernames must be lowercase and unique' => 'Nama pengguna harus huruf kecil dan unik',
'Passwords will be encrypted if present' => 'Kata sandi akan di enkripsi jika ada',
- '%s attached a new file to the task %s' => '%s berkas baru dilampirkan untuk tugas %s',
+ '%s attached a new file to the task %s' => '%s melampirkan berkas baru untuk tugas %s',
'Link type' => 'Tipe tautan',
- 'Assign automatically a category based on a link' => 'Menetapkan otomatis kategori berdasarkan tautan',
+ 'Assign automatically a category based on a link' => 'Otomatis menetapkan kategori berdasarkan tautan',
'BAM - Konvertible Mark' => 'BAM - Konvertible Mark',
- 'Assignee Username' => 'Username yang ditugaskan',
- 'Assignee Name' => 'Nama yang ditugaskan',
+ 'Assignee Username' => 'Nama pengguna orang yang ditugaskan',
+ 'Assignee Name' => 'Nama orang yang ditugaskan',
'Groups' => 'Grup',
'Members of %s' => 'Anggota dari %s',
'New group' => 'Grup baru',
'Group created successfully.' => 'Grup berhasil dibuat',
- 'Unable to create your group.' => 'Tidak dapat membuat grup anda',
- 'Edit group' => 'Rubah grup',
- 'Group updated successfully.' => 'Grup berhasil diperbaharui',
- 'Unable to update your group.' => 'Tidak dapat memperbaharui grup anda',
+ 'Unable to create your group.' => 'Tidak dapat membuat grup Anda',
+ 'Edit group' => 'Edit grup',
+ 'Group updated successfully.' => 'Grup berhasil diperbarui',
+ 'Unable to update your group.' => 'Tidak dapat memperbarui grup anda',
'Add group member to "%s"' => 'Tambahkan anggota grup ke "%s"',
'Group member added successfully.' => 'Anggota grup berhasil ditambahkan',
'Unable to add group member.' => 'Tidak dapat menambahkan anggota grup',
- 'Remove user from group "%s"' => 'hapus pengguna dari grup "%s"',
+ 'Remove user from group "%s"' => 'Hapus pengguna dari grup "%s"',
'User removed successfully from this group.' => 'Pengguna berhasil dihapus dari grup ini',
- 'Unable to remove this user from the group.' => 'Tidak dapat menghapus pengguna dari grup',
+ 'Unable to remove this user from the group.' => 'Tidak dapat menghapus pengguna ini dari grup',
'Remove group' => 'Hapus grup',
'Group removed successfully.' => 'Grup berhasil dihapus',
'Unable to remove this group.' => 'Tidak dapat menghapus grup ini',
@@ -916,75 +903,74 @@ return array(
'Project Member' => 'Anggota Proyek',
'Project Viewer' => 'Penonton Proyek',
'Your account is locked for %d minutes' => 'Akun anda dikunci untuk %d menit',
- 'Invalid captcha' => 'Captcha tidak valid',
+ 'Invalid captcha' => 'Captcha tidak sesuai',
'The name must be unique' => 'Nama harus unik',
'View all groups' => 'Lihat semua grup',
'There is no user available.' => 'Tidak ada pengguna yang tersedia',
- 'Do you really want to remove the user "%s" from the group "%s"?' => 'Anda yakin akan menghapus pengguna "%s" dari grup "%s"?',
+ 'Do you really want to remove the user "%s" from the group "%s"?' => 'Anda yakin mau menghapus pengguna "%s" dari grup "%s"?',
'There is no group.' => 'Tidak ada grup',
- 'External Id' => 'Id Eksternal',
+ 'External Id' => 'ID Eksternal',
'Add group member' => 'Tambah anggota grup',
- 'Do you really want to remove this group: "%s"?' => 'Anda yakin akan menghapus grup ini: "%s"?',
+ 'Do you really want to remove this group: "%s"?' => 'Anda yakin mau menghapus grup ini: "%s"?',
'There is no user in this group.' => 'Tidak ada pengguna dalam grup ini',
'Remove this user' => 'Hapus pengguna ini',
'Permissions' => 'Izin',
- 'Allowed Users' => 'Pengguna Yang Diperbolehkan',
+ 'Allowed Users' => 'Pengguna Yang Diizinkan',
'No user have been allowed specifically.' => 'Tidak ada user yang diperbolehkan secara khusus',
'Role' => 'Peran',
'Enter user name...' => 'Masukkan nama pengguna...',
- 'Allowed Groups' => 'Grup Yang Diperbolehkan',
+ 'Allowed Groups' => 'Grup Yang Diizinkan',
'No group have been allowed specifically.' => 'Tidak ada grup yang diperbolehkan secara khusus',
'Group' => 'Grup',
'Group Name' => 'Nama Grup',
'Enter group name...' => 'Masukkan nama grup...',
'Role:' => 'Peran:',
'Project members' => 'Anggota proyek',
- '%s mentioned you in the task #%d' => '%s menyebut anda dalam tugas #%d',
- '%s mentioned you in a comment on the task #%d' => '%s menyebut anda dalam komentar pada tugas #%d',
+ '%s mentioned you in the task #%d' => '%s menyebut Anda dalam tugas #%d',
+ '%s mentioned you in a comment on the task #%d' => '%s menyebut Anda dalam komentar pada tugas #%d',
'You were mentioned in the task #%d' => 'Anda disebutkan dalam tugas #%d',
'You were mentioned in a comment on the task #%d' => 'Anda disebutkan dalam komentar pada tugas #%d',
- 'Estimated hours: ' => 'Estimasi jam:',
- 'Actual hours: ' => 'Aktual jam',
+ 'Estimated hours: ' => 'Estimasi jam: ',
+ 'Actual hours: ' => 'Jam sebenarnya: ',
'Hours Spent' => 'Jam dihabiskan',
'Hours Estimated' => 'Jam diperkirakan',
'Estimated Time' => 'Waktu Estimasi',
- 'Actual Time' => 'Waktu Aktual',
- 'Estimated vs actual time' => 'Estimasi vs waktu aktual',
- 'RUB - Russian Ruble' => 'RUB - Rusia rubel',
- 'Assign the task to the person who does the action when the column is changed' => 'Menetapkan tugas kepada orang yang melakukan tindakan ketika kolom berubah',
+ 'Actual Time' => 'Waktu Sebenarnya',
+ 'Estimated vs actual time' => 'Estimasi vs waktu sebenarnya',
+ 'RUB - Russian Ruble' => 'RUB - Rubel Rusia',
+ 'Assign the task to the person who does the action when the column is changed' => 'Berikan tugas pada orang yang melakukan tindakan saat kolom diganti',
'Close a task in a specific column' => 'Tutup tugas di kolom tertentu',
- 'Time-based One-time Password Algorithm' => 'Waktu berbasis Satu-waktu Algoritma Kata sandi',
- 'Two-Factor Provider: ' => 'Provider Dua-Faktor',
+ 'Time-based One-time Password Algorithm' => 'Algoritma Password Satu-Kali Berbasis-Waktu',
+ 'Two-Factor Provider: ' => 'Penyedia Dua-Faktor',
'Disable two-factor authentication' => 'Nonaktifkan otentikasi dua-faktor',
'Enable two-factor authentication' => 'Aktifkan otentikasi dua-faktor',
- 'There is no integration registered at the moment.' => 'Tidak ada integrasi yang diregristasi untuk saat ini',
- 'Password Reset for Kanboard' => 'Setel ulang Kata sandi untuk Kanboard',
- 'Forgot password?' => 'Lupa kata sandi',
- 'Enable "Forget Password"' => 'Aktifkan "Lupa Kata Sandi"',
- 'Password Reset' => 'Setel ulang Kata sandi',
- 'New password' => 'Kata sandi baru',
- 'Change Password' => 'Rubah kata sandi',
- 'To reset your password click on this link:' => 'Untuk menyetel ulang kata sandi anda klik tautan ini:',
- 'Last Password Reset' => 'Terakhir Setel Ulang Kata Sandi',
- 'The password has never been reinitialized.' => 'Kata sandi tidak pernah di reinisialisasi',
- 'Creation' => 'Kreasi',
- 'Expiration' => 'Waktu berakhir',
- 'Password reset history' => 'Sejarah setel ulang kata sandi',
+ 'There is no integration registered at the moment.' => 'Tidak ada integrasi yang didaftarkan untuk saat ini',
+ 'Password Reset for Kanboard' => 'Reset Password untuk Kanboard',
+ 'Forgot password?' => 'Lupa password?',
+ 'Enable "Forget Password"' => 'Aktifkan "Lupa Password"',
+ 'Password Reset' => 'Reset Password',
+ 'New password' => 'Password baru',
+ 'Change Password' => 'Ganti Password',
+ 'To reset your password click on this link:' => 'Untuk reset password Anda klik tautan ini:',
+ 'Last Password Reset' => 'Reset Password Terakhir',
+ 'The password has never been reinitialized.' => 'Password tidak pernah di inisialisasi ulang',
+ 'Creation' => 'Pembuatan',
+ 'Expiration' => 'Kadaluarsa',
+ 'Password reset history' => 'Sejarah reset password',
'All tasks of the column "%s" and the swimlane "%s" have been closed successfully.' => 'Semua tugas dalam kolom "%s" dan swimlane "%s" telah berhasil ditutup',
- 'Do you really want to close all tasks of this column?' => 'Apakah anda yakin akan menutup semua tugas dalam kolom ini?',
+ 'Do you really want to close all tasks of this column?' => 'Apakah Anda yakin mau menutup semua tugas dalam kolom ini?',
'%d task(s) in the column "%s" and the swimlane "%s" will be closed.' => '%d tugas dalam kolom "%s" dan swimlane "%s" akan ditutup.',
'Close all tasks of this column' => 'Tutup semua tugas dalam kolom ini',
- 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => 'Tidak ada Plugin yang mendaftar metode pemberitahuan proyek. Anda masih dapat mengkonfigurasi pemberitahuan individu dalam profil pengguna Anda.',
+ 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => 'Tidak ada plugin yang mendaftarkan metode pemberitahuan proyek. Anda masih bisa mengatur pemberitahuan individu di dalam profil pengguna Anda.',
'My dashboard' => 'Dasbor saya',
'My profile' => 'Profil saya',
'Project owner: ' => 'Pemilik proyek',
'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => 'Identifier proyek adalah opsional dan harus alfanumerik, contoh: MYPROJECT.',
'Project owner' => 'Pemilik proyek',
- 'Those dates are useful for the project Gantt chart.' => 'Tanggal tersebut berguna untuk proyek Gantt chart',
'Private projects do not have users and groups management.' => 'Proyek pribadi tidak memiliki manajemen pengguna dan grup',
'There is no project member.' => 'Tidak ada anggota proyek',
'Priority' => 'Prioritas',
- 'Task priority' => 'Tugas prioritas',
+ 'Task priority' => 'Prioritas tugas',
'General' => 'Umum',
'Dates' => 'Tanggal',
'Default priority' => 'Prioritas default',
@@ -995,8 +981,8 @@ return array(
'Duration in days' => 'Durasi dalam hari',
'Send email when there is no activity on a task' => 'Kirim email jika tidak ada aktifitas dalam tugas',
'Unable to fetch link information.' => 'Tidak dapat mengambil informasi tautan',
- 'Daily background job for tasks' => 'Pekerjaan Latar belakang untuk tugas-tugas ',
- 'Auto' => 'Auto',
+ 'Daily background job for tasks' => 'Tugas latar belakang harian untuk tugas',
+ 'Auto' => 'Otomatis',
'Related' => 'Terkait',
'Attachment' => 'Lampiran',
'Title not found' => 'Judul tidak ditemukan',
@@ -1014,7 +1000,7 @@ return array(
'Internal links' => 'Tautan internal',
'Assign to me' => 'Tugaskan ke saya',
'Me' => 'Saya',
- 'Do not duplicate anything' => 'Jangan menduplikasi apa-apa',
+ 'Do not duplicate anything' => 'Jangan menduplikasi apapun',
'Projects management' => 'Manajemen proyek',
'Users management' => 'Manajemen pengguna',
'Groups management' => 'Manajemen grup',
@@ -1023,258 +1009,309 @@ return array(
'closed' => 'tutup',
'Priority:' => 'Prioritas',
'Reference:' => 'Referensi',
- 'Complexity:' => 'Komplesitas',
+ 'Complexity:' => 'Kompleksitas',
'Swimlane:' => 'Swimlane',
- 'Column:' => 'Kolom',
- 'Position:' => 'Posisi',
- 'Creator:' => 'Pembuat',
+ 'Column:' => 'Kolom:',
+ 'Position:' => 'Posisi:',
+ 'Creator:' => 'Pembuat:',
'Time estimated:' => 'Estimasi waktu:',
'%s hours' => '%s jam',
- 'Time spent:' => 'Waktu dihabiskan',
- 'Created:' => 'Dibuat',
- 'Modified:' => 'Dimodifikasi',
- 'Completed:' => 'Selesai',
- 'Started:' => 'Dimulai',
- 'Moved:' => 'Dipindahkan',
+ 'Time spent:' => 'Waktu yang dihabiskan',
+ 'Created:' => 'Dibuat:',
+ 'Modified:' => 'Dimodifikasi:',
+ 'Completed:' => 'Selesai:',
+ 'Started:' => 'Dimulai:',
+ 'Moved:' => 'Dipindahkan:',
'Task #%d' => 'Tugas #%d',
- 'Date and time format' => 'Format tanggal dan waktu',
'Time format' => 'Format waktu',
- 'Start date: ' => 'Tanggal mulai',
- 'End date: ' => 'Tanggal berakhir',
- 'New due date: ' => 'Tanggal jatuh tempo baru',
- 'Start date changed: ' => 'Tanggal mulai berubah',
- 'Disable private projects' => 'Nonaktifkan proyek',
- 'Do you really want to remove this custom filter: "%s"?' => 'Apakah anda yakin akan menghapus kustom filter: "%s"?',
- 'Remove a custom filter' => 'Hapus kustom filter',
- 'User activated successfully.' => 'Pengguna berhasil diaktivasi.',
+ 'Start date: ' => 'Tanggal mulai: ',
+ 'End date: ' => 'Tanggal berakhir: ',
+ 'New due date: ' => 'Tanggal jatuh tempo baru: ',
+ 'Start date changed: ' => 'Tanggal mulai diganti: ',
+ 'Disable private projects' => 'Nonaktifkan proyek pribadi',
+ 'Do you really want to remove this custom filter: "%s"?' => 'Apakah Anda yakin mau menghapus saringan kustom: "%s"?',
+ 'Remove a custom filter' => 'Hapus saringan kustom',
+ 'User activated successfully.' => 'Pengguna berhasil diaktifkan.',
'Unable to enable this user.' => 'Tidak dapat mengaktifkan pengguna ini.',
'User disabled successfully.' => 'Pengguna berhasil dinonaktifkan.',
'Unable to disable this user.' => 'Tidak dapat menonaktifkan pengguna ini.',
- 'All files have been uploaded successfully.' => 'Semua file telah berhasil di unggah.',
- 'View uploaded files' => 'Lihat file yang diunggah',
- 'The maximum allowed file size is %sB.' => 'Maksimum ukuran file yang diiziinkan adalah %sB.',
- 'Choose files again' => 'Pilih file kembali',
- 'Drag and drop your files here' => 'Drag and drop file anda di sini',
- 'choose files' => 'pilih file',
+ 'All files have been uploaded successfully.' => 'Semua berkas berhasil di unggah.',
+ 'The maximum allowed file size is %sB.' => 'Maksimum ukuran berkas yang diiziinkan adalah %sB.',
+ 'Drag and drop your files here' => 'Drag and drop file Anda di sini',
+ 'choose files' => 'pilih berkas',
'View profile' => 'Lihat profil',
'Two Factor' => 'Dua Faktor',
'Disable user' => 'Nonaktifkan pengguna',
- // '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 columns!' => '',
- // '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' => '',
- // 'User not found.' => '',
- // 'Search in activity stream' => '',
- // 'My activities' => '',
- // 'Activity until yesterday' => '',
- // 'Activity until today' => '',
- // 'Search by creator: ' => '',
- // 'Search by creation date: ' => '',
- // 'Search by task status: ' => '',
- // 'Search by task title: ' => '',
- // 'Activity stream search' => '',
- // 'Projects where "%s" is manager' => '',
- // 'Projects where "%s" is member' => '',
- // 'Open tasks assigned to "%s"' => '',
- // 'Closed tasks assigned to "%s"' => '',
- // 'Assign automatically a color based on a priority' => '',
- // 'Overdue tasks for the project(s) "%s"' => '',
- // 'Upload files' => '',
- // 'Installed Plugins' => '',
- // 'Plugin Directory' => '',
- // 'Plugin installed successfully.' => '',
- // 'Plugin updated successfully.' => '',
- // 'Plugin removed successfully.' => '',
- // 'Subtask converted to task successfully.' => '',
- // 'Unable to convert the subtask.' => '',
- // 'Unable to extract plugin archive.' => '',
- // 'Plugin not found.' => '',
- // 'You don\'t have the permission to remove this plugin.' => '',
- // 'Unable to download plugin archive.' => '',
- // 'Unable to write temporary file for plugin.' => '',
- // 'Unable to open plugin archive.' => '',
- // 'There is no file in the plugin archive.' => '',
- // 'Create tasks in bulk' => '',
- // 'Your Kanboard instance is not configured to install plugins from the user interface.' => '',
- // 'There is no plugin available.' => '',
- // 'Install' => '',
- // 'Update' => '',
- // 'Up to date' => '',
- // 'Not available' => '',
- // 'Remove plugin' => '',
- // 'Do you really want to remove this plugin: "%s"?' => '',
- // 'Uninstall' => '',
- // 'Listing' => '',
- // 'Metadata' => '',
- // 'Manage projects' => '',
- // 'Convert to task' => '',
- // 'Convert sub-task to task' => '',
- // 'Do you really want to convert this sub-task to a task?' => '',
- // 'My task title' => '',
- // 'Enter one task by line.' => '',
- // 'Number of failed login:' => '',
- // 'Account locked until:' => '',
- // 'Email settings' => '',
- // 'Email sender address' => '',
- // 'Email transport' => '',
- // 'Webhook token' => '',
- // 'Imports' => '',
- // 'Project tags management' => '',
- // 'Tag created successfully.' => '',
- // 'Unable to create this tag.' => '',
- // 'Tag updated successfully.' => '',
- // 'Unable to update this tag.' => '',
- // 'Tag removed successfully.' => '',
- // 'Unable to remove this tag.' => '',
- // 'Global tags management' => '',
- // 'Tags' => '',
- // 'Tags management' => '',
- // 'Add new tag' => '',
- // 'Edit a tag' => '',
- // 'Project tags' => '',
- // 'There is no specific tag for this project at the moment.' => '',
- // 'Tag' => '',
- // 'Remove a tag' => '',
- // 'Do you really want to remove this tag: "%s"?' => '',
- // 'Global tags' => '',
- // 'There is no global tag at the moment.' => '',
- // 'This field cannot be empty' => '',
- // 'Close a task when there is no activity in an specific column' => '',
- // '%s removed a subtask for the task #%d' => '',
- // '%s removed a comment on the task #%d' => '',
- // 'Comment removed on task #%d' => '',
- // 'Subtask removed on task #%d' => '',
- // 'Hide tasks in this column in the dashboard' => '',
- // '%s removed a comment on the task %s' => '',
- // '%s removed a subtask for the task %s' => '',
- // 'Comment removed' => '',
- // 'Subtask removed' => '',
- // '%s set a new internal link for the task #%d' => '',
- // '%s removed an internal link for the task #%d' => '',
- // 'A new internal link for the task #%d have been defined' => '',
- // 'Internal link removed for the task #%d' => '',
- // '%s set a new internal link for the task %s' => '',
- // '%s removed an internal link for the task %s' => '',
- // 'Automatically set the due date on task creation' => '',
- // 'Move the task to another column when closed' => '',
- // 'Move the task to another column when not moved during a given period' => '',
- // 'Dashboard for %s' => '',
- // 'Tasks overview for %s' => '',
- // 'Subtasks overview for %s' => '',
- // 'Projects overview for %s' => '',
- // 'Activity stream for %s' => '',
- // 'Calendar for %s' => '',
- // 'Notifications for %s' => '',
- // 'Subtasks export' => '',
- // 'Tasks exportation' => '',
- // 'Assign a color when the task is moved to a specific swimlane' => '',
- // 'Assign a priority when the task is moved to a specific swimlane' => '',
- // 'User unlocked successfully.' => '',
- // 'Unable to unlock the user.' => '',
- // 'Move a task to another swimlane' => '',
- // 'Creator Name' => '',
- // 'Time spent and estimated' => '',
- // 'Move position' => '',
- // 'Move task to another position on the board' => '',
- // 'Insert before this task' => '',
- // 'Insert after this task' => '',
- // 'Unlock this user' => '',
- // 'Custom Project Roles' => '',
- // 'Add a new custom role' => '',
- // 'Restrictions for the role "%s"' => '',
- // 'Add a new project restriction' => '',
- // 'Add a new drag and drop restriction' => '',
- // 'Add a new column restriction' => '',
- // 'Edit this role' => '',
- // 'Remove this role' => '',
- // 'There is no restriction for this role.' => '',
- // 'Only moving task between those columns is permitted' => '',
- // 'Close a task in a specific column when not moved during a given period' => '',
- // 'Edit columns' => '',
- // 'The column restriction has been created successfully.' => '',
- // 'Unable to create this column restriction.' => '',
- // 'Column restriction removed successfully.' => '',
- // 'Unable to remove this restriction.' => '',
- // 'Your custom project role has been created successfully.' => '',
- // 'Unable to create custom project role.' => '',
- // 'Your custom project role has been updated successfully.' => '',
- // 'Unable to update custom project role.' => '',
- // 'Custom project role removed successfully.' => '',
- // 'Unable to remove this project role.' => '',
- // 'The project restriction has been created successfully.' => '',
- // 'Unable to create this project restriction.' => '',
- // 'Project restriction removed successfully.' => '',
- // 'You cannot create tasks in this column.' => '',
- // 'Task creation is permitted for this column' => '',
- // 'Closing or opening a task is permitted for this column' => '',
- // 'Task creation is blocked for this column' => '',
- // 'Closing or opening a task is blocked for this column' => '',
- // 'Task creation is not permitted' => '',
- // 'Closing or opening a task is not permitted' => '',
- // 'New drag and drop restriction for the role "%s"' => '',
- // 'People belonging to this role will be able to move tasks only between the source and the destination column.' => '',
- // 'Remove a column restriction' => '',
- // 'Do you really want to remove this column restriction: "%s" to "%s"?' => '',
- // 'New column restriction for the role "%s"' => '',
- // 'Rule' => '',
- // 'Do you really want to remove this column restriction?' => '',
- // 'Custom roles' => '',
- // 'New custom project role' => '',
- // 'Edit custom project role' => '',
- // 'Remove a custom role' => '',
- // 'Do you really want to remove this custom role: "%s"? All people assigned to this role will become project member.' => '',
- // 'There is no custom role for this project.' => '',
- // 'New project restriction for the role "%s"' => '',
- // 'Restriction' => '',
- // 'Remove a project restriction' => '',
- // 'Do you really want to remove this project restriction: "%s"?' => '',
- // 'Duplicate to multiple projects' => '',
- // 'This field is required' => '',
- // 'Moving a task is not permitted' => '',
- // 'This value must be in the range %d to %d' => '',
+ 'Do you really want to disable this user: "%s"?' => 'Anda yakin mau menonaktifkan pengguna ini: "%s"?',
+ 'Enable user' => 'Aktifkan pengguna',
+ 'Do you really want to enable this user: "%s"?' => 'Anda yakin mau mengaktifkan pengguna ini: "%s"?',
+ 'Download' => 'Unduh',
+ 'Uploaded: %s' => 'Diunggah: %s',
+ 'Size: %s' => 'Ukuran: %s',
+ 'Uploaded by %s' => 'Diunggah oleh %s',
+ 'Filename' => 'Nama berkas',
+ 'Size' => 'Ukuran',
+ 'Column created successfully.' => 'Kolom berhasil dibuat.',
+ 'Another column with the same name exists in the project' => 'Ada kolom lain dengan nama yang sama di proyek ini',
+ 'Default filters' => 'Saringan default',
+ 'Your board doesn\'t have any columns!' => 'Papan Anda tidak memiliki kolom!',
+ 'Change column position' => 'Ganti posisi kolom',
+ 'Switch to the project overview' => 'Pindah ke ringkasan proyek',
+ 'User filters' => 'Saringan pengguna',
+ 'Category filters' => 'Saringan kategori',
+ 'Upload a file' => 'Unggah berkas',
+ 'View file' => 'Lihat berkas',
+ 'Last activity' => 'Aktivitas terakhir',
+ 'Change subtask position' => 'Ganti posisi sub-tugas',
+ 'This value must be greater than %d' => 'Nilai ini harus lebih besar dari %d',
+ 'Another swimlane with the same name exists in the project' => 'Swimlane lain dengan nama yang sama sudah ada di proyek ini',
+ 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => 'Contoh: http://contoh.kanboard.net/ (digunakan untuk menghasilkan URL yang absolut',
+ 'Actions duplicated successfully.' => 'Tindakan berhasil di duplikasi.',
+ 'Unable to duplicate actions.' => 'Tidak bisa menduplikasi tindakan.',
+ 'Add a new action' => 'Tambahkan tindakan baru',
+ 'Import from another project' => 'Impor dari proyek lain',
+ 'There is no action at the moment.' => 'Belum ada tindakan pada saat ini.',
+ 'Import actions from another project' => 'Impor tindakan dari proyek lain',
+ 'There is no available project.' => 'Tidak ada proyek yang tersedia',
+ 'Local File' => 'Berkas Lokal',
+ 'Configuration' => 'Konfigurasi',
+ 'PHP version:' => 'Versi PHP:',
+ 'PHP SAPI:' => 'PHP SAPI:',
+ 'OS version:' => 'Versi sistem operasi:',
+ 'Database version:' => 'Versi database:',
+ 'Browser:' => 'Peramban:',
+ 'Task view' => 'Tampilan Tugas',
+ 'Edit task' => 'Edit tugas',
+ 'Edit description' => 'Edit deskripsi',
+ 'New internal link' => 'Tautan internal baru',
+ 'Display list of keyboard shortcuts' => 'Tampilkan daftar pintasan keyboard',
+ 'Menu' => 'Menu',
+ 'Set start date' => 'Atur tanggal mulai',
+ 'Avatar' => 'Avatar',
+ 'Upload my avatar image' => 'Unggah foto avatar saya',
+ 'Remove my image' => 'Hapus foto saya',
+ 'The OAuth2 state parameter is invalid' => 'Status parameter OAuth2 tidak sesuai',
+ 'User not found.' => 'Pengguna tidak ditemukan.',
+ 'Search in activity stream' => 'Cari di saluran aktivitas',
+ 'My activities' => 'Aktivitas saya',
+ 'Activity until yesterday' => 'Aktivitas sampai kemarin',
+ 'Activity until today' => 'Aktivitas sampai hari ini',
+ 'Search by creator: ' => 'Cari berdasarkan pembuat: ',
+ 'Search by creation date: ' => 'Cari berdasarkan tanggal pembuatan: ',
+ 'Search by task status: ' => 'Cari berdasarkanstatus tugas: ',
+ 'Search by task title: ' => 'Cari berdasarkan judul tugas: ',
+ 'Activity stream search' => 'Pencarian saluran aktivitas',
+ 'Projects where "%s" is manager' => 'Proyek dimana "%s" adalah manajernya',
+ 'Projects where "%s" is member' => 'Proyek dimana "%s" adalah anggotanya',
+ 'Open tasks assigned to "%s"' => 'Tugas terbuka ditugaskan pada "%s"',
+ 'Closed tasks assigned to "%s"' => 'Tugas tertutup ditugaskan pada "%s"',
+ 'Assign automatically a color based on a priority' => 'Berikan warna otomatis berdasarkan prioritas',
+ 'Overdue tasks for the project(s) "%s"' => 'Tugas yang kadaluarsa untuk proyek "%s"',
+ 'Upload files' => 'Unggah berkas',
+ 'Installed Plugins' => 'Plugin terpasang',
+ 'Plugin Directory' => 'Direktori Plugin',
+ 'Plugin installed successfully.' => 'Plugin berhasil dipasang.',
+ 'Plugin updated successfully.' => 'Plugin berhasil diperbarui.',
+ 'Plugin removed successfully.' => 'Plugin berhasil dihapus.',
+ 'Subtask converted to task successfully.' => 'Sub-tugas berhasil diubah menjadi tugas.',
+ 'Unable to convert the subtask.' => 'Tidak dapat mengubah sub-tugas.',
+ 'Unable to extract plugin archive.' => 'Tidak bisa mengekstrak arsip plugin.',
+ 'Plugin not found.' => 'Plugin tidak ditemukan.',
+ 'You don\'t have the permission to remove this plugin.' => 'Anda tidak memiliki izin untuk menghapus plugin ini.',
+ 'Unable to download plugin archive.' => 'Tidak dapat mengunduh arsip plugin.',
+ 'Unable to write temporary file for plugin.' => 'Tidak dapat menulis berkas sementara untuk plugin.',
+ 'Unable to open plugin archive.' => 'Tidak dapat membuka arsip plugin.',
+ 'There is no file in the plugin archive.' => 'Tidak ada berkas di dalam arsip plugin.',
+ 'Create tasks in bulk' => 'Buat tugas sekaligus',
+ 'Your Kanboard instance is not configured to install plugins from the user interface.' => 'Instalasi Kanboard Anda tidak diatur untuk memasang plugin dari antar muka pengguna.',
+ 'There is no plugin available.' => 'Tidak ada plugin yang tersedia.',
+ 'Install' => 'Pasang',
+ 'Update' => 'Perbarui',
+ 'Up to date' => 'Terbaru',
+ 'Not available' => 'Tidak tersedia',
+ 'Remove plugin' => 'Hapus plugin',
+ 'Do you really want to remove this plugin: "%s"?' => 'Anda yakin ingin menghapus plugin ini: "%s"?',
+ 'Uninstall' => 'Lepaskan',
+ 'Listing' => 'Daftar',
+ 'Metadata' => 'Metadata',
+ 'Manage projects' => 'Atur proyek',
+ 'Convert to task' => 'Ubah menjadi tugas',
+ 'Convert sub-task to task' => 'Ubah sub-tugas menjadi tugas',
+ 'Do you really want to convert this sub-task to a task?' => 'Anda yakin ingin mengubah sub-tugas ini menjadi tugas?',
+ 'My task title' => 'Judul tugas saya',
+ 'Enter one task by line.' => 'Masukkan satu tugas berdasarkan baris.',
+ 'Number of failed login:' => 'Jumlah login yang gagal:',
+ 'Account locked until:' => 'Akun terkunci hingga:',
+ 'Email settings' => 'Pengaturan email',
+ 'Email sender address' => 'Alamat pengirim email',
+ 'Email transport' => 'Transportasi email',
+ 'Webhook token' => 'Token Webhook',
+ 'Project tags management' => 'Manajemen tag proyek',
+ 'Tag created successfully.' => 'Tag berhasil dibuat.',
+ 'Unable to create this tag.' => 'Tidak dapat membuat tag ini.',
+ 'Tag updated successfully.' => 'Tag berhasil diperbarui',
+ 'Unable to update this tag.' => 'Tidak dapat memperbarui tag ini.',
+ 'Tag removed successfully.' => 'Tag berhasil dihapus.',
+ 'Unable to remove this tag.' => 'Tidak dapat menghapus tag ini.',
+ 'Global tags management' => 'Manajemen tag global',
+ 'Tags' => 'Tag',
+ 'Tags management' => 'Manajemen tag',
+ 'Add new tag' => 'Tambah tag baru',
+ 'Edit a tag' => 'Edit tag',
+ 'Project tags' => 'Tag proyek',
+ 'There is no specific tag for this project at the moment.' => 'Saat ini tidak ada tag yang spesifik pada proyek ini.',
+ 'Tag' => 'Tag',
+ 'Remove a tag' => 'Hapus tag',
+ 'Do you really want to remove this tag: "%s"?' => 'Anda yakin ingin menghapus tag ini: "%s"?',
+ 'Global tags' => 'Tag global',
+ 'There is no global tag at the moment.' => 'Saat ini tidak ada tag global.',
+ 'This field cannot be empty' => 'Bidang ini tidak boleh kosong',
+ 'Close a task when there is no activity in an specific column' => 'Tutup tugas saat tidak ada aktivitas di kolom tertentu',
+ '%s removed a subtask for the task #%d' => '%s menghapus sub-tugas untuk tugas #%d',
+ '%s removed a comment on the task #%d' => '%s menghapus komentar pada tugas #%d',
+ 'Comment removed on task #%d' => 'Komentar dihapus pada tugas #%d',
+ 'Subtask removed on task #%d' => 'Sub-tugas dihapus pada tugas #%d',
+ 'Hide tasks in this column in the dashboard' => 'Sembunyikan tugas-tugas di kolom ini di dasbor',
+ '%s removed a comment on the task %s' => '%s menghapus komentar pada tugas %s',
+ '%s removed a subtask for the task %s' => '%s menghapus sub-tugas untuk tugas %s',
+ 'Comment removed' => 'Komentar dihapus',
+ 'Subtask removed' => 'Sub-tugas dihapus',
+ '%s set a new internal link for the task #%d' => '%s memasang tautan internal baru untuk tugas #%d',
+ '%s removed an internal link for the task #%d' => '%s menghapus tautan internal untuk tugas #%d',
+ 'A new internal link for the task #%d have been defined' => 'Tautan internal baru untuk tugas #%d telah ditentukan',
+ 'Internal link removed for the task #%d' => 'Tautan internal untuk tugas #%d telah dihapus',
+ '%s set a new internal link for the task %s' => '%s memasang tautan internal baru untuk tugas %s',
+ '%s removed an internal link for the task %s' => '%s menghapus tautan internal untuk tugas %s',
+ 'Automatically set the due date on task creation' => 'Otomatis memasang tanggal kadaluarsa saat pembuatan tugas',
+ 'Move the task to another column when closed' => 'Pindahkan tugas ke kolom lain saat ditutup',
+ 'Move the task to another column when not moved during a given period' => 'Pindahkan tugas ke kolom lain saat tidak dipindahkan selama periode yang diberikan',
+ 'Dashboard for %s' => 'Dasbor untuk %s',
+ 'Tasks overview for %s' => 'Ringkasan tugas-tugas untuk %s',
+ 'Subtasks overview for %s' => 'Ringkasan sub-tugas untuk %s',
+ 'Projects overview for %s' => 'Ringkasan proyek untuk %s',
+ 'Activity stream for %s' => 'Arus aktivitas untuk %s',
+ 'Calendar for %s' => 'Kalender untuk %s',
+ 'Notifications for %s' => 'Notifikasi untuk %s',
+ 'Assign a color when the task is moved to a specific swimlane' => 'Berikan warna saat tugas dipindahkan ke swimlane tertentu',
+ 'Assign a priority when the task is moved to a specific swimlane' => 'Berikan prioritas saat tugas dipindahkan ke swimlane tertentu',
+ 'User unlocked successfully.' => 'Berhasil membuka blokir pengguna.',
+ 'Unable to unlock the user.' => 'Tidak bisa membuka blokir pengguna.',
+ 'Move a task to another swimlane' => 'Pindahkan tugas ke swimlane lain',
+ 'Creator Name' => 'Nama Pembuat',
+ 'Time spent and estimated' => 'Waktu yang dihabiskan dan diperkirakan',
+ 'Move position' => 'Pindahkan posisi',
+ 'Move task to another position on the board' => 'Pindahkan tugas ke posisi lain di dalam papan',
+ 'Insert before this task' => 'Masukkan sebelum tugas ini',
+ 'Insert after this task' => 'Masukkan setelah tugas ini',
+ 'Unlock this user' => 'Buka pengguna ini',
+ 'Custom Project Roles' => 'Peran Proyek Kustom',
+ 'Add a new custom role' => 'Tambahkan peran kustom baru',
+ 'Restrictions for the role "%s"' => 'Batasan untuk peran "%s"',
+ 'Add a new project restriction' => 'Tambahkan batasan proyek baru',
+ 'Add a new drag and drop restriction' => 'Tambahkan batasan drag and drop baru',
+ 'Add a new column restriction' => 'Tambahkan batasan kolom baru',
+ 'Edit this role' => 'Edit peran ini',
+ 'Remove this role' => 'Hapus peran ini',
+ 'There is no restriction for this role.' => 'Tidak ada batasan untuk peran ini.',
+ 'Only moving task between those columns is permitted' => 'Hanya diizinkan untuk memindahkan tugas diantara kolom-kolom tersebut',
+ 'Close a task in a specific column when not moved during a given period' => 'Tutup tugas pada kolom tertentu saat tidak dipindahkan pada periode yang diberikan',
+ 'Edit columns' => 'Edit kolom',
+ 'The column restriction has been created successfully.' => 'Batasan kolom berhasil dibuat.',
+ 'Unable to create this column restriction.' => 'Tidak dapat membuat batasan kolom ini.',
+ 'Column restriction removed successfully.' => 'Batasan kolom berhasil dihapus.',
+ 'Unable to remove this restriction.' => 'Gagal menghapus batasan ini.',
+ 'Your custom project role has been created successfully.' => 'Peran kustom proyek Anda berhasil dibuat.',
+ 'Unable to create custom project role.' => 'Tidak dapat membuat peran proyek kustom.',
+ 'Your custom project role has been updated successfully.' => 'Peran proyek kustom Anda berhasil diperbarui.',
+ 'Unable to update custom project role.' => 'Tidak dapat memperbarui peran kustom proyek',
+ 'Custom project role removed successfully.' => 'Peran kustom proyek berhasil dihapus.',
+ 'Unable to remove this project role.' => 'Tidak dapat menghapus peran proyek ini.',
+ 'The project restriction has been created successfully.' => 'Batasan proyek ini berhasil dibuat.',
+ 'Unable to create this project restriction.' => 'Tidak dapat membuat batasan proyek ini.',
+ 'Project restriction removed successfully.' => 'Batasan proyek berhasil dihapus.',
+ 'You cannot create tasks in this column.' => 'Anda tidak dapat membuat tugas di kolom ini.',
+ 'Task creation is permitted for this column' => 'Pembuatan tugas diizinkan untuk kolom ini',
+ 'Closing or opening a task is permitted for this column' => 'Penutupan atau pembukaan tugas diizinkan untuk kolom ini',
+ 'Task creation is blocked for this column' => 'Pembuatan tugas diblokir dari kolom ini',
+ 'Closing or opening a task is blocked for this column' => 'Penutupan atau pembukaan tugas diblokir di kolom ini',
+ 'Task creation is not permitted' => 'Oembuatan tugas tidak diizinkan',
+ 'Closing or opening a task is not permitted' => 'Penutupan atau pembukaan tugas tidak diizinkan',
+ 'New drag and drop restriction for the role "%s"' => 'Larangan drag and drop baru untuk peran "%s"',
+ 'People belonging to this role will be able to move tasks only between the source and the destination column.' => 'Orang-orang dengan peran ini dapat memindahkan tugas diantara kolom sumber dan destinasi.',
+ 'Remove a column restriction' => 'Hapus pembatasan kolom',
+ 'Do you really want to remove this column restriction: "%s" to "%s"?' => 'Anda yakin ingin menghapus pembatasan kolom ini: "%s" ke "%s"?',
+ 'New column restriction for the role "%s"' => 'Kolom pembatasan baru untuk peran "%s"',
+ 'Rule' => 'Aturan',
+ 'Do you really want to remove this column restriction?' => 'Anda yakin ingin menghapus pembatasan kolom ini?',
+ 'Custom roles' => 'Peran kustom',
+ 'New custom project role' => 'Peran kustom proyek baru',
+ 'Edit custom project role' => 'Edit peran kustom proyek',
+ 'Remove a custom role' => 'Hapus peran kustom',
+ 'Do you really want to remove this custom role: "%s"? All people assigned to this role will become project member.' => 'Anda yakin ingin menghapus peran kustom ini: "%s"? Semua orang yang memiliki peran ini akan berubah menjadi anggota proyek.',
+ 'There is no custom role for this project.' => 'Tidak ada peran kustom untuk proyek ini.',
+ 'New project restriction for the role "%s"' => 'Batasan proyek baru untuk peran "%s"',
+ 'Restriction' => 'Pembatasan',
+ 'Remove a project restriction' => 'Hapus batasan proyek',
+ 'Do you really want to remove this project restriction: "%s"?' => 'Anda yakin ingin menghapus pembatasan proyek ini: "%s"?',
+ 'Duplicate to multiple projects' => 'Duplikasikan ke banyak proyek',
+ 'This field is required' => 'Bidang ini dibutuhkan',
+ 'Moving a task is not permitted' => 'Memindahkan tugas tidak diizinkan',
+ 'This value must be in the range %d to %d' => 'Nilai ini harus berkisar antara %d hingga %d',
+ 'You are not allowed to move this task.' => 'Anda tidak diizinkan untuk memindahkan tugas ini.',
+ 'API User Access' => 'API Akses Pengguna',
+ 'Preview' => 'Pratinjau',
+ 'Write' => 'Tulis',
+ 'Write your text in Markdown' => 'Tuliskan teks Anda di Markdown',
+ 'New External Task: %s' => 'Tugas Eksternal Baru: %s',
+ 'No personal API access token registered.' => 'Tidak ada token akses API personal yang terdaftar.',
+ 'Your personal API access token is "%s"' => 'Token akses API personal Anda adalah "%s"',
+ 'Remove your token' => 'Hapus token Anda',
+ 'Generate a new token' => 'Generate token baru',
+ 'Showing %d-%d of %d' => 'Menampilkan %d-%d of %d',
+ // 'Outgoing Emails' => '',
+ // 'Add or change currency rate' => '',
+ // 'Reference currency: %s' => '',
+ // 'Add custom filters' => '',
+ // 'Export' => '',
+ // 'Add link label' => '',
+ // 'Incompatible Plugins' => '',
+ // 'Compatibility' => '',
+ // 'Permissions and ownership' => '',
+ // 'Priorities' => '',
+ // 'Close this window' => '',
+ // 'Unable to upload this file.' => '',
+ // 'Import tasks' => '',
+ // 'Choose a project' => '',
+ // 'Profile' => '',
+ // 'Application role' => '',
+ // '%d invitations were sent.' => '',
+ // '%d invitation was sent.' => '',
+ // 'Unable to create this user.' => '',
+ // 'Kanboard Invitation' => '',
+ // 'Visible on dashboard' => '',
+ // 'Created at:' => '',
+ // 'Updated at:' => '',
+ // 'There is no custom filter.' => '',
+ // 'New User' => '',
+ // 'Authentication' => '',
+ // 'If checked, this user will use a third-party system for authentication.' => '',
+ // 'The password is necessary only for local users.' => '',
+ // 'You have been invited to register on Kanboard.' => '',
+ // 'Click here to join your team' => '',
+ // 'Invite people' => '',
+ // 'Emails' => '',
+ // 'Enter one email address by line.' => '',
+ // 'Add these people to this project' => '',
+ // 'Add this person to this project' => '',
+ // 'Sign-up' => '',
+ // 'Credentials' => '',
+ // 'New user' => '',
+ // 'This username is already taken' => '',
+ // 'A link to reset your password has been sent by email.' => '',
+ // 'Your profile must have a valid email address.' => '',
+ // 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
+ // 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
+ // 'The email configuration has been disabled by the administrator.' => '',
);
diff --git a/app/Locale/it_IT/translations.php b/app/Locale/it_IT/translations.php
index e4f51b3a..93128cd2 100644
--- a/app/Locale/it_IT/translations.php
+++ b/app/Locale/it_IT/translations.php
@@ -61,7 +61,6 @@ return array(
'%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.',
- 'Edit board' => 'Modifica questa bacheca',
'Disable' => 'Disattiva',
'Enable' => 'Attiva',
'New project' => 'Nuovo progetto',
@@ -72,7 +71,6 @@ return array(
'Title' => 'Titolo',
'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"?' => '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!',
@@ -160,9 +158,7 @@ return array(
'Task count' => 'Numero di task',
'User' => 'Utente',
'Comments' => 'Commenti',
- 'Leave a comment' => 'Lascia un commento',
'Comment is required' => 'Si richiede un commento',
- 'Leave a description' => 'Lascia una descrizione',
'Comment added successfully.' => 'Commenti aggiunti con successo.',
'Unable to create your comment.' => 'Impossibile creare questo commento.',
'Due Date' => 'Data di scadenza',
@@ -224,7 +220,6 @@ return array(
'Search' => 'Cerca',
'Nothing found.' => 'Non si è trovato nulla.',
'Due date' => 'Data di scadenza',
- 'Others formats accepted: %s and %s' => 'Altri formati accettati: %s e %s',
'Description' => 'Descrizione',
'%d comments' => '%d commenti',
'%d comment' => '%d commento',
@@ -297,8 +292,7 @@ return array(
'Display another project' => 'Mostra un altro progetto',
'Created by %s' => 'Creato da %s',
'Tasks Export' => 'Export dei task',
- 'Start Date' => 'Data d\'inizio',
- 'End Date' => 'Data di fine',
+ 'Start Date' => 'Data di inizio',
'Execute' => 'Esegui',
'Task Id' => 'Id del task',
'Creator' => 'Creatore',
@@ -342,8 +336,8 @@ return array(
'Remote' => 'Remoto',
'Enabled' => 'Abilitato',
'Disabled' => 'Disabilitato',
- 'Username:' => 'Nome utente:',
- 'Name:' => 'Nome:',
+ 'Login:' => 'Nome utente:',
+ 'Full Name:' => 'Nome:',
// 'Email:' => '',
'Notifications:' => 'Notifiche:',
'Notifications' => 'Notifiche',
@@ -516,10 +510,8 @@ return array(
'Link labels' => 'Etichette delle relazioni',
'Link modification' => 'Modifica relazione',
'Links' => 'Relazioni',
- 'Link settings' => 'Impostazioni relazioni',
'Opposite label' => 'Etichetta contraria',
'Remove a link' => 'Rimuovi una relazione',
- 'Task\'s links' => 'Relazioni del task',
'The labels must be different' => 'Le etichette devono essere diverse',
'There is no link.' => 'Nessuna relazione presente.',
'This label must be unique' => 'Questa etichetta deve essere univoca',
@@ -552,7 +544,6 @@ return array(
'Compact view' => 'Vista compatta',
'Horizontal scrolling' => 'Scrolling orizzontale',
'Compact/wide view' => 'Vista compatta/estesa',
- 'No results match:' => 'Nessun risultato trovato:',
'Currency' => 'Valuta',
'Private project' => 'Progetto privato',
'AUD - Australian Dollar' => 'AUD - Dollari Australiani',
@@ -566,6 +557,7 @@ return array(
'JPY - Japanese Yen' => 'JPY - Yen Giapponesi',
'NZD - New Zealand Dollar' => 'NZD - Dollari della Nuova Zelanda',
'RSD - Serbian dinar' => 'RSD - Dinar Serbi',
+ // 'CNY - Chinese Yuan' => '',
'USD - US Dollar' => 'USD - Dollari Americani',
'Destination column' => 'Colonna destinazione',
'Move the task to another column when assigned to a user' => 'Sposta il task in un\'altra colonna quando viene assegnato ad un utente',
@@ -580,7 +572,6 @@ return array(
'Currency rates' => 'Tassi di cambio',
'Rate' => 'Cambio',
'Change reference currency' => 'Cambia la valuta di riferimento',
- 'Add a new currency rate' => 'Aggiungi un nuovo tasso di cambio',
'Reference currency' => 'Valuta di riferimento',
'The currency rate have been added successfully.' => 'Il tasso di cambio è stato aggiunto con successo.',
'Unable to add this currency rate.' => 'Impossibile aggiungere questo tasso di cambio.',
@@ -645,10 +636,10 @@ return array(
'Project settings' => 'Impostazioni di progetto',
'Show subtasks based on the time tracking' => 'Mostra i sotto-task in base al time tracking',
'Show tasks based on the creation date' => 'Mostra i task in base alla data di creazione',
- 'Show tasks based on the start date' => 'Mostra i task in base alla data di inzio',
+ 'Show tasks based on the start date' => 'Mostra i task in base alla data di inizio',
'Subtasks time tracking' => 'Time tracking per i sotto-task',
'User calendar view' => 'Vista utente a calendario',
- 'Automatically update the start date' => 'Aggiorna automaticamente la data di inzio',
+ 'Automatically update the start date' => 'Aggiorna automaticamente la data di inizio',
'iCal feed' => 'feed iCal',
'Preferences' => 'Preferenze',
'Security' => 'Sicurezza',
@@ -702,7 +693,6 @@ return array(
// '<30m' => '',
'Stop timer' => 'Ferma il timer',
'Start timer' => 'Avvia il timer',
- 'Add project member' => 'Aggiungi un membro di progetto',
'My activity stream' => 'Il mio flusso attività',
'My calendar' => 'Il mio calendario',
'Search tasks' => 'Ricerca task',
@@ -750,15 +740,13 @@ return array(
'Cycle time: ' => 'Tempo di lavorazione (Cycle Time): ',
'Time spent into each column' => 'Tempo trascorso in ogni colonna',
'The lead time is the duration between the task creation and the completion.' => 'Il tempo di consegna (Lead Time) è la durata tra la creazione di un task ed il suo completamento.',
- 'The cycle time is the duration between the start date and the completion.' => 'Il tempo di lavorazione (Cycle Time) è la durata tra la data di inzio della lavorazione di un task ed il suo completamento.',
+ 'The cycle time is the duration between the start date and the completion.' => 'Il tempo di lavorazione (Cycle Time) è la durata tra la data di inizio della lavorazione di un task ed il suo completamento.',
'If the task is not closed the current time is used instead of the completion date.' => 'Se il task non è chiuso sarà usata la data attuale invece della data di completamento.',
- 'Set automatically the start date' => 'Imposta automaticamente la data di inzio',
+ 'Set automatically the start date' => 'Imposta automaticamente la data di inizio',
'Edit Authentication' => 'Modifica Autenticazione',
'Remote user' => 'Utente remoto',
'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => 'La password degli utenti remoti (ad esempio: LDAP, account Google e Github) non è salvata nel database di Kanboard',
'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => 'Se imposti l\'opzione "Disabilita il form di login", le credenzali inserite nella saranno ignorate.',
- 'New remote user' => 'Nuovo utente remoto',
- 'New local user' => 'Nuovo utente locale',
'Default task color' => 'Colore predefinito dei task',
'This feature does not work with all browsers.' => 'Questa feature non funziona con tutti i browser.',
'There is no destination project available.' => 'Non ci sono progetti disponbili come destinazione.',
@@ -780,8 +768,8 @@ return array(
'Add task' => 'Aggiungi task',
'Start date:' => 'Data di inizio:',
'Due date:' => 'Data di completamento:',
- 'There is no start date or due date for this task.' => 'Nessuna data di inzio o di scadenza per questo task.',
- 'Moving or resizing a task will change the start and due date of the task.' => 'Spostando o ridimensionado un task ne modifca la data di inzio e di scadenza.',
+ 'There is no start date or due date for this task.' => 'Nessuna data di inizio o di scadenza per questo task.',
+ 'Moving or resizing a task will change the start and due date of the task.' => 'Spostando o ridimensionado un task ne modifca la data di inizio e di scadenza.',
'There is no task in your project.' => 'Non ci sono task nel tuo progetto.',
'Gantt chart' => 'Grafici Gantt',
'People who are project managers' => 'Persone che sono manager di progetto',
@@ -800,7 +788,7 @@ return array(
'Gantt chart for this project' => 'Grafico Gantt per questo progetto',
'Project board' => 'Bacheca del progetto',
'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.',
+ 'There is no start date or end date for this project.' => 'Non è prevista una data di inizio o fine per questo progetto.',
'Projects Gantt chart' => 'Grafico Gantt dei progetti',
'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',
@@ -852,7 +840,6 @@ return array(
'Owner' => 'Proprietario',
'Unread notifications' => 'Notifiche non lette',
'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 successo.',
'Nothing have been imported!' => 'Non è stato importato nulla!',
@@ -980,7 +967,6 @@ return array(
'Project owner: ' => 'Proprietario del progetto: ',
'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => 'L\'identificativo del progetto è opzionale e deve essere alfanumerico, ad esempio: MIOPROGETTO.',
'Project owner' => 'Proprietario del progetto',
- 'Those dates are useful for the project Gantt chart.' => 'Le seguenti date sono utilizzate per i grafici Gantt di progetto.',
'Private projects do not have users and groups management.' => 'Per i progetti privati non è prevista la gestione di utenti e gruppi.',
'There is no project member.' => 'Non è impostato un membro del progetto.',
'Priority' => 'Priorità',
@@ -1037,7 +1023,6 @@ return array(
'Started:' => 'Iniziato:',
'Moved:' => 'Spostato:',
// 'Task #%d' => '',
- 'Date and time format' => 'Formato data e ora',
'Time format' => 'Formato ora',
'Start date: ' => 'Data di inizio: ',
'End date: ' => 'Data di fine: ',
@@ -1051,9 +1036,7 @@ return array(
'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',
@@ -1103,7 +1086,7 @@ return array(
'New internal link' => 'Nuovo link interno',
'Display list of keyboard shortcuts' => 'Mostra una lista di scorciatoie da tastiera',
// 'Menu' => '',
- 'Set start date' => 'Imposta la data di inzio',
+ 'Set start date' => 'Imposta la data di inizio',
// 'Avatar' => '',
'Upload my avatar image' => 'Carica l\'immagine del mio avatar',
'Remove my image' => 'Rimuovi la mia immagine',
@@ -1162,8 +1145,7 @@ return array(
'Email settings' => 'Impostazioni Email',
'Email sender address' => 'Indirizzo Email mittente',
'Email transport' => 'Trasporto Email',
- // 'Webhook token' => '',
- 'Imports' => 'Importa',
+ 'Webhook token' => 'Token Webhook',
'Project tags management' => 'Gestione tag di progetto',
'Tag created successfully.' => 'Tag creato con successo.',
'Unable to create this tag.' => 'Impossibile creare questo tag.',
@@ -1184,97 +1166,152 @@ return array(
'Global tags' => 'Tag globali',
'There is no global tag at the moment.' => 'Non sono definiti tag globali al momento.',
'This field cannot be empty' => 'Questo campo non può essere vuoto',
- // 'Close a task when there is no activity in an specific column' => '',
- // '%s removed a subtask for the task #%d' => '',
- // '%s removed a comment on the task #%d' => '',
- // 'Comment removed on task #%d' => '',
- // 'Subtask removed on task #%d' => '',
- // 'Hide tasks in this column in the dashboard' => '',
- // '%s removed a comment on the task %s' => '',
- // '%s removed a subtask for the task %s' => '',
- // 'Comment removed' => '',
- // 'Subtask removed' => '',
- // '%s set a new internal link for the task #%d' => '',
- // '%s removed an internal link for the task #%d' => '',
- // 'A new internal link for the task #%d have been defined' => '',
- // 'Internal link removed for the task #%d' => '',
- // '%s set a new internal link for the task %s' => '',
- // '%s removed an internal link for the task %s' => '',
- // 'Automatically set the due date on task creation' => '',
- // 'Move the task to another column when closed' => '',
- // 'Move the task to another column when not moved during a given period' => '',
- // 'Dashboard for %s' => '',
- // 'Tasks overview for %s' => '',
- // 'Subtasks overview for %s' => '',
- // 'Projects overview for %s' => '',
- // 'Activity stream for %s' => '',
- // 'Calendar for %s' => '',
- // 'Notifications for %s' => '',
- // 'Subtasks export' => '',
- // 'Tasks exportation' => '',
- // 'Assign a color when the task is moved to a specific swimlane' => '',
- // 'Assign a priority when the task is moved to a specific swimlane' => '',
- // 'User unlocked successfully.' => '',
- // 'Unable to unlock the user.' => '',
- // 'Move a task to another swimlane' => '',
- // 'Creator Name' => '',
- // 'Time spent and estimated' => '',
- // 'Move position' => '',
- // 'Move task to another position on the board' => '',
- // 'Insert before this task' => '',
- // 'Insert after this task' => '',
- // 'Unlock this user' => '',
- // 'Custom Project Roles' => '',
- // 'Add a new custom role' => '',
- // 'Restrictions for the role "%s"' => '',
- // 'Add a new project restriction' => '',
- // 'Add a new drag and drop restriction' => '',
- // 'Add a new column restriction' => '',
- // 'Edit this role' => '',
- // 'Remove this role' => '',
- // 'There is no restriction for this role.' => '',
- // 'Only moving task between those columns is permitted' => '',
- // 'Close a task in a specific column when not moved during a given period' => '',
- // 'Edit columns' => '',
- // 'The column restriction has been created successfully.' => '',
- // 'Unable to create this column restriction.' => '',
- // 'Column restriction removed successfully.' => '',
- // 'Unable to remove this restriction.' => '',
- // 'Your custom project role has been created successfully.' => '',
- // 'Unable to create custom project role.' => '',
- // 'Your custom project role has been updated successfully.' => '',
- // 'Unable to update custom project role.' => '',
- // 'Custom project role removed successfully.' => '',
- // 'Unable to remove this project role.' => '',
- // 'The project restriction has been created successfully.' => '',
- // 'Unable to create this project restriction.' => '',
- // 'Project restriction removed successfully.' => '',
- // 'You cannot create tasks in this column.' => '',
- // 'Task creation is permitted for this column' => '',
- // 'Closing or opening a task is permitted for this column' => '',
- // 'Task creation is blocked for this column' => '',
- // 'Closing or opening a task is blocked for this column' => '',
- // 'Task creation is not permitted' => '',
- // 'Closing or opening a task is not permitted' => '',
- // 'New drag and drop restriction for the role "%s"' => '',
- // 'People belonging to this role will be able to move tasks only between the source and the destination column.' => '',
- // 'Remove a column restriction' => '',
- // 'Do you really want to remove this column restriction: "%s" to "%s"?' => '',
- // 'New column restriction for the role "%s"' => '',
- // 'Rule' => '',
- // 'Do you really want to remove this column restriction?' => '',
- // 'Custom roles' => '',
- // 'New custom project role' => '',
- // 'Edit custom project role' => '',
- // 'Remove a custom role' => '',
- // 'Do you really want to remove this custom role: "%s"? All people assigned to this role will become project member.' => '',
- // 'There is no custom role for this project.' => '',
- // 'New project restriction for the role "%s"' => '',
- // 'Restriction' => '',
- // 'Remove a project restriction' => '',
- // 'Do you really want to remove this project restriction: "%s"?' => '',
- // 'Duplicate to multiple projects' => '',
- // 'This field is required' => '',
- // 'Moving a task is not permitted' => '',
- // 'This value must be in the range %d to %d' => '',
+ 'Close a task when there is no activity in an specific column' => 'Chiudi un task quando non vi è alcuna attività in una specifica colonna',
+ '%s removed a subtask for the task #%d' => '%s rimosso un subtask per il task #%d',
+ '%s removed a comment on the task #%d' => '%s rimosso un commento nel task #%d',
+ 'Comment removed on task #%d' => 'Commento rimosso nel task #%d',
+ 'Subtask removed on task #%d' => 'Subtask rimosso nel task #%d',
+ 'Hide tasks in this column in the dashboard' => 'Nascondi tasks in questa colonna nella dashboard',
+ '%s removed a comment on the task %s' => '%s rimosso un commento nel task %s',
+ '%s removed a subtask for the task %s' => '%s rimosso un subtask per il task %s',
+ 'Comment removed' => 'Commento rimosso',
+ 'Subtask removed' => 'Subtask rimosso',
+ '%s set a new internal link for the task #%d' => '%s imposta un nuovo link interno per il task #%d',
+ '%s removed an internal link for the task #%d' => '%s rimosso un link interno per il task #%d',
+ 'A new internal link for the task #%d have been defined' => 'E\' stato definito un nuovo link interno per il task #%d',
+ 'Internal link removed for the task #%d' => 'Link interno rimosso per il task #%d',
+ '%s set a new internal link for the task %s' => '%s imposta un nuovo link interno per il task %s',
+ '%s removed an internal link for the task %s' => '%s rimosso un link interno per il task %s',
+ 'Automatically set the due date on task creation' => 'Imposta automaticamente la data di scadenza alla creazione del task',
+ 'Move the task to another column when closed' => 'Sposta il task su un\'altra colonna quando viene chiuso',
+ 'Move the task to another column when not moved during a given period' => 'Sposta il task su un\'altra colonna quando non viene spostato entro un certo periodo',
+ 'Dashboard for %s' => 'Dashboard per %s',
+ 'Tasks overview for %s' => 'Panoramica tasks per %s',
+ 'Subtasks overview for %s' => 'Panoramica tasks per %s',
+ 'Projects overview for %s' => 'Panoramica progetti per %s',
+ 'Activity stream for %s' => 'Flusso attività per %s',
+ 'Calendar for %s' => 'Calendario per %s',
+ 'Notifications for %s' => 'Notifiche per %s',
+ 'Assign a color when the task is moved to a specific swimlane' => 'Assegna un colore quando il task viene spostato su una specifica swimlane',
+ 'Assign a priority when the task is moved to a specific swimlane' => 'Assegna una priorità quando il task viene spostato su una specifica swimlane',
+ 'User unlocked successfully.' => 'Utente sbloccato con successo.',
+ 'Unable to unlock the user.' => 'Impossibile sbloccare l\'utente.',
+ 'Move a task to another swimlane' => 'Sposta un task su un\'altra swimlane',
+ 'Creator Name' => 'Nome del creatore',
+ 'Time spent and estimated' => 'Tempo trascorso e stima',
+ 'Move position' => 'Cambia posizione',
+ 'Move task to another position on the board' => 'Sposta task su un\'altra posizione nella board',
+ 'Insert before this task' => 'Inserisci prima di questo task',
+ 'Insert after this task' => 'Inserisci dopo questo task',
+ 'Unlock this user' => 'Sblocca quest\'utente',
+ 'Custom Project Roles' => 'Personalizza Ruoli del Progetto',
+ 'Add a new custom role' => 'Aggiungi un nuovo ruolo personalizzato',
+ 'Restrictions for the role "%s"' => 'Restrizioni per il ruolo "%s"',
+ 'Add a new project restriction' => 'Aggiungi una nuova restrizione per il progetto',
+ 'Add a new drag and drop restriction' => 'Aggiungi una nuova restrizione per il trascinamento',
+ 'Add a new column restriction' => 'Aggiungi una nuova restrizione per la colonna',
+ 'Edit this role' => 'Modifica questo ruolo',
+ 'Remove this role' => 'Cancella questo ruolo',
+ 'There is no restriction for this role.' => 'Non ci sono restrizioni per questo ruolo.',
+ 'Only moving task between those columns is permitted' => 'È permesso solo muovere i tast tra queste colonne',
+ 'Close a task in a specific column when not moved during a given period' => 'Chiudi un task in una colonna specifica quando non viene mosso per un determinato periodo',
+ 'Edit columns' => 'Modifica colonne',
+ 'The column restriction has been created successfully.' => 'La restrizione per le colonne è stata creata correttamente.',
+ 'Unable to create this column restriction.' => 'Impossibile creare questa restrizione per colonne.',
+ 'Column restriction removed successfully.' => 'Restrizione per colonne rimossa correttamente.',
+ 'Unable to remove this restriction.' => 'Impossibile rimuovere questa restrizione.',
+ 'Your custom project role has been created successfully.' => 'La regola personalizzata per il progetto è stata creata correttamente.',
+ 'Unable to create custom project role.' => 'Impossibile creare la regola personalizzata per il progetto.',
+ 'Your custom project role has been updated successfully.' => 'La regola personalizzata per il progetto è stata modificata correttamente.',
+ 'Unable to update custom project role.' => 'Impossibile modificare correttamente la regola personalizzata per il progetto.',
+ 'Custom project role removed successfully.' => 'Regola personalizzata per il progetto rimossa correttamente.',
+ 'Unable to remove this project role.' => 'Impossibile rimuovere questa regola per il progetto.',
+ 'The project restriction has been created successfully.' => 'La restrizione di progetto è stata creata con successo.',
+ 'Unable to create this project restriction.' => 'Impossibile creare la restrizione di progetto.',
+ 'Project restriction removed successfully.' => 'Restrizione di progetto rimossa correttamente.',
+ 'You cannot create tasks in this column.' => 'Non puoi creare dei task in questa colonna.',
+ 'Task creation is permitted for this column' => 'La creazione di task è permessa per questa colonna',
+ 'Closing or opening a task is permitted for this column' => 'Chiudere o aprire task è permesso per questa colonna',
+ 'Task creation is blocked for this column' => 'La creazione di task è bloccata per questa colonna',
+ 'Closing or opening a task is blocked for this column' => 'Chiudere o aprire task è bloccato per questa colonna',
+ 'Task creation is not permitted' => 'Creazione task non permessa',
+ 'Closing or opening a task is not permitted' => 'Chiudere o aprire task non è permesso',
+ 'New drag and drop restriction for the role "%s"' => 'Nuova restrizione "drag and drop" per la regola "%s"',
+ 'People belonging to this role will be able to move tasks only between the source and the destination column.' => 'Gli utenti che appartengono a questa regola saranno in grado di spostare i task solo tra la colonna di origine e quella di destinazione',
+ 'Remove a column restriction' => 'Rimuovere una restrizione di colonna',
+ 'Do you really want to remove this column restriction: "%s" to "%s"?' => 'Vuoi davvero rimuovere questa restrizione di colonna: "%s" a "%s"?',
+ 'New column restriction for the role "%s"' => 'Nuova restrizione di colonna per la regola "%s"',
+ 'Rule' => 'Regola',
+ 'Do you really want to remove this column restriction?' => 'Vuoi davvero rimuovere questa restrizione di colonna?',
+ 'Custom roles' => 'Regole personalizzate',
+ 'New custom project role' => 'Nuova regola per progetto personalizzato',
+ 'Edit custom project role' => 'Modifica regola per progetto personalizzato',
+ 'Remove a custom role' => 'Rimuovi regola personalizzata',
+ 'Do you really want to remove this custom role: "%s"? All people assigned to this role will become project member.' => 'Vuoi davvero rimuovere questa regola personalizzata: "%s"? Tutti gli utenti assegnati a questa regola diventeranno membri del progetto',
+ 'There is no custom role for this project.' => 'Non c\'è regola personalizzata per questo progetto.',
+ 'New project restriction for the role "%s"' => 'Nuova restrizione di progetto per la regola "%s"',
+ 'Restriction' => 'Restrizione',
+ 'Remove a project restriction' => 'Rimuovi restrizione di progetto',
+ 'Do you really want to remove this project restriction: "%s"?' => 'Vuoi davvero rimuovere questa restrizione di progetto: "%s"?',
+ 'Duplicate to multiple projects' => 'Duplica su più progetti',
+ 'This field is required' => 'Questo campo è obbligatorio',
+ 'Moving a task is not permitted' => 'Spostare task non è permesso',
+ 'This value must be in the range %d to %d' => 'Questo valore deve essere compreso tra %d e %d',
+ 'You are not allowed to move this task.' => 'Non ti è permesso spostare questo task.',
+ // 'API User Access' => '',
+ // 'Preview' => '',
+ // 'Write' => '',
+ // 'Write your text in Markdown' => '',
+ // 'New External Task: %s' => '',
+ // 'No personal API access token registered.' => '',
+ // 'Your personal API access token is "%s"' => '',
+ // 'Remove your token' => '',
+ // 'Generate a new token' => '',
+ // 'Showing %d-%d of %d' => '',
+ // 'Outgoing Emails' => '',
+ // 'Add or change currency rate' => '',
+ // 'Reference currency: %s' => '',
+ // 'Add custom filters' => '',
+ // 'Export' => '',
+ // 'Add link label' => '',
+ // 'Incompatible Plugins' => '',
+ // 'Compatibility' => '',
+ // 'Permissions and ownership' => '',
+ // 'Priorities' => '',
+ // 'Close this window' => '',
+ // 'Unable to upload this file.' => '',
+ // 'Import tasks' => '',
+ // 'Choose a project' => '',
+ // 'Profile' => '',
+ // 'Application role' => '',
+ // '%d invitations were sent.' => '',
+ // '%d invitation was sent.' => '',
+ // 'Unable to create this user.' => '',
+ // 'Kanboard Invitation' => '',
+ // 'Visible on dashboard' => '',
+ // 'Created at:' => '',
+ // 'Updated at:' => '',
+ // 'There is no custom filter.' => '',
+ // 'New User' => '',
+ // 'Authentication' => '',
+ // 'If checked, this user will use a third-party system for authentication.' => '',
+ // 'The password is necessary only for local users.' => '',
+ // 'You have been invited to register on Kanboard.' => '',
+ // 'Click here to join your team' => '',
+ // 'Invite people' => '',
+ // 'Emails' => '',
+ // 'Enter one email address by line.' => '',
+ // 'Add these people to this project' => '',
+ // 'Add this person to this project' => '',
+ // 'Sign-up' => '',
+ // 'Credentials' => '',
+ // 'New user' => '',
+ // 'This username is already taken' => '',
+ // 'A link to reset your password has been sent by email.' => '',
+ // 'Your profile must have a valid email address.' => '',
+ // 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
+ // 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
+ // 'The email configuration has been disabled by the administrator.' => '',
);
diff --git a/app/Locale/ja_JP/translations.php b/app/Locale/ja_JP/translations.php
index 20d2a145..820d1b86 100644
--- a/app/Locale/ja_JP/translations.php
+++ b/app/Locale/ja_JP/translations.php
@@ -61,7 +61,6 @@ return array(
'%d tasks on the board' => '%d 個のタスク',
'%d tasks in total' => '合計 %d 個のタスク',
'Unable to update this board.' => 'ボードを更新できませんでした',
- 'Edit board' => 'ボードを変更する',
'Disable' => '無効にする',
'Enable' => '有効にする',
'New project' => 'プロジェクトを作る',
@@ -72,7 +71,6 @@ return array(
'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"?' => 'カラム「%s」を削除しますか?',
'This action will REMOVE ALL TASKS associated to this column!' => 'この操作はこのカラムに割当てられた『全てのタスクを削除』します!',
@@ -160,9 +158,7 @@ return array(
'Task count' => 'タスク数',
'User' => 'ユーザ',
'Comments' => 'コメント',
- 'Leave a comment' => 'コメントを書く',
'Comment is required' => 'コメントを入力してください',
- 'Leave a description' => '説明を書く',
'Comment added successfully.' => 'コメントを追加しました。',
'Unable to create your comment.' => 'コメントの追加に失敗しました。',
'Due Date' => '期限',
@@ -224,7 +220,6 @@ return array(
'Search' => '検索',
'Nothing found.' => '結果なし。',
'Due date' => '期限',
- 'Others formats accepted: %s and %s' => '他の書式: %s または %s',
'Description' => '説明',
'%d comments' => '%d 個のコメント',
'%d comment' => '%d 個のコメント',
@@ -298,7 +293,6 @@ return array(
'Created by %s' => '%s が作成',
'Tasks Export' => 'タスクの出力',
'Start Date' => '開始日',
- 'End Date' => '終了日',
'Execute' => '実行',
'Task Id' => 'タスク ID',
'Creator' => '作成者',
@@ -342,8 +336,8 @@ return array(
'Remote' => 'リモート',
'Enabled' => '有効',
'Disabled' => '無効',
- 'Username:' => 'ユーザ名:',
- 'Name:' => '名前:',
+ 'Login:' => 'ユーザ名:',
+ 'Full Name:' => '名前:',
'Email:' => 'Email:',
'Notifications:' => '通知:',
'Notifications' => '通知',
@@ -516,10 +510,8 @@ return array(
'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' => 'ラベルはユニークである必要があります',
@@ -552,7 +544,6 @@ return array(
'Compact view' => 'コンパクトビュー',
'Horizontal scrolling' => '縦スクロール',
'Compact/wide view' => 'コンパクト/ワイドビュー',
- 'No results match:' => '結果が一致しませんでした',
'Currency' => '通貨',
'Private project' => 'プライベートプロジェクト',
'AUD - Australian Dollar' => 'AUD - 豪ドル',
@@ -566,6 +557,7 @@ return array(
'JPY - Japanese Yen' => 'JPY - 日本円',
'NZD - New Zealand Dollar' => 'NZD - NZ ドル',
'RSD - Serbian dinar' => 'RSD - セルビアデナール',
+ // 'CNY - Chinese Yuan' => '',
'USD - US Dollar' => 'USD - 米ドル',
'Destination column' => '移動先のカラム',
'Move the task to another column when assigned to a user' => 'ユーザの割り当てをしたらタスクを他のカラムに移動',
@@ -580,7 +572,6 @@ return array(
'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.' => 'この通貨レートを追加できません。',
@@ -702,7 +693,6 @@ return array(
// '<30m' => '',
// 'Stop timer' => '',
// 'Start timer' => '',
- // 'Add project member' => '',
// 'My activity stream' => '',
// 'My calendar' => '',
// 'Search tasks' => '',
@@ -757,8 +747,6 @@ return array(
// '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.' => '',
@@ -852,7 +840,6 @@ return array(
// '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!' => '',
@@ -980,7 +967,6 @@ return array(
// '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' => '',
@@ -1037,7 +1023,6 @@ return array(
// 'Started:' => '',
// 'Moved:' => '',
// 'Task #%d' => '',
- // 'Date and time format' => '',
// 'Time format' => '',
// 'Start date: ' => '',
// 'End date: ' => '',
@@ -1051,9 +1036,7 @@ return array(
// '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' => '',
@@ -1163,7 +1146,6 @@ return array(
// 'Email sender address' => '',
// 'Email transport' => '',
// 'Webhook token' => '',
- // 'Imports' => '',
// 'Project tags management' => '',
// 'Tag created successfully.' => '',
// 'Unable to create this tag.' => '',
@@ -1210,8 +1192,6 @@ return array(
// 'Activity stream for %s' => '',
// 'Calendar for %s' => '',
// 'Notifications for %s' => '',
- // 'Subtasks export' => '',
- // 'Tasks exportation' => '',
// 'Assign a color when the task is moved to a specific swimlane' => '',
// 'Assign a priority when the task is moved to a specific swimlane' => '',
// 'User unlocked successfully.' => '',
@@ -1277,4 +1257,61 @@ return array(
// 'This field is required' => '',
// 'Moving a task is not permitted' => '',
// 'This value must be in the range %d to %d' => '',
+ // 'You are not allowed to move this task.' => '',
+ // 'API User Access' => '',
+ // 'Preview' => '',
+ // 'Write' => '',
+ // 'Write your text in Markdown' => '',
+ // 'New External Task: %s' => '',
+ // 'No personal API access token registered.' => '',
+ // 'Your personal API access token is "%s"' => '',
+ // 'Remove your token' => '',
+ // 'Generate a new token' => '',
+ // 'Showing %d-%d of %d' => '',
+ // 'Outgoing Emails' => '',
+ // 'Add or change currency rate' => '',
+ // 'Reference currency: %s' => '',
+ // 'Add custom filters' => '',
+ // 'Export' => '',
+ // 'Add link label' => '',
+ // 'Incompatible Plugins' => '',
+ // 'Compatibility' => '',
+ // 'Permissions and ownership' => '',
+ // 'Priorities' => '',
+ // 'Close this window' => '',
+ // 'Unable to upload this file.' => '',
+ // 'Import tasks' => '',
+ // 'Choose a project' => '',
+ // 'Profile' => '',
+ // 'Application role' => '',
+ // '%d invitations were sent.' => '',
+ // '%d invitation was sent.' => '',
+ // 'Unable to create this user.' => '',
+ // 'Kanboard Invitation' => '',
+ // 'Visible on dashboard' => '',
+ // 'Created at:' => '',
+ // 'Updated at:' => '',
+ // 'There is no custom filter.' => '',
+ // 'New User' => '',
+ // 'Authentication' => '',
+ // 'If checked, this user will use a third-party system for authentication.' => '',
+ // 'The password is necessary only for local users.' => '',
+ // 'You have been invited to register on Kanboard.' => '',
+ // 'Click here to join your team' => '',
+ // 'Invite people' => '',
+ // 'Emails' => '',
+ // 'Enter one email address by line.' => '',
+ // 'Add these people to this project' => '',
+ // 'Add this person to this project' => '',
+ // 'Sign-up' => '',
+ // 'Credentials' => '',
+ // 'New user' => '',
+ // 'This username is already taken' => '',
+ // 'A link to reset your password has been sent by email.' => '',
+ // 'Your profile must have a valid email address.' => '',
+ // 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
+ // 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
+ // 'The email configuration has been disabled by the administrator.' => '',
);
diff --git a/app/Locale/ko_KR/translations.php b/app/Locale/ko_KR/translations.php
index 5e9110ea..56bac068 100644
--- a/app/Locale/ko_KR/translations.php
+++ b/app/Locale/ko_KR/translations.php
@@ -61,7 +61,6 @@ return array(
'%d tasks on the board' => '%d개의 할일',
'%d tasks in total' => '총 %d개의 할일',
'Unable to update this board.' => '보드를 갱신할 수 없었습니다',
- 'Edit board' => '보드를 변경하는 ',
'Disable' => '비활성화',
'Enable' => '유효하게 한다',
'New project' => '새 프로젝트',
@@ -72,7 +71,6 @@ return array(
'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"?' => '컬럼을 삭제하시겠습니까: "%s"?',
'This action will REMOVE ALL TASKS associated to this column!' => '이 조작은 이 컬럼에 할당된 『 모든 할일을 삭제 』합니다!',
@@ -160,9 +158,7 @@ return array(
'Task count' => '할일 수',
'User' => '사용자',
'Comments' => '댓글',
- 'Leave a comment' => '댓글 남기기',
'Comment is required' => '댓글을 입력하세요',
- 'Leave a description' => '설명을 입력하세요',
'Comment added successfully.' => '의견을 추가했습니다.',
'Unable to create your comment.' => '댓글의 추가에 실패했습니다.',
'Due Date' => '마감일',
@@ -224,7 +220,6 @@ return array(
'Search' => '검색',
'Nothing found.' => '결과가 없습니다',
'Due date' => '마감일',
- 'Others formats accepted: %s and %s' => ' 다른 서식: %s 또는 %s',
'Description' => '설명',
'%d comments' => '%d개의 댓글',
'%d comment' => '%d개의 댓글',
@@ -298,7 +293,6 @@ return array(
'Created by %s' => '작성자 %s',
'Tasks Export' => '할일 내보내기',
'Start Date' => '시작일',
- 'End Date' => '종료일',
'Execute' => '실행',
'Task Id' => '할일 ID',
'Creator' => '작성자',
@@ -342,8 +336,8 @@ return array(
'Remote' => '원격',
'Enabled' => '활성화',
'Disabled' => '비활성화',
- 'Username:' => '사용자명',
- 'Name:' => '이름:',
+ 'Login:' => '사용자명',
+ 'Full Name:' => '이름:',
'Email:' => '이메일:',
'Notifications:' => '알림:',
'Notifications' => '알림',
@@ -402,9 +396,9 @@ return array(
'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)' => '',
+ 'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => '최근 수정된 작업 고려 기간(초), (비활성화:0, 기본값:2일)',
+ 'Frequency in second (60 seconds by default)' => '초당 횟수(기본값:60초)',
+ 'Frequency in second (0 to disable this feature, 10 seconds by default)' => '초당 횟수(비활성화:0, 기본값:10초)',
'Application URL' => '애플리케이션의 URL',
'Token regenerated.' => '토큰이 다시 생성되었습니다.',
'Date format' => '데이터 포멧',
@@ -516,10 +510,8 @@ return array(
'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' => '라벨은 독특할 필요가 있습니다',
@@ -552,21 +544,21 @@ return array(
'Compact view' => '컴팩트 뷰',
'Horizontal scrolling' => '세로 스크롤',
'Compact/wide view' => '컴팩트/와이드 뷰',
- 'No results match:' => '결과가 일치하지 않았습니다',
'Currency' => '통화',
'Private project' => '개인 프로젝트',
- // 'AUD - Australian Dollar' => '',
- // 'CAD - Canadian Dollar' => '',
- // 'CHF - Swiss Francs' => '',
+ 'AUD - Australian Dollar' => 'AUD - 호주 달러',
+ 'CAD - Canadian Dollar' => 'CAD -캐나다 달러',
+ 'CHF - Swiss Francs' => 'CHF - 스위스 프랑',
'Custom Stylesheet' => '커스텀 스타일 시트',
'download' => '다운로드',
- // 'EUR - Euro' => '',
- // 'GBP - British Pound' => '',
- // 'INR - Indian Rupee' => '',
- // 'JPY - Japanese Yen' => '',
- // 'NZD - New Zealand Dollar' => '',
- // 'RSD - Serbian dinar' => '',
- // 'USD - US Dollar' => '',
+ 'EUR - Euro' => 'EUR - 유로',
+ 'GBP - British Pound' => 'GBP - 영국 파운드',
+ 'INR - Indian Rupee' => 'INR - 인도 루피',
+ 'JPY - Japanese Yen' => 'JPY - 일본 엔',
+ 'NZD - New Zealand Dollar' => 'NZD - 뉴질랜드 달러',
+ 'RSD - Serbian dinar' => 'RSD - 세르비아 디나르',
+ // 'CNY - Chinese Yuan' => '',
+ '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' => '사용자의 할당이 없어지면 할일을 다른 컬럼에 이동',
@@ -580,7 +572,6 @@ return array(
'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.' => '이 통화 환율을 추가할 수 없습니다.',
@@ -600,12 +591,12 @@ return array(
'Assign a color when the task is moved to a specific column' => '상세 컬럼으로 이동할 할일의 색깔을 지정하세요',
'%s via Kanboard' => '%s via E-board',
'Burndown chart' => '번다운 차트',
- // 'This chart show the task complexity over the time (Work Remaining).' => '',
+ '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' => '',
+ 'SEK - Swedish Krona' => 'SEK - 스위스 크로나',
'Identifier' => '식별자',
'Disable two factor authentication' => '이중 인증 비활성화',
'Do you really want to disable the two factor authentication for this user: "%s"?' => '"%s" 담당자의 이중 인증을 비활성화 하시겠습니까?',
@@ -613,7 +604,7 @@ return array(
'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' => '',
+ 'Recurrent task is scheduled to be generated' => '반복 할일이 생성된 예정입니다.',
'Score' => '점수',
'The identifier must be unique' => '식별자는 유일해야 합니다',
'This linked task id doesn\'t exists' => '연결된 할일 ID가 존재하지 않습니다',
@@ -626,7 +617,7 @@ return array(
'Base date to calculate new due date' => '새로운 기본 종료날짜 계산',
'Action date' => '시작날짜',
'Base date to calculate new due date: ' => '새로운 기본 종료날짜 계산: ',
- // 'This task has created this child task: ' => '',
+ 'This task has created this child task: ' => '이 할일은 하위 할일을 만들었습니다.',
'Day(s)' => '일',
'Existing due date' => '기존 종료날짜',
'Factor to calculate new due date: ' => '새로운 종료날짜 계산: ',
@@ -635,7 +626,7 @@ return array(
'This task has been created by: ' => '할일을 만들었습니다: ',
'Recurrent task has been generated:' => '반복 할일이 생성되었습니다',
'Timeframe to calculate new due date: ' => '종료날짜 계산 단위',
- // 'Trigger to generate recurrent task: ' => '',
+ 'Trigger to generate recurrent task: ' => '반복 할일 생성 트리거',
'When task is closed' => '할일을 마쳤을때',
'When task is moved from first column' => '할일이 첫번째 컬럼으로 옮겨졌을때',
'When task is moved to last column' => '할일이 마지막 컬럼으로 옮겨졌을때',
@@ -649,7 +640,7 @@ return array(
'Subtasks time tracking' => '서브 할일 시간 트래킹',
'User calendar view' => '담당자 달력 보기',
'Automatically update the start date' => '시작일에 자동 갱신',
- // 'iCal feed' => '',
+ 'iCal feed' => 'iCal 피드',
'Preferences' => '우선권',
'Security' => '보안',
'Two factor authentication disabled' => '이중 인증이 비활성화 되었습니다',
@@ -666,7 +657,7 @@ return array(
'Notification' => '알림',
'%s moved the task #%d to the first swimlane' => '%s가 할일 #%d를 첫번째 스웜레인으로 이동시켰습니다',
'Swimlane' => '스윔레인',
- // 'Gravatar' => '',
+ 'Gravatar' => '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.' => '해당 기간의 모든 서브 할일 정보가 보고서에 포함됩니다',
@@ -695,14 +686,13 @@ return array(
'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' => '%%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' => '프로젝트 맴버 추가',
'My activity stream' => '내 활동기록',
'My calendar' => '내 캘린더',
'Search tasks' => '할일 찾기',
@@ -757,8 +747,6 @@ return array(
'Remote user' => '원격 담당자',
'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => '예를 들어 LDAP, Google, Github 계정같은 원격 담당자의 비밀번호는 칸반보드 데이터베이스에 저장하지 않습니다',
'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.' => '가능한 목적 프로젝트가 없습니다',
@@ -781,12 +769,12 @@ return array(
'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.' => '',
+ '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 - Norwegian Krone' => 'NOK - 노르웨이 크로네',
'Show this column' => '컬럼 보이기',
'Hide this column' => '컬럼 숨기기',
'open file' => '열기',
@@ -802,14 +790,14 @@ return array(
'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' => '',
+ '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' => '',
+ 'Reset the search/filter box' => '찾기/필터 박스 초기화',
'Documentation' => '문서',
- // 'Table of contents' => '',
+ 'Table of contents' => '목차',
'Gantt' => '간트',
'Author' => '글쓴이',
'Version' => '버전',
@@ -825,7 +813,7 @@ return array(
'Your custom filter have been updated successfully.' => '사용자 정의 필터가 성공적으로 수정되었습니다',
'Unable to update custom filter.' => '정의 필터 수정 비활성화',
'Web' => '웹',
- // 'New attachment on task #%d: %s' => '',
+ '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이 갱신 되었습니다',
@@ -843,7 +831,7 @@ return array(
'No new notifications.' => '알림이 없습니다',
'Mark all as read' => '모두 읽음',
'Mark as read' => '읽음',
- // 'Total number of tasks in this column across all swimlanes' => '',
+ 'Total number of tasks in this column across all swimlanes' => '모든 스웜라인 칼럼의 할일 수',
'Collapse swimlane' => '스웜라인 붕괴',
'Expand swimlane' => '스웜라인 확장',
'Add a new filter' => '새로운 필터 추가',
@@ -852,7 +840,6 @@ return array(
'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!' => '추가가 되지 않았습니다!',
@@ -866,7 +853,7 @@ return array(
'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 filter (instead of replacement)' => '필터 (변경 대신)추가',
'Append/Replace' => '추가/변경',
'Append' => '추가',
'Replace' => '변경',
@@ -890,7 +877,7 @@ return array(
'%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' => 'BAM - 보스니아 마르카',
'Assignee Username' => '담당자의 사용자이름',
'Assignee Name' => '당장자 이름',
'Groups' => '그룹',
@@ -916,7 +903,7 @@ return array(
'Project Member' => '프로젝트 멤버',
'Project Viewer' => '프로젝트 뷰어',
'Your account is locked for %d minutes' => '%d분 동안 계정이 잠깁니다',
- // 'Invalid captcha' => '',
+ 'Invalid captcha' => '잘못된 보안 문자',
'The name must be unique' => '이름은 유일해야 합니다',
'View all groups' => '모든그룹보기',
'There is no user available.' => '가능한 사용자가 없습니다',
@@ -950,14 +937,14 @@ return array(
'Estimated Time' => '예상 시간',
'Actual Time' => '실제 시간',
'Estimated vs actual time' => '예상 vs 실제 시간',
- // 'RUB - Russian Ruble' => '',
+ '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' => '시간에 기반한 1회용 패스워드 알고리즘',
'Two-Factor Provider: ' => '이중 인증: ',
'Disable two-factor authentication' => '이중 인증 비활성화',
'Enable 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?' => '비밀번호 찾기',
'Enable "Forget Password"' => '"비밀번호 분실" 활성화',
@@ -977,10 +964,9 @@ return array(
'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => '프로젝트 알림 방법으로 플러그인이 등록되지 않았습니다. 각각의 알림을 프로파일에서 설정하실 수 있습니다',
'My dashboard' => '대시보드',
'My profile' => '프로필',
- 'Project owner: ' => '프로젝트 소유자',
+ '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.' => '이 날짜는 프로젝트 간트 차트에 사용됩니다',
+ 'Project owner' => '프로젝트 소유자',
'Private projects do not have users and groups management.' => '비밀 프로젝트는 사용자나 관리 그룹이 소유하지 않습니다',
'There is no project member.' => '프로젝트 맴버가 없습니다',
'Priority' => '우선순위',
@@ -995,7 +981,7 @@ return array(
'Duration in days' => '기간',
'Send email when there is no activity on a task' => '활동이 없는 할일을 이메일로 보냅니다',
'Unable to fetch link information.' => '링크 정보 가져오기 비활성화',
- // 'Daily background job for tasks' => '',
+ 'Daily background job for tasks' => '할일의 일일 배경 작업 ',
'Auto' => '자동',
'Related' => '연관된',
'Attachment' => '첨부',
@@ -1010,7 +996,7 @@ return array(
'Edit external link' => '외부 링크 수정',
'External link' => '외부 링크',
'Copy and paste your link here...' => '여기에 링크를 복사/붙여넣기',
- // 'URL' => '',
+ 'URL' => '인터넷 주소',
'Internal links' => '내부 링크',
'Assign to me' => '나에게 할당',
'Me' => '나',
@@ -1037,7 +1023,6 @@ return array(
'Started:' => '시작:',
'Moved:' => '이동:',
'Task #%d' => '할일 #%d',
- 'Date and time format' => '날짜와 시간 형식',
'Time format' => '시간 형식',
'Start date: ' => '시작일: ',
'End date: ' => '종료일: ',
@@ -1047,13 +1032,11 @@ return array(
'Do you really want to remove this custom filter: "%s"?' => '정의 필터를 삭제하시겠습니까: "%s"?',
'Remove a custom filter' => '정의 필터 삭제',
'User activated successfully.' => '사용자가 성공적으로 활성화되었습니다',
- // 'Unable to enable this user.' => '',
+ 'Unable to enable this user.' => '이 사용자를 활성화할 수 없습니다.',
'User disabled successfully.' => '사용자가 성공적으로 비활성화되었습니다',
- // 'Unable to disable this user.' => '',
+ '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' => '프로파일 보기',
@@ -1093,7 +1076,7 @@ return array(
'Local File' => '로컬 파일',
'Configuration' => '구성',
'PHP version:' => 'PHP 버전:',
- // 'PHP SAPI:' => '',
+ 'PHP SAPI:' => 'PHP SAPI:',
'OS version:' => '운영체제 버전:',
'Database version:' => '데이터베이스 버전:',
'Browser:' => '브라우저:',
@@ -1140,7 +1123,7 @@ return array(
'Unable to open plugin archive.' => '플러그인 아카이브를 열수 없습니다.',
'There is no file in the plugin archive.' => '플러그인 아카이브에 파일이 존재하지 않습니다.',
'Create tasks in bulk' => '대량의 할일 만들기',
- // 'Your Kanboard instance is not configured to install plugins from the user interface.' => '',
+ 'Your Kanboard instance is not configured to install plugins from the user interface.' => '칸보드 인스턴스가 사용자 인터페이스에서 플러그인을 설치하도록 구성되지 않았습니다',
'There is no plugin available.' => '사용 가능한 플러그인이 없습니다.',
'Install' => '설치',
'Update' => '갱신',
@@ -1163,7 +1146,6 @@ return array(
'Email sender address' => '이메일 보낸이 주소',
'Email transport' => '이메일 전송',
'Webhook token' => 'Webhook토큰',
- 'Imports' => '가져오기',
'Project tags management' => '프로젝트 태그 관리',
'Tag created successfully.' => '태그가 성공적으로 생성되었습니다.',
'Unable to create this tag.' => '태그를 생성할 수 없습니다.',
@@ -1210,71 +1192,126 @@ return array(
'Activity stream for %s' => '%s의 활동기록',
'Calendar for %s' => '%s의 달력',
'Notifications for %s' => '%s의 알림',
- 'Subtasks export' => '서브할일 내보내기',
- 'Tasks exportation' => '할일 내보내기',
- // 'Assign a color when the task is moved to a specific swimlane' => '',
- // 'Assign a priority when the task is moved to a specific swimlane' => '',
- // 'User unlocked successfully.' => '',
- // 'Unable to unlock the user.' => '',
- // 'Move a task to another swimlane' => '',
- // 'Creator Name' => '',
- // 'Time spent and estimated' => '',
- // 'Move position' => '',
- // 'Move task to another position on the board' => '',
- // 'Insert before this task' => '',
- // 'Insert after this task' => '',
- // 'Unlock this user' => '',
- // 'Custom Project Roles' => '',
- // 'Add a new custom role' => '',
- // 'Restrictions for the role "%s"' => '',
- // 'Add a new project restriction' => '',
- // 'Add a new drag and drop restriction' => '',
- // 'Add a new column restriction' => '',
- // 'Edit this role' => '',
- // 'Remove this role' => '',
- // 'There is no restriction for this role.' => '',
- // 'Only moving task between those columns is permitted' => '',
- // 'Close a task in a specific column when not moved during a given period' => '',
- // 'Edit columns' => '',
- // 'The column restriction has been created successfully.' => '',
- // 'Unable to create this column restriction.' => '',
- // 'Column restriction removed successfully.' => '',
- // 'Unable to remove this restriction.' => '',
- // 'Your custom project role has been created successfully.' => '',
- // 'Unable to create custom project role.' => '',
- // 'Your custom project role has been updated successfully.' => '',
- // 'Unable to update custom project role.' => '',
- // 'Custom project role removed successfully.' => '',
- // 'Unable to remove this project role.' => '',
- // 'The project restriction has been created successfully.' => '',
- // 'Unable to create this project restriction.' => '',
- // 'Project restriction removed successfully.' => '',
- // 'You cannot create tasks in this column.' => '',
- // 'Task creation is permitted for this column' => '',
- // 'Closing or opening a task is permitted for this column' => '',
- // 'Task creation is blocked for this column' => '',
- // 'Closing or opening a task is blocked for this column' => '',
- // 'Task creation is not permitted' => '',
- // 'Closing or opening a task is not permitted' => '',
- // 'New drag and drop restriction for the role "%s"' => '',
- // 'People belonging to this role will be able to move tasks only between the source and the destination column.' => '',
- // 'Remove a column restriction' => '',
- // 'Do you really want to remove this column restriction: "%s" to "%s"?' => '',
- // 'New column restriction for the role "%s"' => '',
- // 'Rule' => '',
- // 'Do you really want to remove this column restriction?' => '',
- // 'Custom roles' => '',
- // 'New custom project role' => '',
- // 'Edit custom project role' => '',
- // 'Remove a custom role' => '',
- // 'Do you really want to remove this custom role: "%s"? All people assigned to this role will become project member.' => '',
- // 'There is no custom role for this project.' => '',
- // 'New project restriction for the role "%s"' => '',
- // 'Restriction' => '',
- // 'Remove a project restriction' => '',
- // 'Do you really want to remove this project restriction: "%s"?' => '',
- // 'Duplicate to multiple projects' => '',
- // 'This field is required' => '',
- // 'Moving a task is not permitted' => '',
- // 'This value must be in the range %d to %d' => '',
+ 'Assign a color when the task is moved to a specific swimlane' => '할일이 특정 스웜라인으로 옮겨질 때 색상 지정',
+ 'Assign a priority when the task is moved to a specific swimlane' => '할일이 특정 스웜라인으로 옮겨질 때 우선순위 지정',
+ 'User unlocked successfully.' => '사용자 잠금 성공',
+ 'Unable to unlock the user.' => '사용자 해제 성공',
+ 'Move a task to another swimlane' => '다른 스웜라인으로 할일 이동',
+ 'Creator Name' => '생성자 이름',
+ 'Time spent and estimated' => '소요시간과 예상시간',
+ 'Move position' => '이동 위치',
+ 'Move task to another position on the board' => '할일을 보드의 다른 위치로 이동',
+ 'Insert before this task' => '이 할일 이전에 삽입',
+ 'Insert after this task' => '이 할일 이후에 삽입',
+ 'Unlock this user' => '사용자 잠금',
+ 'Custom Project Roles' => '정의 프로젝트 규칙',
+ 'Add a new custom role' => '새로운 정의 규칙 추가',
+ 'Restrictions for the role "%s"' => '"%s" 역할의 제약',
+ 'Add a new project restriction' => '새로운 프로젝트 제약 추가',
+ 'Add a new drag and drop restriction' => '새로운 드래그 앤 드롭 제약 추가',
+ 'Add a new column restriction' => '새로운 칼럼 제약 추가',
+ 'Edit this role' => '역할 수정',
+ 'Remove this role' => '역할 삭제',
+ 'There is no restriction for this role.' => '역할에 대한 제약이 없습니다.',
+ 'Only moving task between those columns is permitted' => '칼럼간 이동만 허용됩니다.',
+ 'Close a task in a specific column when not moved during a given period' => '특정 기간동안 이동하지 않은 특정 칼럼의 할일 마치기',
+ 'Edit columns' => '칼럼 수정',
+ 'The column restriction has been created successfully.' => '칼럼 제약이 생성되었습니다.',
+ 'Unable to create this column restriction.' => '칼럼 제약을 생성할 수 없습니다.',
+ 'Column restriction removed successfully.' => '칼럼 제약이 삭제되었습니다.',
+ 'Unable to remove this restriction.' => '칼럼 제약을 삭제할 수 없습니다.',
+ 'Your custom project role has been created successfully.' => '정의 프로젝트 역할이 생성되었습니다.',
+ 'Unable to create custom project role.' => '정의 프로젝트 역할을 생성할 수 없습니다.',
+ 'Your custom project role has been updated successfully.' => '정의 프로젝트 역할이 수정되었습니다.',
+ 'Unable to update custom project role.' => '정의 프로젝트 역할을 수정할 수 없습니다.',
+ 'Custom project role removed successfully.' => '정의 프로젝트 역할이 삭제되었습니다.',
+ 'Unable to remove this project role.' => '정의 프로젝트 역할을 삭제할 수 없습니다.',
+ 'The project restriction has been created successfully.' => '프로젝트 제약이 생성되었습니다.',
+ 'Unable to create this project restriction.' => '프로젝트 제약을 생성할 수 없습니다.',
+ 'Project restriction removed successfully.' => '프로젝트 제약을 삭제하였습니다.',
+ 'You cannot create tasks in this column.' => '이 칼럼의 할일을 생성할 수 없습니다.',
+ 'Task creation is permitted for this column' => '이 칼럼의 할일 생성이 허가되었습니다.',
+ 'Closing or opening a task is permitted for this column' => '이 칼럼의 할일 열기 혹은 닫기가 허가되었습니다.',
+ 'Task creation is blocked for this column' => '이 칼럼의 할일 생성이 거부되었습니다.',
+ 'Closing or opening a task is blocked for this column' => '이 칼럼의 할일 열기 혹은 닫기가 거부되었습니다.',
+ 'Task creation is not permitted' => '할일 생성이 거부되었습니다.',
+ 'Closing or opening a task is not permitted' => '할일 열기 혹은 닫기가 거부되었습니다.',
+ 'New drag and drop restriction for the role "%s"' => '"%s" 역할의 새로운 드래그 앤 드롭 제약',
+ 'People belonging to this role will be able to move tasks only between the source and the destination column.' => '이 역할에 속한 사용자는 원본 및 대상 칼럼 사이에서만 할일을 이동할 수 있습니다',
+ 'Remove a column restriction' => '칼럼 제약 삭제',
+ 'Do you really want to remove this column restriction: "%s" to "%s"?' => '칼럼 제약을 "%s" 에서 "%s"로 이동하시겠습니까?',
+ 'New column restriction for the role "%s"' => '"%s" 역할의 새로운 칼럼 제약',
+ 'Rule' => '역할',
+ 'Do you really want to remove this column restriction?' => '칼럼 제약을 삭제하시겠습니까?',
+ 'Custom roles' => '정의 역할',
+ 'New custom project role' => '새로운 정의 프로젝트 역할',
+ 'Edit custom project role' => '정의 프로젝트 역할 수정',
+ 'Remove a custom role' => '정의 역할 삭제',
+ 'Do you really want to remove this custom role: "%s"? All people assigned to this role will become project member.' => '"%s" 정의 역할을 삭제하시겠습니까? 이 역할에 할당 된 모든 사람들이 프로젝트 멤버가됩니다.',
+ 'There is no custom role for this project.' => '이 프로젝트에는 정의 역할이 없습니다.',
+ 'New project restriction for the role "%s"' => '"%s" 역할의 새로운 프로젝트 제약',
+ 'Restriction' => '제약',
+ 'Remove a project restriction' => '프로젝트 제약 삭제',
+ 'Do you really want to remove this project restriction: "%s"?' => '"%s" 프로젝트 제약을 삭제하시겠습니까?',
+ 'Duplicate to multiple projects' => '다수의 프로젝트 복제',
+ 'This field is required' => '이 필드는 필수 항목입니다.',
+ 'Moving a task is not permitted' => '할일 이동이 거부되었습니다.',
+ 'This value must be in the range %d to %d' => '값의 범위는 %d 부터 %d 까지 입니다.',
+ 'You are not allowed to move this task.' => '당신은 할일 이동이 거부되었습니다.',
+ // 'API User Access' => '',
+ // 'Preview' => '',
+ // 'Write' => '',
+ // 'Write your text in Markdown' => '',
+ // 'New External Task: %s' => '',
+ // 'No personal API access token registered.' => '',
+ // 'Your personal API access token is "%s"' => '',
+ // 'Remove your token' => '',
+ // 'Generate a new token' => '',
+ // 'Showing %d-%d of %d' => '',
+ // 'Outgoing Emails' => '',
+ // 'Add or change currency rate' => '',
+ // 'Reference currency: %s' => '',
+ // 'Add custom filters' => '',
+ // 'Export' => '',
+ // 'Add link label' => '',
+ // 'Incompatible Plugins' => '',
+ // 'Compatibility' => '',
+ // 'Permissions and ownership' => '',
+ // 'Priorities' => '',
+ // 'Close this window' => '',
+ // 'Unable to upload this file.' => '',
+ // 'Import tasks' => '',
+ // 'Choose a project' => '',
+ // 'Profile' => '',
+ // 'Application role' => '',
+ // '%d invitations were sent.' => '',
+ // '%d invitation was sent.' => '',
+ // 'Unable to create this user.' => '',
+ // 'Kanboard Invitation' => '',
+ // 'Visible on dashboard' => '',
+ // 'Created at:' => '',
+ // 'Updated at:' => '',
+ // 'There is no custom filter.' => '',
+ // 'New User' => '',
+ // 'Authentication' => '',
+ // 'If checked, this user will use a third-party system for authentication.' => '',
+ // 'The password is necessary only for local users.' => '',
+ // 'You have been invited to register on Kanboard.' => '',
+ // 'Click here to join your team' => '',
+ // 'Invite people' => '',
+ // 'Emails' => '',
+ // 'Enter one email address by line.' => '',
+ // 'Add these people to this project' => '',
+ // 'Add this person to this project' => '',
+ // 'Sign-up' => '',
+ // 'Credentials' => '',
+ // 'New user' => '',
+ // 'This username is already taken' => '',
+ // 'A link to reset your password has been sent by email.' => '',
+ // 'Your profile must have a valid email address.' => '',
+ // 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
+ // 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
+ // 'The email configuration has been disabled by the administrator.' => '',
);
diff --git a/app/Locale/my_MY/translations.php b/app/Locale/my_MY/translations.php
index e3c852ac..1121a880 100644
--- a/app/Locale/my_MY/translations.php
+++ b/app/Locale/my_MY/translations.php
@@ -61,7 +61,6 @@ return array(
'%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',
- 'Edit board' => 'ubah papan',
'Disable' => 'Nyah-Upaya',
'Enable' => 'Aktifkan',
'New project' => 'Projek Baru',
@@ -72,7 +71,6 @@ return array(
'Title' => 'Judul',
'Assigned to %s' => 'Ditugaskan ke %s',
'Remove a column' => 'Hapus kolom',
- 'Remove a column from a board' => 'Hapus kolom dari papan',
'Unable to remove this column.' => 'Tidak dapat menghapus kolom ini.',
'Do you really want to remove this column: "%s"?' => 'Apakah anda yakin akan menghapus kolom ini : « %s » ?',
'This action will REMOVE ALL TASKS associated to this column!' => 'tindakan ini akan MENGHAPUS SEMUA TUGAS yang terkait dengan kolom ini!',
@@ -160,9 +158,7 @@ return array(
'Task count' => 'Jumlah tugas',
'User' => 'Pengguna',
'Comments' => 'Komentar',
- 'Leave a comment' => 'Tinggalkan komentar',
'Comment is required' => 'Komentar diperlukan',
- 'Leave a description' => 'Tinggalkan deskripsi',
'Comment added successfully.' => 'Komentar berhasil ditambahkan.',
'Unable to create your comment.' => 'Tidak dapat menambahkan komentar anda.',
'Due Date' => 'Batas Tanggal Terakhir',
@@ -224,7 +220,6 @@ return array(
'Search' => 'Cari',
'Nothing found.' => 'Tidak ditemukan.',
'Due date' => 'Batas tanggal terakhir',
- 'Others formats accepted: %s and %s' => 'Format lain yang didukung : %s et %s',
'Description' => 'Deskripsi',
'%d comments' => '%d komentar',
'%d comment' => '%d komentar',
@@ -298,7 +293,6 @@ return array(
'Created by %s' => 'Dibuat oleh %s',
'Tasks Export' => 'Ekspor Tugas',
'Start Date' => 'Tanggal Mulai',
- 'End Date' => 'Tanggal Berakhir',
'Execute' => 'Eksekusi',
'Task Id' => 'Id Tugas',
'Creator' => 'Pembuat',
@@ -342,8 +336,8 @@ return array(
'Remote' => 'Jauh',
'Enabled' => 'Aktif',
'Disabled' => 'Tidak aktif',
- 'Username:' => 'Nama pengguna :',
- 'Name:' => 'Nama:',
+ 'Login:' => 'Nama pengguna :',
+ 'Full Name:' => 'Nama:',
'Email:' => 'Emel:',
'Notifications:' => 'Makluman:',
'Notifications' => 'Makluman',
@@ -516,10 +510,8 @@ return array(
'Link labels' => 'Label Pautan',
'Link modification' => 'Modifikasi Pautan',
'Links' => 'Pautan',
- 'Link settings' => 'Pengaturan Pautan',
'Opposite label' => 'Label berlawanan',
'Remove a link' => 'Hapus Pautan',
- 'Task\'s links' => 'Pautan tugas',
'The labels must be different' => 'Label harus berbeda',
'There is no link.' => 'Tidak ada Pautan.',
'This label must be unique' => 'Label ini harus unik',
@@ -552,7 +544,6 @@ return array(
'Compact view' => 'Tampilan kompak',
'Horizontal scrolling' => 'Horisontal bergulir',
'Compact/wide view' => 'Beralih antara tampilan kompak dan diperluas',
- 'No results match:' => 'Tidak ada hasil :',
'Currency' => 'Mata uang',
'Private project' => 'projek pribadi',
'AUD - Australian Dollar' => 'AUD - Dollar Australia',
@@ -566,6 +557,7 @@ return array(
'JPY - Japanese Yen' => 'JPY - Yen Jepang',
'NZD - New Zealand Dollar' => 'NZD - Dollar Selandia baru',
'RSD - Serbian dinar' => 'RSD - Dinar Serbia',
+ // 'CNY - Chinese Yuan' => '',
'USD - US Dollar' => 'USD - Dollar Amerika',
'Destination column' => 'Kolom tujuan',
'Move the task to another column when assigned to a user' => 'Pindahkan tugas ke kolom lain ketika ditugaskan ke pengguna',
@@ -580,7 +572,6 @@ return array(
'Currency rates' => 'Nilai tukar mata uang',
'Rate' => 'Tarif',
'Change reference currency' => 'Mengubah referensi mata uang',
- 'Add a new currency rate' => 'Tambahkan nilai tukar mata uang baru',
'Reference currency' => 'Referensi mata uang',
'The currency rate have been added successfully.' => 'Nilai tukar mata uang berhasil ditambahkan.',
'Unable to add this currency rate.' => 'Tidak dapat menambahkan nilai tukar mata uang',
@@ -702,7 +693,6 @@ return array(
'<30m' => '<30m',
'Stop timer' => 'Hentikan timer',
'Start timer' => 'Mulai timer',
- 'Add project member' => 'Tambahkan anggota projek',
'My activity stream' => 'Aliran kegiatan saya',
'My calendar' => 'Kalender saya',
'Search tasks' => 'Cari tugas',
@@ -757,8 +747,6 @@ return array(
'Remote user' => 'Pengguna jauh',
'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => 'Pengguna jauh tidak menyimpan kata laluan mereka dalam basis data Kanboard, contoh: Akaun LDAP, Google dan Github.',
'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => 'Jika anda mencentang kotak "Larang formulir login", kredensial masuk ke formulis login akan diabaikan.',
- 'New remote user' => 'Pengguna baru jauh',
- 'New local user' => 'Pengguna baru lokal',
'Default task color' => 'Standar warna tugas',
'This feature does not work with all browsers.' => 'Ciri ini tidak dapat digunakan pada semua browsers',
'There is no destination project available.' => 'Tiada destinasi projek yang tersedia.',
@@ -852,7 +840,6 @@ return array(
// '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!' => '',
@@ -980,7 +967,6 @@ return array(
// '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' => '',
@@ -1037,7 +1023,6 @@ return array(
// 'Started:' => '',
// 'Moved:' => '',
// 'Task #%d' => '',
- // 'Date and time format' => '',
// 'Time format' => '',
// 'Start date: ' => '',
// 'End date: ' => '',
@@ -1051,9 +1036,7 @@ return array(
// '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' => '',
@@ -1163,7 +1146,6 @@ return array(
// 'Email sender address' => '',
// 'Email transport' => '',
// 'Webhook token' => '',
- // 'Imports' => '',
// 'Project tags management' => '',
// 'Tag created successfully.' => '',
// 'Unable to create this tag.' => '',
@@ -1210,8 +1192,6 @@ return array(
// 'Activity stream for %s' => '',
// 'Calendar for %s' => '',
// 'Notifications for %s' => '',
- // 'Subtasks export' => '',
- // 'Tasks exportation' => '',
// 'Assign a color when the task is moved to a specific swimlane' => '',
// 'Assign a priority when the task is moved to a specific swimlane' => '',
// 'User unlocked successfully.' => '',
@@ -1277,4 +1257,61 @@ return array(
// 'This field is required' => '',
// 'Moving a task is not permitted' => '',
// 'This value must be in the range %d to %d' => '',
+ // 'You are not allowed to move this task.' => '',
+ // 'API User Access' => '',
+ // 'Preview' => '',
+ // 'Write' => '',
+ // 'Write your text in Markdown' => '',
+ // 'New External Task: %s' => '',
+ // 'No personal API access token registered.' => '',
+ // 'Your personal API access token is "%s"' => '',
+ // 'Remove your token' => '',
+ // 'Generate a new token' => '',
+ // 'Showing %d-%d of %d' => '',
+ // 'Outgoing Emails' => '',
+ // 'Add or change currency rate' => '',
+ // 'Reference currency: %s' => '',
+ // 'Add custom filters' => '',
+ // 'Export' => '',
+ // 'Add link label' => '',
+ // 'Incompatible Plugins' => '',
+ // 'Compatibility' => '',
+ // 'Permissions and ownership' => '',
+ // 'Priorities' => '',
+ // 'Close this window' => '',
+ // 'Unable to upload this file.' => '',
+ // 'Import tasks' => '',
+ // 'Choose a project' => '',
+ // 'Profile' => '',
+ // 'Application role' => '',
+ // '%d invitations were sent.' => '',
+ // '%d invitation was sent.' => '',
+ // 'Unable to create this user.' => '',
+ // 'Kanboard Invitation' => '',
+ // 'Visible on dashboard' => '',
+ // 'Created at:' => '',
+ // 'Updated at:' => '',
+ // 'There is no custom filter.' => '',
+ // 'New User' => '',
+ // 'Authentication' => '',
+ // 'If checked, this user will use a third-party system for authentication.' => '',
+ // 'The password is necessary only for local users.' => '',
+ // 'You have been invited to register on Kanboard.' => '',
+ // 'Click here to join your team' => '',
+ // 'Invite people' => '',
+ // 'Emails' => '',
+ // 'Enter one email address by line.' => '',
+ // 'Add these people to this project' => '',
+ // 'Add this person to this project' => '',
+ // 'Sign-up' => '',
+ // 'Credentials' => '',
+ // 'New user' => '',
+ // 'This username is already taken' => '',
+ // 'A link to reset your password has been sent by email.' => '',
+ // 'Your profile must have a valid email address.' => '',
+ // 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
+ // 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
+ // 'The email configuration has been disabled by the administrator.' => '',
);
diff --git a/app/Locale/nb_NO/translations.php b/app/Locale/nb_NO/translations.php
index ff819787..2743009c 100644
--- a/app/Locale/nb_NO/translations.php
+++ b/app/Locale/nb_NO/translations.php
@@ -61,7 +61,6 @@ return array(
'%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',
- 'Edit board' => 'Endre prosjektsiden',
'Disable' => 'Deaktiver',
'Enable' => 'Aktiver',
'New project' => 'Nytt prosjekt',
@@ -72,7 +71,6 @@ return array(
'Title' => 'Tittel',
'Assigned to %s' => 'Tildelt: %s',
'Remove a column' => 'Fjern en kolonne',
- 'Remove a column from a board' => 'Fjern en kolonne fra et board',
'Unable to remove this column.' => 'Ikke mulig ø fjerne denne kolonnen',
'Do you really want to remove this column: "%s"?' => 'Vil du fjerne denne kolonnen: "%s"?',
'This action will REMOVE ALL TASKS associated to this column!' => 'Denne handlingen vil SLETTE ALLE OPPGAVER tilknyttet denne kolonnen',
@@ -160,9 +158,7 @@ return array(
'Task count' => 'Antall oppgaver',
'User' => 'Bruker',
'Comments' => 'Kommentarer',
- 'Leave a comment' => 'Legg inn en kommentar',
'Comment is required' => 'Kommentar må legges inn',
- 'Leave a description' => 'Legg inn en beskrivelse...',
'Comment added successfully.' => 'Kommentaren er lagt til.',
'Unable to create your comment.' => 'Din kommentar kunne ikke opprettes.',
'Due Date' => 'Forfallsdato',
@@ -224,7 +220,6 @@ return array(
'Search' => 'Søk',
'Nothing found.' => 'Intet funnet.',
'Due date' => 'Forfallsdato',
- 'Others formats accepted: %s and %s' => 'Andre formater: %s og %s',
'Description' => 'Beskrivelse',
'%d comments' => '%d kommentarer',
'%d comment' => '%d kommentar',
@@ -298,7 +293,6 @@ return array(
'Created by %s' => 'Opprettet av %s',
'Tasks Export' => 'Oppgave eksport',
'Start Date' => 'Start-dato',
- 'End Date' => 'Slutt-dato',
'Execute' => 'KKjør',
'Task Id' => 'Oppgave ID',
'Creator' => 'Laget av',
@@ -342,8 +336,8 @@ return array(
'Remote' => 'Fjernstyrt',
'Enabled' => 'Aktiv',
'Disabled' => 'Deaktivert',
- 'Username:' => 'Brukernavn',
- 'Name:' => 'Navn:',
+ 'Login:' => 'Brukernavn',
+ 'Full Name:' => 'Navn:',
'Email:' => 'Epost:',
'Notifications:' => 'Varslinger:',
'Notifications' => 'Varslinger',
@@ -516,10 +510,8 @@ return array(
'Link labels' => 'Relasjonsetiketter',
'Link modification' => 'Relasjonsmodifisering',
'Links' => 'Relasjoner',
- 'Link settings' => 'Relasjonsinnstillinger',
'Opposite label' => 'Etikett for relatert motsatt oppgave',
'Remove a link' => 'Fjern relasjon',
- // 'Task\'s links' => '',
// 'The labels must be different' => '',
// 'There is no link.' => '',
// 'This label must be unique' => '',
@@ -552,7 +544,6 @@ return array(
'Compact view' => 'Kompakt visning',
'Horizontal scrolling' => 'Bla horisontalt',
'Compact/wide view' => 'Kompakt/bred visning',
- 'No results match:' => 'Ingen resultater',
'Currency' => 'Valuta',
'Private project' => 'Privat prosjekt',
// 'AUD - Australian Dollar' => '',
@@ -566,6 +557,7 @@ return array(
// 'JPY - Japanese Yen' => '',
// 'NZD - New Zealand Dollar' => '',
// 'RSD - Serbian dinar' => '',
+ // 'CNY - Chinese Yuan' => '',
// 'USD - US Dollar' => '',
'Destination column' => 'Ny kolonne',
'Move the task to another column when assigned to a user' => 'Flytt oppgaven til en annen kolonne når den er tildelt en bruker',
@@ -580,7 +572,6 @@ return array(
'Currency rates' => 'Valutakurser',
// 'Rate' => '',
// 'Change reference currency' => '',
- // 'Add a new currency rate' => '',
// 'Reference currency' => '',
// 'The currency rate have been added successfully.' => '',
// 'Unable to add this currency rate.' => '',
@@ -702,7 +693,6 @@ return array(
// '<30m' => '',
'Stop timer' => 'Stopp timer',
'Start timer' => 'Start timer',
- 'Add project member' => 'Legg til prosjektmedlem',
'My activity stream' => 'Aktivitetslogg',
'My calendar' => 'Min kalender',
'Search tasks' => 'Søk oppgave',
@@ -757,8 +747,6 @@ return array(
// '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' => 'Ny eksternbruker',
- 'New local user' => 'Ny internbruker',
'Default task color' => 'Standard oppgavefarge',
// 'This feature does not work with all browsers.' => '',
// 'There is no destination project available.' => '',
@@ -852,7 +840,6 @@ return array(
// '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!' => '',
@@ -980,7 +967,6 @@ return array(
// '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' => '',
@@ -1037,7 +1023,6 @@ return array(
// 'Started:' => '',
// 'Moved:' => '',
// 'Task #%d' => '',
- // 'Date and time format' => '',
// 'Time format' => '',
// 'Start date: ' => '',
// 'End date: ' => '',
@@ -1051,9 +1036,7 @@ return array(
// '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' => '',
@@ -1163,7 +1146,6 @@ return array(
// 'Email sender address' => '',
// 'Email transport' => '',
// 'Webhook token' => '',
- // 'Imports' => '',
// 'Project tags management' => '',
// 'Tag created successfully.' => '',
// 'Unable to create this tag.' => '',
@@ -1210,8 +1192,6 @@ return array(
// 'Activity stream for %s' => '',
// 'Calendar for %s' => '',
// 'Notifications for %s' => '',
- // 'Subtasks export' => '',
- // 'Tasks exportation' => '',
// 'Assign a color when the task is moved to a specific swimlane' => '',
// 'Assign a priority when the task is moved to a specific swimlane' => '',
// 'User unlocked successfully.' => '',
@@ -1277,4 +1257,61 @@ return array(
// 'This field is required' => '',
// 'Moving a task is not permitted' => '',
// 'This value must be in the range %d to %d' => '',
+ // 'You are not allowed to move this task.' => '',
+ // 'API User Access' => '',
+ // 'Preview' => '',
+ // 'Write' => '',
+ // 'Write your text in Markdown' => '',
+ // 'New External Task: %s' => '',
+ // 'No personal API access token registered.' => '',
+ // 'Your personal API access token is "%s"' => '',
+ // 'Remove your token' => '',
+ // 'Generate a new token' => '',
+ // 'Showing %d-%d of %d' => '',
+ // 'Outgoing Emails' => '',
+ // 'Add or change currency rate' => '',
+ // 'Reference currency: %s' => '',
+ // 'Add custom filters' => '',
+ // 'Export' => '',
+ // 'Add link label' => '',
+ // 'Incompatible Plugins' => '',
+ // 'Compatibility' => '',
+ // 'Permissions and ownership' => '',
+ // 'Priorities' => '',
+ // 'Close this window' => '',
+ // 'Unable to upload this file.' => '',
+ // 'Import tasks' => '',
+ // 'Choose a project' => '',
+ // 'Profile' => '',
+ // 'Application role' => '',
+ // '%d invitations were sent.' => '',
+ // '%d invitation was sent.' => '',
+ // 'Unable to create this user.' => '',
+ // 'Kanboard Invitation' => '',
+ // 'Visible on dashboard' => '',
+ // 'Created at:' => '',
+ // 'Updated at:' => '',
+ // 'There is no custom filter.' => '',
+ // 'New User' => '',
+ // 'Authentication' => '',
+ // 'If checked, this user will use a third-party system for authentication.' => '',
+ // 'The password is necessary only for local users.' => '',
+ // 'You have been invited to register on Kanboard.' => '',
+ // 'Click here to join your team' => '',
+ // 'Invite people' => '',
+ // 'Emails' => '',
+ // 'Enter one email address by line.' => '',
+ // 'Add these people to this project' => '',
+ // 'Add this person to this project' => '',
+ // 'Sign-up' => '',
+ // 'Credentials' => '',
+ // 'New user' => '',
+ // 'This username is already taken' => '',
+ // 'A link to reset your password has been sent by email.' => '',
+ // 'Your profile must have a valid email address.' => '',
+ // 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
+ // 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
+ // 'The email configuration has been disabled by the administrator.' => '',
);
diff --git a/app/Locale/nl_NL/translations.php b/app/Locale/nl_NL/translations.php
index 22c76713..45a8c5bc 100644
--- a/app/Locale/nl_NL/translations.php
+++ b/app/Locale/nl_NL/translations.php
@@ -61,7 +61,6 @@ return array(
'%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.',
- 'Edit board' => 'Bord bewerken',
'Disable' => 'Deactiveren',
'Enable' => 'Activeren',
'New project' => 'Nieuw project',
@@ -72,7 +71,6 @@ return array(
'Title' => 'Titel',
'Assigned to %s' => 'Toegewezen aan %s',
'Remove a column' => 'Kolom verwijderen',
- 'Remove a column from a board' => 'Kolom verwijderen van het bord',
'Unable to remove this column.' => 'Verwijderen van deze kolom niet mogelijk.',
'Do you really want to remove this column: "%s"?' => 'Weet u zeker dat u deze kolom wil verwijderen : « %s » ?',
'This action will REMOVE ALL TASKS associated to this column!' => 'Deze actie zal ALLE TAKEN VERWIJDEREN die zijn geassocieerd met deze kolom!',
@@ -160,9 +158,7 @@ return array(
'Task count' => 'Aantal taken',
'User' => 'Gebruiker',
'Comments' => 'Commentaar',
- 'Leave a comment' => 'Schrijf een commentaar',
'Comment is required' => 'Commentaar is verplicht',
- 'Leave a description' => 'Schrijf een omschrijving',
'Comment added successfully.' => 'Commentaar succesvol toegevoegd.',
'Unable to create your comment.' => 'Commentaar toevoegen niet gelukt.',
'Due Date' => 'Vervaldag',
@@ -224,7 +220,6 @@ return array(
'Search' => 'Zoek',
'Nothing found.' => 'Niets gevonden.',
'Due date' => 'Vervaldatum',
- 'Others formats accepted: %s and %s' => 'Andere toegestane formaten : %s en %s',
'Description' => 'Omschrijving',
'%d comments' => '%d commentaren',
'%d comment' => '%d commentaar',
@@ -298,7 +293,6 @@ return array(
'Created by %s' => 'Aangemaakt door %s',
'Tasks Export' => 'Taken exporteren',
'Start Date' => 'Startdatum',
- 'End Date' => 'Einddatum',
'Execute' => 'Uitvoeren',
'Task Id' => 'Taak Id',
'Creator' => 'Aangemaakt door',
@@ -342,8 +336,8 @@ return array(
'Remote' => 'Remote',
'Enabled' => 'Actief',
'Disabled' => 'Inactief',
- 'Username:' => 'Gebruikersnaam :',
- 'Name:' => 'Naam :',
+ 'Login:' => 'Gebruikersnaam :',
+ 'Full Name:' => 'Naam :',
'Email:' => 'Email :',
'Notifications:' => 'Notificaties :',
'Notifications' => 'Notificaties',
@@ -516,10 +510,8 @@ return array(
'Link labels' => 'Link labels',
'Link modification' => 'Link aanpassing',
'Links' => 'Links',
- 'Link settings' => 'Link instellingen',
'Opposite label' => 'Tegenovergesteld label',
'Remove a link' => 'Link verwijderen',
- 'Task\'s links' => 'Links van taak',
'The labels must be different' => 'De labels moeten verschillend zijn',
'There is no link.' => 'Er is geen link.',
'This label must be unique' => 'Dit label moet uniek zijn',
@@ -552,7 +544,6 @@ return array(
'Compact view' => 'Compacte weergave',
// 'Horizontal scrolling' => '',
'Compact/wide view' => 'Compacte/breedbeeld-weergave',
- 'No results match:' => 'Geen resultaten voor',
'Currency' => 'Valuta',
'Private project' => 'Privé project',
// 'AUD - Australian Dollar' => '',
@@ -566,6 +557,7 @@ return array(
// 'JPY - Japanese Yen' => '',
// 'NZD - New Zealand Dollar' => '',
// 'RSD - Serbian dinar' => '',
+ // 'CNY - Chinese Yuan' => '',
// 'USD - US Dollar' => '',
'Destination column' => 'Doel kolom',
// 'Move the task to another column when assigned to a user' => '',
@@ -580,7 +572,6 @@ return array(
'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.' => '',
@@ -702,7 +693,6 @@ return array(
'<30m' => '<30m',
'Stop timer' => 'Stop timer',
'Start timer' => 'Start timer',
- 'Add project member' => 'Voeg projectlid toe',
'My activity stream' => 'Mijn activiteiten',
'My calendar' => 'Mijn kalender',
'Search tasks' => 'Zoek taken',
@@ -757,8 +747,6 @@ return array(
// '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.' => '',
@@ -852,7 +840,6 @@ return array(
// '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!' => '',
@@ -980,7 +967,6 @@ return array(
// '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' => '',
@@ -1037,7 +1023,6 @@ return array(
// 'Started:' => '',
// 'Moved:' => '',
// 'Task #%d' => '',
- // 'Date and time format' => '',
// 'Time format' => '',
// 'Start date: ' => '',
// 'End date: ' => '',
@@ -1051,9 +1036,7 @@ return array(
// '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' => '',
@@ -1163,7 +1146,6 @@ return array(
// 'Email sender address' => '',
// 'Email transport' => '',
// 'Webhook token' => '',
- // 'Imports' => '',
// 'Project tags management' => '',
// 'Tag created successfully.' => '',
// 'Unable to create this tag.' => '',
@@ -1210,8 +1192,6 @@ return array(
// 'Activity stream for %s' => '',
// 'Calendar for %s' => '',
// 'Notifications for %s' => '',
- // 'Subtasks export' => '',
- // 'Tasks exportation' => '',
// 'Assign a color when the task is moved to a specific swimlane' => '',
// 'Assign a priority when the task is moved to a specific swimlane' => '',
// 'User unlocked successfully.' => '',
@@ -1277,4 +1257,61 @@ return array(
// 'This field is required' => '',
// 'Moving a task is not permitted' => '',
// 'This value must be in the range %d to %d' => '',
+ // 'You are not allowed to move this task.' => '',
+ // 'API User Access' => '',
+ // 'Preview' => '',
+ // 'Write' => '',
+ // 'Write your text in Markdown' => '',
+ // 'New External Task: %s' => '',
+ // 'No personal API access token registered.' => '',
+ // 'Your personal API access token is "%s"' => '',
+ // 'Remove your token' => '',
+ // 'Generate a new token' => '',
+ // 'Showing %d-%d of %d' => '',
+ // 'Outgoing Emails' => '',
+ // 'Add or change currency rate' => '',
+ // 'Reference currency: %s' => '',
+ // 'Add custom filters' => '',
+ // 'Export' => '',
+ // 'Add link label' => '',
+ // 'Incompatible Plugins' => '',
+ // 'Compatibility' => '',
+ // 'Permissions and ownership' => '',
+ // 'Priorities' => '',
+ // 'Close this window' => '',
+ // 'Unable to upload this file.' => '',
+ // 'Import tasks' => '',
+ // 'Choose a project' => '',
+ // 'Profile' => '',
+ // 'Application role' => '',
+ // '%d invitations were sent.' => '',
+ // '%d invitation was sent.' => '',
+ // 'Unable to create this user.' => '',
+ // 'Kanboard Invitation' => '',
+ // 'Visible on dashboard' => '',
+ // 'Created at:' => '',
+ // 'Updated at:' => '',
+ // 'There is no custom filter.' => '',
+ // 'New User' => '',
+ // 'Authentication' => '',
+ // 'If checked, this user will use a third-party system for authentication.' => '',
+ // 'The password is necessary only for local users.' => '',
+ // 'You have been invited to register on Kanboard.' => '',
+ // 'Click here to join your team' => '',
+ // 'Invite people' => '',
+ // 'Emails' => '',
+ // 'Enter one email address by line.' => '',
+ // 'Add these people to this project' => '',
+ // 'Add this person to this project' => '',
+ // 'Sign-up' => '',
+ // 'Credentials' => '',
+ // 'New user' => '',
+ // 'This username is already taken' => '',
+ // 'A link to reset your password has been sent by email.' => '',
+ // 'Your profile must have a valid email address.' => '',
+ // 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
+ // 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
+ // 'The email configuration has been disabled by the administrator.' => '',
);
diff --git a/app/Locale/pl_PL/translations.php b/app/Locale/pl_PL/translations.php
index be39d095..b8c4a2c7 100644
--- a/app/Locale/pl_PL/translations.php
+++ b/app/Locale/pl_PL/translations.php
@@ -61,7 +61,6 @@ return array(
'%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.',
- 'Edit board' => 'Edytuj tablicę',
'Disable' => 'Wyłącz',
'Enable' => 'Włącz',
'New project' => 'Nowy projekt',
@@ -72,7 +71,6 @@ return array(
'Title' => 'Nazwa',
'Assigned to %s' => 'Przypisane do %s',
'Remove a column' => 'Usuń kolumnę',
- 'Remove a column from a board' => 'Usuń kolumnę z tablicy',
'Unable to remove this column.' => 'Nie udało się usunąć kolumny.',
'Do you really want to remove this column: "%s"?' => 'Na pewno chcesz usunąć kolumnę: "%s"?',
'This action will REMOVE ALL TASKS associated to this column!' => 'Wszystkie zadania w kolumnie zostaną usunięte!',
@@ -160,9 +158,7 @@ return array(
'Task count' => 'Liczba zadań',
'User' => 'Użytkownik',
'Comments' => 'Komentarze',
- 'Leave a comment' => 'Wstaw komentarz',
'Comment is required' => 'Komentarz jest wymagany',
- 'Leave a description' => 'Dodaj opis',
'Comment added successfully.' => 'Komentarz dodany',
'Unable to create your comment.' => 'Nie udało się dodać komentarza',
'Due Date' => 'Termin',
@@ -224,7 +220,6 @@ return array(
'Search' => 'Szukaj',
'Nothing found.' => 'Nic nie znaleziono',
'Due date' => 'Termin',
- 'Others formats accepted: %s and %s' => 'Inne akceptowane formaty: %s and %s',
'Description' => 'Opis',
'%d comments' => '%d Komentarzy',
'%d comment' => '%d Komentarz',
@@ -298,7 +293,6 @@ return array(
'Created by %s' => 'Utworzone przez %s',
'Tasks Export' => 'Eksport zadań',
'Start Date' => 'Data początkowa',
- 'End Date' => 'Data Końcowa',
'Execute' => 'Wykonaj',
'Task Id' => 'Identyfikator Zadania',
'Creator' => 'Autor',
@@ -342,8 +336,8 @@ return array(
'Remote' => 'Zdalne',
'Enabled' => 'Odblokowane',
'Disabled' => 'Zablokowane',
- 'Username:' => 'Nazwa Użytkownika (login):',
- 'Name:' => 'Imię i Nazwisko',
+ 'Login:' => 'Nazwa Użytkownika (login):',
+ 'Full Name:' => 'Imię i Nazwisko',
'Email:' => 'Email: ',
'Notifications:' => 'Powiadomienia: ',
'Notifications' => 'Powiadomienia',
@@ -516,10 +510,8 @@ return array(
'Link labels' => 'Etykiety linku',
'Link modification' => 'Modyfikuj link',
'Links' => 'Linki',
- 'Link settings' => 'Ustawienia linku',
'Opposite label' => 'Etykieta odwrotna',
'Remove a link' => 'Usuń link',
- 'Task\'s links' => 'Linki zadania',
'The labels must be different' => 'Etykiety muszą być różne',
'There is no link.' => 'Brak linku',
'This label must be unique' => 'Etykieta musi być unikatowa',
@@ -552,7 +544,6 @@ return array(
'Compact view' => 'Widok kompaktowy',
'Horizontal scrolling' => 'Przewijanie poziome',
'Compact/wide view' => 'Pełny/Kompaktowy widok',
- 'No results match:' => 'Brak wyników:',
'Currency' => 'Waluta',
'Private project' => 'Projekt prywatny',
'AUD - Australian Dollar' => 'AUD - Dolar australijski',
@@ -566,6 +557,7 @@ return array(
'JPY - Japanese Yen' => 'JPY - Jen japoński',
'NZD - New Zealand Dollar' => 'NZD - Dolar nowozelandzki',
'RSD - Serbian dinar' => 'RSD - Dinar serbski',
+ // 'CNY - Chinese Yuan' => '',
'USD - US Dollar' => 'USD - Dolar amerykański',
'Destination column' => 'Kolumna docelowa',
'Move the task to another column when assigned to a user' => 'Przenieś zadanie do innej kolumny gdy zostanie przypisane do osoby',
@@ -580,7 +572,6 @@ return array(
'Currency rates' => 'Kursy walut',
'Rate' => 'Kurs',
'Change reference currency' => 'Zmień walutę referencyjną',
- 'Add a new currency rate' => 'Dodaj nowy kurs waluty',
'Reference currency' => 'Waluta referencyjna',
'The currency rate have been added successfully.' => 'Dodano kurs waluty',
'Unable to add this currency rate.' => 'Nie można dodać kursu waluty',
@@ -702,7 +693,6 @@ return array(
// '<30m' => '',
'Stop timer' => 'Zatrzymaj pomiar czasu',
'Start timer' => 'Uruchom pomiar czasu',
- 'Add project member' => 'Dodaj uczestnika projektu',
'My activity stream' => 'Moja aktywność',
'My calendar' => 'Mój kalendarz',
'Search tasks' => 'Szukaj zadań',
@@ -757,8 +747,6 @@ return array(
'Remote user' => 'Zdalny użytkownik',
'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => 'Zdalni użykownicy nie przechowują swojego hasła w bazie danych Kanboard, przykłady: konta LDAP, Google and Github.',
'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => 'Jeśli zaznaczysz "Zablokuj możliwość logowania", dane podane przy logowaniu zostaną zignorowane.',
- 'New remote user' => 'Nowy użytkownik zdalny',
- 'New local user' => 'Nowy użytkownik lokalny',
'Default task color' => 'Domyślny kolor zadań',
'This feature does not work with all browsers.' => 'Ta funkcja może nie działać z każdą przeglądarką.',
'There is no destination project available.' => 'Żaden docelowy projekt nie jest aktualnie dostępny.',
@@ -852,7 +840,6 @@ return array(
'Owner' => 'Właściciel',
'Unread notifications' => 'Nieprzeczytane powiadomienia',
'Notification methods:' => 'Metody powiadomień:',
- 'Import tasks from CSV file' => 'Importuj zadania z pliku CSV',
'Unable to read your file' => 'Nie można odczytać pliku',
'%d task(s) have been imported successfully.' => '%d zadań zostało zaimportowanych.',
'Nothing have been imported!' => 'Nic nie zostało zaimportowane!',
@@ -980,7 +967,6 @@ return array(
'Project owner: ' => 'Właściciel projektu: ',
'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.',
'Private projects do not have users and groups management.' => 'Projekty prywatne nie wspierają obsługi użytkowników i grup.',
'There is no project member.' => 'Projekt nie ma uczestników.',
'Priority' => 'Priorytet',
@@ -1037,7 +1023,6 @@ return array(
'Started:' => 'Rozpoczęte:',
'Moved:' => 'Przeniesione:',
'Task #%d' => 'Zadanie #%d',
- 'Date and time format' => 'Format daty oraz czasu',
'Time format' => 'Format czasu',
'Start date: ' => 'Data rozpoczęcia: ',
'End date: ' => 'Data zakończenia: ',
@@ -1051,9 +1036,7 @@ return array(
'User disabled successfully.' => 'Użytkownik został wyłączony.',
'Unable to disable this user.' => 'Nie można wyłączyć użytkownika.',
'All files have been uploaded successfully.' => 'Wszystkie pliki zostały pomyślnie przesłane.',
- 'View uploaded files' => 'Zobacz przesłane pliki',
'The maximum allowed file size is %sB.' => 'Maksymalny rozmiar pliku to %sB.',
- 'Choose files again' => 'Wybierz jeszcze raz pliki',
'Drag and drop your files here' => 'Przeciągnij i upuść pliki tutaj',
'choose files' => 'wybierz pliki',
'View profile' => 'Zobacz profil',
@@ -1163,7 +1146,6 @@ return array(
// 'Email sender address' => '',
// 'Email transport' => '',
// 'Webhook token' => '',
- // 'Imports' => '',
// 'Project tags management' => '',
// 'Tag created successfully.' => '',
// 'Unable to create this tag.' => '',
@@ -1210,8 +1192,6 @@ return array(
// 'Activity stream for %s' => '',
// 'Calendar for %s' => '',
// 'Notifications for %s' => '',
- // 'Subtasks export' => '',
- // 'Tasks exportation' => '',
// 'Assign a color when the task is moved to a specific swimlane' => '',
// 'Assign a priority when the task is moved to a specific swimlane' => '',
// 'User unlocked successfully.' => '',
@@ -1277,4 +1257,61 @@ return array(
// 'This field is required' => '',
// 'Moving a task is not permitted' => '',
// 'This value must be in the range %d to %d' => '',
+ // 'You are not allowed to move this task.' => '',
+ // 'API User Access' => '',
+ // 'Preview' => '',
+ // 'Write' => '',
+ // 'Write your text in Markdown' => '',
+ // 'New External Task: %s' => '',
+ // 'No personal API access token registered.' => '',
+ // 'Your personal API access token is "%s"' => '',
+ // 'Remove your token' => '',
+ // 'Generate a new token' => '',
+ // 'Showing %d-%d of %d' => '',
+ // 'Outgoing Emails' => '',
+ // 'Add or change currency rate' => '',
+ // 'Reference currency: %s' => '',
+ // 'Add custom filters' => '',
+ // 'Export' => '',
+ // 'Add link label' => '',
+ // 'Incompatible Plugins' => '',
+ // 'Compatibility' => '',
+ // 'Permissions and ownership' => '',
+ // 'Priorities' => '',
+ // 'Close this window' => '',
+ // 'Unable to upload this file.' => '',
+ // 'Import tasks' => '',
+ // 'Choose a project' => '',
+ // 'Profile' => '',
+ // 'Application role' => '',
+ // '%d invitations were sent.' => '',
+ // '%d invitation was sent.' => '',
+ // 'Unable to create this user.' => '',
+ // 'Kanboard Invitation' => '',
+ // 'Visible on dashboard' => '',
+ // 'Created at:' => '',
+ // 'Updated at:' => '',
+ // 'There is no custom filter.' => '',
+ // 'New User' => '',
+ // 'Authentication' => '',
+ // 'If checked, this user will use a third-party system for authentication.' => '',
+ // 'The password is necessary only for local users.' => '',
+ // 'You have been invited to register on Kanboard.' => '',
+ // 'Click here to join your team' => '',
+ // 'Invite people' => '',
+ // 'Emails' => '',
+ // 'Enter one email address by line.' => '',
+ // 'Add these people to this project' => '',
+ // 'Add this person to this project' => '',
+ // 'Sign-up' => '',
+ // 'Credentials' => '',
+ // 'New user' => '',
+ // 'This username is already taken' => '',
+ // 'A link to reset your password has been sent by email.' => '',
+ // 'Your profile must have a valid email address.' => '',
+ // 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
+ // 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
+ // 'The email configuration has been disabled by the administrator.' => '',
);
diff --git a/app/Locale/pt_BR/translations.php b/app/Locale/pt_BR/translations.php
index eebfe9f4..a21e7cb8 100644
--- a/app/Locale/pt_BR/translations.php
+++ b/app/Locale/pt_BR/translations.php
@@ -61,7 +61,6 @@ return array(
'%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.',
- 'Edit board' => 'Editar board',
'Disable' => 'Desativar',
'Enable' => 'Ativar',
'New project' => 'Novo projeto',
@@ -72,7 +71,6 @@ return array(
'Title' => 'Título',
'Assigned to %s' => 'Designado para %s',
'Remove a column' => 'Remover uma coluna',
- 'Remove a column from a board' => 'Remover uma coluna do board',
'Unable to remove this column.' => 'Não foi possível remover esta coluna.',
'Do you really want to remove this column: "%s"?' => 'Você realmente deseja remover esta coluna: "%s"?',
'This action will REMOVE ALL TASKS associated to this column!' => 'Esta ação irá REMOVER TODAS AS TAREFAS associadas a esta coluna!',
@@ -160,9 +158,7 @@ return array(
'Task count' => 'Número de tarefas',
'User' => 'Usuário',
'Comments' => 'Comentários',
- 'Leave a comment' => 'Deixe um comentário',
'Comment is required' => 'Comentário é obrigatório',
- 'Leave a description' => 'Deixe uma descrição',
'Comment added successfully.' => 'Comentário adicionado com sucesso.',
'Unable to create your comment.' => 'Não é possível criar o seu comentário.',
'Due Date' => 'Data fim estimada',
@@ -224,7 +220,6 @@ return array(
'Search' => 'Pesquisar',
'Nothing found.' => 'Nada foi encontrado.',
'Due date' => 'Data fim estimada',
- 'Others formats accepted: %s and %s' => 'Outros formatos permitidos: %s e %s',
'Description' => 'Descrição',
'%d comments' => '%d comentários',
'%d comment' => '%d comentário',
@@ -298,7 +293,6 @@ return array(
'Created by %s' => 'Criado por %s',
'Tasks Export' => 'Exportar Tarefas',
'Start Date' => 'Data inicial',
- 'End Date' => 'Data final',
'Execute' => 'Executar',
'Task Id' => 'ID da Tarefa',
'Creator' => 'Criado por',
@@ -342,8 +336,8 @@ return array(
'Remote' => 'Remoto',
'Enabled' => 'Habilitado',
'Disabled' => 'Desabilitado',
- 'Username:' => 'Usuário:',
- 'Name:' => 'Nome:',
+ 'Login:' => 'Usuário:',
+ 'Full Name:' => 'Nome:',
'Email:' => 'E-mail:',
'Notifications:' => 'Notificações:',
'Notifications' => 'Notificações',
@@ -516,10 +510,8 @@ return array(
'Link labels' => 'Etiquetas das associações',
'Link modification' => 'Modificação de uma associação',
'Links' => 'Associações',
- 'Link settings' => 'Configuração das associações',
'Opposite label' => 'Nome da etiqueta oposta',
'Remove a link' => 'Remover uma associação',
- 'Task\'s links' => 'Associações das tarefas',
'The labels must be different' => 'As etiquetas devem ser diferentes',
'There is no link.' => 'Não há nenhuma associação.',
'This label must be unique' => 'Esta etiqueta deve ser unica',
@@ -552,7 +544,6 @@ return array(
'Compact view' => 'Vista reduzida',
'Horizontal scrolling' => 'Rolagem horizontal',
'Compact/wide view' => 'Alternar entre a vista compacta e ampliada',
- 'No results match:' => 'Nenhum resultado:',
'Currency' => 'Moeda',
'Private project' => 'Projeto privado',
'AUD - Australian Dollar' => 'AUD - Dólar australiano',
@@ -566,6 +557,7 @@ return array(
'JPY - Japanese Yen' => 'JPY - Iene japonês',
'NZD - New Zealand Dollar' => 'NZD - Dólar Neozelandês',
'RSD - Serbian dinar' => 'RSD - Dinar sérvio',
+ // 'CNY - Chinese Yuan' => '',
'USD - US Dollar' => 'USD - Dólar norte-americano',
'Destination column' => 'Coluna de destino',
'Move the task to another column when assigned to a user' => 'Mover a tarefa para uma outra coluna quando esta está atribuída a um usuário',
@@ -580,7 +572,6 @@ return array(
'Currency rates' => 'Taxas de câmbio das moedas estrangeiras',
'Rate' => 'Taxa',
'Change reference currency' => 'Mudar a moeda de referência',
- 'Add a new currency rate' => 'Adicionar uma nova taxa para uma moeda',
'Reference currency' => 'Moeda de Referência',
'The currency rate have been added successfully.' => 'A taxa de câmbio foi adicionada com sucesso.',
'Unable to add this currency rate.' => 'Impossível de adicionar essa taxa de câmbio.',
@@ -702,7 +693,6 @@ return array(
'<30m' => '<30m',
'Stop timer' => 'Stop timer',
'Start timer' => 'Start timer',
- 'Add project member' => 'Adicionar membro ao projeto',
'My activity stream' => 'Meu feed de atividades',
'My calendar' => 'Minha agenda',
'Search tasks' => 'Pesquisar tarefas',
@@ -757,8 +747,6 @@ return array(
'Remote user' => 'Usuário remoto',
'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => 'Os usuários remotos não conservam as suas senhas no banco de dados Kanboard, exemplos: contas LDAP, Github ou Google.',
'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => 'Se você marcar "Interdir o formulário de autenticação", os identificadores entrados no formulário de login serão ignorado.',
- 'New remote user' => 'Criar um usuário remoto',
- 'New local user' => 'Criar um usuário local',
'Default task color' => 'Cor padrão para as tarefas',
'This feature does not work with all browsers.' => 'Esta funcionalidade não é compatível com todos os navegadores.',
'There is no destination project available.' => 'Não há nenhum projeto de destino disponível.',
@@ -852,7 +840,6 @@ return array(
'Owner' => 'Líder',
'Unread notifications' => 'Notificações não lidas',
'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',
'%d task(s) have been imported successfully.' => '%d tarefa(s) importada(s) com sucesso.',
'Nothing have been imported!' => 'Nada foi importado!',
@@ -980,7 +967,6 @@ return array(
'Project owner: ' => 'Líder do projeto: ',
'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => 'O identificador do projeto é opcional e deve ser alfanumérico, por exemplo MEUPROJETO.',
'Project owner' => 'Líder do projeto',
- 'Those dates are useful for the project Gantt chart.' => 'Estas datas são úteis para o gráfico de Gantt dos projetos.',
'Private projects do not have users and groups management.' => 'Projetos privados não têm gestão de usuários e grupos.',
'There is no project member.' => 'Não há nenhum membro do projeto.',
'Priority' => 'Prioridade',
@@ -1037,7 +1023,6 @@ return array(
'Started:' => 'Começado:',
'Moved:' => 'Movido:',
'Task #%d' => 'Tarefa #%d',
- 'Date and time format' => 'Formato da hora e da data',
'Time format' => 'Formato da hora',
'Start date: ' => 'Data de início: ',
'End date: ' => 'Data final: ',
@@ -1051,9 +1036,7 @@ return array(
'User disabled successfully.' => 'Usuário desactivado com sucesso.',
'Unable to disable this user.' => 'Impossível de desativar esse usuário.',
'All files have been uploaded successfully.' => 'Todos os arquivos foram enviados com sucesso.',
- 'View uploaded files' => 'Ver os arquivos enviados',
'The maximum allowed file size is %sB.' => 'O tamanho máximo dos arquivos é %sB.',
- 'Choose files again' => 'Selecionar novamente arquivos',
'Drag and drop your files here' => 'Arraste e solte os arquivos aqui',
'choose files' => 'selecione os arquivos',
'View profile' => 'Ver o perfil',
@@ -1163,7 +1146,6 @@ return array(
'Email sender address' => 'Endereço de envio de Email',
'Email transport' => 'Transportador de Email',
'Webhook token' => 'Token do Webhook',
- 'Imports' => 'Importados',
'Project tags management' => 'Gestão de etiquetas do Projeto',
'Tag created successfully.' => 'Etiqueta criada com sucesso.',
'Unable to create this tag.' => 'Não foi possivel criar esta etiqueta.',
@@ -1210,8 +1192,6 @@ return array(
'Activity stream for %s' => 'Fluxo de atividade de %s',
'Calendar for %s' => 'Calendário de %s',
'Notifications for %s' => 'Notificações de %s',
- 'Subtasks export' => 'Exportar sub-tarefas',
- 'Tasks exportation' => 'Exportação de tarefas',
'Assign a color when the task is moved to a specific swimlane' => 'Atribuir uma cor quando a tarefa é movida para uma swimlane especifica',
'Assign a priority when the task is moved to a specific swimlane' => 'Atribuir uma prioridade quando a tarefa é movida para uma swimlane especifica',
'User unlocked successfully.' => 'Usuário desbloqueado com sucesso.',
@@ -1277,4 +1257,61 @@ return array(
'This field is required' => 'Este campo é obrigatório',
'Moving a task is not permitted' => 'Mover uma tarefa não é permitido',
'This value must be in the range %d to %d' => 'Este valor precisa estar no intervalo %d até %d',
+ // 'You are not allowed to move this task.' => '',
+ // 'API User Access' => '',
+ // 'Preview' => '',
+ // 'Write' => '',
+ // 'Write your text in Markdown' => '',
+ // 'New External Task: %s' => '',
+ // 'No personal API access token registered.' => '',
+ // 'Your personal API access token is "%s"' => '',
+ // 'Remove your token' => '',
+ // 'Generate a new token' => '',
+ // 'Showing %d-%d of %d' => '',
+ // 'Outgoing Emails' => '',
+ // 'Add or change currency rate' => '',
+ // 'Reference currency: %s' => '',
+ // 'Add custom filters' => '',
+ // 'Export' => '',
+ // 'Add link label' => '',
+ // 'Incompatible Plugins' => '',
+ // 'Compatibility' => '',
+ // 'Permissions and ownership' => '',
+ // 'Priorities' => '',
+ // 'Close this window' => '',
+ // 'Unable to upload this file.' => '',
+ // 'Import tasks' => '',
+ // 'Choose a project' => '',
+ // 'Profile' => '',
+ // 'Application role' => '',
+ // '%d invitations were sent.' => '',
+ // '%d invitation was sent.' => '',
+ // 'Unable to create this user.' => '',
+ // 'Kanboard Invitation' => '',
+ // 'Visible on dashboard' => '',
+ // 'Created at:' => '',
+ // 'Updated at:' => '',
+ // 'There is no custom filter.' => '',
+ // 'New User' => '',
+ // 'Authentication' => '',
+ // 'If checked, this user will use a third-party system for authentication.' => '',
+ // 'The password is necessary only for local users.' => '',
+ // 'You have been invited to register on Kanboard.' => '',
+ // 'Click here to join your team' => '',
+ // 'Invite people' => '',
+ // 'Emails' => '',
+ // 'Enter one email address by line.' => '',
+ // 'Add these people to this project' => '',
+ // 'Add this person to this project' => '',
+ // 'Sign-up' => '',
+ // 'Credentials' => '',
+ // 'New user' => '',
+ // 'This username is already taken' => '',
+ // 'A link to reset your password has been sent by email.' => '',
+ // 'Your profile must have a valid email address.' => '',
+ // 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
+ // 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
+ // 'The email configuration has been disabled by the administrator.' => '',
);
diff --git a/app/Locale/pt_PT/translations.php b/app/Locale/pt_PT/translations.php
index 073a68c5..46c23f15 100644
--- a/app/Locale/pt_PT/translations.php
+++ b/app/Locale/pt_PT/translations.php
@@ -61,7 +61,6 @@ return array(
'%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.',
- 'Edit board' => 'Editar quadro',
'Disable' => 'Desactivar',
'Enable' => 'Activar',
'New project' => 'Novo projeto',
@@ -72,7 +71,6 @@ return array(
'Title' => 'Título',
'Assigned to %s' => 'Designado para %s',
'Remove a column' => 'Remover uma coluna',
- 'Remove a column from a board' => 'Remover uma coluna do quadro',
'Unable to remove this column.' => 'Não foi possível remover esta coluna.',
'Do you really want to remove this column: "%s"?' => 'Tem a certeza que quer remover esta coluna: "%s"?',
'This action will REMOVE ALL TASKS associated to this column!' => 'Esta acção irá REMOVER TODAS AS TAREFAS associadas a esta coluna!',
@@ -160,9 +158,7 @@ return array(
'Task count' => 'Número de tarefas',
'User' => 'Utilizador',
'Comments' => 'Comentários',
- 'Leave a comment' => 'Deixe um comentário',
'Comment is required' => 'Comentário é obrigatório',
- 'Leave a description' => 'Deixe uma descrição',
'Comment added successfully.' => 'Comentário adicionado com sucesso.',
'Unable to create your comment.' => 'Não é possível criar o seu comentário.',
'Due Date' => 'Data de vencimento',
@@ -224,7 +220,6 @@ return array(
'Search' => 'Pesquisar',
'Nothing found.' => 'Nada encontrado.',
'Due date' => 'Data de vencimento',
- 'Others formats accepted: %s and %s' => 'Outros formatos permitidos: %s e %s',
'Description' => 'Descrição',
'%d comments' => '%d comentários',
'%d comment' => '%d comentário',
@@ -298,7 +293,6 @@ return array(
'Created by %s' => 'Criado por %s',
'Tasks Export' => 'Exportar Tarefas',
'Start Date' => 'Data inicial',
- 'End Date' => 'Data final',
'Execute' => 'Executar',
'Task Id' => 'ID da Tarefa',
'Creator' => 'Criado por',
@@ -307,7 +301,7 @@ return array(
'Clone' => 'Clonar',
'Project cloned successfully.' => 'Projeto clonado com sucesso.',
'Unable to clone this project.' => 'Não foi possível clonar este projeto.',
- 'Enable email notifications' => 'Activar notificações por email',
+ 'Enable email notifications' => 'Activar notificações por e-mail',
'Task position:' => 'Posição da tarefa:',
'The task #%d have been opened.' => 'A tarefa #%d foi aberta.',
'The task #%d have been closed.' => 'A tarefa #%d foi finalizada.',
@@ -342,8 +336,8 @@ return array(
'Remote' => 'Remoto',
'Enabled' => 'Activado',
'Disabled' => 'Desactivado',
- 'Username:' => 'Utilizador:',
- 'Name:' => 'Nome:',
+ 'Login:' => 'Utilizador:',
+ 'Full Name:' => 'Nome:',
'Email:' => 'E-mail:',
'Notifications:' => 'Notificações:',
'Notifications' => 'Notificações',
@@ -516,10 +510,8 @@ return array(
'Link labels' => 'Etiquetas das associações',
'Link modification' => 'Modificação de uma associação',
'Links' => 'Associações',
- 'Link settings' => 'Configuração das associações',
'Opposite label' => 'Nome da etiqueta oposta',
'Remove a link' => 'Remover uma associação',
- 'Task\'s links' => 'Associações das tarefas',
'The labels must be different' => 'As etiquetas devem ser diferentes',
'There is no link.' => 'Não há nenhuma associação.',
'This label must be unique' => 'Esta etiqueta deve ser unica',
@@ -552,7 +544,6 @@ return array(
'Compact view' => 'Vista reduzida',
'Horizontal scrolling' => 'Deslocamento horizontal',
'Compact/wide view' => 'Alternar entre a vista compacta e ampliada',
- 'No results match:' => 'Nenhum resultado:',
'Currency' => 'Moeda',
'Private project' => 'Projeto privado',
'AUD - Australian Dollar' => 'AUD - Dólar australiano',
@@ -566,6 +557,7 @@ return array(
'JPY - Japanese Yen' => 'JPY - Iene japonês',
'NZD - New Zealand Dollar' => 'NZD - Dólar Neozelandês',
'RSD - Serbian dinar' => 'RSD - Dinar sérvio',
+ // 'CNY - Chinese Yuan' => '',
'USD - US Dollar' => 'USD - Dólar norte-americano',
'Destination column' => 'Coluna de destino',
'Move the task to another column when assigned to a user' => 'Mover a tarefa para uma outra coluna quando esta está atribuída a um utilizador',
@@ -580,7 +572,6 @@ return array(
'Currency rates' => 'Taxas de câmbio das moedas estrangeiras',
'Rate' => 'Taxa',
'Change reference currency' => 'Mudar a moeda de referência',
- 'Add a new currency rate' => 'Adicionar uma nova taxa para uma moeda',
'Reference currency' => 'Moeda de Referência',
'The currency rate have been added successfully.' => 'A taxa de câmbio foi adicionada com sucesso.',
'Unable to add this currency rate.' => 'Impossível adicionar essa taxa de câmbio.',
@@ -702,7 +693,6 @@ return array(
'<30m' => '<30m',
'Stop timer' => 'Parar temporizador',
'Start timer' => 'Iniciar temporizador',
- 'Add project member' => 'Adicionar um membro ao projeto',
'My activity stream' => 'O meu feed de actividade',
'My calendar' => 'A minha agenda',
'Search tasks' => 'Pesquisar tarefas',
@@ -757,8 +747,6 @@ return array(
'Remote user' => 'Utilizador remoto',
'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => 'Utilizadores remotos não guardam a password na base de dados do Kanboard, por exemplo: LDAP, contas do Google e Github.',
'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => 'Se activar a opção "Desactivar login", as credenciais digitadas no login serão ignoradas.',
- 'New remote user' => 'Novo utilizador remoto',
- 'New local user' => 'Novo utilizador local',
'Default task color' => 'Cor de tarefa por defeito',
'This feature does not work with all browsers.' => 'Esta funcionalidade não funciona em todos os browsers',
'There is no destination project available.' => 'Não há projeto de destino disponivel',
@@ -852,7 +840,6 @@ return array(
'Owner' => 'Dono',
'Unread notifications' => 'Notificações por ler',
'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',
'%d task(s) have been imported successfully.' => '%d tarefa(s) importada(s) com successo.',
'Nothing have been imported!' => 'Nada foi importado',
@@ -980,7 +967,6 @@ return array(
'Project owner: ' => 'Dono do projeto: ',
'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => 'O identificador do projeto é opcional e tem de ser alfa-numerico, exemplo: MEUPROJETO.',
'Project owner' => 'Dono do projeto',
- 'Those dates are useful for the project Gantt chart.' => 'Estas datas são uteis para o gráfico de Grantt do projeto.',
'Private projects do not have users and groups management.' => 'Projetos privados não têm gestão de utilizadores nem de grupos.',
'There is no project member.' => 'Não existe membro do projeto.',
'Priority' => 'Prioridade',
@@ -993,7 +979,7 @@ return array(
'If you put zero to the low and high priority, this feature will be disabled.' => 'Se colocar zero na prioridade baixa ou alta, essa funcionalidade será desactivada.',
'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',
+ 'Send email when there is no activity on a task' => 'Enviar e-mail quando não há actividade numa tarefa',
'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',
@@ -1037,7 +1023,6 @@ return array(
'Started:' => 'Iniciado:',
'Moved:' => 'Movido:',
'Task #%d' => 'Tarefa #%d',
- 'Date and time format' => 'Formato tempo e data',
'Time format' => 'Formato tempo',
'Start date: ' => 'Data inicio: ',
'End date: ' => 'Data final: ',
@@ -1051,9 +1036,7 @@ return array(
'User disabled successfully.' => 'Utilizador desactivado com sucesso.',
'Unable to disable this user.' => 'Não foi possivel desactivar este utilizador.',
'All files have been uploaded successfully.' => 'Todos os ficheiros foram enviados com sucesso.',
- 'View uploaded files' => 'Ver ficheiros enviados',
'The maximum allowed file size is %sB.' => 'O tamanho máximo permitido é %sB.',
- 'Choose files again' => 'Escolher ficheiros novamente',
'Drag and drop your files here' => 'Arraste e deixe os ficheiros para aqui',
'choose files' => 'escolher ficheiros',
'View profile' => 'Ver perfil',
@@ -1159,11 +1142,10 @@ return array(
'Enter one task by line.' => 'Escreva uma tarefa por linha.',
'Number of failed login:' => 'Número de logins falhados:',
'Account locked until:' => 'Conta bloqueada até:',
- 'Email settings' => 'Definições de Email',
- 'Email sender address' => 'Endereço de envido de Email',
- 'Email transport' => 'Transportador de Email',
+ 'Email settings' => 'Definições de E-mail',
+ 'Email sender address' => 'Endereço de envido de E-mail',
+ 'Email transport' => 'Transportador de E-mail',
'Webhook token' => 'Token do Webhook',
- 'Imports' => 'Importados',
'Project tags management' => 'Gestão de etiquetas do Projeto',
'Tag created successfully.' => 'Etiqueta criada com sucesso.',
'Unable to create this tag.' => 'Não foi possivel criar esta etiqueta.',
@@ -1210,8 +1192,6 @@ return array(
'Activity stream for %s' => 'Fluxo de actividade de %s',
'Calendar for %s' => 'Calendário de %s',
'Notifications for %s' => 'Notificações de %s',
- 'Subtasks export' => 'Exportar sub-tarefas',
- 'Tasks exportation' => 'Exportação de tarefas',
'Assign a color when the task is moved to a specific swimlane' => 'Atribuir uma cor quando a tarefa é movida para uma swimlane especifica',
'Assign a priority when the task is moved to a specific swimlane' => 'Atribuir uma prioridade quando a tarefa é movida para uma swimlane especifica',
'User unlocked successfully.' => 'Utilizador desbloqueado com sucesso.',
@@ -1275,6 +1255,63 @@ return array(
'Do you really want to remove this project restriction: "%s"?' => 'Tem a certeza que quer remover a restrição de projeto: "%s"?',
'Duplicate to multiple projects' => 'Duplicar para vários projetos',
'This field is required' => 'Este campo é obrigatório',
- // 'Moving a task is not permitted' => '',
- // 'This value must be in the range %d to %d' => '',
+ 'Moving a task is not permitted' => 'Não é permitido mover uma tarefa',
+ 'This value must be in the range %d to %d' => 'Este valor deve estar entre %d e %d',
+ 'You are not allowed to move this task.' => 'Não lhe é permitido mover esta tarefa.',
+ 'API User Access' => 'Acesso de Utilizador ao API',
+ 'Preview' => 'Pré-Visualizar',
+ 'Write' => 'Escrever',
+ 'Write your text in Markdown' => 'Escreva o seu texto em Markdown',
+ 'New External Task: %s' => 'Nova Tarefa Externa: %s',
+ 'No personal API access token registered.' => 'Nenhum token pessoal de acesso ao API ',
+ 'Your personal API access token is "%s"' => 'O seu token de acesso pessoal ao API é "%s"',
+ 'Remove your token' => 'Remover o seu token',
+ 'Generate a new token' => 'Gerar um novo token',
+ 'Showing %d-%d of %d' => 'A mostrar %d-%d de %d',
+ 'Outgoing Emails' => 'E-mails de saída',
+ 'Add or change currency rate' => 'Adicionar ou alterar taxa da moeda',
+ 'Reference currency: %s' => 'Moeda de referência: %s',
+ 'Add custom filters' => 'Adicionar filtros personalizados',
+ 'Export' => 'Exportar',
+ 'Add link label' => 'Adicionar etiqueta de associação',
+ 'Incompatible Plugins' => 'Plugins incompatíveis',
+ 'Compatibility' => 'Compatibilidade',
+ 'Permissions and ownership' => 'Permissões e propriedade',
+ 'Priorities' => 'Prioridades',
+ 'Close this window' => 'Feche esta janela',
+ 'Unable to upload this file.' => 'Não foi possível enviar este ficheiro.',
+ 'Import tasks' => 'Importar tarefas',
+ 'Choose a project' => 'Escolha um projeto',
+ 'Profile' => 'Perfil',
+ 'Application role' => 'Função na Aplicação',
+ '%d invitations were sent.' => '%d convites foram enviados.',
+ '%d invitation was sent.' => '%d convite foi enviado.',
+ 'Unable to create this user.' => 'Não foi possível criar este utilizador.',
+ 'Kanboard Invitation' => 'Convite de Kanboard',
+ 'Visible on dashboard' => 'Visível no painel',
+ 'Created at:' => 'Criado a:',
+ 'Updated at:' => 'Atualizado a:',
+ 'There is no custom filter.' => 'Não existe nenhum filtro personalizado.',
+ 'New User' => 'Novo Utilizador',
+ 'Authentication' => 'Autenticação',
+ 'If checked, this user will use a third-party system for authentication.' => 'Se selecionado, este utilizador irá utilizar um serviços de terceiros para autenticação.',
+ 'The password is necessary only for local users.' => 'A password só é necessária para utilizadores locais.',
+ 'You have been invited to register on Kanboard.' => 'Foi convidado para se registrar no Kanboard.',
+ 'Click here to join your team' => 'Clique aqui para se juntar à sua equipa',
+ 'Invite people' => 'Convidar pessoas',
+ 'Emails' => 'E-mails',
+ 'Enter one email address by line.' => 'Insira um endereço de e-mail por linha.',
+ 'Add these people to this project' => 'Adicione estas pessoas a este projeto',
+ 'Add this person to this project' => 'Adicione esta pessoa a este projeto',
+ 'Sign-up' => 'Registe-se',
+ 'Credentials' => 'Credenciais',
+ 'New user' => 'Novo utilizador',
+ 'This username is already taken' => 'Este nome de utilizador já está a ser utilizado',
+ 'A link to reset your password has been sent by email.' => 'Um link para redefinir a sua password foi enviado por email.',
+ 'Your profile must have a valid email address.' => 'O seu perfil deve ter um endereço de email válido.',
+ 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => 'Infelizmente, não conseguimos redefinir a sua password. Colocou um utilizador válido? Tem um endereço de email definido no seu perfil?',
+ 'TRL - Turkish Lira' => 'TRL - Lira Turca',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
+ // 'The email configuration has been disabled by the administrator.' => '',
);
diff --git a/app/Locale/ru_RU/translations.php b/app/Locale/ru_RU/translations.php
index 2e486e40..9cd16716 100644
--- a/app/Locale/ru_RU/translations.php
+++ b/app/Locale/ru_RU/translations.php
@@ -36,7 +36,7 @@ return array(
'Remove user' => 'Удалить пользователя',
'Do you really want to remove this user: "%s"?' => 'Вы точно хотите удалить пользователя: « %s » ?',
'All users' => 'Все пользователи',
- 'Username' => 'Имя пользователя',
+ 'Username' => 'Логин',
'Password' => 'Пароль',
'Administrator' => 'Администратор',
'Sign in' => 'Войти',
@@ -61,7 +61,6 @@ return array(
'%d tasks on the board' => '%d задач на доске',
'%d tasks in total' => 'всего %d задач',
'Unable to update this board.' => 'Не удалось обновить эту доску.',
- 'Edit board' => 'Изменить доску',
'Disable' => 'Выключить проект',
'Enable' => 'Включить проект',
'New project' => 'Новый проект',
@@ -72,7 +71,6 @@ return array(
'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"?' => 'Вы точно хотите удалить эту колонку: "%s" ?',
'This action will REMOVE ALL TASKS associated to this column!' => 'Вы УДАЛИТЕ ВСЕ ЗАДАЧИ находящиеся в этой колонке!',
@@ -160,9 +158,7 @@ return array(
'Task count' => 'Количество задач',
'User' => 'Пользователь',
'Comments' => 'Комментарии',
- 'Leave a comment' => 'Оставить комментарий',
'Comment is required' => 'Нужен комментарий',
- 'Leave a description' => 'Напишите описание',
'Comment added successfully.' => 'Комментарий успешно добавлен.',
'Unable to create your comment.' => 'Невозможно создать комментарий.',
'Due Date' => 'Сделать до',
@@ -224,7 +220,6 @@ return array(
'Search' => 'Поиск',
'Nothing found.' => 'Ничего не найдено.',
'Due date' => 'Срок',
- 'Others formats accepted: %s and %s' => 'Другой формат приемлем: %s и %s',
'Description' => 'Описание',
'%d comments' => '%d комментариев',
'%d comment' => '%d комментарий',
@@ -298,7 +293,6 @@ return array(
'Created by %s' => 'Создано %s',
'Tasks Export' => 'Экспорт задач',
'Start Date' => 'Дата начала',
- 'End Date' => 'Дата завершения',
'Execute' => 'Выполнить',
'Task Id' => 'ID задачи',
'Creator' => 'Автор',
@@ -342,8 +336,8 @@ return array(
'Remote' => 'Удалённый',
'Enabled' => 'Включён',
'Disabled' => 'Выключены',
- 'Username:' => 'Имя пользователя:',
- 'Name:' => 'Имя:',
+ 'Login:' => 'Логин:',
+ 'Full Name:' => 'Имя:',
'Email:' => 'E-mail:',
'Notifications:' => 'Уведомления:',
'Notifications' => 'Уведомления',
@@ -491,7 +485,7 @@ return array(
'All swimlanes' => 'Все дорожки',
'All colors' => 'Все цвета',
'Moved to column %s' => 'Перемещена в колонку %s',
- 'User dashboard' => 'Пользователь панели мониторинга',
+ 'User dashboard' => 'Панель управления',
'Allow only one subtask in progress at the same time for a user' => 'Разрешена только одна подзадача в разработке одновременно для одного пользователя',
'Edit column "%s"' => 'Редактировать колонку "%s"',
'Select the new status of the subtask: "%s"' => 'Выбрать новый статус для подзадачи: "%s"',
@@ -516,10 +510,8 @@ return array(
'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' => 'Этот ярлык должен быть уникальным ',
@@ -552,7 +544,6 @@ return array(
'Compact view' => 'Компактный вид',
'Horizontal scrolling' => 'Широкий вид',
'Compact/wide view' => 'Компактный/широкий вид',
- 'No results match:' => 'Отсутствуют результаты:',
'Currency' => 'Валюта',
'Private project' => 'Приватный проект',
'AUD - Australian Dollar' => 'AUD - Австралийский доллар',
@@ -563,9 +554,10 @@ return array(
'EUR - Euro' => 'EUR - Евро',
'GBP - British Pound' => 'GBP - Британский фунт',
'INR - Indian Rupee' => 'INR - Индийский рупий',
- 'JPY - Japanese Yen' => 'JPY - Японскай йена',
+ 'JPY - Japanese Yen' => 'JPY - Японская йена',
'NZD - New Zealand Dollar' => 'NZD - Новозеландский доллар',
'RSD - Serbian dinar' => 'RSD - Сербский динар',
+ 'CNY - Chinese Yuan' => 'CNY - Китайский юань',
'USD - US Dollar' => 'USD - доллар США',
'Destination column' => 'Колонка назначения',
'Move the task to another column when assigned to a user' => 'Переместить задачу в другую колонку, когда она назначена пользователю',
@@ -580,7 +572,6 @@ return array(
'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.' => 'Невозможно добавить этот курс валюты.',
@@ -600,7 +591,7 @@ return array(
'Assign a color when the task is moved to a specific column' => 'Назначить цвет, когда задача перемещается в определенную колонку',
'%s via Kanboard' => '%s через Канборд',
'Burndown chart' => 'Диаграмма сгорания',
- 'This chart show the task complexity over the time (Work Remaining).' => 'Эта диаграмма показывают сложность задачи по времени (оставшейся работы).',
+ '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 для вложения',
@@ -702,7 +693,6 @@ return array(
'<30m' => '<30м',
'Stop timer' => 'Остановить таймер',
'Start timer' => 'Запустить таймер',
- 'Add project member' => 'Добавить номер проекта',
'My activity stream' => 'Лента моей активности',
'My calendar' => 'Мой календарь',
'Search tasks' => 'Поиск задачи',
@@ -757,8 +747,6 @@ return array(
'Remote user' => 'Удаленный пользователь',
'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => 'Учётные данные для входа через LDAP, Google и Github не будут сохранены в Kanboard.',
'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => 'Если вы установите флажок "Запретить форму входа", учётные данные, введенные в форму входа будет игнорироваться.',
- 'New remote user' => 'Новый удалённый пользователь',
- 'New local user' => 'Новый локальный пользователь',
'Default task color' => 'Стандартные цвета задач',
'This feature does not work with all browsers.' => 'Эта функция доступна не во всех браузерах.',
'There is no destination project available.' => 'Нет доступного для назначения проекта.',
@@ -852,7 +840,6 @@ return array(
'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!' => 'Ничего не было импортировано!',
@@ -931,7 +918,7 @@ return array(
'Allowed Users' => 'Разрешенные пользователи',
'No user have been allowed specifically.' => 'Нет заданных разрешений для пользователей.',
'Role' => 'Роль',
- 'Enter user name...' => 'Введите имя пользователя...',
+ 'Enter user name...' => 'Введите логин пользователя...',
'Allowed Groups' => 'Разрешенные группы',
'No group have been allowed specifically.' => 'Нет заданных разрешений для групп.',
'Group' => 'Группа',
@@ -950,13 +937,13 @@ return array(
'Estimated Time' => 'Запланировано времени',
'Actual Time' => 'Затрачено времени',
'Estimated vs actual time' => 'Запланировано и реально затрачено времени',
- 'RUB - Russian Ruble' => 'Руб - Российский рубль',
+ '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' => 'Включить двух-факторную авторизацию',
+ 'Two-Factor Provider: ' => 'Провайдер двухфакторной авторизации: ',
+ 'Disable two-factor authentication' => 'Отключить двухфакторную авторизацию',
+ 'Enable two-factor authentication' => 'Включить двухфакторную авторизацию',
'There is no integration registered at the moment.' => 'Интеграции в данный момент не зарегистрированы.',
'Password Reset for Kanboard' => 'Сброс пароля для Kanboard',
'Forgot password?' => 'Забыли пароль?',
@@ -980,7 +967,6 @@ return array(
'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' => 'Приоритет',
@@ -1037,7 +1023,6 @@ return array(
'Started:' => 'Начата:',
'Moved:' => 'Перемещена:',
'Task #%d' => 'Задача #%d',
- 'Date and time format' => 'Формат даты и времени',
'Time format' => 'Формат времени',
'Start date: ' => 'Дата начала:',
'End date: ' => 'Дата окончания:',
@@ -1051,9 +1036,7 @@ return array(
'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' => 'Просмотр профиля',
@@ -1163,7 +1146,6 @@ return array(
'Email sender address' => 'Адрес отправителя',
'Email transport' => 'Почтовый транспорт',
'Webhook token' => 'Webhook токены',
- 'Imports' => 'Импорт',
'Project tags management' => 'Управление метками проекта',
'Tag created successfully.' => 'Метка успешно создана.',
'Unable to create this tag.' => 'Невозможно создать эту метку.',
@@ -1189,7 +1171,7 @@ return array(
'%s removed a comment on the task #%d' => '%s удалил комментарий к задаче #%d',
'Comment removed on task #%d' => 'Комментарий удален в задаче #%d',
'Subtask removed on task #%d' => 'Подзадача удалена в задаче #%d',
- 'Hide tasks in this column in the dashboard' => 'Не показывать задачи из этой колонки в кабинете',
+ 'Hide tasks in this column in the dashboard' => 'Не показывать задачи из этой колонки в панели управления',
'%s removed a comment on the task %s' => '%s удалил комментарии к задаче %s',
'%s removed a subtask for the task %s' => '%s удалил подзадачу для %s',
'Comment removed' => 'Комментарий удален',
@@ -1210,8 +1192,6 @@ return array(
'Activity stream for %s' => 'Лента активности для %s',
'Calendar for %s' => 'Календарь для %s',
'Notifications for %s' => 'Уведомления для %s',
- 'Subtasks export' => 'Экспорт подзадач',
- 'Tasks exportation' => 'Экспортирование задач',
'Assign a color when the task is moved to a specific swimlane' => 'Назначить цвет, когда задача будет перемещена в указанную дорожку',
'Assign a priority when the task is moved to a specific swimlane' => 'Назначить приоритет, когда задача будет перемещена в указанную дорожку',
'User unlocked successfully.' => 'Пользователь успешно разблокирован.',
@@ -1277,4 +1257,61 @@ return array(
'This field is required' => 'Заполните это поле',
'Moving a task is not permitted' => 'Перемещение задачи не разрешено',
'This value must be in the range %d to %d' => 'Значение должно находиться в диапазоне от %d до %d',
+ 'You are not allowed to move this task.' => 'Вам не разрешено перемещать эту задачу.',
+ 'API User Access' => 'Доступ к API',
+ 'Preview' => 'Предпросмотр',
+ 'Write' => 'Редактирование',
+ 'Write your text in Markdown' => 'Добавьте Ваше описание в формате Markdown',
+ 'New External Task: %s' => 'Новая внешняя задача: %s',
+ 'No personal API access token registered.' => 'Персональные токены доступа к API не созданы.',
+ 'Your personal API access token is "%s"' => 'Ваш персональный токен доступа к API: "%s"',
+ 'Remove your token' => 'Удалить токен',
+ 'Generate a new token' => 'Сгенерировать новый токен',
+ 'Showing %d-%d of %d' => 'Показывается %d-%d из %d',
+ 'Outgoing Emails' => 'Исходящие e-mail',
+ 'Add or change currency rate' => 'Добавить или изменить курс валют',
+ 'Reference currency: %s' => 'Базовая валюта: %s',
+ 'Add custom filters' => 'Добавить пользовательские фильтры',
+ 'Export' => 'Экспорт',
+ 'Add link label' => 'Добавить связь в задаче',
+ 'Incompatible Plugins' => 'Несовместимые плагины',
+ 'Compatibility' => 'Совместимость',
+ 'Permissions and ownership' => 'Разрешения и владение проектом',
+ 'Priorities' => 'Приоритеты',
+ 'Close this window' => 'Закрыть окно',
+ 'Unable to upload this file.' => 'Не удаётся загрузить файл.',
+ 'Import tasks' => 'Импорт задач',
+ 'Choose a project' => 'Выберите проект',
+ 'Profile' => 'Профиль',
+ 'Application role' => 'Роль в приложении',
+ // '%d invitations were sent.' => '',
+ // '%d invitation was sent.' => '',
+ // 'Unable to create this user.' => '',
+ // 'Kanboard Invitation' => '',
+ // 'Visible on dashboard' => '',
+ // 'Created at:' => '',
+ // 'Updated at:' => '',
+ 'There is no custom filter.' => 'Пользовательские фильтры отсутствуют.',
+ 'New User' => 'Добавление пользователя',
+ 'Authentication' => 'Данные входа',
+ 'If checked, this user will use a third-party system for authentication.' => 'Если включено, то пользователь будет использовать стороннюю систему для авторизации.',
+ 'The password is necessary only for local users.' => 'Пароль необходим только для локальных пользователей',
+ // 'You have been invited to register on Kanboard.' => '',
+ // 'Click here to join your team' => '',
+ 'Invite people' => 'Приглашение пользователей',
+ 'Emails' => 'Адреса e-mail',
+ 'Enter one email address by line.' => 'Вводите по одному e-mail на строку.',
+ 'Add these people to this project' => 'Добавить приглашенных в проект',
+ // 'Add this person to this project' => '',
+ // 'Sign-up' => '',
+ // 'Credentials' => '',
+ 'New user' => 'Добавить пользователя',
+ // 'This username is already taken' => '',
+ // 'A link to reset your password has been sent by email.' => '',
+ // 'Your profile must have a valid email address.' => '',
+ // 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
+ // 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
+ // 'The email configuration has been disabled by the administrator.' => '',
);
diff --git a/app/Locale/sr_Latn_RS/translations.php b/app/Locale/sr_Latn_RS/translations.php
index 6b5bd784..3ebd5f68 100644
--- a/app/Locale/sr_Latn_RS/translations.php
+++ b/app/Locale/sr_Latn_RS/translations.php
@@ -61,7 +61,6 @@ return array(
'%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' => 'Izmeni tablu',
'Disable' => 'Onemogući',
'Enable' => 'Omogući',
'New project' => 'Novi projekat',
@@ -72,7 +71,6 @@ return array(
'Title' => 'Naslov',
'Assigned to %s' => 'Dodeljen korisniku %s',
'Remove a column' => 'Ukloni kolonu',
- 'Remove a column from a board' => 'Ukloni kolonu sa table',
'Unable to remove this column.' => 'Nemoguće uklanjanje kolone.',
'Do you really want to remove this column: "%s"?' => 'Da li zaista želiš da ukoniš ovu kolonu: "%s"?',
'This action will REMOVE ALL TASKS associated to this column!' => 'Ova akcija BRIŠE SVE ZADATKE vezane za ovu kolonu!',
@@ -160,9 +158,7 @@ return array(
'Task count' => 'Broj zadataka',
'User' => 'Korisnik',
'Comments' => 'Komentari',
- 'Leave a comment' => 'Ostavi komentar',
'Comment is required' => 'Komentar je obavezan',
- 'Leave a description' => 'Dodaj opis',
'Comment added successfully.' => 'Komentar uspešno ostavljen',
'Unable to create your comment.' => 'Nemoguće kreiranje komentara',
'Due Date' => 'Termin',
@@ -224,7 +220,6 @@ return array(
'Search' => 'Traži',
'Nothing found.' => 'Ništa nije pronađeno',
'Due date' => 'Termin',
- 'Others formats accepted: %s and %s' => 'Ostali formati: %s i %s',
'Description' => 'Opis',
'%d comments' => '%d Komentara',
'%d comment' => '%d Komentar',
@@ -298,7 +293,6 @@ return array(
'Created by %s' => 'Kreirao %s',
'Tasks Export' => 'Izvoz zadataka',
'Start Date' => 'Početni datum',
- 'End Date' => 'Krajni datum',
'Execute' => 'Izvrši',
'Task Id' => 'Identifikator Zadatka',
'Creator' => 'Autor',
@@ -342,8 +336,8 @@ return array(
'Remote' => 'Udaljno',
'Enabled' => 'Omogući',
'Disabled' => 'Onemogući',
- 'Username:' => 'Korisničko ime:',
- 'Name:' => 'Ime i Prezime',
+ 'Login:' => 'Korisničko ime:',
+ 'Full Name:' => 'Ime i Prezime',
'Email:' => 'Email: ',
'Notifications:' => 'Obaveštenja: ',
'Notifications' => 'Obaveštenja',
@@ -516,10 +510,8 @@ return array(
// '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' => '',
@@ -552,7 +544,6 @@ return array(
// 'Compact view' => '',
// 'Horizontal scrolling' => '',
// 'Compact/wide view' => '',
- // 'No results match:' => '',
// 'Currency' => '',
// 'Private project' => '',
// 'AUD - Australian Dollar' => '',
@@ -566,6 +557,7 @@ return array(
// 'JPY - Japanese Yen' => '',
// 'NZD - New Zealand Dollar' => '',
// 'RSD - Serbian dinar' => '',
+ // 'CNY - Chinese Yuan' => '',
// 'USD - US Dollar' => '',
// 'Destination column' => '',
// 'Move the task to another column when assigned to a user' => '',
@@ -580,7 +572,6 @@ return array(
// '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.' => '',
@@ -702,7 +693,6 @@ return array(
// '<30m' => '',
// 'Stop timer' => '',
// 'Start timer' => '',
- // 'Add project member' => '',
// 'My activity stream' => '',
// 'My calendar' => '',
// 'Search tasks' => '',
@@ -757,8 +747,6 @@ return array(
// '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.' => '',
@@ -852,7 +840,6 @@ return array(
// '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!' => '',
@@ -980,7 +967,6 @@ return array(
// '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' => '',
@@ -1037,7 +1023,6 @@ return array(
// 'Started:' => '',
// 'Moved:' => '',
// 'Task #%d' => '',
- // 'Date and time format' => '',
// 'Time format' => '',
// 'Start date: ' => '',
// 'End date: ' => '',
@@ -1051,9 +1036,7 @@ return array(
// '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' => '',
@@ -1163,7 +1146,6 @@ return array(
// 'Email sender address' => '',
// 'Email transport' => '',
// 'Webhook token' => '',
- // 'Imports' => '',
// 'Project tags management' => '',
// 'Tag created successfully.' => '',
// 'Unable to create this tag.' => '',
@@ -1210,8 +1192,6 @@ return array(
// 'Activity stream for %s' => '',
// 'Calendar for %s' => '',
// 'Notifications for %s' => '',
- // 'Subtasks export' => '',
- // 'Tasks exportation' => '',
// 'Assign a color when the task is moved to a specific swimlane' => '',
// 'Assign a priority when the task is moved to a specific swimlane' => '',
// 'User unlocked successfully.' => '',
@@ -1277,4 +1257,61 @@ return array(
// 'This field is required' => '',
// 'Moving a task is not permitted' => '',
// 'This value must be in the range %d to %d' => '',
+ // 'You are not allowed to move this task.' => '',
+ // 'API User Access' => '',
+ // 'Preview' => '',
+ // 'Write' => '',
+ // 'Write your text in Markdown' => '',
+ // 'New External Task: %s' => '',
+ // 'No personal API access token registered.' => '',
+ // 'Your personal API access token is "%s"' => '',
+ // 'Remove your token' => '',
+ // 'Generate a new token' => '',
+ // 'Showing %d-%d of %d' => '',
+ // 'Outgoing Emails' => '',
+ // 'Add or change currency rate' => '',
+ // 'Reference currency: %s' => '',
+ // 'Add custom filters' => '',
+ // 'Export' => '',
+ // 'Add link label' => '',
+ // 'Incompatible Plugins' => '',
+ // 'Compatibility' => '',
+ // 'Permissions and ownership' => '',
+ // 'Priorities' => '',
+ // 'Close this window' => '',
+ // 'Unable to upload this file.' => '',
+ // 'Import tasks' => '',
+ // 'Choose a project' => '',
+ // 'Profile' => '',
+ // 'Application role' => '',
+ // '%d invitations were sent.' => '',
+ // '%d invitation was sent.' => '',
+ // 'Unable to create this user.' => '',
+ // 'Kanboard Invitation' => '',
+ // 'Visible on dashboard' => '',
+ // 'Created at:' => '',
+ // 'Updated at:' => '',
+ // 'There is no custom filter.' => '',
+ // 'New User' => '',
+ // 'Authentication' => '',
+ // 'If checked, this user will use a third-party system for authentication.' => '',
+ // 'The password is necessary only for local users.' => '',
+ // 'You have been invited to register on Kanboard.' => '',
+ // 'Click here to join your team' => '',
+ // 'Invite people' => '',
+ // 'Emails' => '',
+ // 'Enter one email address by line.' => '',
+ // 'Add these people to this project' => '',
+ // 'Add this person to this project' => '',
+ // 'Sign-up' => '',
+ // 'Credentials' => '',
+ // 'New user' => '',
+ // 'This username is already taken' => '',
+ // 'A link to reset your password has been sent by email.' => '',
+ // 'Your profile must have a valid email address.' => '',
+ // 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
+ // 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
+ // 'The email configuration has been disabled by the administrator.' => '',
);
diff --git a/app/Locale/sv_SE/translations.php b/app/Locale/sv_SE/translations.php
index d8275616..278c0f3c 100644
--- a/app/Locale/sv_SE/translations.php
+++ b/app/Locale/sv_SE/translations.php
@@ -61,7 +61,6 @@ return array(
'%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',
- 'Edit board' => 'Ändra tavlan',
'Disable' => 'Inaktivera',
'Enable' => 'Aktivera',
'New project' => 'Nytt projekt',
@@ -72,7 +71,6 @@ return array(
'Title' => 'Titel',
'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',
'Unable to remove this column.' => 'Kunde inte ta bort kolumnen.',
'Do you really want to remove this column: "%s"?' => 'Vill du verkligen ta bort kolumnen: "%s"?',
'This action will REMOVE ALL TASKS associated to this column!' => 'Denna åtgärd kommer att TA BORT ALLA uppgifter kopplade till kolumnen!',
@@ -160,9 +158,7 @@ return array(
'Task count' => 'Antal uppgifter',
'User' => 'Användare',
'Comments' => 'Kommentarer',
- 'Leave a comment' => 'Lämna en kommentar',
'Comment is required' => 'En kommentar måste lämnas',
- 'Leave a description' => 'Lämna en beskrivning',
'Comment added successfully.' => 'Kommentaren har lagts till.',
'Unable to create your comment.' => 'Kommentaren kunde inte laddas upp.',
'Due Date' => 'Måldatum',
@@ -224,7 +220,6 @@ return array(
'Search' => 'Sök',
'Nothing found.' => 'Inget kunde hittas.',
'Due date' => 'Måldatum',
- 'Others formats accepted: %s and %s' => 'Andra format som accepteras: %s and %s',
'Description' => 'Beskrivning',
'%d comments' => '%d kommentarer',
'%d comment' => '%d kommentar',
@@ -298,7 +293,6 @@ return array(
'Created by %s' => 'Skapad av %s',
'Tasks Export' => 'Exportera uppgifter',
'Start Date' => 'Startdatum',
- 'End Date' => 'Slutdatum',
'Execute' => 'Utför',
'Task Id' => 'Uppgift ID',
'Creator' => 'Skapare',
@@ -342,8 +336,8 @@ return array(
'Remote' => 'Fjärr',
'Enabled' => 'Aktiverad',
'Disabled' => 'Inaktiverad',
- 'Username:' => 'Användarnam:',
- 'Name:' => 'Namn:',
+ 'Login:' => 'Användarnam:',
+ 'Full Name:' => 'Namn:',
'Email:' => 'E-post:',
'Notifications:' => 'Notiser:',
'Notifications' => 'Notiser',
@@ -516,10 +510,8 @@ return array(
'Link labels' => 'Länketiketter',
'Link modification' => 'Länkändring',
'Links' => 'Länkar',
- 'Link settings' => 'Länkinställningar',
'Opposite label' => 'Motpartslänk',
'Remove a link' => 'Ta bort en länk',
- 'Task\'s links' => 'Uppgiftslänkar',
'The labels must be different' => 'Etiketterna måste vara olika',
'There is no link.' => 'Det finns ingen länk',
'This label must be unique' => 'Länken måste vara unik',
@@ -552,7 +544,6 @@ return array(
'Compact view' => 'Kompakt vy',
'Horizontal scrolling' => 'Horisontell scroll',
'Compact/wide view' => 'Kompakt/bred vy',
- 'No results match:' => 'Inga matchande resultat',
'Currency' => 'Valuta',
'Private project' => 'Privat projekt',
'AUD - Australian Dollar' => 'AUD - Australiska dollar',
@@ -566,6 +557,7 @@ return array(
'JPY - Japanese Yen' => 'JPY - Japanska Yen',
'NZD - New Zealand Dollar' => 'NZD - Nya Zeeländska Dollar',
'RSD - Serbian dinar' => 'RSD - Serbiska Dinarer',
+ // 'CNY - Chinese Yuan' => '',
'USD - US Dollar' => 'USD - Amerikanska Dollar',
'Destination column' => 'Målkolumn',
'Move the task to another column when assigned to a user' => 'Flytta uppgiften till en annan kolumn när den tilldelats en användare',
@@ -580,7 +572,6 @@ return array(
'Currency rates' => 'Valutakurser',
'Rate' => 'Kurs',
'Change reference currency' => 'Ändra referenskurs',
- 'Add a new currency rate' => 'Lägg till ny valutakurs',
'Reference currency' => 'Referensvaluta',
'The currency rate have been added successfully.' => 'Valutakursen har lagts till.',
'Unable to add this currency rate.' => 'Kunde inte lägga till valutakursen.',
@@ -702,7 +693,6 @@ return array(
'<30m' => '<30m',
'Stop timer' => 'Stoppa timer',
'Start timer' => 'Starta timer',
- 'Add project member' => 'Lägg till projektmedlem',
'My activity stream' => 'Min aktivitetsström',
'My calendar' => 'Min kalender',
'Search tasks' => 'Sök uppgifter',
@@ -757,8 +747,6 @@ return array(
'Remote user' => 'Extern användare',
'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => 'Externa användares lösenord lagras inte i Kanboard-databasen, exempel: LDAP, Google och Github-konton.',
'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => 'Om du aktiverar boxen "Tillåt inte loginformulär" kommer inloggningsuppgifter i formuläret att ignoreras.',
- 'New remote user' => 'Ny extern användare',
- 'New local user' => 'Ny lokal användare',
'Default task color' => 'Standardfärg för uppgifter',
'This feature does not work with all browsers.' => 'Denna funktion fungerar inte i alla webbläsare.',
'There is no destination project available.' => 'Det finns inget destinationsprojekt tillgängligt.',
@@ -852,7 +840,6 @@ return array(
// '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!' => '',
@@ -980,7 +967,6 @@ return array(
// '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' => '',
@@ -1037,7 +1023,6 @@ return array(
// 'Started:' => '',
// 'Moved:' => '',
// 'Task #%d' => '',
- // 'Date and time format' => '',
// 'Time format' => '',
// 'Start date: ' => '',
// 'End date: ' => '',
@@ -1051,9 +1036,7 @@ return array(
// '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' => '',
@@ -1163,7 +1146,6 @@ return array(
// 'Email sender address' => '',
// 'Email transport' => '',
// 'Webhook token' => '',
- // 'Imports' => '',
// 'Project tags management' => '',
// 'Tag created successfully.' => '',
// 'Unable to create this tag.' => '',
@@ -1210,8 +1192,6 @@ return array(
// 'Activity stream for %s' => '',
// 'Calendar for %s' => '',
// 'Notifications for %s' => '',
- // 'Subtasks export' => '',
- // 'Tasks exportation' => '',
// 'Assign a color when the task is moved to a specific swimlane' => '',
// 'Assign a priority when the task is moved to a specific swimlane' => '',
// 'User unlocked successfully.' => '',
@@ -1277,4 +1257,61 @@ return array(
// 'This field is required' => '',
// 'Moving a task is not permitted' => '',
// 'This value must be in the range %d to %d' => '',
+ // 'You are not allowed to move this task.' => '',
+ // 'API User Access' => '',
+ // 'Preview' => '',
+ // 'Write' => '',
+ // 'Write your text in Markdown' => '',
+ // 'New External Task: %s' => '',
+ // 'No personal API access token registered.' => '',
+ // 'Your personal API access token is "%s"' => '',
+ // 'Remove your token' => '',
+ // 'Generate a new token' => '',
+ // 'Showing %d-%d of %d' => '',
+ // 'Outgoing Emails' => '',
+ // 'Add or change currency rate' => '',
+ // 'Reference currency: %s' => '',
+ // 'Add custom filters' => '',
+ // 'Export' => '',
+ // 'Add link label' => '',
+ // 'Incompatible Plugins' => '',
+ // 'Compatibility' => '',
+ // 'Permissions and ownership' => '',
+ // 'Priorities' => '',
+ // 'Close this window' => '',
+ // 'Unable to upload this file.' => '',
+ // 'Import tasks' => '',
+ // 'Choose a project' => '',
+ // 'Profile' => '',
+ // 'Application role' => '',
+ // '%d invitations were sent.' => '',
+ // '%d invitation was sent.' => '',
+ // 'Unable to create this user.' => '',
+ // 'Kanboard Invitation' => '',
+ // 'Visible on dashboard' => '',
+ // 'Created at:' => '',
+ // 'Updated at:' => '',
+ // 'There is no custom filter.' => '',
+ // 'New User' => '',
+ // 'Authentication' => '',
+ // 'If checked, this user will use a third-party system for authentication.' => '',
+ // 'The password is necessary only for local users.' => '',
+ // 'You have been invited to register on Kanboard.' => '',
+ // 'Click here to join your team' => '',
+ // 'Invite people' => '',
+ // 'Emails' => '',
+ // 'Enter one email address by line.' => '',
+ // 'Add these people to this project' => '',
+ // 'Add this person to this project' => '',
+ // 'Sign-up' => '',
+ // 'Credentials' => '',
+ // 'New user' => '',
+ // 'This username is already taken' => '',
+ // 'A link to reset your password has been sent by email.' => '',
+ // 'Your profile must have a valid email address.' => '',
+ // 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
+ // 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
+ // 'The email configuration has been disabled by the administrator.' => '',
);
diff --git a/app/Locale/th_TH/translations.php b/app/Locale/th_TH/translations.php
index 3cf7e3e5..00a290da 100644
--- a/app/Locale/th_TH/translations.php
+++ b/app/Locale/th_TH/translations.php
@@ -61,7 +61,6 @@ return array(
'%d tasks on the board' => '%d งานบนบอร์ด',
'%d tasks in total' => '%d งานทั้งหมด',
'Unable to update this board.' => 'ไม่สามารถปรับปรุงบอร์ดได้.',
- 'Edit board' => 'แก้ไขบอร์ด',
'Disable' => 'ปิดการทำงาน',
'Enable' => 'เปิดการทำงาน',
'New project' => 'โปรเจคใหม่',
@@ -72,7 +71,6 @@ return array(
'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"?' => 'คุณต้องการลบคอลัมน์ « %s » ออกใช่หรือไม่?',
'This action will REMOVE ALL TASKS associated to this column!' => 'การกระทำนี้จะลบงานที่เกี่ยวข้องกับคอลัมน์นี้',
@@ -160,9 +158,7 @@ return array(
'Task count' => 'นับงาน',
'User' => 'ผู้ใช้',
'Comments' => 'ความคิดเห็น',
- 'Leave a comment' => 'ออกความคิดเห็น',
'Comment is required' => 'ต้องการความคิดเห็น',
- 'Leave a description' => 'แสดงคำอธิบาย',
'Comment added successfully.' => 'เพิ่มความคิดเห็นเรียบร้อยแล้ว',
'Unable to create your comment.' => 'ไม่สามารถสร้างความคิดเห็น',
'Due Date' => 'วันที่ครบกำหนด',
@@ -224,7 +220,6 @@ return array(
'Search' => 'ค้นหา',
'Nothing found.' => 'ค้นหาไม่พบ.',
'Due date' => 'วันที่ครบกำหนด',
- 'Others formats accepted: %s and %s' => 'รูปแบบอื่นที่ได้รับการยอมรับ: %s และ %s',
'Description' => 'คำอธิบาย',
'%d comments' => '%d ความคิดเห็น',
'%d comment' => '%d ความคิดเห็น',
@@ -298,7 +293,6 @@ return array(
'Created by %s' => 'สร้างโดย %s',
'Tasks Export' => 'ส่งออกงาน',
'Start Date' => 'เริ่มวันที่',
- 'End Date' => 'สิ้นสุดวันที่',
'Execute' => 'ประมวลผล',
'Task Id' => 'งาน ไอดี',
'Creator' => 'ผู้สร้าง',
@@ -342,8 +336,8 @@ return array(
'Remote' => 'รีโมท',
'Enabled' => 'เปิดการใช้',
'Disabled' => 'ปิดการใช้',
- 'Username:' => 'ชื่อผู้ใช้:',
- 'Name:' => 'ชื่อ:',
+ 'Login:' => 'ชื่อผู้ใช้:',
+ 'Full Name:' => 'ชื่อ:',
'Email:' => 'อีเมล:',
'Notifications:' => 'แจ้งเตือน:',
'Notifications' => 'การแจ้งเตือน',
@@ -516,10 +510,8 @@ return array(
'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' => 'ป้ายชื่อต้องไม่ซ้ำกัน',
@@ -552,7 +544,6 @@ return array(
'Compact view' => 'มุมมองพอดี',
'Horizontal scrolling' => 'เลื่อนตามแนวนอน',
'Compact/wide view' => 'พอดี/กว้าง มุมมอง',
- 'No results match:' => 'ไม่มีผลลัพท์ที่ตรง',
'Currency' => 'สกุลเงิน',
'Private project' => 'โปรเจคส่วนตัว',
'AUD - Australian Dollar' => 'AUD - ดอลลาร์ออสเตรเลีย',
@@ -566,6 +557,7 @@ return array(
'JPY - Japanese Yen' => 'JPY - เยน',
'NZD - New Zealand Dollar' => 'NZD - ดอลลาร์นิวซีแลนด์',
'RSD - Serbian dinar' => 'RSD - ดีนาร์เซอร์เบีย',
+ // 'CNY - Chinese Yuan' => '',
'USD - US Dollar' => 'USD - ดอลลาร์สหรัฐ',
'Destination column' => 'คอลัมน์เป้าหมาย',
'Move the task to another column when assigned to a user' => 'ย้ายงานไปคอลัมน์อื่นเมื่อกำหนดบุคคลรับผิดชอบ',
@@ -580,7 +572,6 @@ return array(
'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.' => 'ไม่สามารถเพิ่มค่าเงินนี้',
@@ -702,7 +693,6 @@ return array(
'<30m' => '<30นาที',
'Stop timer' => 'หยุดจับเวลา',
'Start timer' => 'เริ่มจับเวลา',
- 'Add project member' => 'เพิ่มสมาชิกโปรเจค',
'My activity stream' => 'กิจกรรมที่เกิดขึ้นของฉัน',
'My calendar' => 'ปฎิทินของฉัน',
'Search tasks' => 'ค้นหางาน',
@@ -757,8 +747,6 @@ return array(
'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.' => '',
@@ -852,7 +840,6 @@ return array(
'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!' => 'ไม่มีอะไรถูกนำเข้า',
@@ -980,7 +967,6 @@ return array(
'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' => 'ความสำคัญ',
@@ -1037,7 +1023,6 @@ return array(
'Started:' => 'เริ่ม:',
'Moved:' => 'ย้าย:',
'Task #%d' => 'งานที่ #%d',
- 'Date and time format' => 'รูปแบบของวันเวลา',
'Time format' => 'รูปแบบของเวลา',
'Start date: ' => 'เริ่มวันที่:',
'End date: ' => 'จบวันที่:',
@@ -1051,9 +1036,7 @@ return array(
// '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' => '',
@@ -1163,7 +1146,6 @@ return array(
// 'Email sender address' => '',
// 'Email transport' => '',
// 'Webhook token' => '',
- // 'Imports' => '',
// 'Project tags management' => '',
// 'Tag created successfully.' => '',
// 'Unable to create this tag.' => '',
@@ -1210,8 +1192,6 @@ return array(
// 'Activity stream for %s' => '',
// 'Calendar for %s' => '',
// 'Notifications for %s' => '',
- // 'Subtasks export' => '',
- // 'Tasks exportation' => '',
// 'Assign a color when the task is moved to a specific swimlane' => '',
// 'Assign a priority when the task is moved to a specific swimlane' => '',
// 'User unlocked successfully.' => '',
@@ -1277,4 +1257,61 @@ return array(
// 'This field is required' => '',
// 'Moving a task is not permitted' => '',
// 'This value must be in the range %d to %d' => '',
+ // 'You are not allowed to move this task.' => '',
+ // 'API User Access' => '',
+ // 'Preview' => '',
+ // 'Write' => '',
+ // 'Write your text in Markdown' => '',
+ // 'New External Task: %s' => '',
+ // 'No personal API access token registered.' => '',
+ // 'Your personal API access token is "%s"' => '',
+ // 'Remove your token' => '',
+ // 'Generate a new token' => '',
+ // 'Showing %d-%d of %d' => '',
+ // 'Outgoing Emails' => '',
+ // 'Add or change currency rate' => '',
+ // 'Reference currency: %s' => '',
+ // 'Add custom filters' => '',
+ // 'Export' => '',
+ // 'Add link label' => '',
+ // 'Incompatible Plugins' => '',
+ // 'Compatibility' => '',
+ // 'Permissions and ownership' => '',
+ // 'Priorities' => '',
+ // 'Close this window' => '',
+ // 'Unable to upload this file.' => '',
+ // 'Import tasks' => '',
+ // 'Choose a project' => '',
+ // 'Profile' => '',
+ // 'Application role' => '',
+ // '%d invitations were sent.' => '',
+ // '%d invitation was sent.' => '',
+ // 'Unable to create this user.' => '',
+ // 'Kanboard Invitation' => '',
+ // 'Visible on dashboard' => '',
+ // 'Created at:' => '',
+ // 'Updated at:' => '',
+ // 'There is no custom filter.' => '',
+ // 'New User' => '',
+ // 'Authentication' => '',
+ // 'If checked, this user will use a third-party system for authentication.' => '',
+ // 'The password is necessary only for local users.' => '',
+ // 'You have been invited to register on Kanboard.' => '',
+ // 'Click here to join your team' => '',
+ // 'Invite people' => '',
+ // 'Emails' => '',
+ // 'Enter one email address by line.' => '',
+ // 'Add these people to this project' => '',
+ // 'Add this person to this project' => '',
+ // 'Sign-up' => '',
+ // 'Credentials' => '',
+ // 'New user' => '',
+ // 'This username is already taken' => '',
+ // 'A link to reset your password has been sent by email.' => '',
+ // 'Your profile must have a valid email address.' => '',
+ // 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
+ // 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
+ // 'The email configuration has been disabled by the administrator.' => '',
);
diff --git a/app/Locale/tr_TR/translations.php b/app/Locale/tr_TR/translations.php
index de88c1d6..dc25f861 100644
--- a/app/Locale/tr_TR/translations.php
+++ b/app/Locale/tr_TR/translations.php
@@ -19,15 +19,15 @@ return array(
'Red' => 'Kırmızı',
'Orange' => 'Turuncu',
'Grey' => 'Gri',
- 'Brown' => 'Kahverengi',
- 'Deep Orange' => 'Koyu Turuncu',
+ 'Brown' => 'K.rengi',
+ 'Deep Orange' => 'Kavuniçi',
'Dark Grey' => 'Koyu Gri',
'Pink' => 'Pembe',
'Teal' => 'Turkuaz',
'Cyan' => 'Cam Göbeği',
- 'Lime' => 'Limon rengi',
+ 'Lime' => 'Limoni',
'Light Green' => 'Açık Yeşil',
- 'Amber' => 'Koyu sarı',
+ 'Amber' => 'Amber',
'Save' => 'Kaydet',
'Login' => 'Giriş',
'Official website:' => 'Resmi internet sitesi:',
@@ -54,25 +54,23 @@ return array(
'Project' => 'Proje',
'Status' => 'Durum',
'Tasks' => 'Görevler',
- 'Board' => 'Tablo',
+ 'Board' => 'Pano',
'Actions' => 'İşlemler',
'Inactive' => 'Aktif değil',
'Active' => 'Aktif',
- '%d tasks on the board' => '%d görev bu tabloda',
+ '%d tasks on the board' => '%d görev bu panoda',
'%d tasks in total' => '%d görev toplam',
- 'Unable to update this board.' => 'Bu tablo güncellenemiyor.',
- 'Edit board' => 'Tabloyu düzenle',
+ 'Unable to update this board.' => 'Bu pano güncellenemiyor.',
'Disable' => 'Devre dışı bırak',
'Enable' => 'Etkinleştir',
'New project' => 'Yeni proje',
'Do you really want to remove this project: "%s"?' => 'Bu projeyi gerçekten silmek istiyor musunuz: "%s"?',
'Remove project' => 'Projeyi sil',
- 'Edit the board for "%s"' => 'Tabloyu "%s" için güncelle',
+ 'Edit the board for "%s"' => 'Panoyu "%s" için güncelle',
'Add a new column' => 'Yeni sütun ekle',
'Title' => 'Başlık',
'Assigned to %s' => '%s kullanıcısına atanmış',
'Remove a column' => 'Bir sütunu sil',
- 'Remove a column from a board' => 'Tablodan bir sütunu sil',
'Unable to remove this column.' => 'Bu sütun silinemiyor.',
'Do you really want to remove this column: "%s"?' => 'Bu sütunu gerçekten silmek istiyor musunuz: "%s"?',
'This action will REMOVE ALL TASKS associated to this column!' => 'Bu komut sütun içindeki TÜM GÖREVLERİ silecek!',
@@ -94,9 +92,9 @@ return array(
'New task' => 'Yeni görev',
'Open a task' => 'Bir görevi aç',
'Do you really want to open this task: "%s"?' => 'Bu görevi gerçekten açmak istiyor musunuz: "%s"?',
- 'Back to the board' => 'Tabloya dön',
+ 'Back to the board' => 'Panoya dön',
'There is nobody assigned' => 'Kimse atanmamış',
- 'Column on the board:' => 'Tablodaki sütun:',
+ 'Column on the board:' => 'Panodaki sütun:',
'Close this task' => 'Görevi kapat',
'Open this task' => 'Görevi aç',
'There is no description.' => 'Açıklama yok.',
@@ -142,7 +140,7 @@ return array(
'Unable to update your user.' => 'Kullanıcı güncellenemiyor.',
'User removed successfully.' => 'Kullanıcı silindi.',
'Unable to remove this user.' => 'Bu kullanıcı silinemiyor.',
- 'Board updated successfully.' => 'Tablo başarıyla güncellendi.',
+ 'Board updated successfully.' => 'Pano başarıyla güncellendi.',
'Ready' => 'Hazır',
'Backlog' => 'Bekleme listesi',
'Work in progress' => 'İşlemde',
@@ -160,9 +158,7 @@ return array(
'Task count' => 'Görev sayısı',
'User' => 'Kullanıcı',
'Comments' => 'Yorumlar',
- 'Leave a comment' => 'Bir yorum ekle',
'Comment is required' => 'Yorum gerekli',
- 'Leave a description' => 'Açıklama ekleyin',
'Comment added successfully.' => 'Yorum eklendi',
'Unable to create your comment.' => 'Yorumunuz oluşturulamadı',
'Due Date' => 'Bitiş Tarihi',
@@ -212,7 +208,7 @@ return array(
'Login date' => 'Giriş tarihi',
'Authentication method' => 'Doğrulama yöntemi',
'IP address' => 'IP adresi',
- 'User agent' => 'Kullanıcı sistemi',
+ 'User agent' => 'Kullanıcı Arayüzü',
'Persistent connections' => 'Kalıcı bağlantılar',
'No session.' => 'Oturum yok.',
'Expiration date' => 'Geçerlilik sonu',
@@ -224,7 +220,6 @@ return array(
'Search' => 'Ara',
'Nothing found.' => 'Hiçbir şey bulunamadı.',
'Due date' => 'Bitiş tarihi',
- 'Others formats accepted: %s and %s' => 'Diğer kabul edilen formatlar: %s ve %s',
'Description' => 'Açıklama',
'%d comments' => '%d yorum',
'%d comment' => '%d yorum',
@@ -268,7 +263,7 @@ return array(
'Add a comment' => 'Yorum ekle',
'Edit a comment' => 'Yorum değiştir',
'Summary' => 'Özet',
- 'Time tracking' => 'Zaman takibi',
+ 'Time tracking' => 'Süre Çizelgesi',
'Estimate:' => 'Tahmini:',
'Spent:' => 'Harcanan:',
'Do you really want to remove this sub-task?' => 'Bu alt görevi silmek istediğinize emin misiniz',
@@ -280,7 +275,7 @@ return array(
'Add a sub-task' => 'Alt görev ekle',
'Original estimate' => 'Orjinal tahmin',
'Create another sub-task' => 'Başka bir alt görev daha oluştur',
- 'Time spent' => 'Harcanan zaman',
+ 'Time spent' => 'Geçen süre',
'Edit a sub-task' => 'Alt görev düzenle',
'Remove a sub-task' => 'Alt görev sil',
'The time must be a numeric value' => 'Zaman alfanümerik bir değer olmalı',
@@ -298,7 +293,6 @@ return array(
'Created by %s' => '%s tarafından oluşturuldu',
'Tasks Export' => 'Görevleri dışa aktar',
'Start Date' => 'Başlangıç tarihi',
- 'End Date' => 'Bitiş tarihi',
'Execute' => 'Gerçekleştir',
'Task Id' => 'Görev Kimliği',
'Creator' => 'Oluşturan',
@@ -342,8 +336,8 @@ return array(
'Remote' => 'Uzak',
'Enabled' => 'Etkinleştirildi',
'Disabled' => 'Devre dışı bırakıldı',
- 'Username:' => 'Kullanıcı adı',
- 'Name:' => 'Ad',
+ 'Login:' => 'Kullanıcı adı',
+ 'Full Name:' => 'Ad',
'Email:' => 'E-posta',
'Notifications:' => 'Bildirimler:',
'Notifications' => 'Bildirimler',
@@ -395,12 +389,12 @@ return array(
'Database' => 'Veritabanı',
'About' => 'Hakkında',
'Database driver:' => 'Veritabanı sürücüsü:',
- 'Board settings' => 'Tablo ayarları',
+ 'Board settings' => 'Pano ayarları',
'Webhook settings' => 'Webhook ayarları',
'Reset token' => 'Belirteci sıfırla',
'API endpoint:' => 'API bitiş noktası:',
- 'Refresh interval for private board' => 'Özel tablolar için yenileme sıklığı',
- 'Refresh interval for public board' => 'Dışa açık tablolar için yenileme sıklığı',
+ 'Refresh interval for private board' => 'Özel panolar için yenileme sıklığı',
+ 'Refresh interval for public board' => 'Dışa açık panolar için yenileme sıklığı',
'Task highlight period' => 'Görevi öne çıkarma süresi',
'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => 'Bir görevin yeni değiştirilmiş sayılması için süre (saniye olarak) (Bu özelliği iptal etmek için 0, varsayılan değer 2 gün)',
'Frequency in second (60 seconds by default)' => 'Saniye olarak frekans (varsayılan 60 saniye)',
@@ -495,14 +489,14 @@ return array(
'Allow only one subtask in progress at the same time for a user' => 'Bir kullanıcı için aynı anda yalnızca bir alt göreve izin ver',
'Edit column "%s"' => '"%s" sütununu değiştir',
'Select the new status of the subtask: "%s"' => '"%s" alt görevi için yeni durum seçin.',
- 'Subtask timesheet' => 'Alt görev için zaman takip tablosu',
+ 'Subtask timesheet' => 'Alt görev için süre tablosu',
'There is nothing to show.' => 'Gösterilecek hiçbir şey yok.',
- 'Time Tracking' => 'Zaman takibi',
+ 'Time Tracking' => 'Süre Çizelgesi',
'You already have one subtask in progress' => 'Zaten işlemde olan bir alt görev var',
'Which parts of the project do you want to duplicate?' => 'Projenin hangi kısımlarının kopyasını oluşturmak istiyorsunuz?',
'Disallow login form' => 'Giriş formu erişimini engelle',
'Start' => 'Başlangıç',
- 'End' => 'Son',
+ 'End' => 'Bitiş',
'Task age in days' => 'Görev yaşı gün olarak',
'Days in this column' => 'Bu sütunda geçirilen gün',
'%dd' => '%dG',
@@ -516,10 +510,8 @@ return array(
'Link labels' => 'Link etiketleri',
'Link modification' => 'Link değiştirme',
'Links' => 'Links',
- 'Link settings' => 'Link ayarları',
'Opposite label' => 'Zıt etiket',
'Remove a link' => 'Bir link silmek',
- 'Task\'s links' => 'Görevin linkleri',
'The labels must be different' => 'Etiketler farklı olmalı',
'There is no link.' => 'Hiç bir bağ yok',
'This label must be unique' => 'Bu etiket tek olmalı',
@@ -545,42 +537,41 @@ return array(
'Expand/collapse tasks' => 'Görevleri genişlet/daralt',
'Close dialog box' => 'İletiyi kapat',
'Submit a form' => 'Formu gönder',
- 'Board view' => 'Tablo görünümü',
+ 'Board view' => 'Pano görünümü',
'Keyboard shortcuts' => 'Klavye kısayolları',
- 'Open board switcher' => 'Tablo seçim listesini aç',
+ 'Open board switcher' => 'Pano seçim listesini aç',
'Application' => 'Uygulama',
'Compact view' => 'Ekrana sığdır',
'Horizontal scrolling' => 'Geniş görünüm',
'Compact/wide view' => 'Ekrana sığdır / Geniş görünüm',
- 'No results match:' => 'Uygun sonuç bulunamadı',
'Currency' => 'Para birimi',
'Private project' => 'Özel proje',
- // 'AUD - Australian Dollar' => '',
- // 'CAD - Canadian Dollar' => '',
- // 'CHF - Swiss Francs' => '',
- // 'Custom Stylesheet' => '',
+ 'AUD - Australian Dollar' => 'AUD - Avustralya Doları',
+ 'CAD - Canadian Dollar' => 'CAD - Kanada Doları',
+ 'CHF - Swiss Francs' => 'CHF - İsviçre Frangı',
+ 'Custom Stylesheet' => 'Özel Sitil Css',
'download' => 'indir',
// 'EUR - Euro' => '',
- // 'GBP - British Pound' => '',
- // 'INR - Indian Rupee' => '',
- // 'JPY - Japanese Yen' => '',
- // 'NZD - New Zealand Dollar' => '',
+ 'GBP - British Pound' => 'GBP - İngiliz Paund',
+ 'INR - Indian Rupee' => 'INR - Hint Rupesi',
+ 'JPY - Japanese Yen' => 'JPY - Japon Yeni',
+ 'NZD - New Zealand Dollar' => 'NZD - Yeni Zelanda Doları',
// 'RSD - Serbian dinar' => '',
- // 'USD - US Dollar' => '',
+ // 'CNY - Chinese Yuan' => '',
+ 'USD - US Dollar' => 'USD$ Amerikan Doları',
'Destination column' => 'Hedef Sütun',
'Move the task to another column when assigned to a user' => 'Bir kullanıcıya atandığında görevi başka bir sütuna taşı',
'Move the task to another column when assignee is cleared' => 'Atanmış kullanıcı kaldırıldığında görevi başka bir sütuna taşı',
'Source column' => 'Kaynak sütun',
'Transitions' => 'Geçişler',
'Executer' => 'Uygulayıcı',
- 'Time spent in the column' => 'Sütunda harcanan süre',
+ 'Time spent in the column' => 'Sütunda geçen süre',
'Task transitions' => 'Görev geçişleri',
'Task transitions export' => 'Görev geçişlerini dışa aktar',
'This report contains all column moves for each task with the date, the user and the time spent for each transition.' => 'Bu rapor her bir görevin sütunlar arası geçişlerini tarih, kullanıcı ve sütunda harcanan zaman detaylarıyla içerir.',
'Currency rates' => 'Döviz kurları',
'Rate' => 'Kurlar',
'Change reference currency' => 'Referans kur değiştir',
- 'Add a new currency rate' => 'Yeni bir kur ekle',
'Reference currency' => 'Referans kur',
'The currency rate have been added successfully.' => 'Kur başarıyla eklendi',
'Unable to add this currency rate.' => 'Bu kur eklenemedi',
@@ -588,11 +579,11 @@ return array(
'%s removed the assignee of the task %s' => '%s, %s görevinin atanan bilgisini kaldırdı',
'Enable Gravatar images' => 'Gravatar resimlerini kullanıma aç',
'Information' => 'Bilgi',
- 'Check two factor authentication code' => 'İki kademeli doğrulama kodunu kontrol et',
- 'The two factor authentication code is not valid.' => 'İki kademeli doğrulama kodu geçersiz',
- 'The two factor authentication code is valid.' => 'İki kademeli doğrulama kodu onaylandı',
+ 'Check two factor authentication code' => 'Çift-Kademeli doğrulama kodunu kontrol et',
+ 'The two factor authentication code is not valid.' => 'Çift-Kademeli doğrulama kodu geçersiz',
+ 'The two factor authentication code is valid.' => 'Çift-Kademeli doğrulama kodu onaylandı',
'Code' => 'Kod',
- 'Two factor authentication' => 'İki kademeli doğrulama',
+ 'Two factor authentication' => 'Çift-Kademeli doğrulama',
'This QR code contains the key URI: ' => 'Bu QR kodu anahtar URI içerir',
'Check my code' => 'Kodu kontrol et',
'Secret key: ' => 'Gizli anahtar',
@@ -605,10 +596,10 @@ return array(
'Add a screenshot' => 'Bir ekran görüntüsü ekle',
'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => 'Bir ekran görüntüsü alın ve buraya yapıştırmak için CTRL+V veya ⌘+V tuşlarına basın.',
'Screenshot uploaded successfully.' => 'Ekran görüntüsü başarıyla yüklendi',
- // 'SEK - Swedish Krona' => '',
+ 'SEK - Swedish Krona' => ' SEK - İsveç Kronu',
'Identifier' => 'Kimlik',
- 'Disable two factor authentication' => 'İki kademeli doğrulamayı iptal et',
- 'Do you really want to disable the two factor authentication for this user: "%s"?' => 'Bu kullanıcı için iki kademeli doğrulamayı iptal etmek istediğinize emin misiniz: "%s"?',
+ 'Disable two factor authentication' => 'Çift-Kademeli doğrulamayı iptal et',
+ 'Do you really want to disable the two factor authentication for this user: "%s"?' => 'Bu kullanıcı için Çift-Kademeli doğrulamayı iptal etmek istediğinize emin misiniz: "%s"?',
'Edit link' => 'Linki düzenle',
'Start to type task title...' => 'Görev başlığını yazmaya başlayın...',
'A task cannot be linked to itself' => 'Bir görevden kendine link atanamaz',
@@ -652,8 +643,8 @@ return array(
'iCal feed' => 'iCal akışı',
'Preferences' => 'Ayarlar',
'Security' => 'Güvenlik',
- 'Two factor authentication disabled' => 'İki kademeli doğrulamayı devre dışı bırak',
- 'Two factor authentication enabled' => 'İki kademeli doğrulamayı etkinleştir',
+ 'Two factor authentication disabled' => 'Çift-Kademeli doğrulamayı devre dışı bırak',
+ 'Two factor authentication enabled' => 'Çift-Kademeli doğrulamayı etkinleştir',
'Unable to update this user.' => 'Bu kullanıcı güncellenemiyor',
'There is no user management for private projects.' => 'Özel projeler için kullanıcı yönetimi yoktur.',
'User that will receive the email' => 'Email alacak kullanıcı',
@@ -672,7 +663,7 @@ return array(
'This report contains all subtasks information for the given date range.' => 'Bu rapor belirtilen tarih aralığında tüm alt görev bilgilerini içerir.',
'This report contains all tasks information for the given date range.' => 'Bu rapor belirtilen tarih aralığında tüm görev bilgilerini içerir.',
'Project activities for %s' => '%s için proje aktiviteleri',
- 'view the board on Kanboard' => 'Tabloyu Kanboard\'da görüntüle',
+ 'view the board on Kanboard' => 'Pano yu Kanboard\'da görüntüle',
'The task have been moved to the first swimlane' => 'Görev birinci kulvara taşındı',
'The task have been moved to another swimlane:' => 'Görev başka bir kulvara taşındı:',
'New title: %s' => 'Yeni başlık: %s',
@@ -685,7 +676,7 @@ return array(
'The due date have been removed' => 'Tamamlanma tarihi silindi',
'There is no description anymore' => 'Artık açıklama yok',
'Recurrence settings have been modified' => 'Tekrarlanma ayarları değiştirildi',
- 'Time spent changed: %sh' => 'Harcanan zaman değiştirildi: %sh',
+ 'Time spent changed: %sh' => 'Geçen süre 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 has been modified:' => 'Açıklama değiştirildi',
@@ -702,7 +693,6 @@ return array(
'<30m' => '<30dk',
'Stop timer' => 'Zamanlayıcıyı durdur',
'Start timer' => 'Zamanlayıcıyı başlat',
- 'Add project member' => 'Proje üyesi ekle',
'My activity stream' => 'Olay akışım',
'My calendar' => 'Takvimim',
'Search tasks' => 'Görevleri ara',
@@ -715,9 +705,9 @@ return array(
'Open tasks' => 'Açık görevler',
'Not assigned' => 'Atanmamış',
'View advanced search syntax' => 'Gelişmiş arama kodlarını göster',
- 'Overview' => 'Genel bakış',
- 'Board/Calendar/List view' => 'Tablo/Takvim/Liste görünümü',
- 'Switch to the board view' => 'Tablo görünümüne geç',
+ 'Overview' => 'Özet Görünüm',
+ 'Board/Calendar/List view' => 'Pano/Takvim/Liste görünümü',
+ 'Switch to the board view' => 'Pano görünümüne geç',
'Switch to the calendar view' => 'Takvim görünümüne geç',
'Switch to the list view' => 'Liste görünümüne geç',
'Go to the search/filter box' => 'Arama/Filtreleme kutusuna git',
@@ -735,9 +725,9 @@ return array(
'Search by category: ' => 'Kategoriye göre ara',
'Search by description: ' => 'Açıklamaya göre ara',
'Search by due date: ' => 'Tamamlanma tarihine göre ara',
- 'Average time spent into each column' => 'Her bir sütunda geçirilen ortalama zaman',
- 'Average time spent' => 'Harcanan ortalama zaman',
- 'This chart show the average time spent into each column for the last %d tasks.' => 'Bu grafik son %d görev için her bir sütunda geçirilen ortalama zamanı gösterir.',
+ 'Average time spent into each column' => 'Her bir sütunda geçirilen ortalama süre',
+ 'Average time spent' => 'Geçen ortalama süre',
+ 'This chart show the average time spent into each column for the last %d tasks.' => 'Bu grafik son %d görev için her bir sütunda geçirilen ortalama süreyi gösterir.',
'Average Lead and Cycle time' => 'Ortalama teslim ve çevrim süresi',
'Average lead time: ' => 'Ortalama teslim süresi',
'Average cycle time: ' => 'Ortalama çevrim süresi',
@@ -748,7 +738,7 @@ return array(
'Lead and cycle time' => 'Teslim ve çevrim süresi',
'Lead time: ' => 'Teslim süresi: ',
'Cycle time: ' => 'Çevrim süresi: ',
- 'Time spent into each column' => 'Her sütunda harcanan zaman',
+ 'Time spent into each column' => 'Her sütunda geçen süre',
'The lead time is the duration between the task creation and the completion.' => 'Teslim süresi, görevin oluşturulması ile tamamlanması arasında geçen süredir.',
'The cycle time is the duration between the start date and the completion.' => 'Çevrim süresi, görevin başlangıç tarihi ile tamamlanması arasında geçen süredir.',
'If the task is not closed the current time is used instead of the completion date.' => 'Eğer görev henüz kapatılmamışsa, tamamlanma tarihi yerine şu anki tarih kullanılır.',
@@ -757,8 +747,6 @@ return array(
'Remote user' => 'Uzak kullanıcı',
'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => 'Uzak kullanıcıların şifreleri Kanboard veritabanında saklanmaz, örnek: LDAP, Google ve Github hesapları',
'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => 'Eğer giriş formuna erişimi engelleyi seçerseniz, giriş formuna girilen bilgiler gözardı edilir.',
- 'New remote user' => 'Yeni uzak kullanıcı',
- 'New local user' => 'Yeni yerel kullanıcı',
'Default task color' => 'Varsayılan görev rengi',
'This feature does not work with all browsers.' => 'Bu özellik tüm tarayıcılarla çalışmaz',
'There is no destination project available.' => 'Seçilebilecek hedef proje yok.',
@@ -784,9 +772,9 @@ return array(
'Moving or resizing a task will change the start and due date of the task.' => 'Bir görevin boyutunu değiştirmek, görevin başlangıç ve tamamlanması gereken tarihlerini değiştirir.',
'There is no task in your project.' => 'Projenizde hiç görev yok.',
'Gantt chart' => 'Gantt diyagramı',
- 'People who are project managers' => 'Proje yöneticisi olan kişiler',
+ 'People who are project managers' => 'Proje müdürü olan kişiler',
'People who are project members' => 'Proje üyesi olan kişiler',
- // 'NOK - Norwegian Krone' => '',
+ 'NOK - Norwegian Krone' => ' NOK - Norveç Kronu',
'Show this column' => 'Bu sütunu göster',
'Hide this column' => 'Bu sütunu gizle',
'open file' => 'dosyayı aç',
@@ -794,11 +782,11 @@ return array(
'Users overview' => 'Kullanıcılara genel bakış',
'Members' => 'Üyeler',
'Shared project' => 'Paylaşılan proje',
- 'Project managers' => 'Proje yöneticileri',
+ 'Project managers' => 'Proje müdürleri',
'Gantt chart for all projects' => 'Tüm projeler için Gantt diyagramı',
'Projects list' => 'Proje listesi',
'Gantt chart for this project' => 'Bu proje için Gantt diyagramı',
- 'Project board' => 'Proje tablosu',
+ 'Project board' => 'Proje Panosu',
'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ı',
@@ -852,7 +840,6 @@ return array(
'Owner' => 'Sahibi',
'Unread notifications' => 'Okunmamış bildirimler',
'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',
'%d task(s) have been imported successfully.' => '%d görev başarıyla içeri aktarıldı.',
'Nothing have been imported!' => 'Hiçbir şey içeri aktarılamadı!',
@@ -911,8 +898,8 @@ return array(
'Group removed successfully.' => 'Grup başarıyla silindi.',
'Unable to remove this group.' => 'Grup silinemedi.',
'Project Permissions' => 'Proje izimleri',
- 'Manager' => 'Yönetici',
- 'Project Manager' => 'Proje yöneticisi',
+ 'Manager' => 'Müdür',
+ 'Project Manager' => 'Proje müdürü',
'Project Member' => 'Proje üyesi',
'Project Viewer' => 'Proje izleyicisi',
'Your account is locked for %d minutes' => 'Hesabınız %d dakika boyunca kilitlendi',
@@ -950,13 +937,13 @@ return array(
'Estimated Time' => 'Tahmini süre',
'Actual Time' => 'Gerçekleşen süre',
'Estimated vs actual time' => 'Tahmini vs gerçekleşen süre',
- // 'RUB - Russian Ruble' => '',
+ 'RUB - Russian Ruble' => ' RUB - Rus Rublesi',
'Assign the task to the person who does the action when the column is changed' => 'Sütun değiştirildiği zaman görevi eylemi gerçekleştiren kişiye ata',
'Close a task in a specific column' => 'Belirli bir sütundaki görevi kapat',
- 'Time-based One-time Password Algorithm' => 'Zamana bağlı tek kullanımlık şifre algoritması',
- 'Two-Factor Provider: ' => 'Çift kademeli doğrulama sağlayıcısı',
- 'Disable two-factor authentication' => 'Çift kademeli doğrulamayı devre dışı bırak',
- 'Enable two-factor authentication' => 'Çift kademeli doğrulamayı etkinleştir',
+ 'Time-based One-time Password Algorithm' => 'Zamana bağlı Tek-Kullanımlık şifre algoritması',
+ 'Two-Factor Provider: ' => 'Çift-Kademeli doğrulama sağlayıcısı: ',
+ 'Disable two-factor authentication' => 'Çift-Kademeli doğrulamayı devre dışı bırak',
+ 'Enable two-factor authentication' => 'Çift-Kademeli doğrulamayı etkinleştir',
'There is no integration registered at the moment.' => 'Şu anda kayıtlı bir entegrasyon bulunmuyor.',
'Password Reset for Kanboard' => 'Kanboard için şifre sıfırlama',
'Forgot password?' => 'Şifrenizi mi unuttunuz?',
@@ -974,307 +961,357 @@ return array(
'Do you really want to close all tasks of this column?' => 'Bu sütundaki tüm görevleri kapatmak istediğinize emin misiniz?',
'%d task(s) in the column "%s" and the swimlane "%s" will be closed.' => '"%s" sütunu ve "%s" kulvarındaki %d görev kapatılacak.',
'Close all tasks of this column' => 'Bu sütundaki tüm görevleri kapat',
- // '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 columns!' => '',
- // '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' => '',
+ 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => 'Proje bildirimleri için hiçbir plugin kaydedilmedi. Yine de profil sayfanızdan bildirim ayarları yapabilirsiniz.',
+ 'My dashboard' => 'Dashboard um',
+ 'My profile' => 'Profilim',
+ 'Project owner: ' => 'Proje sahibi',
+ 'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => 'Proje kodu opsiyoneldir ve alfanümerik olmalıdır, örneğin: PROJE1',
+ 'Project owner' => 'Proje sahibi',
+ 'Private projects do not have users and groups management.' => '(Kişiye) Özel projelerde kullanıcı ve grup yönetimi yoktur.',
+ 'There is no project member.' => 'Proje ekibi yok.',
+ 'Priority' => 'Öncelik',
+ 'Task priority' => 'Görev önceliği',
+ 'General' => 'Genel',
+ 'Dates' => 'Tarihler',
+ 'Default priority' => 'Varsayılan öncelik',
+ 'Lowest priority' => 'En düşük öncelik',
+ 'Highest priority' => 'En yüksek öncelik',
+ 'If you put zero to the low and high priority, this feature will be disabled.' => 'Eğer en düşük ve en yüksek önceliğe sıfır girerseniz, bu özellik devre dışı bırakılacak.',
+ 'Close a task when there is no activity' => 'Bir aktivite olmadığında görevi kapat',
+ 'Duration in days' => 'Süre (gün olarak)',
+ 'Send email when there is no activity on a task' => 'Bir görevde aktivite olmadığında e-posta gönder',
+ 'Unable to fetch link information.' => 'Link eşleştirilemiyor.',
+ 'Daily background job for tasks' => 'Görevler için günlük otomatik arkaplan işleri',
+ 'Auto' => 'Otomatik',
+ 'Related' => 'İlişkili',
+ 'Attachment' => 'Ek',
+ 'Title not found' => 'Başlık bulunamadı',
+ 'Web Link' => 'Web Linki',
+ 'External links' => 'Harici linkler',
+ 'Add external link' => 'Harici link ekle',
+ 'Type' => 'Tip',
+ 'Dependency' => 'Bağımlılık',
+ 'Add internal link' => 'Dahili link ekle',
+ 'Add a new external link' => 'Yeni bir harici link ekle',
+ 'Edit external link' => 'Harici linki düzenle',
+ 'External link' => 'Harici link',
+ 'Copy and paste your link here...' => 'Linkinizi kopyalayıp buraya yapıştırın...',
+ 'URL' => 'URL',
+ 'Internal links' => 'Dahili linkler',
+ 'Assign to me' => 'Bana ata',
+ 'Me' => 'Ben',
+ 'Do not duplicate anything' => 'Hiçbirşeyi duplike etme',
+ 'Projects management' => 'Proje yönetimi',
+ 'Users management' => 'Kullanıcı yönetimi',
+ 'Groups management' => 'Grup yönetimi',
+ 'Create from another project' => 'Başka bir projeden oluştur',
+ 'open' => 'açık',
+ 'closed' => 'kapalı',
+ 'Priority:' => 'Öncelik',
+ 'Reference:' => 'Referans',
+ 'Complexity:' => 'Zorluk',
+ 'Swimlane:' => 'Kulvar',
+ 'Column:' => 'Kolon',
+ 'Position:' => 'Pozisyon',
+ 'Creator:' => 'Oluşturan',
+ 'Time estimated:' => 'Tahmini zaman',
+ '%s hours' => '%s saat',
+ 'Time spent:' => 'Geçen Süre:',
+ 'Created:' => 'Oluşturuldu',
+ 'Modified:' => 'Güncellendi',
+ 'Completed:' => 'Tamamlandı',
+ 'Started:' => 'Başlatıldı',
+ 'Moved:' => 'Taşındı',
+ 'Task #%d' => 'Görev #%d',
+ 'Time format' => 'Saat formatı',
+ 'Start date: ' => 'Başlangıç tarihi',
+ 'End date: ' => 'Bitiş tarihi',
+ 'New due date: ' => 'Yeni hedef tarih',
+ 'Start date changed: ' => 'Başlangıç tarihi değişti:',
+ 'Disable private projects' => 'Özel projeleri engelle',
+ 'Do you really want to remove this custom filter: "%s"?' => 'Bu özel filtreyi gerçekten kaldırmak istiyor musunuz: "%s"?',
+ 'Remove a custom filter' => 'Özel filtre kaldır',
+ 'User activated successfully.' => 'Kullanıcı başarıyla aktifleştirildi',
+ 'Unable to enable this user.' => 'Bu kullanıcı etkinleştirilemiyor.',
+ 'User disabled successfully.' => 'Kullanıcı başarıyla engellendi.',
+ 'Unable to disable this user.' => 'Bu kullanıcı engellenemez.',
+ 'All files have been uploaded successfully.' => 'Tüm dosyalar başarıyla yüklendi.',
+ 'The maximum allowed file size is %sB.' => 'Maksimum dosya büyüklüğü %s B.',
+ 'Drag and drop your files here' => 'Dosyalarınızı buraya sürükleyip bırakın',
+ 'choose files' => 'dosyaları seç',
+ 'View profile' => 'Profili göster',
+ 'Two Factor' => 'İki faktör',
+ 'Disable user' => 'Kullanıcıyı engelle',
+ 'Do you really want to disable this user: "%s"?' => '%s kullanıcısını gerçekten engellemek istiyor musunuz?',
+ 'Enable user' => 'Kullanıcıyı etkinleştir',
+ 'Do you really want to enable this user: "%s"?' => '%s kullanıcısını gerçekten etkinleştirmek istiyor musunuz?',
+ 'Download' => 'İndir',
+ 'Uploaded: %s' => 'Yükle: %s',
+ 'Size: %s' => 'Boyut: %s',
+ 'Uploaded by %s' => '%s tarafından yüklendi',
+ 'Filename' => 'Dosya adı',
+ 'Size' => 'Boyutu',
+ 'Column created successfully.' => 'Kolon başarıyla oluşturuldu.',
+ 'Another column with the same name exists in the project' => 'Projede aynı isimli başka bir kolon var',
+ 'Default filters' => 'Varsayılan filtreler',
+ 'Your board doesn\'t have any columns!' => 'Pano nuzda kolon bulunmuyor!',
+ 'Change column position' => 'Kolon sıralamasını değiştir',
+ 'Switch to the project overview' => 'Proje özetine geç',
+ 'User filters' => 'Kullanıcı filtreleri',
+ 'Category filters' => 'Kategori filtreleri',
+ 'Upload a file' => 'Bir dosya yükle',
+ 'View file' => 'Dosyayı göster',
+ 'Last activity' => 'Son aktivite',
+ 'Change subtask position' => 'Alt görev sırasını değiştir',
+ 'This value must be greater than %d' => 'Bu değer %d den büyük olmalı',
+ 'Another swimlane with the same name exists in the project' => 'Projede aynı isimli başka bir kulvar var',
+ 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => 'Örneğin: http://ornek.dediteknoloji.com/ (sabit URLler oluşturmak için)',
+ 'Actions duplicated successfully.' => 'İşlemler başarıyla çoklandı.',
+ 'Unable to duplicate actions.' => 'İşlemler çoklanamıyor.',
+ 'Add a new action' => 'Yeni bir işlem ekle',
+ 'Import from another project' => 'Başka bir projeden aktar',
+ 'There is no action at the moment.' => 'Şu anda bir işlem yok',
+ 'Import actions from another project' => 'Başka bir projeden işlemleri aktar',
+ 'There is no available project.' => 'Uygun bir proje yok.',
+ 'Local File' => 'Yerel dosya',
+ 'Configuration' => 'Konfigürasyon',
+ 'PHP version:' => 'PHP versiyonu:',
+ 'PHP SAPI:' => 'PHP SAPI:',
+ 'OS version:' => 'OS versiyonu:',
+ 'Database version:' => 'Veritabanı versiyonu:',
+ 'Browser:' => 'Tarayıcı:',
+ 'Task view' => 'Görev görünümü',
+ 'Edit task' => 'Görev güncelle',
+ 'Edit description' => 'Açıklamayı güncelle',
+ 'New internal link' => 'Yeni iç link',
+ 'Display list of keyboard shortcuts' => 'Kısayol tuşları listesini göster',
+ 'Menu' => 'Menü',
+ 'Set start date' => 'Başlangıç tarihi belirle',
// 'Avatar' => '',
- // 'Upload my avatar image' => '',
- // 'Remove my image' => '',
- // 'The OAuth2 state parameter is invalid' => '',
- // 'User not found.' => '',
- // 'Search in activity stream' => '',
- // 'My activities' => '',
- // 'Activity until yesterday' => '',
- // 'Activity until today' => '',
- // 'Search by creator: ' => '',
- // 'Search by creation date: ' => '',
- // 'Search by task status: ' => '',
- // 'Search by task title: ' => '',
- // 'Activity stream search' => '',
- // 'Projects where "%s" is manager' => '',
- // 'Projects where "%s" is member' => '',
- // 'Open tasks assigned to "%s"' => '',
- // 'Closed tasks assigned to "%s"' => '',
- // 'Assign automatically a color based on a priority' => '',
- // 'Overdue tasks for the project(s) "%s"' => '',
- // 'Upload files' => '',
- // 'Installed Plugins' => '',
- // 'Plugin Directory' => '',
- // 'Plugin installed successfully.' => '',
- // 'Plugin updated successfully.' => '',
- // 'Plugin removed successfully.' => '',
- // 'Subtask converted to task successfully.' => '',
- // 'Unable to convert the subtask.' => '',
- // 'Unable to extract plugin archive.' => '',
- // 'Plugin not found.' => '',
- // 'You don\'t have the permission to remove this plugin.' => '',
- // 'Unable to download plugin archive.' => '',
- // 'Unable to write temporary file for plugin.' => '',
- // 'Unable to open plugin archive.' => '',
- // 'There is no file in the plugin archive.' => '',
- // 'Create tasks in bulk' => '',
- // 'Your Kanboard instance is not configured to install plugins from the user interface.' => '',
- // 'There is no plugin available.' => '',
- // 'Install' => '',
- // 'Update' => '',
- // 'Up to date' => '',
- // 'Not available' => '',
- // 'Remove plugin' => '',
- // 'Do you really want to remove this plugin: "%s"?' => '',
- // 'Uninstall' => '',
- // 'Listing' => '',
- // 'Metadata' => '',
- // 'Manage projects' => '',
- // 'Convert to task' => '',
- // 'Convert sub-task to task' => '',
- // 'Do you really want to convert this sub-task to a task?' => '',
- // 'My task title' => '',
- // 'Enter one task by line.' => '',
- // 'Number of failed login:' => '',
- // 'Account locked until:' => '',
- // 'Email settings' => '',
- // 'Email sender address' => '',
- // 'Email transport' => '',
- // 'Webhook token' => '',
- // 'Imports' => '',
- // 'Project tags management' => '',
- // 'Tag created successfully.' => '',
- // 'Unable to create this tag.' => '',
- // 'Tag updated successfully.' => '',
- // 'Unable to update this tag.' => '',
- // 'Tag removed successfully.' => '',
- // 'Unable to remove this tag.' => '',
- // 'Global tags management' => '',
- // 'Tags' => '',
- // 'Tags management' => '',
- // 'Add new tag' => '',
- // 'Edit a tag' => '',
- // 'Project tags' => '',
- // 'There is no specific tag for this project at the moment.' => '',
- // 'Tag' => '',
- // 'Remove a tag' => '',
- // 'Do you really want to remove this tag: "%s"?' => '',
- // 'Global tags' => '',
- // 'There is no global tag at the moment.' => '',
- // 'This field cannot be empty' => '',
- // 'Close a task when there is no activity in an specific column' => '',
- // '%s removed a subtask for the task #%d' => '',
- // '%s removed a comment on the task #%d' => '',
- // 'Comment removed on task #%d' => '',
- // 'Subtask removed on task #%d' => '',
- // 'Hide tasks in this column in the dashboard' => '',
- // '%s removed a comment on the task %s' => '',
- // '%s removed a subtask for the task %s' => '',
- // 'Comment removed' => '',
- // 'Subtask removed' => '',
- // '%s set a new internal link for the task #%d' => '',
- // '%s removed an internal link for the task #%d' => '',
- // 'A new internal link for the task #%d have been defined' => '',
- // 'Internal link removed for the task #%d' => '',
- // '%s set a new internal link for the task %s' => '',
- // '%s removed an internal link for the task %s' => '',
- // 'Automatically set the due date on task creation' => '',
- // 'Move the task to another column when closed' => '',
- // 'Move the task to another column when not moved during a given period' => '',
- // 'Dashboard for %s' => '',
- // 'Tasks overview for %s' => '',
- // 'Subtasks overview for %s' => '',
- // 'Projects overview for %s' => '',
- // 'Activity stream for %s' => '',
- // 'Calendar for %s' => '',
- // 'Notifications for %s' => '',
- // 'Subtasks export' => '',
- // 'Tasks exportation' => '',
- // 'Assign a color when the task is moved to a specific swimlane' => '',
- // 'Assign a priority when the task is moved to a specific swimlane' => '',
- // 'User unlocked successfully.' => '',
- // 'Unable to unlock the user.' => '',
- // 'Move a task to another swimlane' => '',
- // 'Creator Name' => '',
- // 'Time spent and estimated' => '',
- // 'Move position' => '',
- // 'Move task to another position on the board' => '',
- // 'Insert before this task' => '',
- // 'Insert after this task' => '',
- // 'Unlock this user' => '',
- // 'Custom Project Roles' => '',
- // 'Add a new custom role' => '',
- // 'Restrictions for the role "%s"' => '',
- // 'Add a new project restriction' => '',
- // 'Add a new drag and drop restriction' => '',
- // 'Add a new column restriction' => '',
- // 'Edit this role' => '',
- // 'Remove this role' => '',
- // 'There is no restriction for this role.' => '',
- // 'Only moving task between those columns is permitted' => '',
- // 'Close a task in a specific column when not moved during a given period' => '',
- // 'Edit columns' => '',
- // 'The column restriction has been created successfully.' => '',
- // 'Unable to create this column restriction.' => '',
- // 'Column restriction removed successfully.' => '',
- // 'Unable to remove this restriction.' => '',
- // 'Your custom project role has been created successfully.' => '',
- // 'Unable to create custom project role.' => '',
- // 'Your custom project role has been updated successfully.' => '',
- // 'Unable to update custom project role.' => '',
- // 'Custom project role removed successfully.' => '',
- // 'Unable to remove this project role.' => '',
- // 'The project restriction has been created successfully.' => '',
- // 'Unable to create this project restriction.' => '',
- // 'Project restriction removed successfully.' => '',
- // 'You cannot create tasks in this column.' => '',
- // 'Task creation is permitted for this column' => '',
- // 'Closing or opening a task is permitted for this column' => '',
- // 'Task creation is blocked for this column' => '',
- // 'Closing or opening a task is blocked for this column' => '',
- // 'Task creation is not permitted' => '',
- // 'Closing or opening a task is not permitted' => '',
- // 'New drag and drop restriction for the role "%s"' => '',
- // 'People belonging to this role will be able to move tasks only between the source and the destination column.' => '',
- // 'Remove a column restriction' => '',
- // 'Do you really want to remove this column restriction: "%s" to "%s"?' => '',
- // 'New column restriction for the role "%s"' => '',
- // 'Rule' => '',
- // 'Do you really want to remove this column restriction?' => '',
- // 'Custom roles' => '',
- // 'New custom project role' => '',
- // 'Edit custom project role' => '',
- // 'Remove a custom role' => '',
- // 'Do you really want to remove this custom role: "%s"? All people assigned to this role will become project member.' => '',
- // 'There is no custom role for this project.' => '',
- // 'New project restriction for the role "%s"' => '',
- // 'Restriction' => '',
- // 'Remove a project restriction' => '',
- // 'Do you really want to remove this project restriction: "%s"?' => '',
- // 'Duplicate to multiple projects' => '',
- // 'This field is required' => '',
- // 'Moving a task is not permitted' => '',
- // 'This value must be in the range %d to %d' => '',
+ 'Upload my avatar image' => 'Avatar resmimi yükle',
+ 'Remove my image' => 'Resmimi kaldır',
+ 'The OAuth2 state parameter is invalid' => 'OAuth2 durum parametresi geçersiz',
+ 'User not found.' => 'Kullanıcı bulunamadı',
+ 'Search in activity stream' => 'Aktivite akışında ara',
+ 'My activities' => 'Aktivitelerim',
+ 'Activity until yesterday' => 'Düne kadar olan aktiviteler',
+ 'Activity until today' => 'Bugüne kadar olan aktiviteler',
+ 'Search by creator: ' => 'Oluşturan ile ara',
+ 'Search by creation date: ' => 'Oluşturma tarihi ile ara',
+ 'Search by task status: ' => 'Görev durumu ile ara',
+ 'Search by task title: ' => 'Görev başlığı ile ara',
+ 'Activity stream search' => 'Aktivite akışı araması',
+ 'Projects where "%s" is manager' => '%s in müdürü olduğu projeler',
+ 'Projects where "%s" is member' => '%s in ekip üyesi olduğu projeler',
+ 'Open tasks assigned to "%s"' => '%s e atanan görevleri aç',
+ 'Closed tasks assigned to "%s"' => '%s e atanan görevleri kapat',
+ 'Assign automatically a color based on a priority' => 'Önceliğe bağlı olarak bir renk belirle',
+ 'Overdue tasks for the project(s) "%s"' => '%s proje(leri) için süresi geçen görevler',
+ 'Upload files' => 'Dosyaları yükle',
+ 'Installed Plugins' => 'Yüklenmiş Pluginler',
+ 'Plugin Directory' => 'Plugin Klasörü',
+ 'Plugin installed successfully.' => 'Plugin başarıyla kuruldu.',
+ 'Plugin updated successfully.' => 'Plugin başarıyla güncellendi.',
+ 'Plugin removed successfully.' => 'Plugin başarıyla kaldırıldı.',
+ 'Subtask converted to task successfully.' => 'Alt görev başarıyla göreve dönüştürüldü.',
+ 'Unable to convert the subtask.' => 'Alt görev dönüştürülemedi',
+ 'Unable to extract plugin archive.' => 'Plugin (sıkıştırılmış) dosyası açılamadı.',
+ 'Plugin not found.' => 'Plugin bulunamadı',
+ 'You don\'t have the permission to remove this plugin.' => 'Bu plugin\'i kaldırmak için yetkiniz yok.',
+ 'Unable to download plugin archive.' => 'Plugin dosyası indirilemedi.',
+ 'Unable to write temporary file for plugin.' => 'Plugin için geçici dosya oluşturulamadı.',
+ 'Unable to open plugin archive.' => 'Plugin dosyası açılamadı.',
+ 'There is no file in the plugin archive.' => 'Plugin (sıkıştırılmış) dosyasında, dosya bulunmuyor.',
+ 'Create tasks in bulk' => 'Toplu olarak görev oluştur',
+ 'Your Kanboard instance is not configured to install plugins from the user interface.' => 'Kanbord sisteminiz arayüzden plugin kurulacak şekilde ayarlanmamış.',
+ 'There is no plugin available.' => 'Uygun plugin yok.',
+ 'Install' => 'Kur',
+ 'Update' => 'Güncelle',
+ 'Up to date' => 'Güncel',
+ 'Not available' => 'Uygun değil',
+ 'Remove plugin' => 'Plugini kaldır',
+ 'Do you really want to remove this plugin: "%s"?' => '"%s" plugin i gerçekten kaldırmak istiyor musunuz?',
+ 'Uninstall' => 'Kaldır',
+ 'Listing' => 'Listeliyor',
+ 'Metadata' => 'Meta veri',
+ 'Manage projects' => 'Projeler',
+ 'Convert to task' => 'Göreve dönüştür',
+ 'Convert sub-task to task' => 'Alt görevi göreve dönüştür',
+ 'Do you really want to convert this sub-task to a task?' => 'Bu alt görevi, göreve dönüştüreceğinize emin misiniz?',
+ 'My task title' => 'Görev başlığım',
+ 'Enter one task by line.' => 'Görevleri satır satır girin',
+ 'Number of failed login:' => 'Başarısız login denemesi sayısı',
+ 'Account locked until:' => 'Hesap şu zamana kadar kilitlendi:',
+ 'Email settings' => 'E-posta ayarları',
+ 'Email sender address' => 'E-posta gönderen adresi',
+ 'Email transport' => 'E-posta taşıma',
+ 'Webhook token' => 'Webhook token',
+ 'Project tags management' => 'Proje etiket yönetimi',
+ 'Tag created successfully.' => 'Etiket başarıyla oluturuldu.',
+ 'Unable to create this tag.' => 'Etiket oluşturulamıyor.',
+ 'Tag updated successfully.' => 'Etiket başarıyla güncellendi.',
+ 'Unable to update this tag.' => 'Etiket güncellenemedi.',
+ 'Tag removed successfully.' => 'Etiket başarıyla kaldırıldı.',
+ 'Unable to remove this tag.' => 'Etiket kaldırılamadı.',
+ 'Global tags management' => 'Genel etiket yönetimi',
+ 'Tags' => 'Etiketler',
+ 'Tags management' => 'Etiket yönetimi',
+ 'Add new tag' => 'Yeni etiket ekle',
+ 'Edit a tag' => 'Etiket güncelle',
+ 'Project tags' => 'Proje etiketleri',
+ 'There is no specific tag for this project at the moment.' => 'Proje için şu anda bir etiket bulunmuyor.',
+ 'Tag' => 'Etiket',
+ 'Remove a tag' => 'Etiket kaldır',
+ 'Do you really want to remove this tag: "%s"?' => '"%s" etiketini kaldıracağınıza emin misiniz?',
+ 'Global tags' => 'Genel etiketler',
+ 'There is no global tag at the moment.' => 'Şu anda genel bir etiket bulunmuyor.',
+ 'This field cannot be empty' => 'Bu alan boş bırakılamaz',
+ 'Close a task when there is no activity in an specific column' => 'Bir kolonda hareket olmadığında bir görevi kapat',
+ '%s removed a subtask for the task #%d' => '%d görevi için %s bir alt görevi kaldırdı',
+ '%s removed a comment on the task #%d' => '%s %d görevi için bir yorumu kaldırdı',
+ 'Comment removed on task #%d' => '%d görevindeki yorum kaldırıldı',
+ 'Subtask removed on task #%d' => '%d görevindeki alt görev kaldırıldı',
+ 'Hide tasks in this column in the dashboard' => 'Panoda bu kolondaki görevleri gizle',
+ '%s removed a comment on the task %s' => '%s %s görevinde bir yorumu kaldırdı',
+ '%s removed a subtask for the task %s' => '%s %s alt görevini kaldırdı',
+ 'Comment removed' => 'Yorum kaldırıldı',
+ 'Subtask removed' => 'Alt görev kaldırıldı',
+ '%s set a new internal link for the task #%d' => '%d görevi için %s bir iç link oluşturdu',
+ '%s removed an internal link for the task #%d' => '%d görevi için %s bir iç linki kaldırdı',
+ 'A new internal link for the task #%d have been defined' => '%d görevi için yeni bir iç link tanımlandı',
+ 'Internal link removed for the task #%d' => '%d görevi için iç link kaldırıldı',
+ '%s set a new internal link for the task %s' => '%s görevi için %s yeni bir iç link oluşturdu',
+ '%s removed an internal link for the task %s' => '%s %s görevi için bir iç linki kaldırdı',
+ 'Automatically set the due date on task creation' => 'Görev oluştururken hedef tarihi otomatik ata',
+ 'Move the task to another column when closed' => 'Görev kapandığında başka bir kolona taşı',
+ 'Move the task to another column when not moved during a given period' => 'Bir kolonda belirli bir süre hareketsiz kalırsa görevi başka bir kolona taşı',
+ 'Dashboard for %s' => '%s için Pano',
+ 'Tasks overview for %s' => '%s için görev özeti',
+ 'Subtasks overview for %s' => '%s için alt görev özeti',
+ 'Projects overview for %s' => '%s için proje özeti',
+ 'Activity stream for %s' => '%s için akış',
+ 'Calendar for %s' => '%s için takvim',
+ 'Notifications for %s' => '%s için bildirimler',
+ 'Assign a color when the task is moved to a specific swimlane' => 'Görev bir kulvara taşındığında rengini değiştir',
+ 'Assign a priority when the task is moved to a specific swimlane' => 'Görev bir kulvara taşındığında önceliğini değiştir',
+ 'User unlocked successfully.' => 'Kullanıcı kilidi başarıyla kaldırıldı.',
+ 'Unable to unlock the user.' => 'Kullanıcı kilitlenemiyor.',
+ 'Move a task to another swimlane' => 'Görevi başka bir kulvara taşı',
+ 'Creator Name' => 'Oluşturan Adı',
+ 'Time spent and estimated' => 'Tahmini ve geçen süre',
+ 'Move position' => 'Taşıma sırası',
+ 'Move task to another position on the board' => 'Görevin sırasını değiştir',
+ 'Insert before this task' => 'Bu görevin öncesine oluştur',
+ 'Insert after this task' => 'Bu görevin ardına oluştur',
+ 'Unlock this user' => 'Bu kullanıcının kilidini kaldır',
+ 'Custom Project Roles' => 'Ek Proje Rolleri',
+ 'Add a new custom role' => 'Proje rolü ekle',
+ 'Restrictions for the role "%s"' => '"%s" rolü için kısıtlamalar',
+ 'Add a new project restriction' => 'Yeni kısıtlama ekle',
+ 'Add a new drag and drop restriction' => 'Sürükle bırak kısıtlaması ekle',
+ 'Add a new column restriction' => 'Kolon kısıtlaması ekle',
+ 'Edit this role' => 'Rolü güncelle',
+ 'Remove this role' => 'Rolü kaldır',
+ 'There is no restriction for this role.' => 'Bu rol için bir kısıtlama yok',
+ 'Only moving task between those columns is permitted' => 'Sadece belirlenen kolonlar arasında taşıma mümkündür',
+ 'Close a task in a specific column when not moved during a given period' => 'Bir kolonda belirli bir süre hareketsiz kalan görev kapatılsın',
+ 'Edit columns' => 'Kolonları güncelle',
+ 'The column restriction has been created successfully.' => 'Kolon kısıtlaması başarıyla oluşturuldu.',
+ 'Unable to create this column restriction.' => 'Kolon kısıtlaması oluşturulamadı.',
+ 'Column restriction removed successfully.' => 'Kolon kısıtlaması başarıyla kaldırıldı.',
+ 'Unable to remove this restriction.' => 'Bu kısıtlama kaldırılamıyor.',
+ 'Your custom project role has been created successfully.' => 'Ek proje rolü başarıyla oluşturuldu.',
+ 'Unable to create custom project role.' => 'Ek proje rolü oluşturulamadı',
+ 'Your custom project role has been updated successfully.' => 'Ek proje rolü başarıyla güncellendi.',
+ 'Unable to update custom project role.' => 'Ek proje rolü güncellenemiyor.',
+ 'Custom project role removed successfully.' => 'Ek proje rolü başarıyla kaldırıldı.',
+ 'Unable to remove this project role.' => 'Proje rolü kaldırılamıyor.',
+ 'The project restriction has been created successfully.' => 'Proje kısıtlaması başarıyla oluşturuldu.',
+ 'Unable to create this project restriction.' => 'Proje kısıtlaması oluşturulamadı',
+ 'Project restriction removed successfully.' => 'Proje kısıtlaması başarıyla kaldırıldı.',
+ 'You cannot create tasks in this column.' => 'Bu kolonda görev oluşturamazsınız.',
+ 'Task creation is permitted for this column' => 'Bu kolonda görev oluşturulabilir.',
+ 'Closing or opening a task is permitted for this column' => 'Bu kolonda görev açma yahut kapatma yapılabilir.',
+ 'Task creation is blocked for this column' => 'Bu kolonda görev oluşturma bloke edilmiştir.',
+ 'Closing or opening a task is blocked for this column' => 'Bu kolonda görev açma yahut kapatma bloke edilmiştir.',
+ 'Task creation is not permitted' => 'Görev oluşturmaya izin verilmemiştir',
+ 'Closing or opening a task is not permitted' => 'Görev açmaya yahut kapatmaya izin verilmemiştir',
+ 'New drag and drop restriction for the role "%s"' => '"%s" rolü için yeni sürükle bırak kısıtlaması',
+ 'People belonging to this role will be able to move tasks only between the source and the destination column.' => 'Bu roldeki kullanıcılar sadece kaynak ve hedef kolonlar arasında görevi hareket ettirebilir.',
+ 'Remove a column restriction' => 'Kolon kısıtlamasını kaldır',
+ 'Do you really want to remove this column restriction: "%s" to "%s"?' => 'Kolon kısıtlamasının "%s" den "%s" e değiştireceğinize emin misiniz?',
+ 'New column restriction for the role "%s"' => '"%s" rolü için yeni kolon kısıtlaması',
+ 'Rule' => 'Kural',
+ 'Do you really want to remove this column restriction?' => 'Kolon kısıtlamasını kaldırmak istediğinize emin misiniz?',
+ 'Custom roles' => 'Ek roller',
+ 'New custom project role' => 'Yeni ek proje rolü',
+ 'Edit custom project role' => 'Ek proje rolünü güncelle',
+ 'Remove a custom role' => 'Ek rolü kaldır',
+ 'Do you really want to remove this custom role: "%s"? All people assigned to this role will become project member.' => '"%s" ek rolünü kaldıracağınıza emin misiniz? Bu role ait tüm kullanıcılar proje kullanıcısı olacak.',
+ 'There is no custom role for this project.' => 'Bu proje için ek rol bulunmuyor.',
+ 'New project restriction for the role "%s"' => '"%s" rolü için yeni proje kısıtlaması',
+ 'Restriction' => 'Kısıtlama',
+ 'Remove a project restriction' => 'Proje kısıtlaması kaldır',
+ 'Do you really want to remove this project restriction: "%s"?' => '"%s" proje kısıtlamasını kaldırmak istediğinize emin misiniz?',
+ 'Duplicate to multiple projects' => 'Birden çok projeye çokla',
+ 'This field is required' => 'Bu alan gerekli',
+ 'Moving a task is not permitted' => 'Görev taşımaya izin verilmemiş',
+ 'This value must be in the range %d to %d' => 'Bu değer şu aralıkta olmalı: "%d" "%d"',
+ 'You are not allowed to move this task.' => 'Bu görevi taşımaya izniniz yok.',
+ 'API User Access' => 'API Kullanıcı Erişimi',
+ 'Preview' => 'Öngörünüm',
+ 'Write' => 'Yaz',
+ 'Write your text in Markdown' => 'Metninizi Markdown a yazın',
+ 'New External Task: %s' => 'Yeni Harici Görev: %s',
+ 'No personal API access token registered.' => 'Kişisel API erişim belirteç-token ınız kaydedilmedi.',
+ 'Your personal API access token is "%s"' => 'Kişisel API erişim belirteç-token ınız"%s"',
+ 'Remove your token' => 'Belirteç-token ınızı kaldır',
+ 'Generate a new token' => 'Yeni bir belirteç-token oluştur',
+ // 'Showing %d-%d of %d' => '',
+ // 'Outgoing Emails' => '',
+ 'Add or change currency rate' => 'Kur Oranını ekle veya değiştir',
+ // 'Reference currency: %s' => '',
+ // 'Add custom filters' => '',
+ // 'Export' => '',
+ // 'Add link label' => '',
+ // 'Incompatible Plugins' => '',
+ // 'Compatibility' => '',
+ // 'Permissions and ownership' => '',
+ // 'Priorities' => '',
+ // 'Close this window' => '',
+ // 'Unable to upload this file.' => '',
+ // 'Import tasks' => '',
+ // 'Choose a project' => '',
+ // 'Profile' => '',
+ // 'Application role' => '',
+ // '%d invitations were sent.' => '',
+ // '%d invitation was sent.' => '',
+ // 'Unable to create this user.' => '',
+ // 'Kanboard Invitation' => '',
+ // 'Visible on dashboard' => '',
+ // 'Created at:' => '',
+ // 'Updated at:' => '',
+ // 'There is no custom filter.' => '',
+ // 'New User' => '',
+ // 'Authentication' => '',
+ // 'If checked, this user will use a third-party system for authentication.' => '',
+ // 'The password is necessary only for local users.' => '',
+ // 'You have been invited to register on Kanboard.' => '',
+ // 'Click here to join your team' => '',
+ // 'Invite people' => '',
+ // 'Emails' => '',
+ // 'Enter one email address by line.' => '',
+ // 'Add these people to this project' => '',
+ // 'Add this person to this project' => '',
+ // 'Sign-up' => '',
+ // 'Credentials' => '',
+ // 'New user' => '',
+ // 'This username is already taken' => '',
+ // 'A link to reset your password has been sent by email.' => '',
+ // 'Your profile must have a valid email address.' => '',
+ // 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
+ // 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
+ // 'The email configuration has been disabled by the administrator.' => '',
);
diff --git a/app/Locale/zh_CN/translations.php b/app/Locale/zh_CN/translations.php
index 6dccd6cc..e49386df 100644
--- a/app/Locale/zh_CN/translations.php
+++ b/app/Locale/zh_CN/translations.php
@@ -61,7 +61,6 @@ return array(
'%d tasks on the board' => '看板目前有%d个任务',
'%d tasks in total' => '总共有%d个任务',
'Unable to update this board.' => '无法更新该看板。',
- 'Edit board' => '修改看板',
'Disable' => '停用',
'Enable' => '启用',
'New project' => '新建项目',
@@ -72,7 +71,6 @@ return array(
'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"?' => '确定要移除栏目"%s"吗?',
'This action will REMOVE ALL TASKS associated to this column!' => '该动作将移除与该栏目相关的所有项目!',
@@ -160,9 +158,7 @@ return array(
'Task count' => '任务数',
'User' => '用户',
'Comments' => '评论',
- 'Leave a comment' => '留言',
'Comment is required' => '必须得有评论',
- 'Leave a description' => '给一个描述',
'Comment added successfully.' => '评论成功添加。',
'Unable to create your comment.' => '无法创建评论。',
'Due Date' => '到期时间',
@@ -224,7 +220,6 @@ return array(
'Search' => '查找',
'Nothing found.' => '没找到。',
'Due date' => '到期时间',
- 'Others formats accepted: %s and %s' => '可以使用的其它格式:%s 和 %s',
'Description' => '描述',
'%d comments' => '%d个评论',
'%d comment' => '%d个评论',
@@ -298,7 +293,6 @@ return array(
'Created by %s' => '创建者:%s',
'Tasks Export' => '任务导出',
'Start Date' => '开始时间',
- 'End Date' => '结束时间',
'Execute' => '执行',
'Task Id' => '任务ID',
'Creator' => '创建者',
@@ -342,8 +336,8 @@ return array(
'Remote' => '远程',
'Enabled' => '启用',
'Disabled' => '停用',
- 'Username:' => '用户名:',
- 'Name:' => '姓名:',
+ 'Login:' => '用户名:',
+ 'Full Name:' => '姓名:',
'Email:' => '电子邮件:',
'Notifications:' => '通知:',
'Notifications' => '通知',
@@ -516,10 +510,8 @@ return array(
'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' => '关联必须唯一',
@@ -552,7 +544,6 @@ return array(
'Compact view' => '紧凑视图',
'Horizontal scrolling' => '水平滚动',
'Compact/wide view' => '紧凑/宽视图',
- 'No results match:' => '无匹配结果:',
'Currency' => '货币',
'Private project' => '私人项目',
'AUD - Australian Dollar' => '澳元',
@@ -566,6 +557,7 @@ return array(
'JPY - Japanese Yen' => '日元',
'NZD - New Zealand Dollar' => '新西兰元',
'RSD - Serbian dinar' => '第纳尔',
+ 'CNY - Chinese Yuan' => '人民币',
'USD - US Dollar' => '美元',
'Destination column' => '目标栏目',
'Move the task to another column when assigned to a user' => '指定负责人时移动到其它栏目',
@@ -580,7 +572,6 @@ return array(
'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.' => '无法添加此汇率',
@@ -702,7 +693,6 @@ return array(
'<30m' => '小于30分钟',
'Stop timer' => '停止计时器',
'Start timer' => '开启计时器',
- 'Add project member' => '添加项目成员',
'My activity stream' => '我的活动流',
'My calendar' => '我的日程表',
'Search tasks' => '搜索任务',
@@ -751,14 +741,12 @@ return array(
// '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' => '',
+ '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.' => '远程用户不会在看板数据库保存密码,例如:LDAP,GOOGLE,GitHub。',
'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.' => '当前没有目标项目可用',
@@ -852,7 +840,6 @@ return array(
'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!' => '没有信息被导入!',
@@ -980,7 +967,6 @@ return array(
'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' => '优先级',
@@ -1037,7 +1023,6 @@ return array(
'Started:' => '已开始:',
'Moved:' => '已移走',
'Task #%d' => '任务#%d',
- 'Date and time format' => '时间和日期格式',
'Time format' => '时间格式',
'Start date: ' => '开始时间:',
'End date: ' => '结束时间:',
@@ -1051,9 +1036,7 @@ return array(
'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' => '查看个人信息',
@@ -1090,191 +1073,245 @@ return array(
'There is no action at the moment.' => '当前没有动作。',
'Import actions from another project' => '从另一个项目中导入动作',
'There is no available project.' => '当前没有可用项目',
- // 'Local File' => '',
- // 'Configuration' => '',
+ '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' => '',
- // 'User not found.' => '',
- // 'Search in activity stream' => '',
- // 'My activities' => '',
- // 'Activity until yesterday' => '',
- // 'Activity until today' => '',
- // 'Search by creator: ' => '',
- // 'Search by creation date: ' => '',
- // 'Search by task status: ' => '',
- // 'Search by task title: ' => '',
- // 'Activity stream search' => '',
- // 'Projects where "%s" is manager' => '',
- // 'Projects where "%s" is member' => '',
- // 'Open tasks assigned to "%s"' => '',
- // 'Closed tasks assigned to "%s"' => '',
- // 'Assign automatically a color based on a priority' => '',
- // 'Overdue tasks for the project(s) "%s"' => '',
- // 'Upload files' => '',
- // 'Installed Plugins' => '',
- // 'Plugin Directory' => '',
- // 'Plugin installed successfully.' => '',
- // 'Plugin updated successfully.' => '',
- // 'Plugin removed successfully.' => '',
- // 'Subtask converted to task successfully.' => '',
- // 'Unable to convert the subtask.' => '',
- // 'Unable to extract plugin archive.' => '',
- // 'Plugin not found.' => '',
- // 'You don\'t have the permission to remove this plugin.' => '',
- // 'Unable to download plugin archive.' => '',
- // 'Unable to write temporary file for plugin.' => '',
- // 'Unable to open plugin archive.' => '',
- // 'There is no file in the plugin archive.' => '',
- // 'Create tasks in bulk' => '',
- // 'Your Kanboard instance is not configured to install plugins from the user interface.' => '',
- // 'There is no plugin available.' => '',
- // 'Install' => '',
- // 'Update' => '',
- // 'Up to date' => '',
- // 'Not available' => '',
- // 'Remove plugin' => '',
- // 'Do you really want to remove this plugin: "%s"?' => '',
- // 'Uninstall' => '',
- // 'Listing' => '',
- // 'Metadata' => '',
- // 'Manage projects' => '',
- // 'Convert to task' => '',
- // 'Convert sub-task to task' => '',
- // 'Do you really want to convert this sub-task to a task?' => '',
- // 'My task title' => '',
- // 'Enter one task by line.' => '',
- // 'Number of failed login:' => '',
- // 'Account locked until:' => '',
- // 'Email settings' => '',
- // 'Email sender address' => '',
- // 'Email transport' => '',
- // 'Webhook token' => '',
- // 'Imports' => '',
- // 'Project tags management' => '',
- // 'Tag created successfully.' => '',
- // 'Unable to create this tag.' => '',
- // 'Tag updated successfully.' => '',
- // 'Unable to update this tag.' => '',
- // 'Tag removed successfully.' => '',
- // 'Unable to remove this tag.' => '',
- // 'Global tags management' => '',
- // 'Tags' => '',
- // 'Tags management' => '',
- // 'Add new tag' => '',
- // 'Edit a tag' => '',
- // 'Project tags' => '',
- // 'There is no specific tag for this project at the moment.' => '',
- // 'Tag' => '',
- // 'Remove a tag' => '',
- // 'Do you really want to remove this tag: "%s"?' => '',
- // 'Global tags' => '',
- // 'There is no global tag at the moment.' => '',
- // 'This field cannot be empty' => '',
- // 'Close a task when there is no activity in an specific column' => '',
- // '%s removed a subtask for the task #%d' => '',
- // '%s removed a comment on the task #%d' => '',
- // 'Comment removed on task #%d' => '',
- // 'Subtask removed on task #%d' => '',
- // 'Hide tasks in this column in the dashboard' => '',
- // '%s removed a comment on the task %s' => '',
- // '%s removed a subtask for the task %s' => '',
- // 'Comment removed' => '',
- // 'Subtask removed' => '',
- // '%s set a new internal link for the task #%d' => '',
- // '%s removed an internal link for the task #%d' => '',
- // 'A new internal link for the task #%d have been defined' => '',
- // 'Internal link removed for the task #%d' => '',
- // '%s set a new internal link for the task %s' => '',
- // '%s removed an internal link for the task %s' => '',
- // 'Automatically set the due date on task creation' => '',
- // 'Move the task to another column when closed' => '',
- // 'Move the task to another column when not moved during a given period' => '',
- // 'Dashboard for %s' => '',
- // 'Tasks overview for %s' => '',
- // 'Subtasks overview for %s' => '',
- // 'Projects overview for %s' => '',
- // 'Activity stream for %s' => '',
- // 'Calendar for %s' => '',
- // 'Notifications for %s' => '',
- // 'Subtasks export' => '',
- // 'Tasks exportation' => '',
- // 'Assign a color when the task is moved to a specific swimlane' => '',
- // 'Assign a priority when the task is moved to a specific swimlane' => '',
- // 'User unlocked successfully.' => '',
- // 'Unable to unlock the user.' => '',
- // 'Move a task to another swimlane' => '',
- // 'Creator Name' => '',
- // 'Time spent and estimated' => '',
- // 'Move position' => '',
- // 'Move task to another position on the board' => '',
- // 'Insert before this task' => '',
- // 'Insert after this task' => '',
- // 'Unlock this user' => '',
- // 'Custom Project Roles' => '',
- // 'Add a new custom role' => '',
- // 'Restrictions for the role "%s"' => '',
- // 'Add a new project restriction' => '',
- // 'Add a new drag and drop restriction' => '',
- // 'Add a new column restriction' => '',
- // 'Edit this role' => '',
- // 'Remove this role' => '',
- // 'There is no restriction for this role.' => '',
- // 'Only moving task between those columns is permitted' => '',
- // 'Close a task in a specific column when not moved during a given period' => '',
- // 'Edit columns' => '',
- // 'The column restriction has been created successfully.' => '',
- // 'Unable to create this column restriction.' => '',
- // 'Column restriction removed successfully.' => '',
- // 'Unable to remove this restriction.' => '',
- // 'Your custom project role has been created successfully.' => '',
- // 'Unable to create custom project role.' => '',
- // 'Your custom project role has been updated successfully.' => '',
- // 'Unable to update custom project role.' => '',
- // 'Custom project role removed successfully.' => '',
- // 'Unable to remove this project role.' => '',
- // 'The project restriction has been created successfully.' => '',
- // 'Unable to create this project restriction.' => '',
- // 'Project restriction removed successfully.' => '',
- // 'You cannot create tasks in this column.' => '',
- // 'Task creation is permitted for this column' => '',
- // 'Closing or opening a task is permitted for this column' => '',
- // 'Task creation is blocked for this column' => '',
- // 'Closing or opening a task is blocked for this column' => '',
- // 'Task creation is not permitted' => '',
- // 'Closing or opening a task is not permitted' => '',
- // 'New drag and drop restriction for the role "%s"' => '',
- // 'People belonging to this role will be able to move tasks only between the source and the destination column.' => '',
- // 'Remove a column restriction' => '',
- // 'Do you really want to remove this column restriction: "%s" to "%s"?' => '',
- // 'New column restriction for the role "%s"' => '',
- // 'Rule' => '',
- // 'Do you really want to remove this column restriction?' => '',
- // 'Custom roles' => '',
- // 'New custom project role' => '',
- // 'Edit custom project role' => '',
- // 'Remove a custom role' => '',
- // 'Do you really want to remove this custom role: "%s"? All people assigned to this role will become project member.' => '',
- // 'There is no custom role for this project.' => '',
- // 'New project restriction for the role "%s"' => '',
- // 'Restriction' => '',
- // 'Remove a project restriction' => '',
- // 'Do you really want to remove this project restriction: "%s"?' => '',
- // 'Duplicate to multiple projects' => '',
- // 'This field is required' => '',
- // 'Moving a task is not permitted' => '',
- // 'This value must be in the range %d to %d' => '',
+ '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' => 'OAuth2状态参数无效',
+ 'User not found.' => '用户未找到',
+ 'Search in activity stream' => '在活动足迹里搜索',
+ 'My activities' => '我的活动足迹',
+ 'Activity until yesterday' => '今天以前的活动足迹',
+ 'Activity until today' => '今天为止的活动足迹',
+ 'Search by creator: ' => '以创建者搜索',
+ 'Search by creation date: ' => '以创建日期搜索',
+ 'Search by task status: ' => '以任务状态搜索',
+ 'Search by task title: ' => '以任务标题搜索',
+ 'Activity stream search' => '活动足迹搜索',
+ 'Projects where "%s" is manager' => '"%s" 管理的项目',
+ 'Projects where "%s" is member' => '"%s" 参与的项目',
+ 'Open tasks assigned to "%s"' => '指派给"%s"的开放任务',
+ 'Closed tasks assigned to "%s"' => '指派给"%s"的已结束任务',
+ 'Assign automatically a color based on a priority' => '基于优先级自动标记颜色',
+ 'Overdue tasks for the project(s) "%s"' => '"%s"项目下的超期任务',
+ 'Upload files' => '上传文件',
+ 'Installed Plugins' => '已安装插件',
+ 'Plugin Directory' => '插件目录',
+ 'Plugin installed successfully.' => '插件安装成功。',
+ 'Plugin updated successfully.' => '插件更新成功。',
+ 'Plugin removed successfully.' => '插件卸载成功。',
+ 'Subtask converted to task successfully.' => '子任务成功转换成普通任务。',
+ 'Unable to convert the subtask.' => '无法转换子任务。',
+ 'Unable to extract plugin archive.' => '无法解压插件包。',
+ 'Plugin not found.' => '插件未找到。',
+ 'You don\'t have the permission to remove this plugin.' => '你没有权限移除此插件。',
+ 'Unable to download plugin archive.' => '无法下载插件包。',
+ 'Unable to write temporary file for plugin.' => '无法为插件写入临时文件。',
+ 'Unable to open plugin archive.' => '无法打开插件包。',
+ 'There is no file in the plugin archive.' => '当前插件包内无文件。',
+ 'Create tasks in bulk' => '批量创建任务',
+ 'Your Kanboard instance is not configured to install plugins from the user interface.' => '你的Kanboard没有启用插件安装。',
+ 'There is no plugin available.' => '当前无可用插件。',
+ 'Install' => '安装',
+ 'Update' => '更新',
+ 'Up to date' => '已更新',
+ 'Not available' => '不可用',
+ 'Remove plugin' => '移除插件',
+ 'Do you really want to remove this plugin: "%s"?' => '你真的要移除插件:"%s"?',
+ 'Uninstall' => '移除',
+ 'Listing' => '列表',
+ 'Metadata' => '元数据',
+ 'Manage projects' => '管理项目',
+ 'Convert to task' => '转化为普通任务',
+ 'Convert sub-task to task' => '转化子任务为普通任务',
+ 'Do you really want to convert this sub-task to a task?' => '你真的要将此子任务转化为普通任务?',
+ 'My task title' => '我的任务标题',
+ 'Enter one task by line.' => '写入一行任务。',
+ 'Number of failed login:' => '登录失败次数:',
+ 'Account locked until:' => '账户被锁定至:',
+ 'Email settings' => '邮件设置',
+ 'Email sender address' => '邮件发送地址',
+ 'Email transport' => '邮件转发',
+ 'Webhook token' => 'Web钩子Token',
+ 'Project tags management' => '项目标签管理',
+ 'Tag created successfully.' => '成功创建标签。',
+ 'Unable to create this tag.' => '无法创建此标签。',
+ 'Tag updated successfully.' => '标签更新成功。',
+ 'Unable to update this tag.' => '无法更新此标签。',
+ 'Tag removed successfully.' => '标签删除成功。',
+ 'Unable to remove this tag.' => '无法删除此标签',
+ 'Global tags management' => '全局标签管理',
+ 'Tags' => '标签',
+ 'Tags management' => '标签管理',
+ 'Add new tag' => '添加新标签',
+ 'Edit a tag' => '编辑标签',
+ 'Project tags' => '项目标签',
+ 'There is no specific tag for this project at the moment.' => '当前项目没有指定任何标签。',
+ 'Tag' => '标签',
+ 'Remove a tag' => '移除标签',
+ 'Do you really want to remove this tag: "%s"?' => '你真的要删除此标签:"%s"?',
+ 'Global tags' => '全局标签',
+ 'There is no global tag at the moment.' => '当前没有全局标签。',
+ 'This field cannot be empty' => '此栏不能为空',
+ 'Close a task when there is no activity in an specific column' => '当指定栏目没有更新时关闭任务',
+ '%s removed a subtask for the task #%d' => '"%s"从任务#%d删除了子任务',
+ '%s removed a comment on the task #%d' => '"%s"从任务#%d删除了评论',
+ 'Comment removed on task #%d' => '任务#%d上的评论已删除',
+ 'Subtask removed on task #%d' => '任务#%d上的子任务已删除',
+ 'Hide tasks in this column in the dashboard' => '在面板首页隐藏此栏下的任务',
+ '%s removed a comment on the task %s' => '"%s"从任务%s 删除了评论',
+ '%s removed a subtask for the task %s' => '"%s"从任务%s 删除了子任务',
+ 'Comment removed' => '评论已删除',
+ 'Subtask removed' => '子任务已删除',
+ '%s set a new internal link for the task #%d' => '%s为任务#%d 设置了新内部链接',
+ '%s removed an internal link for the task #%d' => '%s 从任务 #%d 删除内部链接',
+ 'A new internal link for the task #%d have been defined' => '#%d新内部链接已定义',
+ 'Internal link removed for the task #%d' => '#%d内部链接已删除',
+ '%s set a new internal link for the task %s' => '%s为任务%s设置了新链接',
+ '%s removed an internal link for the task %s' => '%s删除了任务%s内部链接',
+ 'Automatically set the due date on task creation' => '创建任务时自动设置过期时间',
+ 'Move the task to another column when closed' => '当任务关闭时移动到另一栏',
+ 'Move the task to another column when not moved during a given period' => '当任务在指定时间内未移动时,移动到另一栏',
+ 'Dashboard for %s' => '%s的看板',
+ 'Tasks overview for %s' => '%s的任务预览',
+ 'Subtasks overview for %s' => '%s的子任务预览',
+ 'Projects overview for %s' => '%s的项目预览',
+ 'Activity stream for %s' => '%s的活动足迹',
+ 'Calendar for %s' => '%s的日历',
+ 'Notifications for %s' => '%s的通知',
+ 'Assign a color when the task is moved to a specific swimlane' => '当任务移动到指定里程碑时标记颜色',
+ 'Assign a priority when the task is moved to a specific swimlane' => '当任务移动到指定里程碑时标记优先级',
+ 'User unlocked successfully.' => '用户解锁成功。',
+ 'Unable to unlock the user.' => '无法解锁用户。',
+ 'Move a task to another swimlane' => '移动任务到里程碑',
+ 'Creator Name' => '创建人名称',
+ 'Time spent and estimated' => '时间花费预估',
+ 'Move position' => '移动位置',
+ 'Move task to another position on the board' => '移动任务到另一个位置',
+ 'Insert before this task' => '在此任务之前插入',
+ 'Insert after this task' => '在此任务之后插入',
+ 'Unlock this user' => '解锁用户',
+ 'Custom Project Roles' => '自定义项目角色',
+ 'Add a new custom role' => '添加新角色',
+ 'Restrictions for the role "%s"' => '"%s"角色限制',
+ 'Add a new project restriction' => '添加新的项目限制',
+ 'Add a new drag and drop restriction' => '添加新的拖放限制',
+ 'Add a new column restriction' => '添加新的栏目限制',
+ 'Edit this role' => '编辑角色',
+ 'Remove this role' => '删除角色',
+ 'There is no restriction for this role.' => '当前角色无限制。',
+ 'Only moving task between those columns is permitted' => '只能在以下栏目间移动任务',
+ 'Close a task in a specific column when not moved during a given period' => '当指定栏目下的任务在指定时间内未移动时关闭任务',
+ 'Edit columns' => '编辑栏目',
+ 'The column restriction has been created successfully.' => '成功创建栏目限制。',
+ 'Unable to create this column restriction.' => '无法创建栏目限制。',
+ 'Column restriction removed successfully.' => '成功删除栏目限制。',
+ 'Unable to remove this restriction.' => '无法删除限制。',
+ 'Your custom project role has been created successfully.' => '自定义项目角色创建成功。',
+ 'Unable to create custom project role.' => '无法删除自定义项目角色。',
+ 'Your custom project role has been updated successfully.' => '自定义项目角色更新成功。',
+ 'Unable to update custom project role.' => '无法更新自定义项目角色。',
+ 'Custom project role removed successfully.' => '成功删除自定义项目角色。',
+ 'Unable to remove this project role.' => '无法删除项目角色。',
+ 'The project restriction has been created successfully.' => '成功创建项目限制。',
+ 'Unable to create this project restriction.' => '无法创建项目限制。',
+ 'Project restriction removed successfully.' => '成功删除项目限制。',
+ 'You cannot create tasks in this column.' => '你不能在此栏目下创建任务。',
+ 'Task creation is permitted for this column' => '当前栏目下不能创建任务。',
+ 'Closing or opening a task is permitted for this column' => '当前栏目下不能开关任务。',
+ 'Task creation is blocked for this column' => '当前栏目下禁止创建任务。',
+ 'Closing or opening a task is blocked for this column' => '禁止在此栏下开关任务',
+ 'Task creation is not permitted' => '不能创建任务',
+ 'Closing or opening a task is not permitted' => '禁止开关任务',
+ 'New drag and drop restriction for the role "%s"' => '为角色"%s"新建拖动限制',
+ 'People belonging to this role will be able to move tasks only between the source and the destination column.' => '此角色下的用户将只能在源栏目和目标栏目间移动任务。',
+ 'Remove a column restriction' => '移除栏目限制',
+ 'Do you really want to remove this column restriction: "%s" to "%s"?' => '你真的要删除栏目限制:"%s"到"%s"?',
+ 'New column restriction for the role "%s"' => '为角色"%s"增加栏目限制?',
+ 'Rule' => '规则',
+ 'Do you really want to remove this column restriction?' => '你真的要移除栏目限制?',
+ 'Custom roles' => '自定义角色',
+ 'New custom project role' => '新建项目角色',
+ 'Edit custom project role' => '编辑项目角色',
+ 'Remove a custom role' => '删除自定义角色',
+ 'Do you really want to remove this custom role: "%s"? All people assigned to this role will become project member.' => '你真的要删除这个自定义橘色:"%s"?当前角色下的用户将转换成普通项目成员。',
+ 'There is no custom role for this project.' => '当前项目没有自定义角色',
+ 'New project restriction for the role "%s"' => '给角色"%s"新建项目限制',
+ 'Restriction' => '限制',
+ 'Remove a project restriction' => '移除项目限制',
+ 'Do you really want to remove this project restriction: "%s"?' => '你真的要删除项目限制:"%s"?',
+ 'Duplicate to multiple projects' => '复制到多个项目',
+ 'This field is required' => '此项必填',
+ 'Moving a task is not permitted' => '禁止移动任务',
+ 'This value must be in the range %d to %d' => '输入值必须在%d到%d之间',
+ 'You are not allowed to move this task.' => '你不能移动此任务',
+ // 'API User Access' => '',
+ // 'Preview' => '',
+ // 'Write' => '',
+ // 'Write your text in Markdown' => '',
+ // 'New External Task: %s' => '',
+ // 'No personal API access token registered.' => '',
+ // 'Your personal API access token is "%s"' => '',
+ // 'Remove your token' => '',
+ // 'Generate a new token' => '',
+ 'Showing %d-%d of %d' => '本页显示 %d-%d 条,共有: %d 条',
+ // 'Outgoing Emails' => '',
+ // 'Add or change currency rate' => '',
+ // 'Reference currency: %s' => '',
+ // 'Add custom filters' => '',
+ // 'Export' => '',
+ // 'Add link label' => '',
+ // 'Incompatible Plugins' => '',
+ // 'Compatibility' => '',
+ // 'Permissions and ownership' => '',
+ // 'Priorities' => '',
+ // 'Close this window' => '',
+ // 'Unable to upload this file.' => '',
+ // 'Import tasks' => '',
+ // 'Choose a project' => '',
+ // 'Profile' => '',
+ // 'Application role' => '',
+ // '%d invitations were sent.' => '',
+ // '%d invitation was sent.' => '',
+ // 'Unable to create this user.' => '',
+ // 'Kanboard Invitation' => '',
+ // 'Visible on dashboard' => '',
+ // 'Created at:' => '',
+ // 'Updated at:' => '',
+ // 'There is no custom filter.' => '',
+ // 'New User' => '',
+ // 'Authentication' => '',
+ // 'If checked, this user will use a third-party system for authentication.' => '',
+ // 'The password is necessary only for local users.' => '',
+ // 'You have been invited to register on Kanboard.' => '',
+ // 'Click here to join your team' => '',
+ // 'Invite people' => '',
+ // 'Emails' => '',
+ // 'Enter one email address by line.' => '',
+ // 'Add these people to this project' => '',
+ // 'Add this person to this project' => '',
+ // 'Sign-up' => '',
+ // 'Credentials' => '',
+ // 'New user' => '',
+ // 'This username is already taken' => '',
+ // 'A link to reset your password has been sent by email.' => '',
+ // 'Your profile must have a valid email address.' => '',
+ // 'Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?' => '',
+ // 'TRL - Turkish Lira' => '',
+ // 'The project email is optional and could be used by several plugins.' => '',
+ // 'The email project must be unique across all projects' => '',
+ // 'The email configuration has been disabled by the administrator.' => '',
);
diff --git a/app/Middleware/BootstrapMiddleware.php b/app/Middleware/BootstrapMiddleware.php
index 727f600c..778221b3 100644
--- a/app/Middleware/BootstrapMiddleware.php
+++ b/app/Middleware/BootstrapMiddleware.php
@@ -32,6 +32,7 @@ class BootstrapMiddleware extends BaseMiddleware
{
$this->response->withContentSecurityPolicy($this->container['cspRules']);
$this->response->withSecurityHeaders();
+ $this->response->withP3P();
if (ENABLE_XFRAME) {
$this->response->withXframe();
diff --git a/app/Model/CommentModel.php b/app/Model/CommentModel.php
index a9e48bd3..e44a5ecd 100644
--- a/app/Model/CommentModel.php
+++ b/app/Model/CommentModel.php
@@ -60,6 +60,7 @@ class CommentModel extends Base
->columns(
self::TABLE.'.id',
self::TABLE.'.date_creation',
+ self::TABLE.'.date_modification',
self::TABLE.'.task_id',
self::TABLE.'.user_id',
self::TABLE.'.comment',
@@ -69,7 +70,7 @@ class CommentModel extends Base
UserModel::TABLE.'.avatar_path'
)
->join(UserModel::TABLE, 'id', 'user_id')
- ->orderBy(self::TABLE.'.date_creation', $sorting)
+ ->orderBy(self::TABLE.'.date_modification', $sorting)
->eq(self::TABLE.'.task_id', $task_id)
->findAll();
}
@@ -90,6 +91,7 @@ class CommentModel extends Base
self::TABLE.'.task_id',
self::TABLE.'.user_id',
self::TABLE.'.date_creation',
+ self::TABLE.'.date_modification',
self::TABLE.'.comment',
self::TABLE.'.reference',
UserModel::TABLE.'.username',
@@ -127,6 +129,7 @@ class CommentModel extends Base
public function create(array $values)
{
$values['date_creation'] = time();
+ $values['date_modification'] = time();
$comment_id = $this->db->table(self::TABLE)->persist($values);
if ($comment_id !== false) {
@@ -148,7 +151,7 @@ class CommentModel extends Base
$result = $this->db
->table(self::TABLE)
->eq('id', $values['id'])
- ->update(array('comment' => $values['comment']));
+ ->update(array('comment' => $values['comment'], 'date_modification' => time()));
if ($result) {
$this->queueManager->push($this->commentEventJob->withParams($values['id'], self::EVENT_UPDATE));
diff --git a/app/Model/CurrencyModel.php b/app/Model/CurrencyModel.php
index bfd9697c..55a5b2fe 100644
--- a/app/Model/CurrencyModel.php
+++ b/app/Model/CurrencyModel.php
@@ -42,6 +42,8 @@ class CurrencyModel extends Base
'NOK' => t('NOK - Norwegian Krone'),
'BAM' => t('BAM - Konvertible Mark'),
'RUB' => t('RUB - Russian Ruble'),
+ 'CNY' => t('CNY - Chinese Yuan'),
+ 'TRL' => t('TRL - Turkish Lira'),
);
}
diff --git a/app/Model/FileModel.php b/app/Model/FileModel.php
index 98032f9d..d04b03bf 100644
--- a/app/Model/FileModel.php
+++ b/app/Model/FileModel.php
@@ -210,9 +210,7 @@ abstract class FileModel extends Base
*/
public function isImage($filename)
{
- $extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
-
- switch ($extension) {
+ switch (get_file_extension($filename)) {
case 'jpeg':
case 'jpg':
case 'png':
@@ -309,31 +307,35 @@ abstract class FileModel extends Base
* Handle file upload (base64 encoded content)
*
* @access public
- * @param integer $id
- * @param string $original_filename
- * @param string $blob
- * @return bool|integer
+ * @param integer $id
+ * @param string $originalFilename
+ * @param string $data
+ * @param bool $isEncoded
+ * @return bool|int
*/
- public function uploadContent($id, $original_filename, $blob)
+ public function uploadContent($id, $originalFilename, $data, $isEncoded = true)
{
try {
- $data = base64_decode($blob);
+ if ($isEncoded) {
+ $data = base64_decode($data);
+ }
if (empty($data)) {
+ $this->logger->error(__METHOD__.': Content upload with no data');
return false;
}
- $destination_filename = $this->generatePath($id, $original_filename);
- $this->objectStorage->put($destination_filename, $data);
+ $destinationFilename = $this->generatePath($id, $originalFilename);
+ $this->objectStorage->put($destinationFilename, $data);
- if ($this->isImage($original_filename)) {
- $this->generateThumbnailFromData($destination_filename, $data);
+ if ($this->isImage($originalFilename)) {
+ $this->generateThumbnailFromData($destinationFilename, $data);
}
return $this->create(
$id,
- $original_filename,
- $destination_filename,
+ $originalFilename,
+ $destinationFilename,
strlen($data)
);
} catch (ObjectStorageException $e) {
diff --git a/app/Model/InviteModel.php b/app/Model/InviteModel.php
new file mode 100644
index 00000000..13d75f69
--- /dev/null
+++ b/app/Model/InviteModel.php
@@ -0,0 +1,73 @@
+<?php
+
+namespace Kanboard\Model;
+
+use Kanboard\Core\Base;
+use Kanboard\Core\Security\Token;
+
+/**
+ * Class InviteModel
+ *
+ * @package Kanboard\Model
+ * @author Frederic Guillot
+ */
+class InviteModel extends Base
+{
+ const TABLE = 'invites';
+
+ public function createInvites(array $emails, $projectId)
+ {
+ $emails = array_unique($emails);
+ $nb = 0;
+
+ foreach ($emails as $email) {
+ $email = trim($email);
+
+ if (! empty($email) && $this->createInvite($email, $projectId)) {
+ $nb++;
+ }
+ }
+
+ return $nb;
+ }
+
+ protected function createInvite($email, $projectId)
+ {
+ $values = array(
+ 'email' => $email,
+ 'project_id' => $projectId,
+ 'token' => Token::getToken(),
+ );
+
+ if ($this->db->table(self::TABLE)->insert($values)) {
+ $this->sendInvite($values);
+ return true;
+ }
+
+ return false;
+ }
+
+ protected function sendInvite(array $values)
+ {
+ $this->emailClient->send(
+ $values['email'],
+ $values['email'],
+ e('Kanboard Invitation'),
+ $this->template->render('user_invite/email', array('token' => $values['token']))
+ );
+ }
+
+ public function getByToken($token)
+ {
+ return $this->db->table(self::TABLE)
+ ->eq('token', $token)
+ ->findOne();
+ }
+
+ public function remove($email)
+ {
+ return $this->db->table(self::TABLE)
+ ->eq('email', $email)
+ ->remove();
+ }
+}
diff --git a/app/Model/ProjectModel.php b/app/Model/ProjectModel.php
index aba5eee2..080217cb 100644
--- a/app/Model/ProjectModel.php
+++ b/app/Model/ProjectModel.php
@@ -106,6 +106,22 @@ class ProjectModel extends Base
}
/**
+ * Get a project by the email address
+ *
+ * @access public
+ * @param string $email
+ * @return array|boolean
+ */
+ public function getByEmail($email)
+ {
+ if (empty($email)) {
+ return false;
+ }
+
+ return $this->db->table(self::TABLE)->eq('email', $email)->findOne();
+ }
+
+ /**
* Fetch project data by using the token
*
* @access public
diff --git a/app/Model/ProjectPermissionModel.php b/app/Model/ProjectPermissionModel.php
index 25b6a382..dabd406c 100644
--- a/app/Model/ProjectPermissionModel.php
+++ b/app/Model/ProjectPermissionModel.php
@@ -62,17 +62,33 @@ class ProjectPermissionModel extends Base
->withFilter(new ProjectUserRoleProjectFilter($project_id))
->withFilter(new ProjectUserRoleUsernameFilter($input))
->getQuery()
- ->findAllByColumn('username');
+ ->columns(
+ UserModel::TABLE.'.id',
+ UserModel::TABLE.'.username',
+ UserModel::TABLE.'.name',
+ UserModel::TABLE.'.email',
+ UserModel::TABLE.'.avatar_path'
+ )
+ ->findAll();
$groupMembers = $this->projectGroupRoleQuery
->withFilter(new ProjectGroupRoleProjectFilter($project_id))
->withFilter(new ProjectGroupRoleUsernameFilter($input))
->getQuery()
- ->findAllByColumn('username');
+ ->columns(
+ UserModel::TABLE.'.id',
+ UserModel::TABLE.'.username',
+ UserModel::TABLE.'.name',
+ UserModel::TABLE.'.email',
+ UserModel::TABLE.'.avatar_path'
+ )
+ ->findAll();
- $members = array_unique(array_merge($userMembers, $groupMembers));
+ $userMembers = array_column_index_unique($userMembers, 'username');
+ $groupMembers = array_column_index_unique($groupMembers, 'username');
+ $members = array_merge($userMembers, $groupMembers);
- sort($members);
+ ksort($members);
return $members;
}
diff --git a/app/Model/UserMentionModel.php b/app/Model/UserMentionModel.php
deleted file mode 100644
index cdb9949e..00000000
--- a/app/Model/UserMentionModel.php
+++ /dev/null
@@ -1,62 +0,0 @@
-<?php
-
-namespace Kanboard\Model;
-
-use Kanboard\Core\Base;
-use Kanboard\Event\GenericEvent;
-
-/**
- * User Mention
- *
- * @package Kanboard\Model
- * @author Frederic Guillot
- */
-class UserMentionModel extends Base
-{
- /**
- * Get list of mentioned users
- *
- * @access public
- * @param string $content
- * @return array
- */
- public function getMentionedUsers($content)
- {
- $users = array();
-
- if (preg_match_all('/@([^\s]+)/', $content, $matches)) {
- $users = $this->db->table(UserModel::TABLE)
- ->columns('id', 'username', 'name', 'email', 'language')
- ->eq('notifications_enabled', 1)
- ->neq('id', $this->userSession->getId())
- ->in('username', array_unique($matches[1]))
- ->findAll();
- }
-
- return $users;
- }
-
- /**
- * Fire events for user mentions
- *
- * @access public
- * @param string $content
- * @param string $eventName
- * @param GenericEvent $event
- */
- public function fireEvents($content, $eventName, GenericEvent $event)
- {
- if (empty($event['project_id'])) {
- $event['project_id'] = $this->taskFinderModel->getProjectId($event['task_id']);
- }
-
- $users = $this->getMentionedUsers($content);
-
- foreach ($users as $user) {
- if ($this->projectPermissionModel->isMember($event['project_id'], $user['id'])) {
- $event['mention'] = $user;
- $this->dispatcher->dispatch($eventName, $event);
- }
- }
- }
-}
diff --git a/app/Schema/Mysql.php b/app/Schema/Mysql.php
index 274ce8c8..ca9f45ad 100644
--- a/app/Schema/Mysql.php
+++ b/app/Schema/Mysql.php
@@ -6,7 +6,48 @@ use PDO;
use Kanboard\Core\Security\Token;
use Kanboard\Core\Security\Role;
-const VERSION = 115;
+const VERSION = 121;
+
+function version_121(PDO $pdo)
+{
+ $pdo->exec('ALTER TABLE projects ADD COLUMN email VARCHAR(255)');
+}
+
+function version_120(PDO $pdo)
+{
+ $pdo->exec("
+ CREATE TABLE invites (
+ email VARCHAR(255) NOT NULL,
+ project_id INTEGER NOT NULL,
+ token VARCHAR(255) NOT NULL,
+ PRIMARY KEY(email, token)
+ ) ENGINE=InnoDB CHARSET=utf8
+ ");
+
+ $pdo->exec("DELETE FROM settings WHERE `option`='application_datetime_format'");
+}
+
+function version_119(PDO $pdo)
+{
+ $pdo->exec('ALTER TABLE `comments` ADD COLUMN `date_modification` BIGINT(20)');
+ $pdo->exec('UPDATE `comments` SET `date_modification` = `date_creation` WHERE `date_modification` IS NULL');
+}
+
+function version_118(PDO $pdo)
+{
+ $pdo->exec('ALTER TABLE `users` ADD COLUMN `api_access_token` VARCHAR(255) DEFAULT NULL');
+}
+
+function version_117(PDO $pdo)
+{
+ $pdo->exec("ALTER TABLE `settings` MODIFY `value` TEXT");
+}
+
+function version_116(PDO $pdo)
+{
+ $pdo->exec("ALTER TABLE tasks ADD COLUMN external_provider VARCHAR(255)");
+ $pdo->exec("ALTER TABLE tasks ADD COLUMN external_uri VARCHAR(255)");
+}
function version_115(PDO $pdo)
{
@@ -47,9 +88,9 @@ function version_113(PDO $pdo)
$pdo->exec("
CREATE TABLE project_has_roles (
role_id INT NOT NULL AUTO_INCREMENT,
- role VARCHAR(255) NOT NULL,
+ `role` VARCHAR(255) NOT NULL,
project_id INT NOT NULL,
- UNIQUE(project_id, role),
+ UNIQUE(project_id, `role`),
FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE,
PRIMARY KEY(role_id)
) ENGINE=InnoDB CHARSET=utf8
diff --git a/app/Schema/Postgres.php b/app/Schema/Postgres.php
index 213d9869..cbea908f 100644
--- a/app/Schema/Postgres.php
+++ b/app/Schema/Postgres.php
@@ -6,7 +6,48 @@ use PDO;
use Kanboard\Core\Security\Token;
use Kanboard\Core\Security\Role;
-const VERSION = 94;
+const VERSION = 100;
+
+function version_100(PDO $pdo)
+{
+ $pdo->exec('ALTER TABLE "projects" ADD COLUMN email VARCHAR(255)');
+}
+
+function version_99(PDO $pdo)
+{
+ $pdo->exec("
+ CREATE TABLE invites (
+ email VARCHAR(255) NOT NULL,
+ project_id INTEGER NOT NULL,
+ token VARCHAR(255) NOT NULL,
+ PRIMARY KEY(email, token)
+ )
+ ");
+
+ $pdo->exec("DELETE FROM settings WHERE \"option\"='application_datetime_format'");
+}
+
+function version_98(PDO $pdo)
+{
+ $pdo->exec('ALTER TABLE "comments" ADD COLUMN date_modification BIGINT');
+ $pdo->exec('UPDATE "comments" SET date_modification = date_creation WHERE date_modification IS NULL');
+}
+
+function version_97(PDO $pdo)
+{
+ $pdo->exec('ALTER TABLE "users" ADD COLUMN api_access_token VARCHAR(255) DEFAULT NULL');
+}
+
+function version_96(PDO $pdo)
+{
+ $pdo->exec('ALTER TABLE "settings" ALTER COLUMN "value" TYPE TEXT');
+}
+
+function version_95(PDO $pdo)
+{
+ $pdo->exec("ALTER TABLE tasks ADD COLUMN external_provider VARCHAR(255)");
+ $pdo->exec("ALTER TABLE tasks ADD COLUMN external_uri VARCHAR(255)");
+}
function version_94(PDO $pdo)
{
diff --git a/app/Schema/Sql/mysql.sql b/app/Schema/Sql/mysql.sql
index 8d494dcf..487560f3 100644
--- a/app/Schema/Sql/mysql.sql
+++ b/app/Schema/Sql/mysql.sql
@@ -35,6 +35,44 @@ CREATE TABLE `actions` (
CONSTRAINT `actions_ibfk_1` FOREIGN KEY (`project_id`) REFERENCES `projects` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
+DROP TABLE IF EXISTS `column_has_move_restrictions`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `column_has_move_restrictions` (
+ `restriction_id` int(11) NOT NULL AUTO_INCREMENT,
+ `project_id` int(11) NOT NULL,
+ `role_id` int(11) NOT NULL,
+ `src_column_id` int(11) NOT NULL,
+ `dst_column_id` int(11) NOT NULL,
+ PRIMARY KEY (`restriction_id`),
+ UNIQUE KEY `role_id` (`role_id`,`src_column_id`,`dst_column_id`),
+ KEY `project_id` (`project_id`),
+ KEY `src_column_id` (`src_column_id`),
+ KEY `dst_column_id` (`dst_column_id`),
+ CONSTRAINT `column_has_move_restrictions_ibfk_1` FOREIGN KEY (`project_id`) REFERENCES `projects` (`id`) ON DELETE CASCADE,
+ CONSTRAINT `column_has_move_restrictions_ibfk_2` FOREIGN KEY (`role_id`) REFERENCES `project_has_roles` (`role_id`) ON DELETE CASCADE,
+ CONSTRAINT `column_has_move_restrictions_ibfk_3` FOREIGN KEY (`src_column_id`) REFERENCES `columns` (`id`) ON DELETE CASCADE,
+ CONSTRAINT `column_has_move_restrictions_ibfk_4` FOREIGN KEY (`dst_column_id`) REFERENCES `columns` (`id`) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+DROP TABLE IF EXISTS `column_has_restrictions`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `column_has_restrictions` (
+ `restriction_id` int(11) NOT NULL AUTO_INCREMENT,
+ `project_id` int(11) NOT NULL,
+ `role_id` int(11) NOT NULL,
+ `column_id` int(11) NOT NULL,
+ `rule` varchar(255) NOT NULL,
+ PRIMARY KEY (`restriction_id`),
+ UNIQUE KEY `role_id` (`role_id`,`column_id`,`rule`),
+ KEY `project_id` (`project_id`),
+ KEY `column_id` (`column_id`),
+ CONSTRAINT `column_has_restrictions_ibfk_1` FOREIGN KEY (`project_id`) REFERENCES `projects` (`id`) ON DELETE CASCADE,
+ CONSTRAINT `column_has_restrictions_ibfk_2` FOREIGN KEY (`role_id`) REFERENCES `project_has_roles` (`role_id`) ON DELETE CASCADE,
+ CONSTRAINT `column_has_restrictions_ibfk_3` FOREIGN KEY (`column_id`) REFERENCES `columns` (`id`) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
DROP TABLE IF EXISTS `columns`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
@@ -62,6 +100,7 @@ CREATE TABLE `comments` (
`date_creation` bigint(20) DEFAULT NULL,
`comment` text,
`reference` varchar(50) DEFAULT '',
+ `date_modification` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
KEY `comments_reference_idx` (`reference`),
@@ -119,6 +158,16 @@ CREATE TABLE `groups` (
UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
+DROP TABLE IF EXISTS `invites`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `invites` (
+ `email` varchar(255) NOT NULL,
+ `project_id` int(11) NOT NULL,
+ `token` varchar(255) NOT NULL,
+ PRIMARY KEY (`email`,`token`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
DROP TABLE IF EXISTS `last_logins`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
@@ -260,7 +309,7 @@ DROP TABLE IF EXISTS `project_has_groups`;
CREATE TABLE `project_has_groups` (
`group_id` int(11) NOT NULL,
`project_id` int(11) NOT NULL,
- `role` varchar(25) NOT NULL,
+ `role` varchar(255) NOT NULL,
UNIQUE KEY `group_id` (`group_id`,`project_id`),
KEY `project_id` (`project_id`),
CONSTRAINT `project_has_groups_ibfk_1` FOREIGN KEY (`group_id`) REFERENCES `groups` (`id`) ON DELETE CASCADE,
@@ -292,19 +341,46 @@ CREATE TABLE `project_has_notification_types` (
CONSTRAINT `project_has_notification_types_ibfk_1` FOREIGN KEY (`project_id`) REFERENCES `projects` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
+DROP TABLE IF EXISTS `project_has_roles`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `project_has_roles` (
+ `role_id` int(11) NOT NULL AUTO_INCREMENT,
+ `role` varchar(255) NOT NULL,
+ `project_id` int(11) NOT NULL,
+ PRIMARY KEY (`role_id`),
+ UNIQUE KEY `project_id` (`project_id`,`role`),
+ CONSTRAINT `project_has_roles_ibfk_1` FOREIGN KEY (`project_id`) REFERENCES `projects` (`id`) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
DROP TABLE IF EXISTS `project_has_users`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `project_has_users` (
`project_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
- `role` varchar(25) NOT NULL DEFAULT 'project-viewer',
+ `role` varchar(255) NOT NULL,
UNIQUE KEY `idx_project_user` (`project_id`,`user_id`),
KEY `user_id` (`user_id`),
CONSTRAINT `project_has_users_ibfk_1` FOREIGN KEY (`project_id`) REFERENCES `projects` (`id`) ON DELETE CASCADE,
CONSTRAINT `project_has_users_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
+DROP TABLE IF EXISTS `project_role_has_restrictions`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `project_role_has_restrictions` (
+ `restriction_id` int(11) NOT NULL AUTO_INCREMENT,
+ `project_id` int(11) NOT NULL,
+ `role_id` int(11) NOT NULL,
+ `rule` varchar(255) NOT NULL,
+ PRIMARY KEY (`restriction_id`),
+ UNIQUE KEY `role_id` (`role_id`,`rule`),
+ KEY `project_id` (`project_id`),
+ CONSTRAINT `project_role_has_restrictions_ibfk_1` FOREIGN KEY (`project_id`) REFERENCES `projects` (`id`) ON DELETE CASCADE,
+ CONSTRAINT `project_role_has_restrictions_ibfk_2` FOREIGN KEY (`role_id`) REFERENCES `project_has_roles` (`role_id`) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
DROP TABLE IF EXISTS `projects`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
@@ -359,7 +435,7 @@ DROP TABLE IF EXISTS `settings`;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `settings` (
`option` varchar(100) NOT NULL,
- `value` varchar(255) DEFAULT '',
+ `value` text,
`changed_by` int(11) NOT NULL DEFAULT '0',
`changed_on` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`option`)
@@ -537,6 +613,8 @@ CREATE TABLE `tasks` (
`recurrence_parent` int(11) DEFAULT NULL,
`recurrence_child` int(11) DEFAULT NULL,
`priority` int(11) DEFAULT '0',
+ `external_provider` varchar(255) DEFAULT NULL,
+ `external_uri` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_task_active` (`is_active`),
KEY `column_id` (`column_id`),
@@ -648,6 +726,7 @@ CREATE TABLE `users` (
`role` varchar(25) NOT NULL DEFAULT 'app-user',
`is_active` tinyint(1) DEFAULT '1',
`avatar_path` varchar(255) DEFAULT NULL,
+ `api_access_token` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `users_username_idx` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
@@ -671,7 +750,7 @@ CREATE TABLE `users` (
LOCK TABLES `settings` WRITE;
/*!40000 ALTER TABLE `settings` DISABLE KEYS */;
-INSERT INTO `settings` VALUES ('api_token','4064ef3d26efa9a0ff78fa7067d8bb9d99323455128edd89e9dc7c53ed76',0,0),('application_currency','USD',0,0),('application_date_format','m/d/Y',0,0),('application_language','en_US',0,0),('application_stylesheet','',0,0),('application_timezone','UTC',0,0),('application_url','',0,0),('board_columns','',0,0),('board_highlight_period','172800',0,0),('board_private_refresh_interval','10',0,0),('board_public_refresh_interval','60',0,0),('calendar_project_tasks','date_started',0,0),('calendar_user_subtasks_time_tracking','0',0,0),('calendar_user_tasks','date_started',0,0),('cfd_include_closed_tasks','1',0,0),('default_color','yellow',0,0),('integration_gravatar','0',0,0),('password_reset','1',0,0),('project_categories','',0,0),('subtask_restriction','0',0,0),('subtask_time_tracking','1',0,0),('webhook_token','c8f53c0bcd8aead902ad04f180ffafd7889b9c0062c2d510e2297ef543b8',0,0),('webhook_url','',0,0);
+INSERT INTO `settings` VALUES ('api_token','b428b1088a5ee28730a8405774084f7a35f27f2a218cdb63582f99c008ee',0,0),('application_currency','USD',0,0),('application_date_format','m/d/Y',0,0),('application_language','en_US',0,0),('application_stylesheet','',0,0),('application_timezone','UTC',0,0),('application_url','',0,0),('board_columns','',0,0),('board_highlight_period','172800',0,0),('board_private_refresh_interval','10',0,0),('board_public_refresh_interval','60',0,0),('calendar_project_tasks','date_started',0,0),('calendar_user_subtasks_time_tracking','0',0,0),('calendar_user_tasks','date_started',0,0),('cfd_include_closed_tasks','1',0,0),('default_color','yellow',0,0),('integration_gravatar','0',0,0),('password_reset','1',0,0),('project_categories','',0,0),('subtask_restriction','0',0,0),('subtask_time_tracking','1',0,0),('webhook_token','e0d3e2613a79f1d751135f4a4d6c3e5b869348db229e57f706b5b54fc3c7',0,0),('webhook_url','',0,0);
/*!40000 ALTER TABLE `settings` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
@@ -700,4 +779,4 @@ UNLOCK TABLES;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-INSERT INTO users (username, password, role) VALUES ('admin', '$2y$10$yUJ9QnhG.f47yO.YvWKo3eMAHULukpluDNTOF9.Z7QQg0vOfFRB6u', 'app-admin');INSERT INTO schema_version VALUES ('112');
+INSERT INTO users (username, password, role) VALUES ('admin', '$2y$10$R3.YibAi6H0ZzzrSHFa7qeaiEqep1X2TF/bKQX5jMQ7fZ9KIfzUte', 'app-admin');INSERT INTO schema_version VALUES ('120');
diff --git a/app/Schema/Sql/postgres.sql b/app/Schema/Sql/postgres.sql
index 0add9c91..8c6b0dd8 100644
--- a/app/Schema/Sql/postgres.sql
+++ b/app/Schema/Sql/postgres.sql
@@ -2,8 +2,8 @@
-- PostgreSQL database dump
--
--- Dumped from database version 9.5.2
--- Dumped by pg_dump version 9.5.2
+-- Dumped from database version 9.6.1
+-- Dumped by pg_dump version 9.6.1
SET statement_timeout = 0;
SET lock_timeout = 0;
@@ -89,6 +89,70 @@ ALTER SEQUENCE "actions_id_seq" OWNED BY "actions"."id";
--
+-- Name: column_has_move_restrictions; Type: TABLE; Schema: public; Owner: -
+--
+
+CREATE TABLE "column_has_move_restrictions" (
+ "restriction_id" integer NOT NULL,
+ "project_id" integer NOT NULL,
+ "role_id" integer NOT NULL,
+ "src_column_id" integer NOT NULL,
+ "dst_column_id" integer NOT NULL
+);
+
+
+--
+-- Name: column_has_move_restrictions_restriction_id_seq; Type: SEQUENCE; Schema: public; Owner: -
+--
+
+CREATE SEQUENCE "column_has_move_restrictions_restriction_id_seq"
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+--
+-- Name: column_has_move_restrictions_restriction_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
+--
+
+ALTER SEQUENCE "column_has_move_restrictions_restriction_id_seq" OWNED BY "column_has_move_restrictions"."restriction_id";
+
+
+--
+-- Name: column_has_restrictions; Type: TABLE; Schema: public; Owner: -
+--
+
+CREATE TABLE "column_has_restrictions" (
+ "restriction_id" integer NOT NULL,
+ "project_id" integer NOT NULL,
+ "role_id" integer NOT NULL,
+ "column_id" integer NOT NULL,
+ "rule" character varying(255) NOT NULL
+);
+
+
+--
+-- Name: column_has_restrictions_restriction_id_seq; Type: SEQUENCE; Schema: public; Owner: -
+--
+
+CREATE SEQUENCE "column_has_restrictions_restriction_id_seq"
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+--
+-- Name: column_has_restrictions_restriction_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
+--
+
+ALTER SEQUENCE "column_has_restrictions_restriction_id_seq" OWNED BY "column_has_restrictions"."restriction_id";
+
+
+--
-- Name: columns; Type: TABLE; Schema: public; Owner: -
--
@@ -132,7 +196,8 @@ CREATE TABLE "comments" (
"user_id" integer DEFAULT 0,
"date_creation" bigint NOT NULL,
"comment" "text",
- "reference" character varying(50) DEFAULT ''::character varying
+ "reference" character varying(50) DEFAULT ''::character varying,
+ "date_modification" bigint
);
@@ -240,6 +305,17 @@ ALTER SEQUENCE "groups_id_seq" OWNED BY "groups"."id";
--
+-- Name: invites; Type: TABLE; Schema: public; Owner: -
+--
+
+CREATE TABLE "invites" (
+ "email" character varying(255) NOT NULL,
+ "project_id" integer NOT NULL,
+ "token" character varying(255) NOT NULL
+);
+
+
+--
-- Name: last_logins; Type: TABLE; Schema: public; Owner: -
--
@@ -499,7 +575,7 @@ ALTER SEQUENCE "project_has_files_id_seq" OWNED BY "project_has_files"."id";
CREATE TABLE "project_has_groups" (
"group_id" integer NOT NULL,
"project_id" integer NOT NULL,
- "role" character varying(25) NOT NULL
+ "role" character varying(255) NOT NULL
);
@@ -547,17 +623,78 @@ ALTER SEQUENCE "project_has_notification_types_id_seq" OWNED BY "project_has_not
--
+-- Name: project_has_roles; Type: TABLE; Schema: public; Owner: -
+--
+
+CREATE TABLE "project_has_roles" (
+ "role_id" integer NOT NULL,
+ "role" character varying(255) NOT NULL,
+ "project_id" integer NOT NULL
+);
+
+
+--
+-- Name: project_has_roles_role_id_seq; Type: SEQUENCE; Schema: public; Owner: -
+--
+
+CREATE SEQUENCE "project_has_roles_role_id_seq"
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+--
+-- Name: project_has_roles_role_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
+--
+
+ALTER SEQUENCE "project_has_roles_role_id_seq" OWNED BY "project_has_roles"."role_id";
+
+
+--
-- Name: project_has_users; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE "project_has_users" (
"project_id" integer NOT NULL,
"user_id" integer NOT NULL,
- "role" character varying(25) DEFAULT 'project-viewer'::character varying NOT NULL
+ "role" character varying(255) DEFAULT 'project-viewer'::character varying NOT NULL
);
--
+-- Name: project_role_has_restrictions; Type: TABLE; Schema: public; Owner: -
+--
+
+CREATE TABLE "project_role_has_restrictions" (
+ "restriction_id" integer NOT NULL,
+ "project_id" integer NOT NULL,
+ "role_id" integer NOT NULL,
+ "rule" character varying(255) NOT NULL
+);
+
+
+--
+-- Name: project_role_has_restrictions_restriction_id_seq; Type: SEQUENCE; Schema: public; Owner: -
+--
+
+CREATE SEQUENCE "project_role_has_restrictions_restriction_id_seq"
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+--
+-- Name: project_role_has_restrictions_restriction_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
+--
+
+ALTER SEQUENCE "project_role_has_restrictions_restriction_id_seq" OWNED BY "project_role_has_restrictions"."restriction_id";
+
+
+--
-- Name: projects; Type: TABLE; Schema: public; Owner: -
--
@@ -652,7 +789,7 @@ CREATE TABLE "schema_version" (
CREATE TABLE "settings" (
"option" character varying(100) NOT NULL,
- "value" character varying(255) DEFAULT ''::character varying,
+ "value" "text" DEFAULT ''::character varying,
"changed_by" integer DEFAULT 0 NOT NULL,
"changed_on" integer DEFAULT 0 NOT NULL
);
@@ -948,7 +1085,9 @@ CREATE TABLE "tasks" (
"recurrence_basedate" integer DEFAULT 0 NOT NULL,
"recurrence_parent" integer,
"recurrence_child" integer,
- "priority" integer DEFAULT 0
+ "priority" integer DEFAULT 0,
+ "external_provider" character varying(255),
+ "external_uri" character varying(255)
);
@@ -1117,7 +1256,8 @@ CREATE TABLE "users" (
"gitlab_id" integer,
"role" character varying(25) DEFAULT 'app-user'::character varying NOT NULL,
"is_active" boolean DEFAULT true,
- "avatar_path" character varying(255)
+ "avatar_path" character varying(255),
+ "api_access_token" character varying(255) DEFAULT NULL::character varying
);
@@ -1141,203 +1281,231 @@ ALTER SEQUENCE "users_id_seq" OWNED BY "users"."id";
--
--- Name: id; Type: DEFAULT; Schema: public; Owner: -
+-- Name: action_has_params id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY "action_has_params" ALTER COLUMN "id" SET DEFAULT "nextval"('"action_has_params_id_seq"'::"regclass");
--
--- Name: id; Type: DEFAULT; Schema: public; Owner: -
+-- Name: actions id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY "actions" ALTER COLUMN "id" SET DEFAULT "nextval"('"actions_id_seq"'::"regclass");
--
--- Name: id; Type: DEFAULT; Schema: public; Owner: -
+-- Name: column_has_move_restrictions restriction_id; Type: DEFAULT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY "column_has_move_restrictions" ALTER COLUMN "restriction_id" SET DEFAULT "nextval"('"column_has_move_restrictions_restriction_id_seq"'::"regclass");
+
+
+--
+-- Name: column_has_restrictions restriction_id; Type: DEFAULT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY "column_has_restrictions" ALTER COLUMN "restriction_id" SET DEFAULT "nextval"('"column_has_restrictions_restriction_id_seq"'::"regclass");
+
+
+--
+-- Name: columns id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY "columns" ALTER COLUMN "id" SET DEFAULT "nextval"('"columns_id_seq"'::"regclass");
--
--- Name: id; Type: DEFAULT; Schema: public; Owner: -
+-- Name: comments id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY "comments" ALTER COLUMN "id" SET DEFAULT "nextval"('"comments_id_seq"'::"regclass");
--
--- Name: id; Type: DEFAULT; Schema: public; Owner: -
+-- Name: custom_filters id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY "custom_filters" ALTER COLUMN "id" SET DEFAULT "nextval"('"custom_filters_id_seq"'::"regclass");
--
--- Name: id; Type: DEFAULT; Schema: public; Owner: -
+-- Name: groups id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY "groups" ALTER COLUMN "id" SET DEFAULT "nextval"('"groups_id_seq"'::"regclass");
--
--- Name: id; Type: DEFAULT; Schema: public; Owner: -
+-- Name: last_logins id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY "last_logins" ALTER COLUMN "id" SET DEFAULT "nextval"('"last_logins_id_seq"'::"regclass");
--
--- Name: id; Type: DEFAULT; Schema: public; Owner: -
+-- Name: links id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY "links" ALTER COLUMN "id" SET DEFAULT "nextval"('"links_id_seq"'::"regclass");
--
--- Name: id; Type: DEFAULT; Schema: public; Owner: -
+-- Name: project_activities id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY "project_activities" ALTER COLUMN "id" SET DEFAULT "nextval"('"project_activities_id_seq"'::"regclass");
--
--- Name: id; Type: DEFAULT; Schema: public; Owner: -
+-- Name: project_daily_column_stats id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY "project_daily_column_stats" ALTER COLUMN "id" SET DEFAULT "nextval"('"project_daily_summaries_id_seq"'::"regclass");
--
--- Name: id; Type: DEFAULT; Schema: public; Owner: -
+-- Name: project_daily_stats id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY "project_daily_stats" ALTER COLUMN "id" SET DEFAULT "nextval"('"project_daily_stats_id_seq"'::"regclass");
--
--- Name: id; Type: DEFAULT; Schema: public; Owner: -
+-- Name: project_has_categories id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY "project_has_categories" ALTER COLUMN "id" SET DEFAULT "nextval"('"project_has_categories_id_seq"'::"regclass");
--
--- Name: id; Type: DEFAULT; Schema: public; Owner: -
+-- Name: project_has_files id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY "project_has_files" ALTER COLUMN "id" SET DEFAULT "nextval"('"project_has_files_id_seq"'::"regclass");
--
--- Name: id; Type: DEFAULT; Schema: public; Owner: -
+-- Name: project_has_notification_types id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY "project_has_notification_types" ALTER COLUMN "id" SET DEFAULT "nextval"('"project_has_notification_types_id_seq"'::"regclass");
--
--- Name: id; Type: DEFAULT; Schema: public; Owner: -
+-- Name: project_has_roles role_id; Type: DEFAULT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY "project_has_roles" ALTER COLUMN "role_id" SET DEFAULT "nextval"('"project_has_roles_role_id_seq"'::"regclass");
+
+
+--
+-- Name: project_role_has_restrictions restriction_id; Type: DEFAULT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY "project_role_has_restrictions" ALTER COLUMN "restriction_id" SET DEFAULT "nextval"('"project_role_has_restrictions_restriction_id_seq"'::"regclass");
+
+
+--
+-- Name: projects id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY "projects" ALTER COLUMN "id" SET DEFAULT "nextval"('"projects_id_seq"'::"regclass");
--
--- Name: id; Type: DEFAULT; Schema: public; Owner: -
+-- Name: remember_me id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY "remember_me" ALTER COLUMN "id" SET DEFAULT "nextval"('"remember_me_id_seq"'::"regclass");
--
--- Name: id; Type: DEFAULT; Schema: public; Owner: -
+-- Name: subtask_time_tracking id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY "subtask_time_tracking" ALTER COLUMN "id" SET DEFAULT "nextval"('"subtask_time_tracking_id_seq"'::"regclass");
--
--- Name: id; Type: DEFAULT; Schema: public; Owner: -
+-- Name: subtasks id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY "subtasks" ALTER COLUMN "id" SET DEFAULT "nextval"('"task_has_subtasks_id_seq"'::"regclass");
--
--- Name: id; Type: DEFAULT; Schema: public; Owner: -
+-- Name: swimlanes id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY "swimlanes" ALTER COLUMN "id" SET DEFAULT "nextval"('"swimlanes_id_seq"'::"regclass");
--
--- Name: id; Type: DEFAULT; Schema: public; Owner: -
+-- Name: tags id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY "tags" ALTER COLUMN "id" SET DEFAULT "nextval"('"tags_id_seq"'::"regclass");
--
--- Name: id; Type: DEFAULT; Schema: public; Owner: -
+-- Name: task_has_external_links id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY "task_has_external_links" ALTER COLUMN "id" SET DEFAULT "nextval"('"task_has_external_links_id_seq"'::"regclass");
--
--- Name: id; Type: DEFAULT; Schema: public; Owner: -
+-- Name: task_has_files id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY "task_has_files" ALTER COLUMN "id" SET DEFAULT "nextval"('"task_has_files_id_seq"'::"regclass");
--
--- Name: id; Type: DEFAULT; Schema: public; Owner: -
+-- Name: task_has_links id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY "task_has_links" ALTER COLUMN "id" SET DEFAULT "nextval"('"task_has_links_id_seq"'::"regclass");
--
--- Name: id; Type: DEFAULT; Schema: public; Owner: -
+-- Name: tasks id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY "tasks" ALTER COLUMN "id" SET DEFAULT "nextval"('"tasks_id_seq"'::"regclass");
--
--- Name: id; Type: DEFAULT; Schema: public; Owner: -
+-- Name: transitions id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY "transitions" ALTER COLUMN "id" SET DEFAULT "nextval"('"transitions_id_seq"'::"regclass");
--
--- Name: id; Type: DEFAULT; Schema: public; Owner: -
+-- Name: user_has_notification_types id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY "user_has_notification_types" ALTER COLUMN "id" SET DEFAULT "nextval"('"user_has_notification_types_id_seq"'::"regclass");
--
--- Name: id; Type: DEFAULT; Schema: public; Owner: -
+-- Name: user_has_unread_notifications id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY "user_has_unread_notifications" ALTER COLUMN "id" SET DEFAULT "nextval"('"user_has_unread_notifications_id_seq"'::"regclass");
--
--- Name: id; Type: DEFAULT; Schema: public; Owner: -
+-- Name: users id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY "users" ALTER COLUMN "id" SET DEFAULT "nextval"('"users_id_seq"'::"regclass");
--
--- Name: action_has_params_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: action_has_params action_has_params_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "action_has_params"
@@ -1345,7 +1513,7 @@ ALTER TABLE ONLY "action_has_params"
--
--- Name: actions_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: actions actions_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "actions"
@@ -1353,7 +1521,39 @@ ALTER TABLE ONLY "actions"
--
--- Name: columns_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: column_has_move_restrictions column_has_move_restrictions_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY "column_has_move_restrictions"
+ ADD CONSTRAINT "column_has_move_restrictions_pkey" PRIMARY KEY ("restriction_id");
+
+
+--
+-- Name: column_has_move_restrictions column_has_move_restrictions_role_id_src_column_id_dst_colu_key; Type: CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY "column_has_move_restrictions"
+ ADD CONSTRAINT "column_has_move_restrictions_role_id_src_column_id_dst_colu_key" UNIQUE ("role_id", "src_column_id", "dst_column_id");
+
+
+--
+-- Name: column_has_restrictions column_has_restrictions_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY "column_has_restrictions"
+ ADD CONSTRAINT "column_has_restrictions_pkey" PRIMARY KEY ("restriction_id");
+
+
+--
+-- Name: column_has_restrictions column_has_restrictions_role_id_column_id_rule_key; Type: CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY "column_has_restrictions"
+ ADD CONSTRAINT "column_has_restrictions_role_id_column_id_rule_key" UNIQUE ("role_id", "column_id", "rule");
+
+
+--
+-- Name: columns columns_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "columns"
@@ -1361,7 +1561,7 @@ ALTER TABLE ONLY "columns"
--
--- Name: columns_title_project_id_key; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: columns columns_title_project_id_key; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "columns"
@@ -1369,7 +1569,7 @@ ALTER TABLE ONLY "columns"
--
--- Name: comments_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: comments comments_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "comments"
@@ -1377,7 +1577,7 @@ ALTER TABLE ONLY "comments"
--
--- Name: currencies_currency_key; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: currencies currencies_currency_key; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "currencies"
@@ -1385,7 +1585,7 @@ ALTER TABLE ONLY "currencies"
--
--- Name: custom_filters_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: custom_filters custom_filters_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "custom_filters"
@@ -1393,7 +1593,7 @@ ALTER TABLE ONLY "custom_filters"
--
--- Name: group_has_users_group_id_user_id_key; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: group_has_users group_has_users_group_id_user_id_key; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "group_has_users"
@@ -1401,7 +1601,7 @@ ALTER TABLE ONLY "group_has_users"
--
--- Name: groups_name_key; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: groups groups_name_key; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "groups"
@@ -1409,7 +1609,7 @@ ALTER TABLE ONLY "groups"
--
--- Name: groups_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: groups groups_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "groups"
@@ -1417,7 +1617,15 @@ ALTER TABLE ONLY "groups"
--
--- Name: last_logins_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: invites invites_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY "invites"
+ ADD CONSTRAINT "invites_pkey" PRIMARY KEY ("email", "token");
+
+
+--
+-- Name: last_logins last_logins_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "last_logins"
@@ -1425,7 +1633,7 @@ ALTER TABLE ONLY "last_logins"
--
--- Name: links_label_key; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: links links_label_key; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "links"
@@ -1433,7 +1641,7 @@ ALTER TABLE ONLY "links"
--
--- Name: links_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: links links_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "links"
@@ -1441,7 +1649,7 @@ ALTER TABLE ONLY "links"
--
--- Name: password_reset_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: password_reset password_reset_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "password_reset"
@@ -1449,7 +1657,7 @@ ALTER TABLE ONLY "password_reset"
--
--- Name: plugin_schema_versions_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: plugin_schema_versions plugin_schema_versions_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "plugin_schema_versions"
@@ -1457,7 +1665,7 @@ ALTER TABLE ONLY "plugin_schema_versions"
--
--- Name: project_activities_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: project_activities project_activities_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "project_activities"
@@ -1465,7 +1673,7 @@ ALTER TABLE ONLY "project_activities"
--
--- Name: project_daily_stats_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: project_daily_stats project_daily_stats_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "project_daily_stats"
@@ -1473,7 +1681,7 @@ ALTER TABLE ONLY "project_daily_stats"
--
--- Name: project_daily_summaries_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: project_daily_column_stats project_daily_summaries_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "project_daily_column_stats"
@@ -1481,7 +1689,7 @@ ALTER TABLE ONLY "project_daily_column_stats"
--
--- Name: project_has_categories_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: project_has_categories project_has_categories_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "project_has_categories"
@@ -1489,7 +1697,7 @@ ALTER TABLE ONLY "project_has_categories"
--
--- Name: project_has_categories_project_id_name_key; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: project_has_categories project_has_categories_project_id_name_key; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "project_has_categories"
@@ -1497,7 +1705,7 @@ ALTER TABLE ONLY "project_has_categories"
--
--- Name: project_has_files_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: project_has_files project_has_files_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "project_has_files"
@@ -1505,7 +1713,7 @@ ALTER TABLE ONLY "project_has_files"
--
--- Name: project_has_groups_group_id_project_id_key; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: project_has_groups project_has_groups_group_id_project_id_key; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "project_has_groups"
@@ -1513,7 +1721,7 @@ ALTER TABLE ONLY "project_has_groups"
--
--- Name: project_has_metadata_project_id_name_key; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: project_has_metadata project_has_metadata_project_id_name_key; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "project_has_metadata"
@@ -1521,7 +1729,7 @@ ALTER TABLE ONLY "project_has_metadata"
--
--- Name: project_has_notification_types_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: project_has_notification_types project_has_notification_types_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "project_has_notification_types"
@@ -1529,7 +1737,7 @@ ALTER TABLE ONLY "project_has_notification_types"
--
--- Name: project_has_notification_types_project_id_notification_type_key; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: project_has_notification_types project_has_notification_types_project_id_notification_type_key; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "project_has_notification_types"
@@ -1537,7 +1745,23 @@ ALTER TABLE ONLY "project_has_notification_types"
--
--- Name: project_has_users_project_id_user_id_key; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: project_has_roles project_has_roles_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY "project_has_roles"
+ ADD CONSTRAINT "project_has_roles_pkey" PRIMARY KEY ("role_id");
+
+
+--
+-- Name: project_has_roles project_has_roles_project_id_role_key; Type: CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY "project_has_roles"
+ ADD CONSTRAINT "project_has_roles_project_id_role_key" UNIQUE ("project_id", "role");
+
+
+--
+-- Name: project_has_users project_has_users_project_id_user_id_key; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "project_has_users"
@@ -1545,7 +1769,23 @@ ALTER TABLE ONLY "project_has_users"
--
--- Name: projects_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: project_role_has_restrictions project_role_has_restrictions_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY "project_role_has_restrictions"
+ ADD CONSTRAINT "project_role_has_restrictions_pkey" PRIMARY KEY ("restriction_id");
+
+
+--
+-- Name: project_role_has_restrictions project_role_has_restrictions_role_id_rule_key; Type: CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY "project_role_has_restrictions"
+ ADD CONSTRAINT "project_role_has_restrictions_role_id_rule_key" UNIQUE ("role_id", "rule");
+
+
+--
+-- Name: projects projects_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "projects"
@@ -1553,7 +1793,7 @@ ALTER TABLE ONLY "projects"
--
--- Name: remember_me_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: remember_me remember_me_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "remember_me"
@@ -1561,7 +1801,7 @@ ALTER TABLE ONLY "remember_me"
--
--- Name: settings_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: settings settings_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "settings"
@@ -1569,7 +1809,7 @@ ALTER TABLE ONLY "settings"
--
--- Name: subtask_time_tracking_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: subtask_time_tracking subtask_time_tracking_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "subtask_time_tracking"
@@ -1577,7 +1817,7 @@ ALTER TABLE ONLY "subtask_time_tracking"
--
--- Name: swimlanes_name_project_id_key; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: swimlanes swimlanes_name_project_id_key; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "swimlanes"
@@ -1585,7 +1825,7 @@ ALTER TABLE ONLY "swimlanes"
--
--- Name: swimlanes_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: swimlanes swimlanes_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "swimlanes"
@@ -1593,7 +1833,7 @@ ALTER TABLE ONLY "swimlanes"
--
--- Name: tags_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: tags tags_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "tags"
@@ -1601,7 +1841,7 @@ ALTER TABLE ONLY "tags"
--
--- Name: tags_project_id_name_key; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: tags tags_project_id_name_key; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "tags"
@@ -1609,7 +1849,7 @@ ALTER TABLE ONLY "tags"
--
--- Name: task_has_external_links_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: task_has_external_links task_has_external_links_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "task_has_external_links"
@@ -1617,7 +1857,7 @@ ALTER TABLE ONLY "task_has_external_links"
--
--- Name: task_has_files_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: task_has_files task_has_files_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "task_has_files"
@@ -1625,7 +1865,7 @@ ALTER TABLE ONLY "task_has_files"
--
--- Name: task_has_links_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: task_has_links task_has_links_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "task_has_links"
@@ -1633,7 +1873,7 @@ ALTER TABLE ONLY "task_has_links"
--
--- Name: task_has_metadata_task_id_name_key; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: task_has_metadata task_has_metadata_task_id_name_key; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "task_has_metadata"
@@ -1641,7 +1881,7 @@ ALTER TABLE ONLY "task_has_metadata"
--
--- Name: task_has_subtasks_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: subtasks task_has_subtasks_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "subtasks"
@@ -1649,7 +1889,7 @@ ALTER TABLE ONLY "subtasks"
--
--- Name: task_has_tags_tag_id_task_id_key; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: task_has_tags task_has_tags_tag_id_task_id_key; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "task_has_tags"
@@ -1657,7 +1897,7 @@ ALTER TABLE ONLY "task_has_tags"
--
--- Name: tasks_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: tasks tasks_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "tasks"
@@ -1665,7 +1905,7 @@ ALTER TABLE ONLY "tasks"
--
--- Name: transitions_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: transitions transitions_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "transitions"
@@ -1673,7 +1913,7 @@ ALTER TABLE ONLY "transitions"
--
--- Name: user_has_metadata_user_id_name_key; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: user_has_metadata user_has_metadata_user_id_name_key; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "user_has_metadata"
@@ -1681,7 +1921,7 @@ ALTER TABLE ONLY "user_has_metadata"
--
--- Name: user_has_notification_types_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: user_has_notification_types user_has_notification_types_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "user_has_notification_types"
@@ -1689,7 +1929,7 @@ ALTER TABLE ONLY "user_has_notification_types"
--
--- Name: user_has_notifications_project_id_user_id_key; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: user_has_notifications user_has_notifications_project_id_user_id_key; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "user_has_notifications"
@@ -1697,7 +1937,7 @@ ALTER TABLE ONLY "user_has_notifications"
--
--- Name: user_has_unread_notifications_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: user_has_unread_notifications user_has_unread_notifications_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "user_has_unread_notifications"
@@ -1705,7 +1945,7 @@ ALTER TABLE ONLY "user_has_unread_notifications"
--
--- Name: users_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+-- Name: users users_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "users"
@@ -1839,7 +2079,7 @@ CREATE UNIQUE INDEX "users_username_idx" ON "users" USING "btree" ("username");
--
--- Name: action_has_params_action_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: action_has_params action_has_params_action_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "action_has_params"
@@ -1847,7 +2087,7 @@ ALTER TABLE ONLY "action_has_params"
--
--- Name: actions_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: actions actions_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "actions"
@@ -1855,7 +2095,63 @@ ALTER TABLE ONLY "actions"
--
--- Name: columns_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: column_has_move_restrictions column_has_move_restrictions_dst_column_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY "column_has_move_restrictions"
+ ADD CONSTRAINT "column_has_move_restrictions_dst_column_id_fkey" FOREIGN KEY ("dst_column_id") REFERENCES "columns"("id") ON DELETE CASCADE;
+
+
+--
+-- Name: column_has_move_restrictions column_has_move_restrictions_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY "column_has_move_restrictions"
+ ADD CONSTRAINT "column_has_move_restrictions_project_id_fkey" FOREIGN KEY ("project_id") REFERENCES "projects"("id") ON DELETE CASCADE;
+
+
+--
+-- Name: column_has_move_restrictions column_has_move_restrictions_role_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY "column_has_move_restrictions"
+ ADD CONSTRAINT "column_has_move_restrictions_role_id_fkey" FOREIGN KEY ("role_id") REFERENCES "project_has_roles"("role_id") ON DELETE CASCADE;
+
+
+--
+-- Name: column_has_move_restrictions column_has_move_restrictions_src_column_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY "column_has_move_restrictions"
+ ADD CONSTRAINT "column_has_move_restrictions_src_column_id_fkey" FOREIGN KEY ("src_column_id") REFERENCES "columns"("id") ON DELETE CASCADE;
+
+
+--
+-- Name: column_has_restrictions column_has_restrictions_column_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY "column_has_restrictions"
+ ADD CONSTRAINT "column_has_restrictions_column_id_fkey" FOREIGN KEY ("column_id") REFERENCES "columns"("id") ON DELETE CASCADE;
+
+
+--
+-- Name: column_has_restrictions column_has_restrictions_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY "column_has_restrictions"
+ ADD CONSTRAINT "column_has_restrictions_project_id_fkey" FOREIGN KEY ("project_id") REFERENCES "projects"("id") ON DELETE CASCADE;
+
+
+--
+-- Name: column_has_restrictions column_has_restrictions_role_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY "column_has_restrictions"
+ ADD CONSTRAINT "column_has_restrictions_role_id_fkey" FOREIGN KEY ("role_id") REFERENCES "project_has_roles"("role_id") ON DELETE CASCADE;
+
+
+--
+-- Name: columns columns_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "columns"
@@ -1863,7 +2159,7 @@ ALTER TABLE ONLY "columns"
--
--- Name: comments_task_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: comments comments_task_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "comments"
@@ -1871,7 +2167,7 @@ ALTER TABLE ONLY "comments"
--
--- Name: group_has_users_group_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: group_has_users group_has_users_group_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "group_has_users"
@@ -1879,7 +2175,7 @@ ALTER TABLE ONLY "group_has_users"
--
--- Name: group_has_users_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: group_has_users group_has_users_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "group_has_users"
@@ -1887,7 +2183,7 @@ ALTER TABLE ONLY "group_has_users"
--
--- Name: last_logins_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: last_logins last_logins_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "last_logins"
@@ -1895,7 +2191,7 @@ ALTER TABLE ONLY "last_logins"
--
--- Name: password_reset_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: password_reset password_reset_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "password_reset"
@@ -1903,7 +2199,7 @@ ALTER TABLE ONLY "password_reset"
--
--- Name: project_activities_creator_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: project_activities project_activities_creator_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "project_activities"
@@ -1911,7 +2207,7 @@ ALTER TABLE ONLY "project_activities"
--
--- Name: project_activities_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: project_activities project_activities_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "project_activities"
@@ -1919,7 +2215,7 @@ ALTER TABLE ONLY "project_activities"
--
--- Name: project_activities_task_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: project_activities project_activities_task_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "project_activities"
@@ -1927,7 +2223,7 @@ ALTER TABLE ONLY "project_activities"
--
--- Name: project_daily_stats_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: project_daily_stats project_daily_stats_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "project_daily_stats"
@@ -1935,7 +2231,7 @@ ALTER TABLE ONLY "project_daily_stats"
--
--- Name: project_daily_summaries_column_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: project_daily_column_stats project_daily_summaries_column_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "project_daily_column_stats"
@@ -1943,7 +2239,7 @@ ALTER TABLE ONLY "project_daily_column_stats"
--
--- Name: project_daily_summaries_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: project_daily_column_stats project_daily_summaries_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "project_daily_column_stats"
@@ -1951,7 +2247,7 @@ ALTER TABLE ONLY "project_daily_column_stats"
--
--- Name: project_has_categories_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: project_has_categories project_has_categories_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "project_has_categories"
@@ -1959,7 +2255,7 @@ ALTER TABLE ONLY "project_has_categories"
--
--- Name: project_has_files_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: project_has_files project_has_files_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "project_has_files"
@@ -1967,7 +2263,7 @@ ALTER TABLE ONLY "project_has_files"
--
--- Name: project_has_groups_group_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: project_has_groups project_has_groups_group_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "project_has_groups"
@@ -1975,7 +2271,7 @@ ALTER TABLE ONLY "project_has_groups"
--
--- Name: project_has_groups_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: project_has_groups project_has_groups_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "project_has_groups"
@@ -1983,7 +2279,7 @@ ALTER TABLE ONLY "project_has_groups"
--
--- Name: project_has_metadata_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: project_has_metadata project_has_metadata_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "project_has_metadata"
@@ -1991,7 +2287,7 @@ ALTER TABLE ONLY "project_has_metadata"
--
--- Name: project_has_notification_types_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: project_has_notification_types project_has_notification_types_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "project_has_notification_types"
@@ -1999,7 +2295,15 @@ ALTER TABLE ONLY "project_has_notification_types"
--
--- Name: project_has_users_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: project_has_roles project_has_roles_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY "project_has_roles"
+ ADD CONSTRAINT "project_has_roles_project_id_fkey" FOREIGN KEY ("project_id") REFERENCES "projects"("id") ON DELETE CASCADE;
+
+
+--
+-- Name: project_has_users project_has_users_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "project_has_users"
@@ -2007,7 +2311,7 @@ ALTER TABLE ONLY "project_has_users"
--
--- Name: project_has_users_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: project_has_users project_has_users_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "project_has_users"
@@ -2015,7 +2319,23 @@ ALTER TABLE ONLY "project_has_users"
--
--- Name: remember_me_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: project_role_has_restrictions project_role_has_restrictions_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY "project_role_has_restrictions"
+ ADD CONSTRAINT "project_role_has_restrictions_project_id_fkey" FOREIGN KEY ("project_id") REFERENCES "projects"("id") ON DELETE CASCADE;
+
+
+--
+-- Name: project_role_has_restrictions project_role_has_restrictions_role_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY "project_role_has_restrictions"
+ ADD CONSTRAINT "project_role_has_restrictions_role_id_fkey" FOREIGN KEY ("role_id") REFERENCES "project_has_roles"("role_id") ON DELETE CASCADE;
+
+
+--
+-- Name: remember_me remember_me_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "remember_me"
@@ -2023,7 +2343,7 @@ ALTER TABLE ONLY "remember_me"
--
--- Name: subtask_time_tracking_subtask_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: subtask_time_tracking subtask_time_tracking_subtask_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "subtask_time_tracking"
@@ -2031,7 +2351,7 @@ ALTER TABLE ONLY "subtask_time_tracking"
--
--- Name: subtask_time_tracking_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: subtask_time_tracking subtask_time_tracking_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "subtask_time_tracking"
@@ -2039,7 +2359,7 @@ ALTER TABLE ONLY "subtask_time_tracking"
--
--- Name: swimlanes_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: swimlanes swimlanes_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "swimlanes"
@@ -2047,7 +2367,7 @@ ALTER TABLE ONLY "swimlanes"
--
--- Name: task_has_external_links_task_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: task_has_external_links task_has_external_links_task_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "task_has_external_links"
@@ -2055,7 +2375,7 @@ ALTER TABLE ONLY "task_has_external_links"
--
--- Name: task_has_files_task_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: task_has_files task_has_files_task_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "task_has_files"
@@ -2063,7 +2383,7 @@ ALTER TABLE ONLY "task_has_files"
--
--- Name: task_has_links_link_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: task_has_links task_has_links_link_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "task_has_links"
@@ -2071,7 +2391,7 @@ ALTER TABLE ONLY "task_has_links"
--
--- Name: task_has_links_opposite_task_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: task_has_links task_has_links_opposite_task_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "task_has_links"
@@ -2079,7 +2399,7 @@ ALTER TABLE ONLY "task_has_links"
--
--- Name: task_has_links_task_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: task_has_links task_has_links_task_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "task_has_links"
@@ -2087,7 +2407,7 @@ ALTER TABLE ONLY "task_has_links"
--
--- Name: task_has_metadata_task_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: task_has_metadata task_has_metadata_task_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "task_has_metadata"
@@ -2095,7 +2415,7 @@ ALTER TABLE ONLY "task_has_metadata"
--
--- Name: task_has_subtasks_task_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: subtasks task_has_subtasks_task_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "subtasks"
@@ -2103,7 +2423,7 @@ ALTER TABLE ONLY "subtasks"
--
--- Name: task_has_tags_tag_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: task_has_tags task_has_tags_tag_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "task_has_tags"
@@ -2111,7 +2431,7 @@ ALTER TABLE ONLY "task_has_tags"
--
--- Name: task_has_tags_task_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: task_has_tags task_has_tags_task_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "task_has_tags"
@@ -2119,7 +2439,7 @@ ALTER TABLE ONLY "task_has_tags"
--
--- Name: tasks_column_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: tasks tasks_column_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "tasks"
@@ -2127,7 +2447,7 @@ ALTER TABLE ONLY "tasks"
--
--- Name: tasks_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: tasks tasks_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "tasks"
@@ -2135,7 +2455,7 @@ ALTER TABLE ONLY "tasks"
--
--- Name: transitions_dst_column_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: transitions transitions_dst_column_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "transitions"
@@ -2143,7 +2463,7 @@ ALTER TABLE ONLY "transitions"
--
--- Name: transitions_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: transitions transitions_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "transitions"
@@ -2151,7 +2471,7 @@ ALTER TABLE ONLY "transitions"
--
--- Name: transitions_src_column_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: transitions transitions_src_column_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "transitions"
@@ -2159,7 +2479,7 @@ ALTER TABLE ONLY "transitions"
--
--- Name: transitions_task_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: transitions transitions_task_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "transitions"
@@ -2167,7 +2487,7 @@ ALTER TABLE ONLY "transitions"
--
--- Name: transitions_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: transitions transitions_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "transitions"
@@ -2175,7 +2495,7 @@ ALTER TABLE ONLY "transitions"
--
--- Name: user_has_metadata_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: user_has_metadata user_has_metadata_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "user_has_metadata"
@@ -2183,7 +2503,7 @@ ALTER TABLE ONLY "user_has_metadata"
--
--- Name: user_has_notification_types_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: user_has_notification_types user_has_notification_types_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "user_has_notification_types"
@@ -2191,7 +2511,7 @@ ALTER TABLE ONLY "user_has_notification_types"
--
--- Name: user_has_notifications_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: user_has_notifications user_has_notifications_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "user_has_notifications"
@@ -2199,7 +2519,7 @@ ALTER TABLE ONLY "user_has_notifications"
--
--- Name: user_has_notifications_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: user_has_notifications user_has_notifications_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "user_has_notifications"
@@ -2207,7 +2527,7 @@ ALTER TABLE ONLY "user_has_notifications"
--
--- Name: user_has_unread_notifications_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
+-- Name: user_has_unread_notifications user_has_unread_notifications_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY "user_has_unread_notifications"
@@ -2222,8 +2542,8 @@ ALTER TABLE ONLY "user_has_unread_notifications"
-- PostgreSQL database dump
--
--- Dumped from database version 9.5.2
--- Dumped by pg_dump version 9.5.2
+-- Dumped from database version 9.6.1
+-- Dumped by pg_dump version 9.6.1
SET statement_timeout = 0;
SET lock_timeout = 0;
@@ -2243,8 +2563,8 @@ INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('board_high
INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('board_public_refresh_interval', '60', 0, 0);
INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('board_private_refresh_interval', '10', 0, 0);
INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('board_columns', '', 0, 0);
-INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('webhook_token', 'c9a7c2a4523f1724b2ca047c5685f8e2b26bba47eb69baf4f22d5d50d837', 0, 0);
-INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('api_token', 'c57a6cb1789269547b616454e4e2f06d3de0514f83baf8fa5b5a8af44a08', 0, 0);
+INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('webhook_token', 'a41accd9dabc3d45a3d26de5edd5c43b3b0082cabebfbc7a175b8d6b2e5a', 0, 0);
+INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('api_token', 'dbbf966938e4400746ebcb2337bb4a3cdce0bab2dd053d57dbbc243ccc9d', 0, 0);
INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('application_language', 'en_US', 0, 0);
INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('application_timezone', 'UTC', 0, 0);
INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('application_url', '', 0, 0);
@@ -2272,8 +2592,8 @@ INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('password_r
-- PostgreSQL database dump
--
--- Dumped from database version 9.5.2
--- Dumped by pg_dump version 9.5.2
+-- Dumped from database version 9.6.1
+-- Dumped by pg_dump version 9.6.1
SET statement_timeout = 0;
SET lock_timeout = 0;
@@ -2313,4 +2633,4 @@ SELECT pg_catalog.setval('links_id_seq', 11, true);
-- PostgreSQL database dump complete
--
-INSERT INTO users (username, password, role) VALUES ('admin', '$2y$10$yUJ9QnhG.f47yO.YvWKo3eMAHULukpluDNTOF9.Z7QQg0vOfFRB6u', 'app-admin');INSERT INTO schema_version VALUES ('91');
+INSERT INTO users (username, password, role) VALUES ('admin', '$2y$10$R3.YibAi6H0ZzzrSHFa7qeaiEqep1X2TF/bKQX5jMQ7fZ9KIfzUte', 'app-admin');INSERT INTO schema_version VALUES ('99');
diff --git a/app/Schema/Sqlite.php b/app/Schema/Sqlite.php
index f86a6af0..a68ed418 100644
--- a/app/Schema/Sqlite.php
+++ b/app/Schema/Sqlite.php
@@ -6,7 +6,43 @@ use Kanboard\Core\Security\Token;
use Kanboard\Core\Security\Role;
use PDO;
-const VERSION = 106;
+const VERSION = 111;
+
+function version_111(PDO $pdo)
+{
+ $pdo->exec('ALTER TABLE "projects" ADD COLUMN email TEXT');
+}
+
+function version_110(PDO $pdo)
+{
+ $pdo->exec("
+ CREATE TABLE invites (
+ email TEXT NOT NULL,
+ project_id INTEGER NOT NULL,
+ token TEXT NOT NULL,
+ PRIMARY KEY(email, token)
+ )
+ ");
+
+ $pdo->exec("DELETE FROM settings WHERE \"option\"='application_datetime_format'");
+}
+
+function version_109(PDO $pdo)
+{
+ $pdo->exec('ALTER TABLE comments ADD COLUMN date_modification INTEGER');
+ $pdo->exec('UPDATE comments SET date_modification = date_creation WHERE date_modification IS NULL;');
+}
+
+function version_108(PDO $pdo)
+{
+ $pdo->exec('ALTER TABLE users ADD COLUMN api_access_token VARCHAR(255) DEFAULT NULL');
+}
+
+function version_107(PDO $pdo)
+{
+ $pdo->exec("ALTER TABLE tasks ADD COLUMN external_provider TEXT");
+ $pdo->exec("ALTER TABLE tasks ADD COLUMN external_uri TEXT");
+}
function version_106(PDO $pdo)
{
diff --git a/app/ServiceProvider/ApiProvider.php b/app/ServiceProvider/ApiProvider.php
index d5d1f260..2c9abec7 100644
--- a/app/ServiceProvider/ApiProvider.php
+++ b/app/ServiceProvider/ApiProvider.php
@@ -10,6 +10,7 @@ use Kanboard\Api\Procedure\CategoryProcedure;
use Kanboard\Api\Procedure\ColumnProcedure;
use Kanboard\Api\Procedure\CommentProcedure;
use Kanboard\Api\Procedure\ProjectFileProcedure;
+use Kanboard\Api\Procedure\TagProcedure;
use Kanboard\Api\Procedure\TaskExternalLinkProcedure;
use Kanboard\Api\Procedure\TaskFileProcedure;
use Kanboard\Api\Procedure\GroupProcedure;
@@ -25,6 +26,7 @@ use Kanboard\Api\Procedure\SwimlaneProcedure;
use Kanboard\Api\Procedure\TaskMetadataProcedure;
use Kanboard\Api\Procedure\TaskProcedure;
use Kanboard\Api\Procedure\TaskLinkProcedure;
+use Kanboard\Api\Procedure\TaskTagProcedure;
use Kanboard\Api\Procedure\UserProcedure;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
@@ -71,9 +73,11 @@ class ApiProvider implements ServiceProviderInterface
->withObject(new TaskLinkProcedure($container))
->withObject(new TaskExternalLinkProcedure($container))
->withObject(new TaskMetadataProcedure($container))
+ ->withObject(new TaskTagProcedure($container))
->withObject(new UserProcedure($container))
->withObject(new GroupProcedure($container))
->withObject(new GroupMemberProcedure($container))
+ ->withObject(new TagProcedure($container))
->withBeforeMethod('beforeProcedure')
;
diff --git a/app/ServiceProvider/AuthenticationProvider.php b/app/ServiceProvider/AuthenticationProvider.php
index adff1e63..6a9a820e 100644
--- a/app/ServiceProvider/AuthenticationProvider.php
+++ b/app/ServiceProvider/AuthenticationProvider.php
@@ -2,6 +2,7 @@
namespace Kanboard\ServiceProvider;
+use Kanboard\Auth\ApiAccessTokenAuth;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
use Kanboard\Core\Security\AuthenticationManager;
@@ -44,6 +45,8 @@ class AuthenticationProvider implements ServiceProviderInterface
$container['authenticationManager']->register(new LdapAuth($container));
}
+ $container['authenticationManager']->register(new ApiAccessTokenAuth($container));
+
$container['projectAccessMap'] = $this->getProjectAccessMap();
$container['applicationAccessMap'] = $this->getApplicationAccessMap();
$container['apiAccessMap'] = $this->getApiAccessMap();
@@ -85,7 +88,6 @@ class AuthenticationProvider implements ServiceProviderInterface
$acl->add('ExportController', '*', Role::PROJECT_MANAGER);
$acl->add('TaskFileController', array('screenshot', 'create', 'save', 'remove', 'confirm'), Role::PROJECT_MEMBER);
$acl->add('TaskGanttController', '*', Role::PROJECT_MANAGER);
- $acl->add('TaskGanttCreationController', '*', Role::PROJECT_MANAGER);
$acl->add('ProjectViewController', array('share', 'updateSharing', 'integrations', 'updateIntegrations', 'notifications', 'updateNotifications', 'duplicate', 'doDuplication'), Role::PROJECT_MANAGER);
$acl->add('ProjectPermissionController', '*', Role::PROJECT_MANAGER);
$acl->add('ProjectEditController', '*', Role::PROJECT_MANAGER);
@@ -133,7 +135,8 @@ class AuthenticationProvider implements ServiceProviderInterface
$acl->add('BoardViewController', 'readonly', Role::APP_PUBLIC);
$acl->add('ICalendarController', '*', Role::APP_PUBLIC);
$acl->add('FeedController', '*', Role::APP_PUBLIC);
- $acl->add('AvatarFileController', 'show', Role::APP_PUBLIC);
+ $acl->add('AvatarFileController', array('show', 'image'), Role::APP_PUBLIC);
+ $acl->add('UserInviteController', array('signup', 'register'), Role::APP_PUBLIC);
$acl->add('ConfigController', '*', Role::APP_ADMIN);
$acl->add('TagController', '*', Role::APP_ADMIN);
@@ -194,19 +197,21 @@ class AuthenticationProvider implements ServiceProviderInterface
$acl->setRoleHierarchy(Role::PROJECT_MEMBER, array(Role::PROJECT_VIEWER));
$acl->add('ActionProcedure', array('removeAction', 'getActions', 'createAction'), Role::PROJECT_MANAGER);
- $acl->add('CategoryProcedure', '*', Role::PROJECT_MANAGER);
- $acl->add('ColumnProcedure', '*', Role::PROJECT_MANAGER);
+ $acl->add('CategoryProcedure', array('removeCategory', 'createCategory', 'updateCategory'), Role::PROJECT_MANAGER);
+ $acl->add('ColumnProcedure', array('updateColumn', 'addColumn', 'removeColumn', 'changeColumnPosition'), Role::PROJECT_MANAGER);
$acl->add('CommentProcedure', array('removeComment', 'createComment', 'updateComment'), Role::PROJECT_MEMBER);
- $acl->add('ProjectPermissionProcedure', '*', Role::PROJECT_MANAGER);
+ $acl->add('ProjectPermissionProcedure', array('addProjectUser', 'addProjectGroup', 'removeProjectUser', 'removeProjectGroup', 'changeProjectUserRole', 'changeProjectGroupRole'), Role::PROJECT_MANAGER);
$acl->add('ProjectProcedure', array('updateProject', 'removeProject', 'enableProject', 'disableProject', 'enableProjectPublicAccess', 'disableProjectPublicAccess'), Role::PROJECT_MANAGER);
- $acl->add('SubtaskProcedure', '*', Role::PROJECT_MEMBER);
- $acl->add('SubtaskTimeTrackingProcedure', '*', Role::PROJECT_MEMBER);
- $acl->add('SwimlaneProcedure', '*', Role::PROJECT_MANAGER);
- $acl->add('ProjectFileProcedure', '*', Role::PROJECT_MEMBER);
- $acl->add('TaskFileProcedure', '*', Role::PROJECT_MEMBER);
- $acl->add('TaskLinkProcedure', '*', Role::PROJECT_MEMBER);
+ $acl->add('SubtaskProcedure', array('removeSubtask', 'createSubtask', 'updateSubtask'), Role::PROJECT_MEMBER);
+ $acl->add('SubtaskTimeTrackingProcedure', array('setSubtaskStartTime', 'setSubtaskEndTime'), Role::PROJECT_MEMBER);
+ $acl->add('SwimlaneProcedure', array('addSwimlane', 'updateSwimlane', 'removeSwimlane', 'disableSwimlane', 'enableSwimlane', 'changeSwimlanePosition'), Role::PROJECT_MANAGER);
+ $acl->add('ProjectFileProcedure', array('createProjectFile', 'removeProjectFile', 'removeAllProjectFiles'), Role::PROJECT_MEMBER);
+ $acl->add('TaskFileProcedure', array('createTaskFile', 'removeTaskFile', 'removeAllTaskFiles'), Role::PROJECT_MEMBER);
+ $acl->add('TaskLinkProcedure', array('createTaskLink', 'updateTaskLink', 'removeTaskLink'), Role::PROJECT_MEMBER);
$acl->add('TaskExternalLinkProcedure', array('createExternalTaskLink', 'updateExternalTaskLink', 'removeExternalTaskLink'), Role::PROJECT_MEMBER);
- $acl->add('TaskProcedure', '*', Role::PROJECT_MEMBER);
+ $acl->add('TaskProcedure', array('openTask', 'closeTask', 'removeTask', 'moveTaskPosition', 'moveTaskToProject', 'duplicateTaskToProject', 'createTask', 'updateTask'), Role::PROJECT_MEMBER);
+ $acl->add('TaskTagProcedure', array('setTaskTags'), Role::PROJECT_MEMBER);
+ $acl->add('TagProcedure', array('createTag', 'updateTag', 'removeTag'), Role::PROJECT_MEMBER);
return $acl;
}
diff --git a/app/ServiceProvider/CacheProvider.php b/app/ServiceProvider/CacheProvider.php
index e93dd502..af8a8e7a 100644
--- a/app/ServiceProvider/CacheProvider.php
+++ b/app/ServiceProvider/CacheProvider.php
@@ -8,6 +8,7 @@ use Kanboard\Decorator\ColumnMoveRestrictionCacheDecorator;
use Kanboard\Decorator\ColumnRestrictionCacheDecorator;
use Kanboard\Decorator\MetadataCacheDecorator;
use Kanboard\Decorator\ProjectRoleRestrictionCacheDecorator;
+use Kanboard\Decorator\UserCacheDecorator;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
@@ -40,6 +41,13 @@ class CacheProvider implements ServiceProviderInterface
$container['cacheDriver'] = $container['memoryCache'];
}
+ $container['userCacheDecorator'] = function($c) {
+ return new UserCacheDecorator(
+ $c['memoryCache'],
+ $c['userModel']
+ );
+ };
+
$container['userMetadataCacheDecorator'] = function($c) {
return new MetadataCacheDecorator(
$c['cacheDriver'],
diff --git a/app/ServiceProvider/ClassProvider.php b/app/ServiceProvider/ClassProvider.php
index c5bf0678..50ce531f 100644
--- a/app/ServiceProvider/ClassProvider.php
+++ b/app/ServiceProvider/ClassProvider.php
@@ -42,6 +42,7 @@ class ClassProvider implements ServiceProviderInterface
'CustomFilterModel',
'GroupModel',
'GroupMemberModel',
+ 'InviteModel',
'LanguageModel',
'LastLoginModel',
'LinkModel',
@@ -91,7 +92,6 @@ class ClassProvider implements ServiceProviderInterface
'TransitionModel',
'UserModel',
'UserLockingModel',
- 'UserMentionModel',
'UserNotificationModel',
'UserNotificationFilterModel',
'UserUnreadNotificationModel',
diff --git a/app/ServiceProvider/CommandProvider.php b/app/ServiceProvider/CommandProvider.php
index 55c2712b..f17ba352 100644
--- a/app/ServiceProvider/CommandProvider.php
+++ b/app/ServiceProvider/CommandProvider.php
@@ -3,6 +3,9 @@
namespace Kanboard\ServiceProvider;
use Kanboard\Console\CronjobCommand;
+use Kanboard\Console\DatabaseMigrationCommand;
+use Kanboard\Console\DatabaseVersionCommand;
+use Kanboard\Console\JobCommand;
use Kanboard\Console\LocaleComparatorCommand;
use Kanboard\Console\LocaleSyncCommand;
use Kanboard\Console\PluginInstallCommand;
@@ -50,11 +53,14 @@ class CommandProvider implements ServiceProviderInterface
$application->add(new TaskTriggerCommand($container));
$application->add(new CronjobCommand($container));
$application->add(new WorkerCommand($container));
+ $application->add(new JobCommand($container));
$application->add(new ResetPasswordCommand($container));
$application->add(new ResetTwoFactorCommand($container));
$application->add(new PluginUpgradeCommand($container));
$application->add(new PluginInstallCommand($container));
$application->add(new PluginUninstallCommand($container));
+ $application->add(new DatabaseMigrationCommand($container));
+ $application->add(new DatabaseVersionCommand($container));
$container['cli'] = $application;
return $container;
diff --git a/app/ServiceProvider/DatabaseProvider.php b/app/ServiceProvider/DatabaseProvider.php
index a3f57457..9998ac43 100644
--- a/app/ServiceProvider/DatabaseProvider.php
+++ b/app/ServiceProvider/DatabaseProvider.php
@@ -27,6 +27,10 @@ class DatabaseProvider implements ServiceProviderInterface
{
$container['db'] = $this->getInstance();
+ if (DB_RUN_MIGRATIONS) {
+ self::runMigrations($container['db']);
+ }
+
if (DEBUG) {
$container['db']->getStatementHandler()
->withLogging()
@@ -38,7 +42,7 @@ class DatabaseProvider implements ServiceProviderInterface
}
/**
- * Setup the database driver and execute schema migration
+ * Setup the database driver
*
* @access public
* @return \PicoDb\Database
@@ -59,12 +63,39 @@ class DatabaseProvider implements ServiceProviderInterface
throw new LogicException('Database driver not supported');
}
- if ($db->schema()->check(\Schema\VERSION)) {
- return $db;
- } else {
+ return $db;
+ }
+
+ /**
+ * Get current database version
+ *
+ * @static
+ * @access public
+ * @param Database $db
+ * @return int
+ */
+ public static function getSchemaVersion(Database $db)
+ {
+ return $db->getDriver()->getSchemaVersion();
+ }
+
+ /**
+ * Execute database migrations
+ *
+ * @static
+ * @access public
+ * @throws RuntimeException
+ * @param Database $db
+ * @return bool
+ */
+ public static function runMigrations(Database $db)
+ {
+ if (! $db->schema()->check(\Schema\VERSION)) {
$messages = $db->getLogMessages();
throw new RuntimeException('Unable to run SQL migrations: '.implode(', ', $messages).' (You may have to fix it manually)');
}
+
+ return true;
}
/**
@@ -79,7 +110,7 @@ class DatabaseProvider implements ServiceProviderInterface
return new Database(array(
'driver' => 'sqlite',
- 'filename' => DB_FILENAME
+ 'filename' => DB_FILENAME,
));
}
diff --git a/app/ServiceProvider/ExternalTaskProvider.php b/app/ServiceProvider/ExternalTaskProvider.php
new file mode 100644
index 00000000..52484ae6
--- /dev/null
+++ b/app/ServiceProvider/ExternalTaskProvider.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace Kanboard\ServiceProvider;
+
+use Kanboard\Core\ExternalTask\ExternalTaskManager;
+use Pimple\Container;
+use Pimple\ServiceProviderInterface;
+
+/**
+ * Class ExternalTaskProvider
+ *
+ * @package Kanboard\ServiceProvider
+ * @author Frederic Guillot
+ */
+class ExternalTaskProvider implements ServiceProviderInterface
+{
+ /**
+ * Register providers
+ *
+ * @access public
+ * @param \Pimple\Container $container
+ * @return \Pimple\Container
+ */
+ public function register(Container $container)
+ {
+ $container['externalTaskManager'] = new ExternalTaskManager();
+ return $container;
+ }
+}
diff --git a/app/ServiceProvider/FilterProvider.php b/app/ServiceProvider/FilterProvider.php
index 1684592b..1cc4da8a 100644
--- a/app/ServiceProvider/FilterProvider.php
+++ b/app/ServiceProvider/FilterProvider.php
@@ -14,6 +14,7 @@ use Kanboard\Filter\TaskCategoryFilter;
use Kanboard\Filter\TaskColorFilter;
use Kanboard\Filter\TaskColumnFilter;
use Kanboard\Filter\TaskCommentFilter;
+use Kanboard\Filter\TaskCompletionDateFilter;
use Kanboard\Filter\TaskCreationDateFilter;
use Kanboard\Filter\TaskCreatorFilter;
use Kanboard\Filter\TaskDescriptionFilter;
@@ -156,6 +157,9 @@ class FilterProvider implements ServiceProviderInterface
->withFilter(TaskStartDateFilter::getInstance()
->setDateParser($c['dateParser'])
)
+ ->withFilter(TaskCompletionDateFilter::getInstance()
+ ->setDateparser($c['dateParser'])
+ )
->withFilter(new TaskIdFilter())
->withFilter(TaskLinkFilter::getInstance()
->setDatabase($c['db'])
diff --git a/app/ServiceProvider/FormatterProvider.php b/app/ServiceProvider/FormatterProvider.php
new file mode 100644
index 00000000..dbba3f3c
--- /dev/null
+++ b/app/ServiceProvider/FormatterProvider.php
@@ -0,0 +1,48 @@
+<?php
+
+namespace Kanboard\ServiceProvider;
+
+use Kanboard\Core\Tool;
+use Pimple\Container;
+use Pimple\ServiceProviderInterface;
+
+/**
+ * Class FormatterProvider
+ *
+ * @package Kanboard\ServiceProvider
+ * @author Frederic Guillot
+ */
+class FormatterProvider implements ServiceProviderInterface
+{
+ protected $formatters = array(
+ 'Formatter' => array(
+ 'BoardColumnFormatter',
+ 'BoardFormatter',
+ 'BoardSwimlaneFormatter',
+ 'BoardTaskFormatter',
+ 'GroupAutoCompleteFormatter',
+ 'ProjectActivityEventFormatter',
+ 'ProjectGanttFormatter',
+ 'SubtaskTimeTrackingCalendarFormatter',
+ 'TaskAutoCompleteFormatter',
+ 'TaskCalendarFormatter',
+ 'TaskGanttFormatter',
+ 'TaskICalFormatter',
+ 'TaskSuggestMenuFormatter',
+ 'UserAutoCompleteFormatter',
+ 'UserMentionFormatter',
+ )
+ );
+
+ /**
+ * Registers services on the given container.
+ *
+ * @param Container $container
+ * @return Container
+ */
+ public function register(Container $container)
+ {
+ Tool::buildFactories($container, $this->formatters);
+ return $container;
+ }
+}
diff --git a/app/ServiceProvider/HelperProvider.php b/app/ServiceProvider/HelperProvider.php
index f4c0db22..dcaf81c6 100644
--- a/app/ServiceProvider/HelperProvider.php
+++ b/app/ServiceProvider/HelperProvider.php
@@ -39,6 +39,7 @@ class HelperProvider implements ServiceProviderInterface
$container['helper']->register('projectHeader', '\Kanboard\Helper\ProjectHeaderHelper');
$container['helper']->register('projectActivity', '\Kanboard\Helper\ProjectActivityHelper');
$container['helper']->register('mail', '\Kanboard\Helper\MailHelper');
+ $container['helper']->register('modal', '\Kanboard\Helper\ModalHelper');
$container['template'] = new Template($container['helper']);
diff --git a/app/ServiceProvider/JobProvider.php b/app/ServiceProvider/JobProvider.php
index 2194b11c..4e5e0f1a 100644
--- a/app/ServiceProvider/JobProvider.php
+++ b/app/ServiceProvider/JobProvider.php
@@ -10,6 +10,7 @@ use Kanboard\Job\SubtaskEventJob;
use Kanboard\Job\TaskEventJob;
use Kanboard\Job\TaskFileEventJob;
use Kanboard\Job\TaskLinkEventJob;
+use Kanboard\Job\UserMentionJob;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
@@ -62,6 +63,10 @@ class JobProvider implements ServiceProviderInterface
return new ProjectMetricJob($c);
});
+ $container['userMentionJob'] = $container->factory(function ($c) {
+ return new UserMentionJob($c);
+ });
+
return $container;
}
}
diff --git a/app/ServiceProvider/RouteProvider.php b/app/ServiceProvider/RouteProvider.php
index 0d1a7931..08759b22 100644
--- a/app/ServiceProvider/RouteProvider.php
+++ b/app/ServiceProvider/RouteProvider.php
@@ -65,10 +65,7 @@ class RouteProvider implements ServiceProviderInterface
$container['route']->addRoute('project/:project_id/overview', 'ProjectOverviewController', 'show');
// ProjectEdit routes
- $container['route']->addRoute('project/:project_id/edit', 'ProjectEditController', 'edit');
- $container['route']->addRoute('project/:project_id/edit/dates', 'ProjectEditController', 'dates');
- $container['route']->addRoute('project/:project_id/edit/description', 'ProjectEditController', 'description');
- $container['route']->addRoute('project/:project_id/edit/priority', 'ProjectEditController', 'priority');
+ $container['route']->addRoute('project/:project_id/edit', 'ProjectEditController', 'show');
// ProjectUser routes
$container['route']->addRoute('projects/managers/:user_id', 'ProjectUserOverviewController', 'managers');
@@ -158,6 +155,7 @@ class RouteProvider implements ServiceProviderInterface
$container['route']->addRoute('user/:user_id/authentication', 'UserCredentialController', 'changeAuthentication');
$container['route']->addRoute('user/:user_id/2fa', 'TwoFactorController', 'index');
$container['route']->addRoute('user/:user_id/avatar', 'AvatarFileController', 'show');
+ $container['route']->addRoute('user/:user_id/api', 'UserApiAccessController', 'show');
// Groups
$container['route']->addRoute('groups', 'GroupListController', 'index');
diff --git a/app/Subscriber/NotificationSubscriber.php b/app/Subscriber/NotificationSubscriber.php
index 7cc68b26..ad16685b 100644
--- a/app/Subscriber/NotificationSubscriber.php
+++ b/app/Subscriber/NotificationSubscriber.php
@@ -15,25 +15,25 @@ class NotificationSubscriber extends BaseSubscriber implements EventSubscriberIn
public static function getSubscribedEvents()
{
return array(
- TaskModel::EVENT_USER_MENTION => 'handleEvent',
- TaskModel::EVENT_CREATE => 'handleEvent',
- TaskModel::EVENT_UPDATE => 'handleEvent',
- TaskModel::EVENT_CLOSE => 'handleEvent',
- TaskModel::EVENT_OPEN => 'handleEvent',
- TaskModel::EVENT_MOVE_COLUMN => 'handleEvent',
- TaskModel::EVENT_MOVE_POSITION => 'handleEvent',
- TaskModel::EVENT_MOVE_SWIMLANE => 'handleEvent',
- TaskModel::EVENT_ASSIGNEE_CHANGE => 'handleEvent',
- SubtaskModel::EVENT_CREATE => 'handleEvent',
- SubtaskModel::EVENT_UPDATE => 'handleEvent',
- SubtaskModel::EVENT_DELETE => 'handleEvent',
- CommentModel::EVENT_CREATE => 'handleEvent',
- CommentModel::EVENT_UPDATE => 'handleEvent',
- CommentModel::EVENT_DELETE => 'handleEvent',
- CommentModel::EVENT_USER_MENTION => 'handleEvent',
- TaskFileModel::EVENT_CREATE => 'handleEvent',
- TaskLinkModel::EVENT_CREATE_UPDATE => 'handleEvent',
- TaskLinkModel::EVENT_DELETE => 'handleEvent',
+ TaskModel::EVENT_USER_MENTION => 'handleEvent',
+ TaskModel::EVENT_CREATE => 'handleEvent',
+ TaskModel::EVENT_UPDATE => 'handleEvent',
+ TaskModel::EVENT_CLOSE => 'handleEvent',
+ TaskModel::EVENT_OPEN => 'handleEvent',
+ TaskModel::EVENT_MOVE_COLUMN => 'handleEvent',
+ TaskModel::EVENT_MOVE_POSITION => 'handleEvent',
+ TaskModel::EVENT_MOVE_SWIMLANE => 'handleEvent',
+ TaskModel::EVENT_ASSIGNEE_CHANGE => 'handleEvent',
+ SubtaskModel::EVENT_CREATE => 'handleEvent',
+ SubtaskModel::EVENT_UPDATE => 'handleEvent',
+ SubtaskModel::EVENT_DELETE => 'handleEvent',
+ CommentModel::EVENT_CREATE => 'handleEvent',
+ CommentModel::EVENT_UPDATE => 'handleEvent',
+ CommentModel::EVENT_DELETE => 'handleEvent',
+ CommentModel::EVENT_USER_MENTION => 'handleEvent',
+ TaskFileModel::EVENT_CREATE => 'handleEvent',
+ TaskLinkModel::EVENT_CREATE_UPDATE => 'handleEvent',
+ TaskLinkModel::EVENT_DELETE => 'handleEvent',
);
}
diff --git a/app/Template/action/index.php b/app/Template/action/index.php
index 7768a0b6..90db0450 100644
--- a/app/Template/action/index.php
+++ b/app/Template/action/index.php
@@ -2,12 +2,10 @@
<h2><?= t('Automatic actions for the project "%s"', $project['name']) ?></h2>
<ul>
<li>
- <i class="fa fa-plus fa-fw"></i>
- <?= $this->url->link(t('Add a new action'), 'ActionCreationController', 'create', array('project_id' => $project['id']), false, 'popover') ?>
+ <?= $this->modal->medium('plus', t('Add a new action'), 'ActionCreationController', 'create', array('project_id' => $project['id'])) ?>
</li>
<li>
- <i class="fa fa-copy fa-fw"></i>
- <?= $this->url->link(t('Import from another project'), 'ProjectActionDuplicationController', 'show', array('project_id' => $project['id']), false, 'popover') ?>
+ <?= $this->modal->medium('copy', t('Import from another project'), 'ProjectActionDuplicationController', 'show', array('project_id' => $project['id'])) ?>
</li>
</ul>
</div>
@@ -17,8 +15,8 @@
<?php else: ?>
<table class="table-scrolling">
<tr>
- <th><?= t('Automatic actions') ?></th>
- <th><?= t('Action parameters') ?></th>
+ <th class="column-60"><?= t('Automatic actions') ?></th>
+ <th class="column-25"><?= t('Action parameters') ?></th>
<th><?= t('Action') ?></th>
</tr>
@@ -65,7 +63,7 @@
</ul>
</td>
<td>
- <?= $this->url->link(t('Remove'), 'ActionController', 'confirm', array('project_id' => $project['id'], 'action_id' => $action['id']), false, 'popover') ?>
+ <?= $this->modal->confirm('trash-o', t('Remove'), 'ActionController', 'confirm', array('project_id' => $project['id'], 'action_id' => $action['id'])) ?>
</td>
</tr>
<?php endforeach ?>
diff --git a/app/Template/action/remove.php b/app/Template/action/remove.php
index 384bec7a..e3cdb206 100644
--- a/app/Template/action/remove.php
+++ b/app/Template/action/remove.php
@@ -7,9 +7,9 @@
<?= t('Do you really want to remove this action: "%s"?', $this->text->in($action['event_name'], $available_events).'/'.$this->text->in($action['action_name'], $available_actions)) ?>
</p>
- <div class="form-actions">
- <?= $this->url->link(t('Yes'), 'ActionController', 'remove', array('project_id' => $project['id'], 'action_id' => $action['id']), true, 'btn btn-red') ?>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'ActionController', 'index', array('project_id' => $project['id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->confirmButtons(
+ 'ActionController',
+ 'remove',
+ array('project_id' => $project['id'], 'action_id' => $action['id'])
+ ) ?>
</div>
diff --git a/app/Template/action_creation/create.php b/app/Template/action_creation/create.php
index c0d2880e..862ee474 100644
--- a/app/Template/action_creation/create.php
+++ b/app/Template/action_creation/create.php
@@ -1,16 +1,14 @@
<div class="page-header">
<h2><?= t('Add an action') ?></h2>
</div>
-<form class="popover-form" method="post" action="<?= $this->url->href('ActionCreationController', 'event', array('project_id' => $project['id'])) ?>">
+<form method="post" action="<?= $this->url->href('ActionCreationController', 'event', array('project_id' => $project['id'])) ?>">
<?= $this->form->csrf() ?>
<?= $this->form->hidden('project_id', $values) ?>
<?= $this->form->label(t('Action'), 'action_name') ?>
<?= $this->form->select('action_name', $available_actions, $values) ?>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Next step') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'ActionController', 'index', array(), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->submitButtons(array(
+ 'submitLabel' => t('Next step')
+ )) ?>
</form>
diff --git a/app/Template/action_creation/event.php b/app/Template/action_creation/event.php
index cdf00310..e4166548 100644
--- a/app/Template/action_creation/event.php
+++ b/app/Template/action_creation/event.php
@@ -2,8 +2,7 @@
<h2><?= t('Choose an event') ?></h2>
</div>
-<form class="popover-form" method="post" action="<?= $this->url->href('ActionCreationController', 'params', array('project_id' => $project['id'])) ?>">
-
+<form method="post" action="<?= $this->url->href('ActionCreationController', 'params', array('project_id' => $project['id'])) ?>">
<?= $this->form->csrf() ?>
<?= $this->form->hidden('project_id', $values) ?>
@@ -19,9 +18,7 @@
<?= t('When the selected event occurs execute the corresponding action.') ?>
</div>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Next step') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'ActionController', 'index', array('project_id' => $project['id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->submitButtons(array(
+ 'submitLabel' => t('Next step')
+ )) ?>
</form>
diff --git a/app/Template/action_creation/params.php b/app/Template/action_creation/params.php
index c9608f21..0cc98f50 100644
--- a/app/Template/action_creation/params.php
+++ b/app/Template/action_creation/params.php
@@ -2,8 +2,7 @@
<h2><?= t('Define action parameters') ?></h2>
</div>
-<form class="popover-form" method="post" action="<?= $this->url->href('ActionCreationController', 'save', array('project_id' => $project['id'])) ?>" autocomplete="off">
-
+<form method="post" action="<?= $this->url->href('ActionCreationController', 'save', array('project_id' => $project['id'])) ?>" autocomplete="off">
<?= $this->form->csrf() ?>
<?= $this->form->hidden('project_id', $values) ?>
@@ -50,9 +49,5 @@
<?php endif ?>
<?php endforeach ?>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'ActionController', 'index', array('project_id' => $project['id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->submitButtons() ?>
</form>
diff --git a/app/Template/activity/project.php b/app/Template/activity/project.php
index ce1c8c0f..ce1f8bba 100644
--- a/app/Template/activity/project.php
+++ b/app/Template/activity/project.php
@@ -1,14 +1,12 @@
-<section id="main">
- <?= $this->projectHeader->render($project, 'AnalyticController', $this->app->getRouterAction()) ?>
+<div class="page-header">
+ <h2><?= t('%s\'s activity', $project['name']) ?></h2>
<?php if ($project['is_public']): ?>
- <div class="menu-inline pull-right">
<ul>
- <li><i class="fa fa-rss-square fa-fw"></i><?= $this->url->link(t('RSS feed'), 'FeedController', 'project', array('token' => $project['token']), false, '', '', true) ?></li>
- <li><i class="fa fa-calendar fa-fw"></i><?= $this->url->link(t('iCal feed'), 'ICalendarController', 'project', array('token' => $project['token'])) ?></li>
+ <li><?= $this->url->icon('rss-square', t('RSS feed'), 'FeedController', 'project', array('token' => $project['token']), false, '', '', true) ?></li>
+ <li><?= $this->url->icon('calendar', t('iCal feed'), 'ICalendarController', 'project', array('token' => $project['token'])) ?></li>
</ul>
- </div>
<?php endif ?>
+</div>
- <?= $this->render('event/events', array('events' => $events)) ?>
-</section>
+<?= $this->render('event/events', array('events' => $events)) ?>
diff --git a/app/Template/analytic/avg_time_columns.php b/app/Template/analytic/avg_time_columns.php
index 91c269fc..1af69c8b 100644
--- a/app/Template/analytic/avg_time_columns.php
+++ b/app/Template/analytic/avg_time_columns.php
@@ -1,29 +1,31 @@
-<div class="page-header">
- <h2><?= t('Average time spent into each column') ?></h2>
-</div>
+<?php if (! $is_ajax): ?>
+ <div class="page-header">
+ <h2><?= t('Average time spent into each column') ?></h2>
+ </div>
+<?php endif ?>
<?php if (empty($metrics)): ?>
<p class="alert"><?= t('Not enough data to show the graph.') ?></p>
<?php else: ?>
- <section id="analytic-avg-time-column">
-
- <div id="chart" data-metrics='<?= json_encode($metrics, JSON_HEX_APOS) ?>' data-label="<?= t('Average time spent') ?>"></div>
+ <?= $this->app->component('chart-project-avg-time-column', array(
+ 'metrics' => $metrics,
+ 'label' => t('Average time spent'),
+ )) ?>
- <table class="table-striped">
+ <table class="table-striped">
<tr>
<th><?= t('Column') ?></th>
<th><?= t('Average time spent') ?></th>
</tr>
<?php foreach ($metrics as $column): ?>
- <tr>
- <td><?= $this->text->e($column['title']) ?></td>
- <td><?= $this->dt->duration($column['average']) ?></td>
- </tr>
+ <tr>
+ <td><?= $this->text->e($column['title']) ?></td>
+ <td><?= $this->dt->duration($column['average']) ?></td>
+ </tr>
<?php endforeach ?>
- </table>
+ </table>
- <p class="alert alert-info">
- <?= t('This chart show the average time spent into each column for the last %d tasks.', 1000) ?>
- </p>
- </section>
+ <p class="alert alert-info">
+ <?= t('This chart show the average time spent into each column for the last %d tasks.', 1000) ?>
+ </p>
<?php endif ?>
diff --git a/app/Template/analytic/burndown.php b/app/Template/analytic/burndown.php
index dfd77604..d62c9ba0 100644
--- a/app/Template/analytic/burndown.php
+++ b/app/Template/analytic/burndown.php
@@ -1,32 +1,26 @@
-<div class="page-header">
- <h2><?= t('Burndown chart') ?></h2>
-</div>
+<?php if (! $is_ajax): ?>
+ <div class="page-header">
+ <h2><?= t('Burndown chart') ?></h2>
+ </div>
+<?php endif ?>
<?php if (! $display_graph): ?>
<p class="alert"><?= t('You need at least 2 days of data to show the chart.') ?></p>
<?php else: ?>
- <section id="analytic-burndown">
- <div id="chart" data-metrics='<?= json_encode($metrics, JSON_HEX_APOS) ?>' data-date-format="<?= e('%%Y-%%m-%%d') ?>" data-label-total="<?= t('Total for all columns') ?>"></div>
- </section>
+ <?= $this->app->component('chart-project-burndown', array(
+ 'metrics' => $metrics,
+ 'labelTotal' => t('Total for all columns'),
+ 'dateFormat' => e('%%Y-%%m-%%d'),
+ )) ?>
<?php endif ?>
<hr/>
<form method="post" class="form-inline" action="<?= $this->url->href('AnalyticController', 'burndown', array('project_id' => $project['id'])) ?>" autocomplete="off">
-
<?= $this->form->csrf() ?>
-
- <div class="form-inline-group">
- <?= $this->form->date(t('Start date'), 'from', $values) ?>
- </div>
-
- <div class="form-inline-group">
- <?= $this->form->date(t('End date'), 'to', $values) ?>
- </div>
-
- <div class="form-inline-group">
- <button type="submit" class="btn btn-blue"><?= t('Execute') ?></button>
- </div>
+ <?= $this->form->date(t('Start date'), 'from', $values) ?>
+ <?= $this->form->date(t('End date'), 'to', $values) ?>
+ <?= $this->modal->submitButtons(array('submitLabel' => t('Execute'))) ?>
</form>
<p class="alert alert-info"><?= t('This chart show the task complexity over the time (Work Remaining).') ?></p>
diff --git a/app/Template/analytic/cfd.php b/app/Template/analytic/cfd.php
index 89ded3ad..dcd7b58f 100644
--- a/app/Template/analytic/cfd.php
+++ b/app/Template/analytic/cfd.php
@@ -1,30 +1,23 @@
-<div class="page-header">
- <h2><?= t('Cumulative flow diagram') ?></h2>
-</div>
+<?php if (! $is_ajax): ?>
+ <div class="page-header">
+ <h2><?= t('Cumulative flow diagram') ?></h2>
+ </div>
+<?php endif ?>
<?php if (! $display_graph): ?>
<p class="alert"><?= t('You need at least 2 days of data to show the chart.') ?></p>
<?php else: ?>
- <section id="analytic-cfd">
- <div id="chart" data-metrics='<?= json_encode($metrics, JSON_HEX_APOS) ?>' data-date-format="<?= e('%%Y-%%m-%%d') ?>"></div>
- </section>
+ <?= $this->app->component('chart-project-cumulative-flow', array(
+ 'metrics' => $metrics,
+ 'dateFormat' => e('%%Y-%%m-%%d'),
+ )) ?>
<?php endif ?>
<hr/>
<form method="post" class="form-inline" action="<?= $this->url->href('AnalyticController', 'cfd', array('project_id' => $project['id'])) ?>" autocomplete="off">
-
<?= $this->form->csrf() ?>
-
- <div class="form-inline-group">
- <?= $this->form->date(t('Start date'), 'from', $values) ?>
- </div>
-
- <div class="form-inline-group">
- <?= $this->form->date(t('End date'), 'to', $values) ?>
- </div>
-
- <div class="form-inline-group">
- <button type="submit" class="btn btn-blue"><?= t('Execute') ?></button>
- </div>
+ <?= $this->form->date(t('Start date'), 'from', $values) ?>
+ <?= $this->form->date(t('End date'), 'to', $values) ?>
+ <?= $this->modal->submitButtons(array('submitLabel' => t('Execute'))) ?>
</form>
diff --git a/app/Template/analytic/layout.php b/app/Template/analytic/layout.php
index e3c6099f..7159094c 100644
--- a/app/Template/analytic/layout.php
+++ b/app/Template/analytic/layout.php
@@ -1,10 +1,14 @@
-<section id="main">
+<?php if ($is_ajax): ?>
+ <div class="page-header">
+ <h2><?= $title ?></h2>
+ </div>
+<?php else: ?>
<?= $this->projectHeader->render($project, 'TaskListController', 'show') ?>
- <section class="sidebar-container">
- <?= $this->render($sidebar_template, array('project' => $project)) ?>
+<?php endif ?>
+<section class="sidebar-container">
+ <?= $this->render($sidebar_template, array('project' => $project)) ?>
- <div class="sidebar-content">
- <?= $content_for_sublayout ?>
- </div>
- </section>
+ <div class="sidebar-content">
+ <?= $content_for_sublayout ?>
+ </div>
</section>
diff --git a/app/Template/analytic/lead_cycle_time.php b/app/Template/analytic/lead_cycle_time.php
index ef595b79..780b47b6 100644
--- a/app/Template/analytic/lead_cycle_time.php
+++ b/app/Template/analytic/lead_cycle_time.php
@@ -1,8 +1,10 @@
-<div class="page-header">
- <h2><?= t('Average Lead and Cycle time') ?></h2>
-</div>
+<?php if (! $is_ajax): ?>
+ <div class="page-header">
+ <h2><?= t('Average Lead and Cycle time') ?></h2>
+ </div>
+<?php endif ?>
-<div class="listing">
+<div class="panel">
<ul>
<li><?= t('Average lead time: ').'<strong>'.$this->dt->duration($average['avg_lead_time']) ?></strong></li>
<li><?= t('Average cycle time: ').'<strong>'.$this->dt->duration($average['avg_cycle_time']) ?></strong></li>
@@ -12,29 +14,20 @@
<?php if (empty($metrics)): ?>
<p class="alert"><?= t('Not enough data to show the graph.') ?></p>
<?php else: ?>
- <section id="analytic-lead-cycle-time">
-
- <div id="chart" data-metrics='<?= json_encode($metrics, JSON_HEX_APOS) ?>' data-label-cycle="<?= t('Cycle Time') ?>" data-label-lead="<?= t('Lead Time') ?>"></div>
-
- <form method="post" class="form-inline" action="<?= $this->url->href('AnalyticController', 'leadAndCycleTime', array('project_id' => $project['id'])) ?>" autocomplete="off">
-
- <?= $this->form->csrf() ?>
-
- <div class="form-inline-group">
- <?= $this->form->date(t('Start date'), 'from', $values) ?>
- </div>
-
- <div class="form-inline-group">
- <?= $this->form->date(t('End date'), 'to', $values) ?>
- </div>
+ <?= $this->app->component('chart-project-lead-cycle-time', array(
+ 'metrics' => $metrics,
+ 'labelCycle' => t('Cycle Time'),
+ 'labelLead' => t('Lead Time'),
+ )) ?>
- <div class="form-inline-group">
- <button type="submit" class="btn btn-blue"><?= t('Execute') ?></button>
- </div>
- </form>
+ <form method="post" class="form-inline" action="<?= $this->url->href('AnalyticController', 'leadAndCycleTime', array('project_id' => $project['id'])) ?>" autocomplete="off">
+ <?= $this->form->csrf() ?>
+ <?= $this->form->date(t('Start date'), 'from', $values) ?>
+ <?= $this->form->date(t('End date'), 'to', $values) ?>
+ <?= $this->modal->submitButtons(array('submitLabel' => t('Execute'))) ?>
+ </form>
- <p class="alert alert-info">
- <?= t('This chart show the average lead and cycle time for the last %d tasks over the time.', 1000) ?>
- </p>
- </section>
+ <p class="alert alert-info">
+ <?= t('This chart show the average lead and cycle time for the last %d tasks over the time.', 1000) ?>
+ </p>
<?php endif ?>
diff --git a/app/Template/analytic/sidebar.php b/app/Template/analytic/sidebar.php
index f768a11d..d5ce88cb 100644
--- a/app/Template/analytic/sidebar.php
+++ b/app/Template/analytic/sidebar.php
@@ -1,28 +1,27 @@
<div class="sidebar">
<ul>
<li <?= $this->app->checkMenuSelection('AnalyticController', 'taskDistribution') ?>>
- <?= $this->url->link(t('Task distribution'), 'AnalyticController', 'taskDistribution', array('project_id' => $project['id'])) ?>
+ <?= $this->modal->replaceLink(t('Task distribution'), 'AnalyticController', 'taskDistribution', array('project_id' => $project['id'])) ?>
</li>
<li <?= $this->app->checkMenuSelection('AnalyticController', 'userDistribution') ?>>
- <?= $this->url->link(t('User repartition'), 'AnalyticController', 'userDistribution', array('project_id' => $project['id'])) ?>
+ <?= $this->modal->replaceLink(t('User repartition'), 'AnalyticController', 'userDistribution', array('project_id' => $project['id'])) ?>
</li>
<li <?= $this->app->checkMenuSelection('AnalyticController', 'cfd') ?>>
- <?= $this->url->link(t('Cumulative flow diagram'), 'AnalyticController', 'cfd', array('project_id' => $project['id'])) ?>
+ <?= $this->modal->replaceLink(t('Cumulative flow diagram'), 'AnalyticController', 'cfd', array('project_id' => $project['id'])) ?>
</li>
<li <?= $this->app->checkMenuSelection('AnalyticController', 'burndown') ?>>
- <?= $this->url->link(t('Burndown chart'), 'AnalyticController', 'burndown', array('project_id' => $project['id'])) ?>
+ <?= $this->modal->replaceLink(t('Burndown chart'), 'AnalyticController', 'burndown', array('project_id' => $project['id'])) ?>
</li>
<li <?= $this->app->checkMenuSelection('AnalyticController', 'averageTimeByColumn') ?>>
- <?= $this->url->link(t('Average time into each column'), 'AnalyticController', 'averageTimeByColumn', array('project_id' => $project['id'])) ?>
+ <?= $this->modal->replaceLink(t('Average time into each column'), 'AnalyticController', 'averageTimeByColumn', array('project_id' => $project['id'])) ?>
</li>
<li <?= $this->app->checkMenuSelection('AnalyticController', 'leadAndCycleTime') ?>>
- <?= $this->url->link(t('Lead and cycle time'), 'AnalyticController', 'leadAndCycleTime', array('project_id' => $project['id'])) ?>
+ <?= $this->modal->replaceLink(t('Lead and cycle time'), 'AnalyticController', 'leadAndCycleTime', array('project_id' => $project['id'])) ?>
</li>
<li <?= $this->app->checkMenuSelection('AnalyticController', 'timeComparison') ?>>
- <?= $this->url->link(t('Estimated vs actual time'), 'AnalyticController', 'timeComparison', array('project_id' => $project['id'])) ?>
+ <?= $this->modal->replaceLink(t('Estimated vs actual time'), 'AnalyticController', 'timeComparison', array('project_id' => $project['id'])) ?>
</li>
<?= $this->hook->render('template:analytic:sidebar', array('project' => $project)) ?>
-
</ul>
</div>
diff --git a/app/Template/analytic/task_distribution.php b/app/Template/analytic/task_distribution.php
index 311e8c65..671d462f 100644
--- a/app/Template/analytic/task_distribution.php
+++ b/app/Template/analytic/task_distribution.php
@@ -1,11 +1,15 @@
-<div class="page-header">
- <h2><?= t('Task distribution') ?></h2>
-</div>
+<?php if (! $is_ajax): ?>
+ <div class="page-header">
+ <h2><?= t('Task distribution') ?></h2>
+ </div>
+<?php endif ?>
<?php if (empty($metrics)): ?>
<p class="alert"><?= t('Not enough data to show the graph.') ?></p>
<?php else: ?>
- <chart-project-task-distribution :metrics='<?= json_encode($metrics, JSON_HEX_APOS) ?>'></chart-project-task-distribution>
+ <?= $this->app->component('chart-project-task-distribution', array(
+ 'metrics' => $metrics,
+ )) ?>
<table class="table-striped">
<tr>
diff --git a/app/Template/analytic/time_comparison.php b/app/Template/analytic/time_comparison.php
index ee0ee4b6..754c68f2 100644
--- a/app/Template/analytic/time_comparison.php
+++ b/app/Template/analytic/time_comparison.php
@@ -1,8 +1,10 @@
-<div class="page-header">
- <h2><?= t('Estimated vs actual time') ?></h2>
-</div>
+<?php if (! $is_ajax): ?>
+ <div class="page-header">
+ <h2><?= t('Estimated vs actual time') ?></h2>
+ </div>
+<?php endif ?>
-<div class="listing">
+<div class="panel">
<ul>
<li><?= t('Estimated hours: ').'<strong>'.$this->text->e($metrics['open']['time_estimated'] + $metrics['closed']['time_estimated']) ?></strong></li>
<li><?= t('Actual hours: ').'<strong>'.$this->text->e($metrics['open']['time_spent'] + $metrics['closed']['time_spent']) ?></strong></li>
@@ -15,21 +17,21 @@
<?php if ($paginator->isEmpty()): ?>
<p class="alert"><?= t('No tasks found.') ?></p>
<?php elseif (! $paginator->isEmpty()): ?>
- <chart-project-time-comparison
- :metrics='<?= json_encode($metrics, JSON_HEX_APOS)?>'
- label-spent="<?= t('Hours Spent') ?>"
- label-estimated="<?= t('Hours Estimated') ?>"
- label-closed="<?= t('Closed') ?>"
- label-open="<?= t('Open') ?>">
- </chart-project-time-comparison>
+ <?= $this->app->component('chart-project-time-comparison', array(
+ 'metrics' => $metrics,
+ 'labelSpent' => t('Hours Spent'),
+ 'labelEstimated' => t('Hours Estimated'),
+ 'labelClosed' => t('Closed'),
+ 'labelOpen' => t('Open'),
+ )) ?>
<table class="table-fixed table-small table-scrolling">
<tr>
<th class="column-5"><?= $paginator->order(t('Id'), 'tasks.id') ?></th>
<th><?= $paginator->order(t('Title'), 'tasks.title') ?></th>
- <th class="column-5"><?= $paginator->order(t('Status'), 'tasks.is_active') ?></th>
- <th class="column-10"><?= $paginator->order(t('Estimated Time'), 'tasks.time_estimated') ?></th>
- <th class="column-10"><?= $paginator->order(t('Actual Time'), 'tasks.time_spent') ?></th>
+ <th class="column-10"><?= $paginator->order(t('Status'), 'tasks.is_active') ?></th>
+ <th class="column-12"><?= $paginator->order(t('Estimated Time'), 'tasks.time_estimated') ?></th>
+ <th class="column-12"><?= $paginator->order(t('Actual Time'), 'tasks.time_spent') ?></th>
</tr>
<?php foreach ($paginator->getCollection() as $task): ?>
<tr>
diff --git a/app/Template/analytic/user_distribution.php b/app/Template/analytic/user_distribution.php
index c3cf4961..cae6fa57 100644
--- a/app/Template/analytic/user_distribution.php
+++ b/app/Template/analytic/user_distribution.php
@@ -1,11 +1,15 @@
-<div class="page-header">
- <h2><?= t('User repartition') ?></h2>
-</div>
+<?php if (! $is_ajax): ?>
+ <div class="page-header">
+ <h2><?= t('User repartition') ?></h2>
+ </div>
+<?php endif ?>
<?php if (empty($metrics)): ?>
<p class="alert"><?= t('Not enough data to show the graph.') ?></p>
<?php else: ?>
- <chart-project-user-distribution :metrics='<?= json_encode($metrics, JSON_HEX_APOS) ?>'></chart-project-user-distribution>
+ <?= $this->app->component('chart-project-user-distribution', array(
+ 'metrics' => $metrics,
+ )) ?>
<table class="table-striped">
<tr>
diff --git a/app/Template/board/table_column.php b/app/Template/board/table_column.php
index e2976f27..df16715f 100644
--- a/app/Template/board/table_column.php
+++ b/app/Template/board/table_column.php
@@ -14,7 +14,7 @@
<div class="board-column-expanded">
<?php if (! $not_editable && $this->projectRole->canCreateTaskInColumn($column['project_id'], $column['id'])): ?>
<div class="board-add-icon">
- <?= $this->url->link('+', 'TaskCreationController', 'show', array('project_id' => $column['project_id'], 'column_id' => $column['id'], 'swimlane_id' => $swimlane['id']), false, 'popover', t('Add a new task')) ?>
+ <?= $this->modal->largeIcon('plus', t('Add a new task'), 'TaskCreationController', 'show', array('project_id' => $column['project_id'], 'column_id' => $column['id'], 'swimlane_id' => $swimlane['id'])) ?>
</div>
<?php endif ?>
@@ -37,15 +37,13 @@
</li>
<?php if ($this->projectRole->canCreateTaskInColumn($column['project_id'], $column['id'])): ?>
<li>
- <i class="fa fa-align-justify fa-fw" aria-hidden="true"></i>
- <?= $this->url->link(t('Create tasks in bulk'), 'TaskBulkController', 'show', array('project_id' => $column['project_id'], 'column_id' => $column['id'], 'swimlane_id' => $swimlane['id']), false, 'popover') ?>
+ <?= $this->modal->medium('align-justify', t('Create tasks in bulk'), 'TaskBulkController', 'show', array('project_id' => $column['project_id'], 'column_id' => $column['id'], 'swimlane_id' => $swimlane['id'])) ?>
</li>
<?php endif ?>
<?php if ($column['nb_tasks'] > 0 && $this->projectRole->canChangeTaskStatusInColumn($column['project_id'], $column['id'])): ?>
<li>
- <i class="fa fa-close fa-fw"></i>
- <?= $this->url->link(t('Close all tasks of this column'), 'BoardPopoverController', 'confirmCloseColumnTasks', array('project_id' => $column['project_id'], 'column_id' => $column['id'], 'swimlane_id' => $swimlane['id']), false, 'popover') ?>
+ <?= $this->modal->confirm('close', t('Close all tasks of this column'), 'BoardPopoverController', 'confirmCloseColumnTasks', array('project_id' => $column['project_id'], 'column_id' => $column['id'], 'swimlane_id' => $swimlane['id'])) ?>
</li>
<?php endif ?>
@@ -76,6 +74,7 @@
(<span id="task-number-column-<?= $column['id'] ?>"><?= $column['nb_tasks'] ?></span>)
</span>
<?php endif ?>
+ <?= $this->hook->render('template:board:column:header', array('swimlane' => $swimlane, 'column' => $column)) ?>
</div>
</th>
diff --git a/app/Template/board/task_footer.php b/app/Template/board/task_footer.php
index 83a582c6..15f1f713 100644
--- a/app/Template/board/task_footer.php
+++ b/app/Template/board/task_footer.php
@@ -10,7 +10,7 @@
'edit',
array('task_id' => $task['id'], 'project_id' => $task['project_id']),
false,
- 'popover' . (! empty($task['category_description']) ? ' tooltip' : ''),
+ 'js-modal-medium' . (! empty($task['category_description']) ? ' tooltip' : ''),
! empty($task['category_description']) ? $this->text->markdownAttribute($task['category_description']) : t('Change category')
) ?>
<?php endif ?>
diff --git a/app/Template/board/tooltip_files.php b/app/Template/board/tooltip_files.php
index 4e704dac..5cb72741 100644
--- a/app/Template/board/tooltip_files.php
+++ b/app/Template/board/tooltip_files.php
@@ -9,9 +9,9 @@
</tr>
<tr>
<td>
- <i class="fa fa-download fa-fw"></i><?= $this->url->link(t('download'), 'FileViewerController', 'download', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id'])) ?>
+ <?= $this->url->icon('download', t('download'), 'FileViewerController', 'download', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id'])) ?>
<?php if ($file['is_image'] == 1): ?>
- &nbsp;<i class="fa fa-eye"></i> <?= $this->url->link(t('open file'), 'FileViewerController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id']), false, 'popover') ?>
+ &nbsp;<?= $this->modal->large('eye', t('open file'), 'FileViewerController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id'])) ?>
<?php endif ?>
</td>
</tr>
diff --git a/app/Template/board_popover/close_all_tasks_column.php b/app/Template/board_popover/close_all_tasks_column.php
index 57f703e3..ab7c2d47 100644
--- a/app/Template/board_popover/close_all_tasks_column.php
+++ b/app/Template/board_popover/close_all_tasks_column.php
@@ -1,18 +1,15 @@
-<section id="main">
- <div class="page-header">
- <h2><?= t('Do you really want to close all tasks of this column?') ?></h2>
- </div>
- <form method="post" action="<?= $this->url->href('BoardPopoverController', 'closeColumnTasks', array('project_id' => $project['id'])) ?>">
- <?= $this->form->csrf() ?>
- <?= $this->form->hidden('column_id', $values) ?>
- <?= $this->form->hidden('swimlane_id', $values) ?>
+<div class="page-header">
+ <h2><?= t('Do you really want to close all tasks of this column?') ?></h2>
+</div>
+<form method="post" action="<?= $this->url->href('BoardPopoverController', 'closeColumnTasks', array('project_id' => $project['id'])) ?>">
+ <?= $this->form->csrf() ?>
+ <?= $this->form->hidden('column_id', $values) ?>
+ <?= $this->form->hidden('swimlane_id', $values) ?>
- <p class="alert"><?= t('%d task(s) in the column "%s" and the swimlane "%s" will be closed.', $nb_tasks, $column, $swimlane) ?></p>
+ <p class="alert"><?= t('%d task(s) in the column "%s" and the swimlane "%s" will be closed.', $nb_tasks, $column, $swimlane) ?></p>
- <div class="form-actions">
- <button type="submit" class="btn btn-red"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'BoardViewController', 'show', array('project_id' => $project['id']), false, 'close-popover') ?>
- </div>
- </form>
-</section>
+ <?= $this->modal->submitButtons(array(
+ 'submitLabel' => t('Yes'),
+ 'color' => 'red',
+ )) ?>
+</form>
diff --git a/app/Template/calendar/show.php b/app/Template/calendar/show.php
index 3635f627..009fc07e 100644
--- a/app/Template/calendar/show.php
+++ b/app/Template/calendar/show.php
@@ -1,9 +1,9 @@
<section id="main">
<?= $this->projectHeader->render($project, 'CalendarController', 'show') ?>
- <div id="calendar"
- data-save-url="<?= $this->url->href('CalendarController', 'save', array('project_id' => $project['id'])) ?>"
- data-check-url="<?= $this->url->href('CalendarController', 'project', array('project_id' => $project['id'])) ?>"
- data-check-interval="<?= $check_interval ?>"
- >
- </div>
+
+ <?= $this->calendar->render(
+ $this->url->href('CalendarController', 'project', array('project_id' => $project['id'])),
+ $this->url->href('CalendarController', 'save', array('project_id' => $project['id']))
+ ) ?>
+
</section>
diff --git a/app/Template/category/edit.php b/app/Template/category/edit.php
index fac56db3..108826f3 100644
--- a/app/Template/category/edit.php
+++ b/app/Template/category/edit.php
@@ -2,22 +2,17 @@
<h2><?= t('Category modification for the project "%s"', $project['name']) ?></h2>
</div>
-<form class="popover-form" method="post" action="<?= $this->url->href('CategoryController', 'update', array('project_id' => $project['id'], 'category_id' => $values['id'])) ?>" autocomplete="off">
-
+<form method="post" action="<?= $this->url->href('CategoryController', 'update', array('project_id' => $project['id'], 'category_id' => $values['id'])) ?>" autocomplete="off">
<?= $this->form->csrf() ?>
<?= $this->form->hidden('id', $values) ?>
<?= $this->form->hidden('project_id', $values) ?>
<?= $this->form->label(t('Category Name'), 'name') ?>
- <?= $this->form->text('name', $values, $errors, array('autofocus', 'required', 'maxlength="50"')) ?>
+ <?= $this->form->text('name', $values, $errors, array('autofocus', 'required', 'maxlength="50"', 'tabindex="1"')) ?>
<?= $this->form->label(t('Description'), 'description') ?>
- <?= $this->form->textarea('description', $values, $errors, array(), 'markdown-editor') ?>
+ <?= $this->form->textEditor('description', $values, $errors, array('tabindex' => 2)) ?>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'CategoryController', 'index', array('project_id' => $project['id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->submitButtons() ?>
</form>
diff --git a/app/Template/category/index.php b/app/Template/category/index.php
index ac60d9a8..e93138fd 100644
--- a/app/Template/category/index.php
+++ b/app/Template/category/index.php
@@ -15,10 +15,10 @@
<a href="#" class="dropdown-menu dropdown-menu-link-icon"><i class="fa fa-cog fa-fw"></i><i class="fa fa-caret-down"></i></a>
<ul>
<li>
- <?= $this->url->link(t('Edit'), 'CategoryController', 'edit', array('project_id' => $project['id'], 'category_id' => $category_id), false, 'popover') ?>
+ <?= $this->modal->medium('edit', t('Edit'), 'CategoryController', 'edit', array('project_id' => $project['id'], 'category_id' => $category_id)) ?>
</li>
<li>
- <?= $this->url->link(t('Remove'), 'CategoryController', 'confirm', array('project_id' => $project['id'], 'category_id' => $category_id), false, 'popover') ?>
+ <?= $this->modal->confirm('trash-o', t('Remove'), 'CategoryController', 'confirm', array('project_id' => $project['id'], 'category_id' => $category_id)) ?>
</li>
</ul>
</div>
diff --git a/app/Template/category/remove.php b/app/Template/category/remove.php
index e7b9c9b4..79e8a560 100644
--- a/app/Template/category/remove.php
+++ b/app/Template/category/remove.php
@@ -1,17 +1,15 @@
-<section id="main">
- <div class="page-header">
- <h2><?= t('Remove a category') ?></h2>
- </div>
+<div class="page-header">
+ <h2><?= t('Remove a category') ?></h2>
+</div>
- <div class="confirm">
- <p class="alert alert-info">
- <?= t('Do you really want to remove this category: "%s"?', $category['name']) ?>
- </p>
+<div class="confirm">
+ <p class="alert alert-info">
+ <?= t('Do you really want to remove this category: "%s"?', $category['name']) ?>
+ </p>
- <div class="form-actions">
- <?= $this->url->link(t('Yes'), 'CategoryController', 'remove', array('project_id' => $project['id'], 'category_id' => $category['id']), true, 'btn btn-red') ?>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'CategoryController', 'index', array('project_id' => $project['id']), false, 'close-popover') ?>
- </div>
- </div>
-</section>
+ <?= $this->modal->confirmButtons(
+ 'CategoryController',
+ 'remove',
+ array('project_id' => $project['id'], 'category_id' => $category['id'])
+ ) ?>
+</div>
diff --git a/app/Template/column/create.php b/app/Template/column/create.php
index 812e9139..aad9606b 100644
--- a/app/Template/column/create.php
+++ b/app/Template/column/create.php
@@ -1,26 +1,21 @@
<div class="page-header">
<h2><?= t('Add a new column') ?></h2>
</div>
-<form class="popover-form" method="post" action="<?= $this->url->href('ColumnController', 'save', array('project_id' => $project['id'])) ?>" autocomplete="off">
-
+<form method="post" action="<?= $this->url->href('ColumnController', 'save', array('project_id' => $project['id'])) ?>" autocomplete="off">
<?= $this->form->csrf() ?>
<?= $this->form->hidden('project_id', $values) ?>
<?= $this->form->label(t('Title'), 'title') ?>
- <?= $this->form->text('title', $values, $errors, array('autofocus', 'required', 'maxlength="50"')) ?>
+ <?= $this->form->text('title', $values, $errors, array('autofocus', 'required', 'maxlength="50"', 'tabindex="1"')) ?>
<?= $this->form->label(t('Task limit'), 'task_limit') ?>
- <?= $this->form->number('task_limit', $values, $errors) ?>
+ <?= $this->form->number('task_limit', $values, $errors, array('tabindex="2"')) ?>
- <?= $this->form->checkbox('hide_in_dashboard', t('Hide tasks in this column in the dashboard'), 1) ?>
+ <?= $this->form->checkbox('hide_in_dashboard', t('Hide tasks in this column in the dashboard'), 1, false, '', array('tabindex' => 3)) ?>
<?= $this->form->label(t('Description'), 'description') ?>
- <?= $this->form->textarea('description', $values, $errors, array(), 'markdown-editor') ?>
+ <?= $this->form->textEditor('description', $values, $errors, array('tabindex' => 4)) ?>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'column', 'index', array('project_id' => $project['id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->submitButtons() ?>
</form>
diff --git a/app/Template/column/edit.php b/app/Template/column/edit.php
index 89487298..e590b5cc 100644
--- a/app/Template/column/edit.php
+++ b/app/Template/column/edit.php
@@ -2,8 +2,7 @@
<h2><?= t('Edit column "%s"', $column['title']) ?></h2>
</div>
-<form class="popover-form" method="post" action="<?= $this->url->href('ColumnController', 'update', array('project_id' => $project['id'], 'column_id' => $column['id'])) ?>" autocomplete="off">
-
+<form method="post" action="<?= $this->url->href('ColumnController', 'update', array('project_id' => $project['id'], 'column_id' => $column['id'])) ?>" autocomplete="off">
<?= $this->form->csrf() ?>
<?= $this->form->hidden('id', $values) ?>
@@ -18,11 +17,7 @@
<?= $this->form->checkbox('hide_in_dashboard', t('Hide tasks in this column in the dashboard'), 1, $values['hide_in_dashboard'] == 1) ?>
<?= $this->form->label(t('Description'), 'description') ?>
- <?= $this->form->textarea('description', $values, $errors, array(), 'markdown-editor') ?>
+ <?= $this->form->textEditor('description', $values, $errors) ?>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'ColumnController', 'index', array('project_id' => $project['id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->submitButtons() ?>
</form>
diff --git a/app/Template/column/index.php b/app/Template/column/index.php
index 8c96a350..eaaae332 100644
--- a/app/Template/column/index.php
+++ b/app/Template/column/index.php
@@ -2,8 +2,7 @@
<h2><?= t('Edit the board for "%s"', $project['name']) ?></h2>
<ul>
<li>
- <i class="fa fa-plus fa-fw"></i>
- <?= $this->url->link(t('Add a new column'), 'ColumnController', 'create', array('project_id' => $project['id']), false, 'popover') ?>
+ <?= $this->modal->medium('plus', t('Add a new column'), 'ColumnController', 'create', array('project_id' => $project['id'])) ?>
</li>
</ul>
</div>
@@ -17,7 +16,8 @@
<thead>
<tr>
<th class="column-70"><?= t('Column title') ?></th>
- <th class="column-25"><?= t('Task limit') ?></th>
+ <th class="column-10"><?= t('Task limit') ?></th>
+ <th class="column-20"><?= t('Visible on dashboard') ?></th>
<th class="column-5"><?= t('Actions') ?></th>
</tr>
</thead>
@@ -37,16 +37,17 @@
<?= $this->text->e($column['task_limit']) ?>
</td>
<td>
+ <?= $column['hide_in_dashboard'] == 1 ? t('Yes') : t('No') ?>
+ </td>
+ <td>
<div class="dropdown">
<a href="#" class="dropdown-menu dropdown-menu-link-icon"><i class="fa fa-cog fa-fw"></i><i class="fa fa-caret-down"></i></a>
<ul>
<li>
- <i class="fa fa-pencil-square-o fa-fw" aria-hidden="true"></i>
- <?= $this->url->link(t('Edit'), 'ColumnController', 'edit', array('project_id' => $project['id'], 'column_id' => $column['id']), false, 'popover') ?>
+ <?= $this->modal->medium('edit', t('Edit'), 'ColumnController', 'edit', array('project_id' => $project['id'], 'column_id' => $column['id'])) ?>
</li>
<li>
- <i class="fa fa-trash-o fa-fw" aria-hidden="true"></i>
- <?= $this->url->link(t('Remove'), 'ColumnController', 'confirm', array('project_id' => $project['id'], 'column_id' => $column['id']), false, 'popover') ?>
+ <?= $this->modal->confirm('trash-o', t('Remove'), 'ColumnController', 'confirm', array('project_id' => $project['id'], 'column_id' => $column['id'])) ?>
</li>
</ul>
</div>
diff --git a/app/Template/column/remove.php b/app/Template/column/remove.php
index dc0a4712..4134b175 100644
--- a/app/Template/column/remove.php
+++ b/app/Template/column/remove.php
@@ -8,8 +8,9 @@
<?= t('This action will REMOVE ALL TASKS associated to this column!') ?>
</p>
- <div class="form-actions">
- <?= $this->url->link(t('Yes'), 'ColumnController', 'remove', array('project_id' => $project['id'], 'column_id' => $column['id']), true, 'btn btn-red') ?>
- <?= t('or') ?> <?= $this->url->link(t('cancel'), 'ColumnController', 'index', array('project_id' => $project['id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->confirmButtons(
+ 'ColumnController',
+ 'remove',
+ array('project_id' => $project['id'], 'column_id' => $column['id'])
+ ) ?>
</div>
diff --git a/app/Template/column_move_restriction/create.php b/app/Template/column_move_restriction/create.php
index 1eb6d539..852df971 100644
--- a/app/Template/column_move_restriction/create.php
+++ b/app/Template/column_move_restriction/create.php
@@ -1,24 +1,18 @@
-<section id="main">
- <div class="page-header">
- <h2><?= t('New drag and drop restriction for the role "%s"', $role['role']) ?></h2>
- </div>
- <form class="popover-form" method="post" action="<?= $this->url->href('ColumnMoveRestrictionController', 'save', array('project_id' => $project['id'])) ?>" autocomplete="off">
- <?= $this->form->csrf() ?>
- <?= $this->form->hidden('project_id', $values) ?>
- <?= $this->form->hidden('role_id', $values) ?>
+<div class="page-header">
+ <h2><?= t('New drag and drop restriction for the role "%s"', $role['role']) ?></h2>
+</div>
+<form method="post" action="<?= $this->url->href('ColumnMoveRestrictionController', 'save', array('project_id' => $project['id'])) ?>" autocomplete="off">
+ <?= $this->form->csrf() ?>
+ <?= $this->form->hidden('project_id', $values) ?>
+ <?= $this->form->hidden('role_id', $values) ?>
- <?= $this->form->label(t('Source column'), 'src_column_id') ?>
- <?= $this->form->select('src_column_id', $columns, $values, $errors) ?>
+ <?= $this->form->label(t('Source column'), 'src_column_id') ?>
+ <?= $this->form->select('src_column_id', $columns, $values, $errors) ?>
- <?= $this->form->label(t('Destination column'), 'dst_column_id') ?>
- <?= $this->form->select('dst_column_id', $columns, $values, $errors) ?>
+ <?= $this->form->label(t('Destination column'), 'dst_column_id') ?>
+ <?= $this->form->select('dst_column_id', $columns, $values, $errors) ?>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'ProjectRoleController', 'show', array(), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->submitButtons() ?>
- <p class="alert alert-info"><?= t('People belonging to this role will be able to move tasks only between the source and the destination column.') ?></p>
- </form>
-</section>
+ <p class="alert alert-info"><?= t('People belonging to this role will be able to move tasks only between the source and the destination column.') ?></p>
+</form>
diff --git a/app/Template/column_move_restriction/remove.php b/app/Template/column_move_restriction/remove.php
index 1985e167..4902cd23 100644
--- a/app/Template/column_move_restriction/remove.php
+++ b/app/Template/column_move_restriction/remove.php
@@ -7,8 +7,9 @@
<?= t('Do you really want to remove this column restriction: "%s" to "%s"?', $restriction['src_column_title'], $restriction['dst_column_title']) ?>
</p>
- <div class="form-actions">
- <?= $this->url->link(t('Yes'), 'ColumnMoveRestrictionController', 'remove', array('project_id' => $project['id'], 'restriction_id' => $restriction['restriction_id']), true, 'btn btn-red') ?>
- <?= t('or') ?> <?= $this->url->link(t('cancel'), 'ProjectRoleController', 'show', array('project_id' => $project['id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->confirmButtons(
+ 'ColumnMoveRestrictionController',
+ 'remove',
+ array('project_id' => $project['id'], 'restriction_id' => $restriction['restriction_id'])
+ ) ?>
</div>
diff --git a/app/Template/column_restriction/create.php b/app/Template/column_restriction/create.php
index 982733b4..be158f19 100644
--- a/app/Template/column_restriction/create.php
+++ b/app/Template/column_restriction/create.php
@@ -1,22 +1,16 @@
-<section id="main">
- <div class="page-header">
- <h2><?= t('New column restriction for the role "%s"', $role['role']) ?></h2>
- </div>
- <form class="popover-form" method="post" action="<?= $this->url->href('ColumnRestrictionController', 'save', array('project_id' => $project['id'])) ?>" autocomplete="off">
- <?= $this->form->csrf() ?>
- <?= $this->form->hidden('project_id', $values) ?>
- <?= $this->form->hidden('role_id', $values) ?>
+<div class="page-header">
+ <h2><?= t('New column restriction for the role "%s"', $role['role']) ?></h2>
+</div>
+<form method="post" action="<?= $this->url->href('ColumnRestrictionController', 'save', array('project_id' => $project['id'])) ?>" autocomplete="off">
+ <?= $this->form->csrf() ?>
+ <?= $this->form->hidden('project_id', $values) ?>
+ <?= $this->form->hidden('role_id', $values) ?>
- <?= $this->form->label(t('Rule'), 'rule') ?>
- <?= $this->form->select('rule', $rules, $values, $errors) ?>
+ <?= $this->form->label(t('Rule'), 'rule') ?>
+ <?= $this->form->select('rule', $rules, $values, $errors) ?>
- <?= $this->form->label(t('Column'), 'column_id') ?>
- <?= $this->form->select('column_id', $columns, $values, $errors) ?>
+ <?= $this->form->label(t('Column'), 'column_id') ?>
+ <?= $this->form->select('column_id', $columns, $values, $errors) ?>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'ProjectRoleController', 'show', array(), false, 'close-popover') ?>
- </div>
- </form>
-</section>
+ <?= $this->modal->submitButtons() ?>
+</form>
diff --git a/app/Template/column_restriction/remove.php b/app/Template/column_restriction/remove.php
index 97650e2d..edbd9d6e 100644
--- a/app/Template/column_restriction/remove.php
+++ b/app/Template/column_restriction/remove.php
@@ -7,8 +7,9 @@
<?= t('Do you really want to remove this column restriction?') ?>
</p>
- <div class="form-actions">
- <?= $this->url->link(t('Yes'), 'ColumnRestrictionController', 'remove', array('project_id' => $project['id'], 'restriction_id' => $restriction['restriction_id']), true, 'btn btn-red') ?>
- <?= t('or') ?> <?= $this->url->link(t('cancel'), 'ProjectRoleController', 'show', array('project_id' => $project['id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->confirmButtons(
+ 'ColumnRestrictionController',
+ 'remove',
+ array('project_id' => $project['id'], 'restriction_id' => $restriction['restriction_id'])
+ ) ?>
</div>
diff --git a/app/Template/comment/create.php b/app/Template/comment/create.php
index 0358107a..8a421759 100644
--- a/app/Template/comment/create.php
+++ b/app/Template/comment/create.php
@@ -1,29 +1,12 @@
<div class="page-header">
<h2><?= t('Add a comment') ?></h2>
</div>
-<form class="popover-form" method="post" action="<?= $this->url->href('CommentController', 'save', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>" autocomplete="off">
+<form method="post" action="<?= $this->url->href('CommentController', 'save', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>" autocomplete="off">
<?= $this->form->csrf() ?>
<?= $this->form->hidden('task_id', $values) ?>
<?= $this->form->hidden('user_id', $values) ?>
- <div class="markdown-editor-small">
- <?= $this->form->textarea(
- 'comment',
- $values,
- $errors,
- array(
- 'autofocus',
- 'required',
- 'placeholder="'.t('Leave a comment').'"',
- 'data-mention-search-url="'.$this->url->href('UserAjaxController', 'mention', array('project_id' => $task['project_id'])).'"',
- ),
- 'markdown-editor'
- ) ?>
- </div>
+ <?= $this->form->textEditor('comment', $values, $errors, array('autofocus' => true, 'required' => true)) ?>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->submitButtons() ?>
</form>
diff --git a/app/Template/comment/edit.php b/app/Template/comment/edit.php
index f69fc0c1..04f6ffd4 100644
--- a/app/Template/comment/edit.php
+++ b/app/Template/comment/edit.php
@@ -2,26 +2,13 @@
<h2><?= t('Edit a comment') ?></h2>
</div>
-<form class="popover-form" method="post" action="<?= $this->url->href('CommentController', 'update', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'comment_id' => $comment['id'])) ?>" autocomplete="off">
-
+<form method="post" action="<?= $this->url->href('CommentController', 'update', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'comment_id' => $comment['id'])) ?>" autocomplete="off">
<?= $this->form->csrf() ?>
<?= $this->form->hidden('id', $values) ?>
<?= $this->form->hidden('task_id', $values) ?>
<?= $this->form->hidden('user_id', $values) ?>
- <div class="markdown-editor-small">
- <?= $this->form->textarea(
- 'comment',
- $values,
- $errors,
- array('autofocus', 'required', 'placeholder="'.t('Leave a comment').'"'),
- 'markdown-editor'
- ) ?>
- </div>
+ <?= $this->form->textEditor('comment', $values, $errors, array('autofocus' => true, 'required' => true)) ?>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->submitButtons() ?>
</form>
diff --git a/app/Template/comment/remove.php b/app/Template/comment/remove.php
index 55587b67..03f16e00 100644
--- a/app/Template/comment/remove.php
+++ b/app/Template/comment/remove.php
@@ -13,9 +13,9 @@
'hide_actions' => true
)) ?>
- <div class="form-actions">
- <?= $this->url->link(t('Yes'), 'CommentController', 'remove', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'comment_id' => $comment['id']), true, 'btn btn-red') ?>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->confirmButtons(
+ 'CommentController',
+ 'remove',
+ array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'comment_id' => $comment['id'])
+ ) ?>
</div>
diff --git a/app/Template/comment/show.php b/app/Template/comment/show.php
index 16a807bc..f8d9607e 100644
--- a/app/Template/comment/show.php
+++ b/app/Template/comment/show.php
@@ -7,7 +7,9 @@
<strong class="comment-username"><?= $this->text->e($comment['name'] ?: $comment['username']) ?></strong>
<?php endif ?>
- <small class="comment-date"><?= $this->dt->datetime($comment['date_creation']) ?></small>
+ <small class="comment-date"><?= t('Created at:') ?> <?= $this->dt->datetime($comment['date_creation']) ?></small>
+ <small class="comment-date"><?= t('Updated at:')?> <?= $this->dt->datetime($comment['date_modification']) ?></small>
+
</div>
<div class="comment-content">
@@ -25,12 +27,10 @@
</li>
<?php if ($editable && ($this->user->isAdmin() || $this->user->isCurrentUser($comment['user_id']))): ?>
<li>
- <i class="fa fa-remove fa-fw"></i>
- <?= $this->url->link(t('remove'), 'CommentController', 'confirm', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'comment_id' => $comment['id']), false, 'popover') ?>
+ <?= $this->modal->medium('edit', t('edit'), 'CommentController', 'edit', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'comment_id' => $comment['id'])) ?>
</li>
<li>
- <i class="fa fa-edit fa-fw"></i>
- <?= $this->url->link(t('edit'), 'CommentController', 'edit', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'comment_id' => $comment['id']), false, 'popover') ?>
+ <?= $this->modal->confirm('trash-o', t('remove'), 'CommentController', 'confirm', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'comment_id' => $comment['id'])) ?>
</li>
<?php endif ?>
</ul>
diff --git a/app/Template/comments/create.php b/app/Template/comments/create.php
index 3fa6ddc0..06173575 100644
--- a/app/Template/comments/create.php
+++ b/app/Template/comments/create.php
@@ -3,20 +3,7 @@
<?= $this->form->hidden('task_id', $values) ?>
<?= $this->form->hidden('user_id', $values) ?>
- <div class="markdown-editor-small">
- <?= $this->form->textarea(
- 'comment',
- $values,
- $errors,
- array(
- 'data-markdown-editor-disable-toolbar="true"',
- 'required',
- 'placeholder="'.t('Leave a comment').'"',
- 'data-mention-search-url="'.$this->url->href('UserAjaxController', 'mention', array('project_id' => $task['project_id'])).'"',
- ),
- 'markdown-editor'
- ) ?>
- </div>
+ <?= $this->form->textEditor('comment', $values, $errors, array('required' => true)) ?>
<div class="form-actions">
<button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
diff --git a/app/Template/comments/show.php b/app/Template/comments/show.php
index 5c6d8e20..3edf7076 100644
--- a/app/Template/comments/show.php
+++ b/app/Template/comments/show.php
@@ -6,8 +6,7 @@
<?php if (!isset($is_public) || !$is_public): ?>
<div class="comment-sorting">
<small>
- <i class="fa fa-sort"></i>
- <?= $this->url->link(t('change sorting'), 'CommentController', 'toggleSorting', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
+ <?= $this->url->icon('sort', t('change sorting'), 'CommentController', 'toggleSorting', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</small>
</div>
<?php endif ?>
@@ -26,6 +25,7 @@
'values' => array(
'user_id' => $this->user->getId(),
'task_id' => $task['id'],
+ 'project_id' => $task['project_id'],
),
'errors' => array(),
'task' => $task,
diff --git a/app/Template/config/about.php b/app/Template/config/about.php
index 8d5a575d..3f078c3d 100644
--- a/app/Template/config/about.php
+++ b/app/Template/config/about.php
@@ -1,7 +1,7 @@
<div class="page-header">
<h2><?= t('About') ?></h2>
</div>
-<div class="listing">
+<div class="panel">
<ul>
<li>
<?= t('Official website:') ?>
@@ -21,7 +21,7 @@
<div class="page-header">
<h2><?= t('Configuration') ?></h2>
</div>
-<div class="listing">
+<div class="panel">
<ul>
<li>
<?= t('Application version:') ?>
@@ -58,7 +58,7 @@
<div class="page-header">
<h2><?= t('Database') ?></h2>
</div>
- <div class="listing">
+ <div class="panel">
<ul>
<li>
<?= t('Database size:') ?>
@@ -81,6 +81,6 @@
<div class="page-header">
<h2><?= t('License') ?></h2>
</div>
-<div class="listing">
+<div class="panel">
<?= nl2br(file_get_contents(ROOT_DIR.DIRECTORY_SEPARATOR.'LICENSE')) ?>
</div>
diff --git a/app/Template/config/api.php b/app/Template/config/api.php
index 95f77355..9a3b06ce 100644
--- a/app/Template/config/api.php
+++ b/app/Template/config/api.php
@@ -1,7 +1,7 @@
<div class="page-header">
<h2><?= t('API') ?></h2>
</div>
-<section class="listing">
+<div class="panel">
<ul>
<li>
<?= t('API token:') ?>
@@ -9,10 +9,10 @@
</li>
<li>
<?= t('API endpoint:') ?>
- <input type="text" class="auto-select" readonly="readonly" value="<?= $this->url->base().'jsonrpc.php' ?>">
- </li>
- <li>
- <?= $this->url->link(t('Reset token'), 'ConfigController', 'token', array('type' => 'api'), true) ?>
+ <strong><?= $this->url->base().'jsonrpc.php' ?></strong>
</li>
</ul>
-</section>
+</div>
+
+<?= $this->url->link(t('Reset token'), 'ConfigController', 'token', array('type' => 'api'), true, 'btn btn-red') ?>
+
diff --git a/app/Template/config/application.php b/app/Template/config/application.php
index 0f842f6e..d3d8c858 100644
--- a/app/Template/config/application.php
+++ b/app/Template/config/application.php
@@ -2,33 +2,35 @@
<h2><?= t('Application settings') ?></h2>
</div>
<form method="post" action="<?= $this->url->href('ConfigController', 'save', array('redirect' => 'application')) ?>" autocomplete="off">
-
<?= $this->form->csrf() ?>
- <?= $this->form->label(t('Application URL'), 'application_url') ?>
- <?= $this->form->text('application_url', $values, $errors, array('placeholder="http://example.kanboard.net/"')) ?>
- <p class="form-help"><?= t('Example: http://example.kanboard.net/ (used to generate absolute URLs)') ?></p>
-
- <?= $this->form->label(t('Language'), 'application_language') ?>
- <?= $this->form->select('application_language', $languages, $values, $errors) ?>
+ <fieldset>
+ <?= $this->form->label(t('Application URL'), 'application_url') ?>
+ <?= $this->form->text('application_url', $values, $errors, array('placeholder="http://example.kanboard.net/"')) ?>
+ <p class="form-help"><?= t('Example: http://example.kanboard.net/ (used to generate absolute URLs)') ?></p>
- <?= $this->form->label(t('Timezone'), 'application_timezone') ?>
- <?= $this->form->select('application_timezone', $timezones, $values, $errors) ?>
+ <?= $this->form->label(t('Language'), 'application_language') ?>
+ <?= $this->form->select('application_language', $languages, $values, $errors) ?>
- <?= $this->form->label(t('Date format'), 'application_date_format') ?>
- <?= $this->form->select('application_date_format', $date_formats, $values, $errors) ?>
- <p class="form-help"><?= t('ISO format is always accepted, example: "%s" and "%s"', date('Y-m-d'), date('Y_m_d')) ?></p>
+ <?= $this->form->checkbox('password_reset', t('Enable "Forget Password"'), 1, $values['password_reset'] == 1) ?>
+ </fieldset>
- <?= $this->form->label(t('Date and time format'), 'application_datetime_format') ?>
- <?= $this->form->select('application_datetime_format', $datetime_formats, $values, $errors) ?>
+ <fieldset>
+ <?= $this->form->label(t('Timezone'), 'application_timezone') ?>
+ <?= $this->form->select('application_timezone', $timezones, $values, $errors) ?>
- <?= $this->form->label(t('Time format'), 'application_time_format') ?>
- <?= $this->form->select('application_time_format', $time_formats, $values, $errors) ?>
+ <?= $this->form->label(t('Date format'), 'application_date_format') ?>
+ <?= $this->form->select('application_date_format', $date_formats, $values, $errors) ?>
+ <p class="form-help"><?= t('ISO format is always accepted, example: "%s" and "%s"', date('Y-m-d'), date('Y_m_d')) ?></p>
- <?= $this->form->checkbox('password_reset', t('Enable "Forget Password"'), 1, $values['password_reset'] == 1) ?>
+ <?= $this->form->label(t('Time format'), 'application_time_format') ?>
+ <?= $this->form->select('application_time_format', $time_formats, $values, $errors) ?>
+ </fieldset>
- <?= $this->form->label(t('Custom Stylesheet'), 'application_stylesheet') ?>
- <?= $this->form->textarea('application_stylesheet', $values, $errors) ?>
+ <fieldset>
+ <?= $this->form->label(t('Custom Stylesheet'), 'application_stylesheet') ?>
+ <?= $this->form->textarea('application_stylesheet', $values, $errors) ?>
+ </fieldset>
<?= $this->hook->render('template:config:application', array('values' => $values, 'errors' => $errors)) ?>
diff --git a/app/Template/config/board.php b/app/Template/config/board.php
index 62a736e7..35058f0f 100644
--- a/app/Template/config/board.php
+++ b/app/Template/config/board.php
@@ -2,20 +2,21 @@
<h2><?= t('Board settings') ?></h2>
</div>
<form method="post" action="<?= $this->url->href('ConfigController', 'save', array('redirect' => 'board')) ?>" autocomplete="off">
-
<?= $this->form->csrf() ?>
- <?= $this->form->label(t('Task highlight period'), 'board_highlight_period') ?>
- <?= $this->form->number('board_highlight_period', $values, $errors) ?>
- <p class="form-help"><?= t('Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)') ?></p>
+ <fieldset>
+ <?= $this->form->label(t('Task highlight period'), 'board_highlight_period') ?>
+ <?= $this->form->number('board_highlight_period', $values, $errors) ?>
+ <p class="form-help"><?= t('Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)') ?></p>
- <?= $this->form->label(t('Refresh interval for public board'), 'board_public_refresh_interval') ?>
- <?= $this->form->number('board_public_refresh_interval', $values, $errors) ?>
- <p class="form-help"><?= t('Frequency in second (60 seconds by default)') ?></p>
+ <?= $this->form->label(t('Refresh interval for public board'), 'board_public_refresh_interval') ?>
+ <?= $this->form->number('board_public_refresh_interval', $values, $errors) ?>
+ <p class="form-help"><?= t('Frequency in second (60 seconds by default)') ?></p>
- <?= $this->form->label(t('Refresh interval for private board'), 'board_private_refresh_interval') ?>
- <?= $this->form->number('board_private_refresh_interval', $values, $errors) ?>
- <p class="form-help"><?= t('Frequency in second (0 to disable this feature, 10 seconds by default)') ?></p>
+ <?= $this->form->label(t('Refresh interval for private board'), 'board_private_refresh_interval') ?>
+ <?= $this->form->number('board_private_refresh_interval', $values, $errors) ?>
+ <p class="form-help"><?= t('Frequency in second (0 to disable this feature, 10 seconds by default)') ?></p>
+ </fieldset>
<div class="form-actions">
<button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
diff --git a/app/Template/config/calendar.php b/app/Template/config/calendar.php
index 90e034e9..0cc3d064 100644
--- a/app/Template/config/calendar.php
+++ b/app/Template/config/calendar.php
@@ -1,34 +1,36 @@
<div class="page-header">
<h2><?= t('Calendar settings') ?></h2>
</div>
-<section>
<form method="post" action="<?= $this->url->href('ConfigController', 'save', array('redirect' => 'calendar')) ?>" autocomplete="off">
<?= $this->form->csrf() ?>
- <div class="listing">
- <h3><?= t('Project calendar view') ?></h3>
+ <fieldset>
+ <legend><?= t('Project calendar view') ?></legend>
<?= $this->form->radios('calendar_project_tasks', array(
'date_creation' => t('Show tasks based on the creation date'),
'date_started' => t('Show tasks based on the start date'),
- ), $values) ?>
- </div>
+ ),
+ $values
+ ) ?>
+ </fieldset>
- <div class="listing">
- <h3><?= t('User calendar view') ?></h3>
+ <fieldset>
+ <legend><?= t('User calendar view') ?></legend>
<?= $this->form->radios('calendar_user_tasks', array(
'date_creation' => t('Show tasks based on the creation date'),
'date_started' => t('Show tasks based on the start date'),
- ), $values) ?>
- </div>
+ ),
+ $values
+ ) ?>
+ </fieldset>
- <div class="listing">
- <h3><?= t('Subtasks time tracking') ?></h3>
+ <fieldset>
+ <legend><?= t('Subtasks time tracking') ?></legend>
<?= $this->form->checkbox('calendar_user_subtasks_time_tracking', t('Show subtasks based on the time tracking'), 1, $values['calendar_user_subtasks_time_tracking'] == 1) ?>
- </div>
+ </fieldset>
<div class="form-actions">
<button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
</div>
</form>
-</section>
diff --git a/app/Template/config/email.php b/app/Template/config/email.php
index 6ff76eca..be729f5d 100644
--- a/app/Template/config/email.php
+++ b/app/Template/config/email.php
@@ -4,11 +4,18 @@
<form method="post" action="<?= $this->url->href('ConfigController', 'save', array('redirect' => 'email')) ?>" autocomplete="off">
<?= $this->form->csrf() ?>
- <?= $this->form->label(t('Email sender address'), 'mail_sender_address') ?>
- <?= $this->form->text('mail_sender_address', $values, $errors, array('placeholder="'.MAIL_FROM.'"')) ?>
+ <fieldset>
+ <legend><?= t('Outgoing Emails') ?></legend>
+ <?php if (MAIL_CONFIGURATION): ?>
+ <?= $this->form->label(t('Email sender address'), 'mail_sender_address') ?>
+ <?= $this->form->text('mail_sender_address', $values, $errors, array('placeholder="'.MAIL_FROM.'"')) ?>
- <?= $this->form->label(t('Email transport'), 'mail_transport') ?>
- <?= $this->form->select('mail_transport', $mail_transports, $values, $errors) ?>
+ <?= $this->form->label(t('Email transport'), 'mail_transport') ?>
+ <?= $this->form->select('mail_transport', $mail_transports, $values, $errors) ?>
+ <?php else: ?>
+ <p class="alert"><?= t('The email configuration has been disabled by the administrator.') ?></p>
+ <?php endif ?>
+ </fieldset>
<?= $this->hook->render('template:config:email', array('values' => $values, 'errors' => $errors)) ?>
diff --git a/app/Template/config/integrations.php b/app/Template/config/integrations.php
index 3ba4e865..07a90ce2 100644
--- a/app/Template/config/integrations.php
+++ b/app/Template/config/integrations.php
@@ -7,11 +7,11 @@
<?= $this->hook->render('template:config:integrations', array('values' => $values)) ?>
<h3><img src="<?= $this->url->dir() ?>assets/img/gravatar-icon.png"/>&nbsp;<?= t('Gravatar') ?></h3>
- <div class="listing">
+ <div class="panel">
<?= $this->form->checkbox('integration_gravatar', t('Enable Gravatar images'), 1, $values['integration_gravatar'] == 1) ?>
+ <div class="form-actions">
+ <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
+ </div>
</div>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- </div>
</form>
diff --git a/app/Template/config/keyboard_shortcuts.php b/app/Template/config/keyboard_shortcuts.php
index 1b1a9477..6ac71ee0 100644
--- a/app/Template/config/keyboard_shortcuts.php
+++ b/app/Template/config/keyboard_shortcuts.php
@@ -1,7 +1,7 @@
<div class="page-header">
<h2><?= t('Keyboard shortcuts') ?></h2>
</div>
-<div class="listing">
+<div class="panel">
<h3><?= t('Board/Calendar/List view') ?></h3>
<ul>
<li><?= t('Switch to the project overview') ?> = <strong>v o</strong></li>
diff --git a/app/Template/config/project.php b/app/Template/config/project.php
index 6d8d131a..514a9baa 100644
--- a/app/Template/config/project.php
+++ b/app/Template/config/project.php
@@ -2,24 +2,27 @@
<h2><?= t('Project settings') ?></h2>
</div>
<form method="post" action="<?= $this->url->href('ConfigController', 'save', array('redirect' => 'project')) ?>" autocomplete="off">
-
<?= $this->form->csrf() ?>
- <?= $this->form->label(t('Default task color'), 'default_color') ?>
- <?= $this->form->select('default_color', $colors, $values, $errors) ?>
+ <fieldset>
+ <?= $this->form->label(t('Default task color'), 'default_color') ?>
+ <?= $this->form->select('default_color', $colors, $values, $errors) ?>
- <?= $this->form->label(t('Default columns for new projects (Comma-separated)'), 'board_columns') ?>
- <?= $this->form->text('board_columns', $values, $errors) ?>
- <p class="form-help"><?= t('Default values are "%s"', $default_columns) ?></p>
+ <?= $this->form->label(t('Default columns for new projects (Comma-separated)'), 'board_columns') ?>
+ <?= $this->form->text('board_columns', $values, $errors) ?>
+ <p class="form-help"><?= t('Default values are "%s"', $default_columns) ?></p>
- <?= $this->form->label(t('Default categories for new projects (Comma-separated)'), 'project_categories') ?>
- <?= $this->form->text('project_categories', $values, $errors) ?>
- <p class="form-help"><?= t('Example: "Bug, Feature Request, Improvement"') ?></p>
+ <?= $this->form->label(t('Default categories for new projects (Comma-separated)'), 'project_categories') ?>
+ <?= $this->form->text('project_categories', $values, $errors) ?>
+ <p class="form-help"><?= t('Example: "Bug, Feature Request, Improvement"') ?></p>
+ </fieldset>
- <?= $this->form->checkbox('disable_private_project', t('Disable private projects'), 1, isset($values['disable_private_project']) && $values['disable_private_project'] == 1) ?>
- <?= $this->form->checkbox('subtask_restriction', t('Allow only one subtask in progress at the same time for a user'), 1, $values['subtask_restriction'] == 1) ?>
- <?= $this->form->checkbox('subtask_time_tracking', t('Trigger automatically subtask time tracking'), 1, $values['subtask_time_tracking'] == 1) ?>
- <?= $this->form->checkbox('cfd_include_closed_tasks', t('Include closed tasks in the cumulative flow diagram'), 1, $values['cfd_include_closed_tasks'] == 1) ?>
+ <fieldset>
+ <?= $this->form->checkbox('disable_private_project', t('Disable private projects'), 1, isset($values['disable_private_project']) && $values['disable_private_project'] == 1) ?>
+ <?= $this->form->checkbox('subtask_restriction', t('Allow only one subtask in progress at the same time for a user'), 1, $values['subtask_restriction'] == 1) ?>
+ <?= $this->form->checkbox('subtask_time_tracking', t('Trigger automatically subtask time tracking'), 1, $values['subtask_time_tracking'] == 1) ?>
+ <?= $this->form->checkbox('cfd_include_closed_tasks', t('Include closed tasks in the cumulative flow diagram'), 1, $values['cfd_include_closed_tasks'] == 1) ?>
+ </fieldset>
<div class="form-actions">
<button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
diff --git a/app/Template/config/sidebar.php b/app/Template/config/sidebar.php
index 239edc19..95be963b 100644
--- a/app/Template/config/sidebar.php
+++ b/app/Template/config/sidebar.php
@@ -22,10 +22,10 @@
<?= $this->url->link(t('Tags management'), 'TagController', 'index') ?>
</li>
<li <?= $this->app->checkMenuSelection('LinkController') ?>>
- <?= $this->url->link(t('Link settings'), 'LinkController', 'index') ?>
+ <?= $this->url->link(t('Link labels'), 'LinkController', 'show') ?>
</li>
- <li <?= $this->app->checkMenuSelection('CurrencyController', 'index') ?>>
- <?= $this->url->link(t('Currency rates'), 'CurrencyController', 'index') ?>
+ <li <?= $this->app->checkMenuSelection('CurrencyController') ?>>
+ <?= $this->url->link(t('Currency rates'), 'CurrencyController', 'show') ?>
</li>
<li <?= $this->app->checkMenuSelection('ConfigController', 'integrations') ?>>
<?= $this->url->link(t('Integrations'), 'ConfigController', 'integrations') ?>
diff --git a/app/Template/config/webhook.php b/app/Template/config/webhook.php
index e3245873..bc4bbfdf 100644
--- a/app/Template/config/webhook.php
+++ b/app/Template/config/webhook.php
@@ -1,9 +1,7 @@
<div class="page-header">
<h2><?= t('Webhook settings') ?></h2>
</div>
-<section>
<form method="post" action="<?= $this->url->href('ConfigController', 'save', array('redirect' => 'webhook')) ?>" autocomplete="off">
-
<?= $this->form->csrf() ?>
<?= $this->form->label(t('Webhook URL'), 'webhook_url') ?>
@@ -13,19 +11,13 @@
<button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
</div>
</form>
-</section>
-<div class="page-header">
+<div class="page-header margin-top">
<h2><?= t('Webhook token') ?></h2>
</div>
-<section class="listing">
- <ul>
- <li>
- <?= t('Webhook token:') ?>
- <strong><?= $this->text->e($values['webhook_token']) ?></strong>
- </li>
- <li>
- <?= $this->url->link(t('Reset token'), 'ConfigController', 'token', array('type' => 'webhook'), true) ?>
- </li>
- </ul>
-</section>
+<div class="panel">
+ <?= t('Webhook token:') ?>
+ <strong><?= $this->text->e($values['webhook_token']) ?></strong>
+</div>
+
+<?= $this->url->link(t('Reset token'), 'ConfigController', 'token', array('type' => 'webhook'), true, 'btn btn-red') ?>
diff --git a/app/Template/currency/change.php b/app/Template/currency/change.php
new file mode 100644
index 00000000..59a7ce37
--- /dev/null
+++ b/app/Template/currency/change.php
@@ -0,0 +1,9 @@
+<div class="page-header">
+ <h2><?= t('Change reference currency') ?></h2>
+</div>
+<form method="post" action="<?= $this->url->href('CurrencyController', 'update') ?>" autocomplete="off">
+ <?= $this->form->csrf() ?>
+ <?= $this->form->label(t('Reference currency'), 'application_currency') ?>
+ <?= $this->form->select('application_currency', $currencies, $values, $errors) ?>
+ <?= $this->modal->submitButtons() ?>
+</form>
diff --git a/app/Template/currency/create.php b/app/Template/currency/create.php
new file mode 100644
index 00000000..578ece81
--- /dev/null
+++ b/app/Template/currency/create.php
@@ -0,0 +1,11 @@
+<div class="page-header">
+ <h2><?= t('Add or change currency rate') ?></h2>
+</div>
+<form method="post" action="<?= $this->url->href('CurrencyController', 'save') ?>" autocomplete="off">
+ <?= $this->form->csrf() ?>
+ <?= $this->form->label(t('Currency'), 'currency') ?>
+ <?= $this->form->select('currency', $currencies, $values, $errors) ?>
+ <?= $this->form->label(t('Rate'), 'rate') ?>
+ <?= $this->form->text('rate', $values, $errors, array('autofocus'), 'form-numeric') ?>
+ <?= $this->modal->submitButtons() ?>
+</form>
diff --git a/app/Template/currency/index.php b/app/Template/currency/index.php
deleted file mode 100644
index db9b21af..00000000
--- a/app/Template/currency/index.php
+++ /dev/null
@@ -1,54 +0,0 @@
-<div class="page-header">
- <h2><?= t('Currency rates') ?></h2>
-</div>
-
-<?php if (! empty($rates)): ?>
-
-<table class="table-striped">
- <tr>
- <th class="column-35"><?= t('Currency') ?></th>
- <th><?= t('Rate') ?></th>
- </tr>
- <?php foreach ($rates as $rate): ?>
- <tr>
- <td>
- <strong><?= $this->text->e($rate['currency']) ?></strong>
- </td>
- <td>
- <?= n($rate['rate']) ?>
- </td>
- </tr>
- <?php endforeach ?>
-</table>
-
-<hr/>
-<h3><?= t('Change reference currency') ?></h3>
-<?php endif ?>
-<form method="post" action="<?= $this->url->href('CurrencyController', 'reference') ?>" autocomplete="off">
-
- <?= $this->form->csrf() ?>
-
- <?= $this->form->label(t('Reference currency'), 'application_currency') ?>
- <?= $this->form->select('application_currency', $currencies, $config_values, $errors) ?>
-
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- </div>
-</form>
-
-<hr/>
-<h3><?= t('Add a new currency rate') ?></h3>
-<form method="post" action="<?= $this->url->href('CurrencyController', 'create') ?>" autocomplete="off">
-
- <?= $this->form->csrf() ?>
-
- <?= $this->form->label(t('Currency'), 'currency') ?>
- <?= $this->form->select('currency', $currencies, $values, $errors) ?>
-
- <?= $this->form->label(t('Rate'), 'rate') ?>
- <?= $this->form->text('rate', $values, $errors, array(), 'form-numeric') ?>
-
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- </div>
-</form>
diff --git a/app/Template/currency/show.php b/app/Template/currency/show.php
new file mode 100644
index 00000000..4b7f34bc
--- /dev/null
+++ b/app/Template/currency/show.php
@@ -0,0 +1,34 @@
+<div class="page-header">
+ <h2><?= t('Currency rates') ?></h2>
+ <ul>
+ <li>
+ <?= $this->modal->medium('plus', t('Add or change currency rate'), 'CurrencyController', 'create') ?>
+ </li>
+ <li>
+ <?= $this->modal->medium('edit', t('Change reference currency'), 'CurrencyController', 'change') ?>
+ </li>
+ </ul>
+</div>
+
+<div class="panel">
+ <strong><?= t('Reference currency: %s', $application_currency) ?></strong>
+</div>
+
+<?php if (! empty($rates)): ?>
+ <table class="table-striped">
+ <tr>
+ <th class="column-35"><?= t('Currency') ?></th>
+ <th><?= t('Rate') ?></th>
+ </tr>
+ <?php foreach ($rates as $rate): ?>
+ <tr>
+ <td>
+ <strong><?= $this->text->e($rate['currency']) ?></strong>
+ </td>
+ <td>
+ <?= n($rate['rate']) ?>
+ </td>
+ </tr>
+ <?php endforeach ?>
+ </table>
+<?php endif ?>
diff --git a/app/Template/custom_filter/add.php b/app/Template/custom_filter/create.php
index 3801cc30..24e896ee 100644
--- a/app/Template/custom_filter/add.php
+++ b/app/Template/custom_filter/create.php
@@ -2,23 +2,20 @@
<h2><?= t('Add a new filter') ?></h2>
</div>
<form method="post" action="<?= $this->url->href('CustomFilterController', 'save', array('project_id' => $project['id'])) ?>" autocomplete="off">
-
<?= $this->form->csrf() ?>
<?= $this->form->hidden('project_id', $values) ?>
<?= $this->form->label(t('Name'), 'name') ?>
- <?= $this->form->text('name', $values, $errors, array('required', 'maxlength="100"')) ?>
+ <?= $this->form->text('name', $values, $errors, array('autofocus', 'required', 'maxlength="100"')) ?>
<?= $this->form->label(t('Filter'), 'filter') ?>
<?= $this->form->text('filter', $values, $errors, array('required', 'maxlength="100"')) ?>
- <?php if ($this->user->hasProjectAccess('ProjectEditController', 'edit', $project['id'])): ?>
+ <?php if ($this->user->hasProjectAccess('ProjectEditController', 'show', $project['id'])): ?>
<?= $this->form->checkbox('is_shared', t('Share with all project members'), 1) ?>
<?php endif ?>
<?= $this->form->checkbox('append', t('Append filter (instead of replacement)'), 1) ?>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- </div>
+ <?= $this->modal->submitButtons() ?>
</form>
diff --git a/app/Template/custom_filter/edit.php b/app/Template/custom_filter/edit.php
index 26da8da2..b64dee53 100644
--- a/app/Template/custom_filter/edit.php
+++ b/app/Template/custom_filter/edit.php
@@ -2,8 +2,7 @@
<h2><?= t('Edit custom filter') ?></h2>
</div>
-<form class="form-popover" method="post" action="<?= $this->url->href('CustomFilterController', 'update', array('project_id' => $filter['project_id'], 'filter_id' => $filter['id'])) ?>" autocomplete="off">
-
+<form method="post" action="<?= $this->url->href('CustomFilterController', 'update', array('project_id' => $filter['project_id'], 'filter_id' => $filter['id'])) ?>" autocomplete="off">
<?= $this->form->csrf() ?>
<?= $this->form->hidden('id', $values) ?>
@@ -16,7 +15,7 @@
<?= $this->form->label(t('Filter'), 'filter') ?>
<?= $this->form->text('filter', $values, $errors, array('required', 'maxlength="100"')) ?>
- <?php if ($this->user->hasProjectAccess('ProjectEditController', 'edit', $project['id'])): ?>
+ <?php if ($this->user->hasProjectAccess('ProjectEditController', 'show', $project['id'])): ?>
<?= $this->form->checkbox('is_shared', t('Share with all project members'), 1, $values['is_shared'] == 1) ?>
<?php else: ?>
<?= $this->form->hidden('is_shared', $values) ?>
@@ -24,9 +23,5 @@
<?= $this->form->checkbox('append', t('Append filter (instead of replacement)'), 1, $values['append'] == 1) ?>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'CustomFilterController', 'index', array('project_id' => $project['id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->submitButtons() ?>
</form>
diff --git a/app/Template/custom_filter/index.php b/app/Template/custom_filter/index.php
index dcab891b..9475c278 100644
--- a/app/Template/custom_filter/index.php
+++ b/app/Template/custom_filter/index.php
@@ -1,8 +1,12 @@
-<?php if (! empty($custom_filters)): ?>
<div class="page-header">
<h2><?= t('Custom filters') ?></h2>
+ <ul>
+ <li>
+ <?= $this->modal->medium('filter', t('Add custom filters'), 'CustomFilterController', 'create', array('project_id' => $project['id'])) ?>
+ </li>
+ </ul>
</div>
-<div>
+<?php if (! empty($custom_filters)): ?>
<table class="table-striped table-scrolling">
<tr>
<th class="column-15"><?= t('Name') ?></th>
@@ -36,8 +40,8 @@
<div class="dropdown">
<a href="#" class="dropdown-menu dropdown-menu-link-icon"><i class="fa fa-cog fa-fw"></i><i class="fa fa-caret-down"></i></a>
<ul>
- <li><?= $this->url->link(t('Remove'), 'CustomFilterController', 'confirm', array('project_id' => $filter['project_id'], 'filter_id' => $filter['id']), false, 'popover') ?></li>
- <li><?= $this->url->link(t('Edit'), 'CustomFilterController', 'edit', array('project_id' => $filter['project_id'], 'filter_id' => $filter['id']), false, 'popover') ?></li>
+ <li><?= $this->modal->medium('edit', t('Edit'), 'CustomFilterController', 'edit', array('project_id' => $filter['project_id'], 'filter_id' => $filter['id'])) ?></li>
+ <li><?= $this->modal->confirm('trash-o', t('Remove'), 'CustomFilterController', 'confirm', array('project_id' => $filter['project_id'], 'filter_id' => $filter['id'])) ?></li>
</ul>
</div>
<?php endif ?>
@@ -45,7 +49,7 @@
</tr>
<?php endforeach ?>
</table>
-</div>
+<?php else: ?>
+ <p class="alert"><?= t('There is no custom filter.') ?></p>
<?php endif ?>
-<?= $this->render('custom_filter/add', array('project' => $project, 'values' => $values, 'errors' => $errors)) ?>
diff --git a/app/Template/custom_filter/remove.php b/app/Template/custom_filter/remove.php
index 609f19b2..1c576fa2 100644
--- a/app/Template/custom_filter/remove.php
+++ b/app/Template/custom_filter/remove.php
@@ -1,17 +1,15 @@
-<section id="main">
- <div class="page-header">
- <h2><?= t('Remove a custom filter') ?></h2>
- </div>
+<div class="page-header">
+ <h2><?= t('Remove a custom filter') ?></h2>
+</div>
- <div class="confirm">
- <p class="alert alert-info">
- <?= t('Do you really want to remove this custom filter: "%s"?', $filter['name']) ?>
- </p>
+<div class="confirm">
+ <p class="alert alert-info">
+ <?= t('Do you really want to remove this custom filter: "%s"?', $filter['name']) ?>
+ </p>
- <div class="form-actions">
- <?= $this->url->link(t('Yes'), 'CustomFilterController', 'remove', array('project_id' => $project['id'], 'filter_id' => $filter['id']), true, 'btn btn-red') ?>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'CustomFilterController', 'index', array('project_id' => $project['id']), false, 'close-popover') ?>
- </div>
- </div>
-</section>
+ <?= $this->modal->confirmButtons(
+ 'CustomFilterController',
+ 'remove',
+ array('project_id' => $project['id'], 'filter_id' => $filter['id'])
+ ) ?>
+</div>
diff --git a/app/Template/dashboard/calendar.php b/app/Template/dashboard/calendar.php
index 75c96d83..0b768b31 100644
--- a/app/Template/dashboard/calendar.php
+++ b/app/Template/dashboard/calendar.php
@@ -1,5 +1,4 @@
-<div id="calendar"
- data-check-url="<?= $this->url->href('CalendarController', 'user', array('user_id' => $user['id'])) ?>"
- data-save-url="<?= $this->url->href('CalendarController', 'save') ?>"
->
-</div>
+<?= $this->calendar->render(
+ $this->url->href('CalendarController', 'user', array('user_id' => $user['id'])),
+ $this->url->href('CalendarController', 'save')
+) ?>
diff --git a/app/Template/dashboard/layout.php b/app/Template/dashboard/layout.php
index 795537a6..15ab8a1a 100644
--- a/app/Template/dashboard/layout.php
+++ b/app/Template/dashboard/layout.php
@@ -3,23 +3,19 @@
<ul>
<?php if ($this->user->hasAccess('ProjectCreationController', 'create')): ?>
<li>
- <i class="fa fa-plus fa-fw"></i>
- <?= $this->url->link(t('New project'), 'ProjectCreationController', 'create', array(), false, 'popover') ?>
+ <?= $this->modal->medium('plus', t('New project'), 'ProjectCreationController', 'create') ?>
</li>
<?php endif ?>
<?php if ($this->app->config('disable_private_project', 0) == 0): ?>
<li>
- <i class="fa fa-lock fa-fw"></i>
- <?= $this->url->link(t('New private project'), 'ProjectCreationController', 'createPrivate', array(), false, 'popover') ?>
+ <?= $this->modal->medium('lock', t('New private project'), 'ProjectCreationController', 'createPrivate') ?>
</li>
<?php endif ?>
<li>
- <i class="fa fa-search fa-fw"></i>
- <?= $this->url->link(t('Search'), 'SearchController', 'index') ?>
+ <?= $this->url->icon('search', t('Search'), 'SearchController', 'index') ?>
</li>
<li>
- <i class="fa fa-folder fa-fw"></i>
- <?= $this->url->link(t('Project management'), 'ProjectListController', 'show') ?>
+ <?= $this->url->icon('folder', t('Project management'), 'ProjectListController', 'show') ?>
</li>
</ul>
</div>
diff --git a/app/Template/dashboard/notifications.php b/app/Template/dashboard/notifications.php
index 4fb59e24..81adb348 100644
--- a/app/Template/dashboard/notifications.php
+++ b/app/Template/dashboard/notifications.php
@@ -7,8 +7,7 @@
<?php else: ?>
<ul>
<li>
- <i class="fa fa-check-square-o fa-fw"></i>
- <?= $this->url->link(t('Mark all as read'), 'WebNotificationController', 'flush', array('user_id' => $user['id'])) ?>
+ <?= $this->url->icon('check-square-o', t('Mark all as read'), 'WebNotificationController', 'flush', array('user_id' => $user['id'])) ?>
</li>
</ul>
</div>
@@ -60,8 +59,7 @@
<?= $this->dt->datetime($notification['date_creation']) ?>
</td>
<td>
- <i class="fa fa-check fa-fw"></i>
- <?= $this->url->link(t('Mark as read'), 'WebNotificationController', 'remove', array('user_id' => $user['id'], 'notification_id' => $notification['id'])) ?>
+ <?= $this->url->icon('check', t('Mark as read'), 'WebNotificationController', 'remove', array('user_id' => $user['id'], 'notification_id' => $notification['id'])) ?>
</td>
</tr>
<?php endforeach ?>
diff --git a/app/Template/dashboard/show.php b/app/Template/dashboard/show.php
index aec6f591..b1d877cf 100644
--- a/app/Template/dashboard/show.php
+++ b/app/Template/dashboard/show.php
@@ -1,4 +1,4 @@
-<div class="filter-box">
+<div class="filter-box margin-bottom">
<form method="get" action="<?= $this->url->dir() ?>" class="search">
<?= $this->form->hidden('controller', array('controller' => 'SearchController')) ?>
<?= $this->form->hidden('action', array('action' => 'index')) ?>
diff --git a/app/Template/doc/show.php b/app/Template/doc/show.php
index a8dbd762..879e45b6 100644
--- a/app/Template/doc/show.php
+++ b/app/Template/doc/show.php
@@ -2,8 +2,7 @@
<div class="page-header">
<ul>
<li>
- <i class="fa fa-life-ring fa-fw"></i>
- <?= $this->url->link(t('Table of contents'), 'DocumentationController', 'show', array('file' => 'index')) ?>
+ <?= $this->url->icon('life-ring', t('Table of contents'), 'DocumentationController', 'show', array('file' => 'index')) ?>
</li>
</ul>
</div>
diff --git a/app/Template/export/header.php b/app/Template/export/header.php
new file mode 100644
index 00000000..35591352
--- /dev/null
+++ b/app/Template/export/header.php
@@ -0,0 +1,17 @@
+<div class="page-header">
+ <h2><?= $this->text->e($project['name']) ?> &gt; <?= $title ?></h2>
+ <ul>
+ <li <?= $this->app->checkMenuSelection('ExportController', 'tasks') ?>>
+ <?= $this->modal->replaceLink(t('Tasks'), 'ExportController', 'tasks', array('project_id' => $project['id'])) ?>
+ </li>
+ <li <?= $this->app->checkMenuSelection('ExportController', 'subtasks') ?>>
+ <?= $this->modal->replaceLink(t('Subtasks'), 'ExportController', 'subtasks', array('project_id' => $project['id'])) ?>
+ </li>
+ <li <?= $this->app->checkMenuSelection('ExportController', 'transitions') ?>>
+ <?= $this->modal->replaceLink(t('Task transitions'), 'ExportController', 'transitions', array('project_id' => $project['id'])) ?>
+ </li>
+ <li <?= $this->app->checkMenuSelection('ExportController', 'summary') ?>>
+ <?= $this->modal->replaceLink(t('Daily project summary'), 'ExportController', 'summary', array('project_id' => $project['id'])) ?>
+ </li>
+ </ul>
+</div>
diff --git a/app/Template/export/sidebar.php b/app/Template/export/sidebar.php
deleted file mode 100644
index 463c0cee..00000000
--- a/app/Template/export/sidebar.php
+++ /dev/null
@@ -1,17 +0,0 @@
-<div class="sidebar">
- <ul>
- <li <?= $this->app->checkMenuSelection('ExportController', 'tasks') ?>>
- <?= $this->url->link(t('Tasks'), 'ExportController', 'tasks', array('project_id' => $project['id'])) ?>
- </li>
- <li <?= $this->app->checkMenuSelection('ExportController', 'subtasks') ?>>
- <?= $this->url->link(t('Subtasks'), 'ExportController', 'subtasks', array('project_id' => $project['id'])) ?>
- </li>
- <li <?= $this->app->checkMenuSelection('ExportController', 'transitions') ?>>
- <?= $this->url->link(t('Task transitions'), 'ExportController', 'transitions', array('project_id' => $project['id'])) ?>
- </li>
- <li <?= $this->app->checkMenuSelection('ExportController', 'summary') ?>>
- <?= $this->url->link(t('Daily project summary'), 'ExportController', 'summary', array('project_id' => $project['id'])) ?>
- </li>
- <?= $this->hook->render('template:export:sidebar') ?>
- </ul>
-</div>
diff --git a/app/Template/export/subtasks.php b/app/Template/export/subtasks.php
index 959f0e47..0e47772b 100644
--- a/app/Template/export/subtasks.php
+++ b/app/Template/export/subtasks.php
@@ -1,20 +1,16 @@
-<div class="page-header">
- <h2><?= t('Subtasks export') ?></h2>
-</div>
+<?= $this->render('export/header', array('project' => $project, 'title' => $title)) ?>
<p class="alert alert-info"><?= t('This report contains all subtasks information for the given date range.') ?></p>
-<form method="get" action="?" autocomplete="off">
-
- <?= $this->form->hidden('controller', $values) ?>
- <?= $this->form->hidden('action', $values) ?>
+<form class="js-modal-ignore-form" method="post" action="<?= $this->url->href('ExportController', 'subtasks', array('project_id' => $project['id'])) ?>" autocomplete="off">
+ <?= $this->form->csrf() ?>
<?= $this->form->hidden('project_id', $values) ?>
<?= $this->form->date(t('Start date'), 'from', $values) ?>
<?= $this->form->date(t('End date'), 'to', $values) ?>
- <div class="form-help"><?= t('Others formats accepted: %s and %s', date('Y-m-d'), date('Y_m_d')) ?></div>
-
<div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Execute') ?></button>
+ <button type="submit" class="btn btn-blue js-form-export"><?= t('Export') ?></button>
+ <?= t('or') ?>
+ <?= $this->url->link(t('cancel'), 'ExportController', 'subtasks', array('project_id' => $project['id']), false, 'js-modal-close') ?>
</div>
</form>
diff --git a/app/Template/export/summary.php b/app/Template/export/summary.php
index a7483fcb..7dc7482f 100644
--- a/app/Template/export/summary.php
+++ b/app/Template/export/summary.php
@@ -1,20 +1,16 @@
-<div class="page-header">
- <h2><?= t('Daily project summary export') ?></h2>
-</div>
+<?= $this->render('export/header', array('project' => $project, 'title' => $title)) ?>
<p class="alert alert-info"><?= t('This export contains the number of tasks per column grouped per day.') ?></p>
-<form method="get" action="?" autocomplete="off">
- <?= $this->form->hidden('controller', $values) ?>
- <?= $this->form->hidden('action', $values) ?>
+<form class="js-modal-ignore-form" method="post" action="<?= $this->url->href('ExportController', 'summary', array('project_id' => $project['id'])) ?>" autocomplete="off">
+ <?= $this->form->csrf() ?>
<?= $this->form->hidden('project_id', $values) ?>
-
<?= $this->form->date(t('Start date'), 'from', $values) ?>
<?= $this->form->date(t('End date'), 'to', $values) ?>
- <div class="form-help"><?= t('Others formats accepted: %s and %s', date('Y-m-d'), date('Y_m_d')) ?></div>
-
<div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Execute') ?></button>
+ <button type="submit" class="btn btn-blue js-form-export"><?= t('Export') ?></button>
+ <?= t('or') ?>
+ <?= $this->url->link(t('cancel'), 'ExportController', 'summary', array('project_id' => $project['id']), false, 'js-modal-close') ?>
</div>
</form>
diff --git a/app/Template/export/tasks.php b/app/Template/export/tasks.php
index ce1c869e..232ff8eb 100644
--- a/app/Template/export/tasks.php
+++ b/app/Template/export/tasks.php
@@ -1,20 +1,16 @@
-<div class="page-header">
- <h2><?= t('Tasks exportation') ?></h2>
-</div>
+<?= $this->render('export/header', array('project' => $project, 'title' => $title)) ?>
<p class="alert alert-info"><?= t('This report contains all tasks information for the given date range.') ?></p>
-<form method="get" action="?" autocomplete="off">
- <?= $this->form->hidden('controller', $values) ?>
- <?= $this->form->hidden('action', $values) ?>
+<form class="js-modal-ignore-form" method="post" action="<?= $this->url->href('ExportController', 'tasks', array('project_id' => $project['id'])) ?>" autocomplete="off">
+ <?= $this->form->csrf() ?>
<?= $this->form->hidden('project_id', $values) ?>
-
<?= $this->form->date(t('Start date'), 'from', $values) ?>
<?= $this->form->date(t('End date'), 'to', $values) ?>
- <div class="form-help"><?= t('Others formats accepted: %s and %s', date('Y-m-d'), date('Y_m_d')) ?></div>
-
<div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Execute') ?></button>
+ <button type="submit" class="btn btn-blue js-form-export"><?= t('Export') ?></button>
+ <?= t('or') ?>
+ <?= $this->url->link(t('cancel'), 'ExportController', 'tasks', array('project_id' => $project['id']), false, 'js-modal-close') ?>
</div>
</form>
diff --git a/app/Template/export/transitions.php b/app/Template/export/transitions.php
index 7cd355db..4f3749b8 100644
--- a/app/Template/export/transitions.php
+++ b/app/Template/export/transitions.php
@@ -1,21 +1,16 @@
-<div class="page-header">
- <h2><?= t('Task transitions export') ?></h2>
-</div>
+<?= $this->render('export/header', array('project' => $project, 'title' => $title)) ?>
<p class="alert alert-info"><?= t('This report contains all column moves for each task with the date, the user and the time spent for each transition.') ?></p>
-<form method="get" action="?" autocomplete="off">
-
- <?= $this->form->hidden('controller', $values) ?>
- <?= $this->form->hidden('action', $values) ?>
+<form class="js-modal-ignore-form" method="post" action="<?= $this->url->href('ExportController', 'transitions', array('project_id' => $project['id'])) ?>" autocomplete="off">
+ <?= $this->form->csrf() ?>
<?= $this->form->hidden('project_id', $values) ?>
-
<?= $this->form->date(t('Start date'), 'from', $values) ?>
<?= $this->form->date(t('End date'), 'to', $values) ?>
- <div class="form-help"><?= t('Others formats accepted: %s and %s', date('Y-m-d'), date('Y_m_d')) ?></div>
-
<div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Execute') ?></button>
+ <button type="submit" class="btn btn-blue js-form-export"><?= t('Export') ?></button>
+ <?= t('or') ?>
+ <?= $this->url->link(t('cancel'), 'ExportController', 'transitions', array('project_id' => $project['id']), false, 'js-modal-close') ?>
</div>
</form>
diff --git a/app/Template/external_task_creation/step1.php b/app/Template/external_task_creation/step1.php
new file mode 100644
index 00000000..2a3b0144
--- /dev/null
+++ b/app/Template/external_task_creation/step1.php
@@ -0,0 +1,16 @@
+<form method="post" action="<?= $this->url->href('ExternalTaskCreationController', 'step2', array('project_id' => $project['id'], 'provider_name' => $provider_name)) ?>">
+ <?= $this->form->csrf() ?>
+ <?= $this->form->hidden('swimlane_id', $values) ?>
+ <?= $this->form->hidden('column_id', $values) ?>
+
+ <?= $this->render($template, array(
+ 'project' => $project,
+ 'values' => $values,
+ )) ?>
+
+ <?php if (! empty($error_message)): ?>
+ <div class="alert alert-error"><?= $this->text->e($error_message) ?></div>
+ <?php endif ?>
+
+ <?= $this->modal->submitButtons(array('submitLabel' => t('Next'))) ?>
+</form>
diff --git a/app/Template/external_task_creation/step2.php b/app/Template/external_task_creation/step2.php
new file mode 100644
index 00000000..baace3ae
--- /dev/null
+++ b/app/Template/external_task_creation/step2.php
@@ -0,0 +1,22 @@
+<form method="post" action="<?= $this->url->href('ExternalTaskCreationController', 'step3', array('project_id' => $project['id'], 'provider_name' => $provider_name)) ?>">
+ <?= $this->form->csrf() ?>
+ <?= $this->form->hidden('external_provider', $values) ?>
+ <?= $this->form->hidden('external_uri', $values) ?>
+
+ <?= $this->render($template, array(
+ 'project' => $project,
+ 'external_task' => $external_task,
+ 'values' => $values,
+ 'errors' => $errors,
+ 'users_list' => $users_list,
+ 'categories_list' => $categories_list,
+ 'swimlanes_list' => $swimlanes_list,
+ 'columns_list' => $columns_list,
+ )) ?>
+
+ <?php if (! empty($error_message)): ?>
+ <div class="alert alert-error"><?= $this->text->e($error_message) ?></div>
+ <?php endif ?>
+
+ <?= $this->modal->submitButtons() ?>
+</form>
diff --git a/app/Template/external_task_modification/show.php b/app/Template/external_task_modification/show.php
new file mode 100644
index 00000000..55180b96
--- /dev/null
+++ b/app/Template/external_task_modification/show.php
@@ -0,0 +1,22 @@
+<form method="post" action="<?= $this->url->href('TaskModificationController', 'update', array('task_id' => $task['id'], 'project_id' => $project['id'])) ?>">
+ <?= $this->form->csrf() ?>
+ <?= $this->form->hidden('id', $values) ?>
+ <?= $this->form->hidden('project_id', $values) ?>
+
+ <?php if (! empty($error_message)): ?>
+ <p class="alert alert-error"><?= $this->text->e($error_message) ?></p>
+ <?php else: ?>
+ <?= $this->render($template, array(
+ 'project' => $project,
+ 'task' => $task,
+ 'external_task' => $external_task,
+ 'tags' => $tags,
+ 'users_list' => $users_list,
+ 'categories_list' => $categories_list,
+ 'values' => $values,
+ 'errors' => $errors,
+ )) ?>
+ <?php endif ?>
+
+ <?= $this->modal->submitButtons() ?>
+</form>
diff --git a/app/Template/group/associate.php b/app/Template/group/associate.php
index 87787568..cd7f2b77 100644
--- a/app/Template/group/associate.php
+++ b/app/Template/group/associate.php
@@ -3,18 +3,21 @@
</div>
<?php if (empty($users)): ?>
<p class="alert"><?= t('There is no user available.') ?></p>
+ <div class="form-actions">
+ <?= $this->url->link(t('Close this window'), 'GroupListController', 'index', array(), false, 'btn js-modal-close') ?>
+ </div>
<?php else: ?>
- <form class="popover-form" method="post" action="<?= $this->url->href('GroupListController', 'addUser', array('group_id' => $group['id'])) ?>" autocomplete="off">
+ <form method="post" action="<?= $this->url->href('GroupListController', 'addUser', array('group_id' => $group['id'])) ?>" autocomplete="off">
<?= $this->form->csrf() ?>
<?= $this->form->hidden('group_id', $values) ?>
<?= $this->form->label(t('User'), 'user_id') ?>
- <?= $this->form->select('user_id', $users, $values, $errors, array('required'), 'chosen-select') ?>
+ <?= $this->app->component('select-dropdown-autocomplete', array(
+ 'name' => 'user_id',
+ 'items' => $users,
+ 'defaultValue' => isset($values['user_id']) ? $values['user_id'] : key($users),
+ )) ?>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'GroupListController', 'index', array(), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->submitButtons() ?>
</form>
<?php endif ?>
diff --git a/app/Template/group/dissociate.php b/app/Template/group/dissociate.php
index 50ef6d61..24836397 100644
--- a/app/Template/group/dissociate.php
+++ b/app/Template/group/dissociate.php
@@ -4,9 +4,9 @@
<div class="confirm">
<p class="alert alert-info"><?= t('Do you really want to remove the user "%s" from the group "%s"?', $user['name'] ?: $user['username'], $group['name']) ?></p>
- <div class="form-actions">
- <?= $this->url->link(t('Yes'), 'GroupListController', 'removeUser', array('group_id' => $group['id'], 'user_id' => $user['id']), true, 'btn btn-red') ?>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'GroupListController', 'users', array('group_id' => $group['id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->confirmButtons(
+ 'GroupListController',
+ 'removeUser',
+ array('group_id' => $group['id'], 'user_id' => $user['id'])
+ ) ?>
</div>
diff --git a/app/Template/group/index.php b/app/Template/group/index.php
index fe8a07e7..fe3f398e 100644
--- a/app/Template/group/index.php
+++ b/app/Template/group/index.php
@@ -1,14 +1,14 @@
<section id="main">
<div class="page-header">
<ul>
- <li><i class="fa fa-user fa-fw"></i><?= $this->url->link(t('All users'), 'UserListController', 'show') ?></li>
- <li><i class="fa fa-user-plus fa-fw"></i><?= $this->url->link(t('New group'), 'GroupCreationController', 'show', array(), false, 'popover') ?></li>
+ <li><?= $this->url->icon('user', t('All users'), 'UserListController', 'show') ?></li>
+ <li><?= $this->modal->medium('user-plus', t('New group'), 'GroupCreationController', 'show') ?></li>
</ul>
</div>
<?php if ($paginator->isEmpty()): ?>
<p class="alert"><?= t('There is no group.') ?></p>
<?php else: ?>
- <table class="table-small table-fixed table-scrolling">
+ <table class="table-fixed table-scrolling">
<tr>
<th class="column-5"><?= $paginator->order(t('Id'), 'id') ?></th>
<th class="column-20"><?= $paginator->order(t('External Id'), 'external_id') ?></th>
@@ -30,10 +30,10 @@
<div class="dropdown">
<a href="#" class="dropdown-menu dropdown-menu-link-icon"><i class="fa fa-cog fa-fw"></i><i class="fa fa-caret-down"></i></a>
<ul>
- <li><?= $this->url->link(t('Add group member'), 'GroupListController', 'associate', array('group_id' => $group['id']), false, 'popover') ?></li>
- <li><?= $this->url->link(t('Members'), 'GroupListController', 'users', array('group_id' => $group['id'])) ?></li>
- <li><?= $this->url->link(t('Edit'), 'GroupModificationController', 'show', array('group_id' => $group['id']), false, 'popover') ?></li>
- <li><?= $this->url->link(t('Remove'), 'GroupListController', 'confirm', array('group_id' => $group['id']), false, 'popover') ?></li>
+ <li><?= $this->modal->medium('plus', t('Add group member'), 'GroupListController', 'associate', array('group_id' => $group['id'])) ?></li>
+ <li><?= $this->url->icon('users', t('Members'), 'GroupListController', 'users', array('group_id' => $group['id'])) ?></li>
+ <li><?= $this->modal->medium('edit', t('Edit'), 'GroupModificationController', 'show', array('group_id' => $group['id'])) ?></li>
+ <li><?= $this->modal->confirm('trash-o', t('Remove'), 'GroupListController', 'confirm', array('group_id' => $group['id'])) ?></li>
</ul>
</div>
</td>
diff --git a/app/Template/group/remove.php b/app/Template/group/remove.php
index 408b3d83..77d602f9 100644
--- a/app/Template/group/remove.php
+++ b/app/Template/group/remove.php
@@ -4,9 +4,9 @@
<div class="confirm">
<p class="alert alert-info"><?= t('Do you really want to remove this group: "%s"?', $group['name']) ?></p>
- <div class="form-actions">
- <?= $this->url->link(t('Yes'), 'GroupListController', 'remove', array('group_id' => $group['id']), true, 'btn btn-red') ?>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'GroupListController', 'index', array(), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->confirmButtons(
+ 'GroupListController',
+ 'remove',
+ array('group_id' => $group['id'])
+ ) ?>
</div>
diff --git a/app/Template/group/users.php b/app/Template/group/users.php
index 73597b39..ef179674 100644
--- a/app/Template/group/users.php
+++ b/app/Template/group/users.php
@@ -1,8 +1,8 @@
<section id="main">
<div class="page-header">
<ul>
- <li><i class="fa fa-users fa-fw"></i><?= $this->url->link(t('View all groups'), 'GroupListController', 'index') ?></li>
- <li><i class="fa fa-plus fa-fw"></i><?= $this->url->link(t('Add group member'), 'GroupListController', 'associate', array('group_id' => $group['id']), false, 'popover') ?></li>
+ <li><?= $this->url->icon('users', t('View all groups'), 'GroupListController', 'index') ?></li>
+ <li><?= $this->modal->medium('plus', t('Add group member'), 'GroupListController', 'associate', array('group_id' => $group['id'])) ?></li>
</ul>
</div>
<?php if ($paginator->isEmpty()): ?>
@@ -31,8 +31,7 @@
<a href="mailto:<?= $this->text->e($user['email']) ?>"><?= $this->text->e($user['email']) ?></a>
</td>
<td>
- <i class="fa fa-times fa-fw" aria-hidden="true"></i>
- <?= $this->url->link(t('Remove this user'), 'GroupListController', 'dissociate', array('group_id' => $group['id'], 'user_id' => $user['id']), false, 'popover') ?>
+ <?= $this->modal->confirm('trash-o', t('Remove this user'), 'GroupListController', 'dissociate', array('group_id' => $group['id'], 'user_id' => $user['id'])) ?>
</td>
</tr>
<?php endforeach ?>
diff --git a/app/Template/group_creation/show.php b/app/Template/group_creation/show.php
index b219bd70..9f4f5608 100644
--- a/app/Template/group_creation/show.php
+++ b/app/Template/group_creation/show.php
@@ -1,15 +1,11 @@
<div class="page-header">
<h2><?= t('New group') ?></h2>
</div>
-<form class="popover-form" method="post" action="<?= $this->url->href('GroupCreationController', 'save') ?>" autocomplete="off">
+<form method="post" action="<?= $this->url->href('GroupCreationController', 'save') ?>" autocomplete="off">
<?= $this->form->csrf() ?>
<?= $this->form->label(t('Name'), 'name') ?>
<?= $this->form->text('name', $values, $errors, array('autofocus', 'required', 'maxlength="100"')) ?>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'GroupListController', 'index', array(), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->submitButtons() ?>
</form>
diff --git a/app/Template/group_modification/show.php b/app/Template/group_modification/show.php
index ddf07369..df4ed01e 100644
--- a/app/Template/group_modification/show.php
+++ b/app/Template/group_modification/show.php
@@ -1,7 +1,7 @@
<div class="page-header">
<h2><?= t('Edit group') ?></h2>
</div>
-<form class="popover-form" method="post" action="<?= $this->url->href('GroupModificationController', 'save') ?>" autocomplete="off">
+<form method="post" action="<?= $this->url->href('GroupModificationController', 'save') ?>" autocomplete="off">
<?= $this->form->csrf() ?>
<?= $this->form->hidden('id', $values) ?>
@@ -10,9 +10,5 @@
<?= $this->form->label(t('Name'), 'name') ?>
<?= $this->form->text('name', $values, $errors, array('autofocus', 'required', 'maxlength="100"')) ?>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'GroupListController', 'index', array(), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->submitButtons() ?>
</form>
diff --git a/app/Template/header/board_selector.php b/app/Template/header/board_selector.php
index b42d47f9..6f87b0d1 100644
--- a/app/Template/header/board_selector.php
+++ b/app/Template/header/board_selector.php
@@ -1,13 +1,13 @@
-<select id="board-selector"
- class="chosen-select select-auto-redirect"
- tabindex="-1"
- data-search-threshold="0"
- data-notfound="<?= t('No results match:') ?>"
- data-placeholder="<?= t('Display another project') ?>"
- data-redirect-regex="PROJECT_ID"
- data-redirect-url="<?= $this->url->href('BoardViewController', 'show', array('project_id' => 'PROJECT_ID')) ?>">
- <option value=""></option>
- <?php foreach ($board_selector as $board_id => $board_name): ?>
- <option value="<?= $board_id ?>"><?= $this->text->e($board_name) ?></option>
- <?php endforeach ?>
-</select>
+<?= $this->app->component('select-dropdown-autocomplete', array(
+ 'name' => 'boardId',
+ 'placeholder' => t('Display another project'),
+ 'items' => $board_selector,
+ 'redirect' => array(
+ 'regex' => 'PROJECT_ID',
+ 'url' => $this->url->to('BoardViewController', 'show', array('project_id' => 'PROJECT_ID')),
+ ),
+ 'onFocus' => array(
+ 'board.selector.open',
+ )
+)) ?>
+
diff --git a/app/Template/header/creation_dropdown.php b/app/Template/header/creation_dropdown.php
index d3b9e7cb..9bdf5ad2 100644
--- a/app/Template/header/creation_dropdown.php
+++ b/app/Template/header/creation_dropdown.php
@@ -6,14 +6,13 @@
<a href="#" class="dropdown-menu dropdown-menu-link-icon"><i class="fa fa-plus fa-fw"></i><i class="fa fa-caret-down"></i></a>
<ul>
<?php if ($has_project_creation_access): ?>
- <li><i class="fa fa-plus fa-fw"></i>
- <?= $this->url->link(t('New project'), 'ProjectCreationController', 'create', array(), false, 'popover') ?>
+ <li>
+ <?= $this->modal->medium('plus', t('New project'), 'ProjectCreationController', 'create') ?>
</li>
<?php endif ?>
<?php if ($is_private_project_enabled): ?>
<li>
- <i class="fa fa-lock fa-fw"></i>
- <?= $this->url->link(t('New private project'), 'ProjectCreationController', 'createPrivate', array(), false, 'popover') ?>
+ <?= $this->modal->medium('lock', t('New private project'), 'ProjectCreationController', 'createPrivate') ?>
</li>
<?php endif ?>
<?= $this->hook->render('template:header:creation-dropdown') ?>
diff --git a/app/Template/header/user_dropdown.php b/app/Template/header/user_dropdown.php
index 49d08213..a74bdd52 100644
--- a/app/Template/header/user_dropdown.php
+++ b/app/Template/header/user_dropdown.php
@@ -3,46 +3,37 @@
<ul>
<li class="no-hover"><strong><?= $this->text->e($this->user->getFullname()) ?></strong></li>
<li>
- <i class="fa fa-tachometer fa-fw"></i>
- <?= $this->url->link(t('My dashboard'), 'DashboardController', 'show', array('user_id' => $this->user->getId())) ?>
+ <?= $this->url->icon('tachometer', t('My dashboard'), 'DashboardController', 'show', array('user_id' => $this->user->getId())) ?>
</li>
<li>
- <i class="fa fa-home fa-fw"></i>
- <?= $this->url->link(t('My profile'), 'UserViewController', 'show', array('user_id' => $this->user->getId())) ?>
+ <?= $this->url->icon('home', t('My profile'), 'UserViewController', 'show', array('user_id' => $this->user->getId())) ?>
</li>
<li>
- <i class="fa fa-folder fa-fw"></i>
- <?= $this->url->link(t('Projects management'), 'ProjectListController', 'show') ?>
+ <?= $this->url->icon('folder', t('Projects management'), 'ProjectListController', 'show') ?>
</li>
<?php if ($this->user->hasAccess('UserListController', 'show')): ?>
<li>
- <i class="fa fa-user fa-fw"></i>
- <?= $this->url->link(t('Users management'), 'UserListController', 'show') ?>
+ <?= $this->url->icon('user', t('Users management'), 'UserListController', 'show') ?>
</li>
<li>
- <i class="fa fa-group fa-fw"></i>
- <?= $this->url->link(t('Groups management'), 'GroupListController', 'index') ?>
+ <?= $this->url->icon('group', t('Groups management'), 'GroupListController', 'index') ?>
</li>
<li>
- <i class="fa fa-cubes" aria-hidden="true"></i>
- <?= $this->url->link(t('Plugins'), 'PluginController', 'show') ?>
+ <?= $this->url->icon('cubes', t('Plugins'), 'PluginController', 'show') ?>
</li>
<li>
- <i class="fa fa-cog fa-fw"></i>
- <?= $this->url->link(t('Settings'), 'ConfigController', 'index') ?>
+ <?= $this->url->icon('cog', t('Settings'), 'ConfigController', 'index') ?>
</li>
<?php endif ?>
<?= $this->hook->render('template:header:dropdown') ?>
<li>
- <i class="fa fa-life-ring fa-fw"></i>
- <?= $this->url->link(t('Documentation'), 'DocumentationController', 'show') ?>
+ <?= $this->url->icon('life-ring', t('Documentation'), 'DocumentationController', 'show') ?>
</li>
<?php if (! DISABLE_LOGOUT): ?>
<li>
- <i class="fa fa-sign-out fa-fw"></i>
- <?= $this->url->link(t('Logout'), 'AuthController', 'logout') ?>
+ <?= $this->url->icon('sign-out', t('Logout'), 'AuthController', 'logout') ?>
</li>
<?php endif ?>
</ul>
diff --git a/app/Template/layout.php b/app/Template/layout.php
index 8c85ffc6..241b99df 100644
--- a/app/Template/layout.php
+++ b/app/Template/layout.php
@@ -53,6 +53,7 @@
>
<?php if (isset($no_layout) && $no_layout): ?>
+ <?= $this->app->flashMessage() ?>
<?= $content_for_layout ?>
<?php else: ?>
<?= $this->hook->render('template:layout:top') ?>
diff --git a/app/Template/link/create.php b/app/Template/link/create.php
index 23990604..37610a3b 100644
--- a/app/Template/link/create.php
+++ b/app/Template/link/create.php
@@ -1,18 +1,12 @@
<div class="page-header">
- <h2><?= t('Add a new link') ?></h2>
+ <h2><?= t('Add link label') ?></h2>
</div>
<form action="<?= $this->url->href('LinkController', 'save') ?>" method="post" autocomplete="off">
-
<?= $this->form->csrf() ?>
-
<?= $this->form->label(t('Label'), 'label') ?>
- <?= $this->form->text('label', $values, $errors, array('required')) ?>
-
+ <?= $this->form->text('label', $values, $errors, array('required', 'autofocus')) ?>
<?= $this->form->label(t('Opposite label'), 'opposite_label') ?>
<?= $this->form->text('opposite_label', $values, $errors) ?>
-
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- </div>
+ <?= $this->modal->submitButtons() ?>
</form>
diff --git a/app/Template/link/edit.php b/app/Template/link/edit.php
index cb4f29e2..4be56573 100644
--- a/app/Template/link/edit.php
+++ b/app/Template/link/edit.php
@@ -13,9 +13,5 @@
<?= $this->form->label(t('Opposite label'), 'opposite_id') ?>
<?= $this->form->select('opposite_id', $labels, $values, $errors) ?>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'LinkController', 'index') ?>
- </div>
+ <?= $this->modal->submitButtons() ?>
</form>
diff --git a/app/Template/link/index.php b/app/Template/link/index.php
deleted file mode 100644
index 70ead4a6..00000000
--- a/app/Template/link/index.php
+++ /dev/null
@@ -1,33 +0,0 @@
-<div class="page-header">
- <h2><?= t('Link labels') ?></h2>
-</div>
-<?php if (! empty($links)): ?>
-<table class="table-striped table-scrolling">
- <tr>
- <th class="column-70"><?= t('Link labels') ?></th>
- <th><?= t('Actions') ?></th>
- </tr>
- <?php foreach ($links as $link): ?>
- <tr>
- <td>
- <strong><?= t($link['label']) ?></strong>
-
- <?php if (! empty($link['opposite_label'])): ?>
- | <?= t($link['opposite_label']) ?>
- <?php endif ?>
- </td>
- <td>
- <ul>
- <?= $this->url->link(t('Edit'), 'LinkController', 'edit', array('link_id' => $link['id'])) ?>
- <?= t('or') ?>
- <?= $this->url->link(t('Remove'), 'LinkController', 'confirm', array('link_id' => $link['id'])) ?>
- </ul>
- </td>
- </tr>
- <?php endforeach ?>
-</table>
-<?php else: ?>
- <?= t('There is no link.') ?>
-<?php endif ?>
-
-<?= $this->render('link/create', array('values' => $values, 'errors' => $errors)) ?>
diff --git a/app/Template/link/remove.php b/app/Template/link/remove.php
index b7fbef5e..e5ea2466 100644
--- a/app/Template/link/remove.php
+++ b/app/Template/link/remove.php
@@ -7,9 +7,9 @@
<?= t('Do you really want to remove this link: "%s"?', $link['label']) ?>
</p>
- <div class="form-actions">
- <?= $this->url->link(t('Yes'), 'LinkController', 'remove', array('link_id' => $link['id']), true, 'btn btn-red') ?>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'LinkController', 'index') ?>
- </div>
+ <?= $this->modal->confirmButtons(
+ 'LinkController',
+ 'remove',
+ array('link_id' => $link['id'])
+ ) ?>
</div>
diff --git a/app/Template/link/show.php b/app/Template/link/show.php
new file mode 100644
index 00000000..6aadd66b
--- /dev/null
+++ b/app/Template/link/show.php
@@ -0,0 +1,36 @@
+<div class="page-header">
+ <h2><?= t('Link labels') ?></h2>
+ <ul>
+ <li>
+ <?= $this->modal->medium('plus', t('Add link label'), 'LinkController', 'create') ?>
+ </li>
+ </ul>
+</div>
+<?php if (! empty($links)): ?>
+ <table class="table-striped table-scrolling">
+ <tr>
+ <th class="column-70"><?= t('Link labels') ?></th>
+ <th><?= t('Actions') ?></th>
+ </tr>
+ <?php foreach ($links as $link): ?>
+ <tr>
+ <td>
+ <strong><?= t($link['label']) ?></strong>
+
+ <?php if (! empty($link['opposite_label'])): ?>
+ | <?= t($link['opposite_label']) ?>
+ <?php endif ?>
+ </td>
+ <td>
+ <ul>
+ <?= $this->modal->medium('edit', t('Edit'), 'LinkController', 'edit', array('link_id' => $link['id'])) ?>
+ <?= t('or') ?>
+ <?= $this->modal->confirm('trash-o', t('Remove'), 'LinkController', 'confirm', array('link_id' => $link['id'])) ?>
+ </ul>
+ </td>
+ </tr>
+ <?php endforeach ?>
+ </table>
+<?php else: ?>
+ <?= t('There is no link.') ?>
+<?php endif ?>
diff --git a/app/Template/notification/comment_create.php b/app/Template/notification/comment_create.php
index fefc8ba1..41262a7e 100644
--- a/app/Template/notification/comment_create.php
+++ b/app/Template/notification/comment_create.php
@@ -6,6 +6,6 @@
<h3><?= t('New comment') ?></h3>
<?php endif ?>
-<?= $this->text->markdown($comment['comment']) ?>
+<?= $this->text->markdown($comment['comment'], true) ?>
<?= $this->render('notification/footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file
diff --git a/app/Template/notification/comment_delete.php b/app/Template/notification/comment_delete.php
index 928623ec..14babbd9 100644
--- a/app/Template/notification/comment_delete.php
+++ b/app/Template/notification/comment_delete.php
@@ -2,6 +2,6 @@
<h3><?= t('Comment removed') ?></h3>
-<?= $this->text->markdown($comment['comment']) ?>
+<?= $this->text->markdown($comment['comment'], true) ?>
<?= $this->render('notification/footer', array('task' => $task, 'application_url' => $application_url)) ?>
diff --git a/app/Template/notification/comment_update.php b/app/Template/notification/comment_update.php
index 2477d8b3..f1cffae6 100644
--- a/app/Template/notification/comment_update.php
+++ b/app/Template/notification/comment_update.php
@@ -2,6 +2,6 @@
<h3><?= t('Comment updated') ?></h3>
-<?= $this->text->markdown($comment['comment']) ?>
+<?= $this->text->markdown($comment['comment'], true) ?>
<?= $this->render('notification/footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file
diff --git a/app/Template/notification/comment_user_mention.php b/app/Template/notification/comment_user_mention.php
index 372183df..0990e7ab 100644
--- a/app/Template/notification/comment_user_mention.php
+++ b/app/Template/notification/comment_user_mention.php
@@ -2,6 +2,6 @@
<p><?= $this->text->e($task['title']) ?></p>
-<?= $this->text->markdown($comment['comment']) ?>
+<?= $this->text->markdown($comment['comment'], true) ?>
<?= $this->render('notification/footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file
diff --git a/app/Template/notification/task_assignee_change.php b/app/Template/notification/task_assignee_change.php
index 53f7c5c1..f075fdbf 100644
--- a/app/Template/notification/task_assignee_change.php
+++ b/app/Template/notification/task_assignee_change.php
@@ -14,7 +14,7 @@
<?php if (! empty($task['description'])): ?>
<h2><?= t('Description') ?></h2>
- <?= $this->text->markdown($task['description']) ?: t('There is no description.') ?>
+ <?= $this->text->markdown($task['description'], true) ?: t('There is no description.') ?>
<?php endif ?>
<?= $this->render('notification/footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file
diff --git a/app/Template/notification/task_create.php b/app/Template/notification/task_create.php
index 3cd68ac0..3439e357 100644
--- a/app/Template/notification/task_create.php
+++ b/app/Template/notification/task_create.php
@@ -37,7 +37,7 @@
<?php if (! empty($task['description'])): ?>
<h2><?= t('Description') ?></h2>
- <?= $this->text->markdown($task['description']) ?>
+ <?= $this->text->markdown($task['description'], true) ?>
<?php endif ?>
<?= $this->render('notification/footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file
diff --git a/app/Template/notification/task_update.php b/app/Template/notification/task_update.php
index 8adb2553..9abe8e0a 100644
--- a/app/Template/notification/task_update.php
+++ b/app/Template/notification/task_update.php
@@ -1,4 +1,4 @@
<h2><?= $this->text->e($task['title']) ?> (#<?= $task['id'] ?>)</h2>
-<?= $this->render('task/changes', array('changes' => $changes, 'task' => $task)) ?>
+<?= $this->render('task/changes', array('changes' => $changes, 'task' => $task, 'public' => true)) ?>
<?= $this->render('notification/footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file
diff --git a/app/Template/notification/task_user_mention.php b/app/Template/notification/task_user_mention.php
index 3d8c8e95..71ad348b 100644
--- a/app/Template/notification/task_user_mention.php
+++ b/app/Template/notification/task_user_mention.php
@@ -2,6 +2,6 @@
<p><?= $this->text->e($task['title']) ?></p>
<h2><?= t('Description') ?></h2>
-<?= $this->text->markdown($task['description']) ?>
+<?= $this->text->markdown($task['description'], true) ?>
<?= $this->render('notification/footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file
diff --git a/app/Template/password_reset/create.php b/app/Template/password_reset/create.php
index f43d95fc..862a02ba 100644
--- a/app/Template/password_reset/create.php
+++ b/app/Template/password_reset/create.php
@@ -5,6 +5,7 @@
<?= $this->form->label(t('Username'), 'username') ?>
<?= $this->form->text('username', $values, $errors, array('autofocus', 'required')) ?>
+ <p class="form-help"><?= t('Your profile must have a valid email address.') ?></p>
<?= $this->form->label(t('Enter the text below'), 'captcha') ?>
<img src="<?= $this->url->href('CaptchaController', 'image') ?>" alt="Captcha">
diff --git a/app/Template/plugin/directory.php b/app/Template/plugin/directory.php
index b6c6734c..b2fffcb9 100644
--- a/app/Template/plugin/directory.php
+++ b/app/Template/plugin/directory.php
@@ -28,11 +28,9 @@
<td>
<?php if ($is_configured): ?>
<?php if (! isset($installed_plugins[$plugin['title']])): ?>
- <i class="fa fa-cloud-download fa-fw" aria-hidden="true"></i>
- <?= $this->url->link(t('Install'), 'PluginController', 'install', array('archive_url' => urlencode($plugin['download'])), true) ?>
+ <?= $this->url->icon('cloud-download', t('Install'), 'PluginController', 'install', array('archive_url' => urlencode($plugin['download'])), true) ?>
<?php elseif ($installed_plugins[$plugin['title']] < $plugin['version']): ?>
- <i class="fa fa-refresh fa-fw" aria-hidden="true"></i>
- <?= $this->url->link(t('Update'), 'PluginController', 'update', array('archive_url' => urlencode($plugin['download'])), true) ?>
+ <?= $this->url->icon('refresh', t('Update'), 'PluginController', 'update', array('archive_url' => urlencode($plugin['download'])), true) ?>
<?php else: ?>
<i class="fa fa-check-circle-o" aria-hidden="true"></i>
<?= t('Up to date') ?>
diff --git a/app/Template/plugin/remove.php b/app/Template/plugin/remove.php
index bd8f4eb8..1280f8aa 100644
--- a/app/Template/plugin/remove.php
+++ b/app/Template/plugin/remove.php
@@ -5,9 +5,9 @@
<div class="confirm">
<p class="alert alert-info"><?= t('Do you really want to remove this plugin: "%s"?', $plugin->getPluginName()) ?></p>
- <div class="form-actions">
- <?= $this->url->link(t('Yes'), 'PluginController', 'uninstall', array('pluginId' => $plugin_id), true, 'btn btn-red') ?>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'PluginController', 'show', array(), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->confirmButtons(
+ 'PluginController',
+ 'uninstall',
+ array('pluginId' => $plugin_id)
+ ) ?>
</div>
diff --git a/app/Template/plugin/show.php b/app/Template/plugin/show.php
index 9c3d6d20..266568ac 100644
--- a/app/Template/plugin/show.php
+++ b/app/Template/plugin/show.php
@@ -1,3 +1,43 @@
+<?php if (! empty($incompatible_plugins)): ?>
+ <div class="page-header">
+ <h2><?= t('Incompatible Plugins') ?></h2>
+ </div>
+ <table>
+ <tr>
+ <th class="column-35"><?= t('Name') ?></th>
+ <th class="column-25"><?= t('Author') ?></th>
+ <th class="column-10"><?= t('Version') ?></th>
+ <th class="column-12"><?= t('Compatibility') ?></th>
+ <?php if ($is_configured): ?>
+ <th><?= t('Action') ?></th>
+ <?php endif ?>
+ </tr>
+
+ <?php foreach ($incompatible_plugins as $pluginFolder => $plugin): ?>
+ <tr>
+ <td>
+ <?php if ($plugin->getPluginHomepage()): ?>
+ <a href="<?= $plugin->getPluginHomepage() ?>" target="_blank" rel="noreferrer"><?= $this->text->e($plugin->getPluginName()) ?></a>
+ <?php else: ?>
+ <?= $this->text->e($plugin->getPluginName()) ?>
+ <?php endif ?>
+ </td>
+ <td><?= $this->text->e($plugin->getPluginAuthor()) ?></td>
+ <td><?= $this->text->e($plugin->getPluginVersion()) ?></td>
+ <td><?= $this->text->e($plugin->getCompatibleVersion()) ?></td>
+ <?php if ($is_configured): ?>
+ <td>
+ <?= $this->modal->confirm('trash-o', t('Uninstall'), 'PluginController', 'confirm', array('pluginId' => $pluginFolder)) ?>
+ </td>
+ <?php endif ?>
+ </tr>
+ <tr>
+ <td colspan="<?= $is_configured ? 6 : 5 ?>"><?= $this->text->e($plugin->getPluginDescription()) ?></td>
+ </tr>
+ <?php endforeach ?>
+ </table>
+<?php endif ?>
+
<div class="page-header">
<h2><?= t('Installed Plugins') ?></h2>
</div>
@@ -28,8 +68,7 @@
<td><?= $this->text->e($plugin->getPluginVersion()) ?></td>
<?php if ($is_configured): ?>
<td>
- <i class="fa fa-trash-o fa-fw" aria-hidden="true"></i>
- <?= $this->url->link(t('Uninstall'), 'PluginController', 'confirm', array('pluginId' => $pluginFolder), false, 'popover') ?>
+ <?= $this->modal->confirm('trash-o', t('Uninstall'), 'PluginController', 'confirm', array('pluginId' => $pluginFolder)) ?>
</td>
<?php endif ?>
</tr>
diff --git a/app/Template/project/dropdown.php b/app/Template/project/dropdown.php
index e3cf41c2..447cd0b4 100644
--- a/app/Template/project/dropdown.php
+++ b/app/Template/project/dropdown.php
@@ -2,42 +2,35 @@
<a href="#" class="dropdown-menu dashboard-table-link">#<?= $project['id'] ?></a>
<ul>
<li>
- <i class="fa fa-th fa-fw"></i>
- <?= $this->url->link(t('Board'), 'BoardViewController', 'show', array('project_id' => $project['id'])) ?>
+ <?= $this->url->icon('th', t('Board'), 'BoardViewController', 'show', array('project_id' => $project['id'])) ?>
</li>
<li>
- <i class="fa fa-calendar fa-fw"></i>
- <?= $this->url->link(t('Calendar'), 'CalendarController', 'show', array('project_id' => $project['id'])) ?>
+ <?= $this->url->icon('calendar', t('Calendar'), 'CalendarController', 'show', array('project_id' => $project['id'])) ?>
</li>
<li>
- <i class="fa fa-list fa-fw"></i>
- <?= $this->url->link(t('Listing'), 'TaskListController', 'show', array('project_id' => $project['id'])) ?>
+ <?= $this->url->icon('list', t('Listing'), 'TaskListController', 'show', array('project_id' => $project['id'])) ?>
</li>
<?php if ($this->user->hasProjectAccess('TaskGanttController', 'show', $project['id'])): ?>
<li>
- <i class="fa fa-sliders fa-fw"></i>
- <?= $this->url->link(t('Gantt'), 'TaskGanttController', 'show', array('project_id' => $project['id'])) ?>
+ <?= $this->url->icon('sliders', t('Gantt'), 'TaskGanttController', 'show', array('project_id' => $project['id'])) ?>
</li>
<?php endif ?>
<li>
- <i class="fa fa-dashboard fa-fw"></i>&nbsp;
- <?= $this->url->link(t('Activity'), 'ActivityController', 'project', array('project_id' => $project['id'])) ?>
+ <?= $this->modal->medium('dashboard', t('Activity'), 'ActivityController', 'project', array('project_id' => $project['id'])) ?>
</li>
<?php if ($this->user->hasProjectAccess('AnalyticController', 'taskDistribution', $project['id'])): ?>
<li>
- <i class="fa fa-line-chart fa-fw"></i>&nbsp;
- <?= $this->url->link(t('Analytics'), 'AnalyticController', 'taskDistribution', array('project_id' => $project['id'])) ?>
+ <?= $this->modal->large('line-chart', t('Analytics'), 'AnalyticController', 'taskDistribution', array('project_id' => $project['id'])) ?>
</li>
<?php endif ?>
<?= $this->hook->render('template:project:dropdown', array('project' => $project)) ?>
- <?php if ($this->user->hasProjectAccess('ProjectEditController', 'edit', $project['id'])): ?>
+ <?php if ($this->user->hasProjectAccess('ProjectEditController', 'show', $project['id'])): ?>
<li>
- <i class="fa fa-cog fa-fw"></i>
- <?= $this->url->link(t('Settings'), 'ProjectViewController', 'show', array('project_id' => $project['id'])) ?>
+ <?= $this->url->icon('cog', t('Settings'), 'ProjectViewController', 'show', array('project_id' => $project['id'])) ?>
</li>
<?php endif ?>
</ul>
diff --git a/app/Template/project/sidebar.php b/app/Template/project/sidebar.php
index 6e7fff05..812eb351 100644
--- a/app/Template/project/sidebar.php
+++ b/app/Template/project/sidebar.php
@@ -9,9 +9,9 @@
</li>
<?php endif ?>
- <?php if ($this->user->hasProjectAccess('ProjectEditController', 'edit', $project['id'])): ?>
+ <?php if ($this->user->hasProjectAccess('ProjectEditController', 'show', $project['id'])): ?>
<li <?= $this->app->checkMenuSelection('ProjectEditController') ?>>
- <?= $this->url->link(t('Edit project'), 'ProjectEditController', 'edit', array('project_id' => $project['id'])) ?>
+ <?= $this->url->link(t('Edit project'), 'ProjectEditController', 'show', array('project_id' => $project['id'])) ?>
</li>
<li <?= $this->app->checkMenuSelection('ProjectViewController', 'share') ?>>
<?= $this->url->link(t('Public access'), 'ProjectViewController', 'share', array('project_id' => $project['id'])) ?>
@@ -50,15 +50,15 @@
</li>
<?php if ($project['is_active']): ?>
<li>
- <?= $this->url->link(t('Disable'), 'ProjectStatusController', 'confirmDisable', array('project_id' => $project['id']), false, 'popover') ?>
+ <?= $this->modal->confirmLink(t('Disable'), 'ProjectStatusController', 'confirmDisable', array('project_id' => $project['id'])) ?>
<?php else: ?>
<li>
- <?= $this->url->link(t('Enable'), 'ProjectStatusController', 'confirmEnable', array('project_id' => $project['id']), false, 'popover') ?>
+ <?= $this->modal->confirmLink(t('Enable'), 'ProjectStatusController', 'confirmEnable', array('project_id' => $project['id'])) ?>
<?php endif ?>
</li>
<?php if ($this->user->hasProjectAccess('ProjectStatusController', 'remove', $project['id'])): ?>
<li>
- <?= $this->url->link(t('Remove'), 'ProjectStatusController', 'confirmRemove', array('project_id' => $project['id']), false, 'popover') ?>
+ <?= $this->modal->confirmLink(t('Remove'), 'ProjectStatusController', 'confirmRemove', array('project_id' => $project['id'])) ?>
</li>
<?php endif ?>
<?php endif ?>
diff --git a/app/Template/project_action_duplication/show.php b/app/Template/project_action_duplication/show.php
index 2eebb262..c2f52e35 100644
--- a/app/Template/project_action_duplication/show.php
+++ b/app/Template/project_action_duplication/show.php
@@ -4,16 +4,12 @@
<?php if (empty($projects_list)): ?>
<p class="alert"><?= t('There is no available project.') ?></p>
<?php else: ?>
- <form class="popover-form" method="post" action="<?= $this->url->href('ProjectActionDuplicationController', 'save', array('project_id' => $project['id'])) ?>" autocomplete="off">
+ <form method="post" action="<?= $this->url->href('ProjectActionDuplicationController', 'save', array('project_id' => $project['id'])) ?>" autocomplete="off">
<?= $this->form->csrf() ?>
<?= $this->form->label(t('Create from another project'), 'src_project_id') ?>
<?= $this->form->select('src_project_id', $projects_list) ?>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'Action', 'index', array(), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->submitButtons() ?>
</form>
<?php endif ?>
diff --git a/app/Template/project_creation/create.php b/app/Template/project_creation/create.php
index b90b15c4..171bd17a 100644
--- a/app/Template/project_creation/create.php
+++ b/app/Template/project_creation/create.php
@@ -2,7 +2,7 @@
<div class="page-header">
<h2><?= $title ?></h2>
</div>
- <form class="popover-form" id="project-creation-form" method="post" action="<?= $this->url->href('ProjectCreationController', 'save') ?>" autocomplete="off">
+ <form id="project-creation-form" method="post" action="<?= $this->url->href('ProjectCreationController', 'save') ?>" autocomplete="off">
<?= $this->form->csrf() ?>
<?= $this->form->hidden('is_private', $values) ?>
@@ -12,10 +12,10 @@
<?php if (count($projects_list) > 1): ?>
<?= $this->form->label(t('Create from another project'), 'src_project_id') ?>
- <?= $this->form->select('src_project_id', $projects_list, $values) ?>
+ <?= $this->form->select('src_project_id', $projects_list, $values, array(), array(), 'js-project-creation-select-options') ?>
<?php endif ?>
- <div class="project-creation-options" <?= isset($values['src_project_id']) && $values['src_project_id'] > 0 ? '' : 'style="display: none"' ?>>
+ <div class="js-project-creation-options" <?= isset($values['src_project_id']) && $values['src_project_id'] > 0 ? '' : 'style="display: none"' ?>>
<p class="alert"><?= t('Which parts of the project do you want to duplicate?') ?></p>
<?php if (! $is_private): ?>
@@ -29,11 +29,7 @@
<?= $this->form->checkbox('projectTaskDuplicationModel', t('Tasks'), 1, false) ?>
</div>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'ProjectListController', 'show', array(), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->submitButtons() ?>
</form>
<?php if ($is_private): ?>
<div class="alert alert-info">
diff --git a/app/Template/project_edit/dates.php b/app/Template/project_edit/dates.php
deleted file mode 100644
index 1c2c3dd4..00000000
--- a/app/Template/project_edit/dates.php
+++ /dev/null
@@ -1,22 +0,0 @@
-<div class="page-header">
- <h2><?= t('Edit project') ?></h2>
- <ul>
- <li ><?= $this->url->link(t('General'), 'ProjectEditController', 'edit', array('project_id' => $project['id']), false, 'popover-link') ?></li>
- <li class="active"><?= $this->url->link(t('Dates'), 'ProjectEditController', 'dates', array('project_id' => $project['id']), false, 'popover-link') ?></li>
- <li><?= $this->url->link(t('Description'), 'ProjectEditController', 'description', array('project_id' => $project['id']), false, 'popover-link') ?></li>
- <li><?= $this->url->link(t('Task priority'), 'ProjectEditController', 'priority', array('project_id' => $project['id']), false, 'popover-link') ?></li>
- </ul>
-</div>
-<form method="post" class="popover-form" action="<?= $this->url->href('ProjectEditController', 'update', array('project_id' => $project['id'], 'redirect' => 'dates')) ?>" autocomplete="off">
- <?= $this->form->csrf() ?>
- <?= $this->form->hidden('id', $values) ?>
- <?= $this->form->hidden('name', $values) ?>
- <?= $this->form->date(t('Start date'), 'start_date', $values, $errors) ?>
- <?= $this->form->date(t('End date'), 'end_date', $values, $errors) ?>
-
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- </div>
-</form>
-
-<p class="alert alert-info"><?= t('Those dates are useful for the project Gantt chart.') ?></p>
diff --git a/app/Template/project_edit/description.php b/app/Template/project_edit/description.php
deleted file mode 100644
index f7e7be46..00000000
--- a/app/Template/project_edit/description.php
+++ /dev/null
@@ -1,19 +0,0 @@
-<div class="page-header">
- <h2><?= t('Edit project') ?></h2>
- <ul>
- <li><?= $this->url->link(t('General'), 'ProjectEditController', 'edit', array('project_id' => $project['id']), false, 'popover-link') ?></li>
- <li><?= $this->url->link(t('Dates'), 'ProjectEditController', 'dates', array('project_id' => $project['id']), false, 'popover-link') ?></li>
- <li class="active"><?= $this->url->link(t('Description'), 'ProjectEditController', 'description', array('project_id' => $project['id']), false, 'popover-link') ?></li>
- <li><?= $this->url->link(t('Task priority'), 'ProjectEditController', 'priority', array('project_id' => $project['id']), false, 'popover-link') ?></li>
- </ul>
-</div>
-<form method="post" class="popover-form" action="<?= $this->url->href('ProjectEditController', 'update', array('project_id' => $project['id'], 'redirect' => 'description')) ?>" autocomplete="off">
- <?= $this->form->csrf() ?>
- <?= $this->form->hidden('id', $values) ?>
- <?= $this->form->hidden('name', $values) ?>
- <?= $this->form->textarea('description', $values, $errors, array(), 'markdown-editor') ?>
-
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- </div>
-</form>
diff --git a/app/Template/project_edit/general.php b/app/Template/project_edit/general.php
deleted file mode 100644
index c7421477..00000000
--- a/app/Template/project_edit/general.php
+++ /dev/null
@@ -1,36 +0,0 @@
-<div class="page-header">
- <h2><?= t('Edit project') ?></h2>
- <ul>
- <li class="active"><?= $this->url->link(t('General'), 'ProjectEditController', 'edit', array('project_id' => $project['id']), false, 'popover-link') ?></li>
- <li><?= $this->url->link(t('Dates'), 'ProjectEditController', 'dates', array('project_id' => $project['id']), false, 'popover-link') ?></li>
- <li><?= $this->url->link(t('Description'), 'ProjectEditController', 'description', array('project_id' => $project['id']), false, 'popover-link') ?></li>
- <li><?= $this->url->link(t('Task priority'), 'ProjectEditController', 'priority', array('project_id' => $project['id']), false, 'popover-link') ?></li>
- </ul>
-</div>
-<form method="post" class="popover-form" action="<?= $this->url->href('ProjectEditController', 'update', array('project_id' => $project['id'], 'redirect' => 'edit')) ?>" autocomplete="off">
- <?= $this->form->csrf() ?>
- <?= $this->form->hidden('id', $values) ?>
-
- <?= $this->form->label(t('Name'), 'name') ?>
- <?= $this->form->text('name', $values, $errors, array('required', 'maxlength="50"')) ?>
-
- <?= $this->form->label(t('Identifier'), 'identifier') ?>
- <?= $this->form->text('identifier', $values, $errors, array('maxlength="50"')) ?>
- <p class="form-help"><?= t('The project identifier is optional and must be alphanumeric, example: MYPROJECT.') ?></p>
-
- <hr>
- <div class="form-inline">
- <?= $this->form->label(t('Project owner'), 'owner_id') ?>
- <?= $this->form->select('owner_id', $owners, $values, $errors) ?>
- </div>
-
- <?php if ($this->user->hasProjectAccess('ProjectCreationController', 'create', $project['id'])): ?>
- <hr>
- <?= $this->form->checkbox('is_private', t('Private project'), 1, $project['is_private'] == 1) ?>
- <p class="form-help"><?= t('Private projects do not have users and groups management.') ?></p>
- <?php endif ?>
-
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- </div>
-</form>
diff --git a/app/Template/project_edit/show.php b/app/Template/project_edit/show.php
new file mode 100644
index 00000000..074f1d37
--- /dev/null
+++ b/app/Template/project_edit/show.php
@@ -0,0 +1,68 @@
+<?php if ($this->app->isAjax()): ?>
+ <div class="page-header">
+ <h2><?= $this->text->e($project['name']) ?> &gt; <?= t('Edit project') ?></h2>
+ </div>
+<?php else: ?>
+ <div class="page-header">
+ <h2><?= t('Edit project') ?></h2>
+ </div>
+<?php endif ?>
+<form method="post" action="<?= $this->url->href('ProjectEditController', 'update', array('project_id' => $project['id'], 'redirect' => 'edit')) ?>" autocomplete="off">
+ <?= $this->form->csrf() ?>
+ <?= $this->form->hidden('id', $values) ?>
+
+ <fieldset>
+ <legend><?= t('General') ?></legend>
+
+ <?= $this->form->label(t('Name'), 'name') ?>
+ <?= $this->form->text('name', $values, $errors, array('required', 'maxlength="50"', 'autofocus', 'tabindex="1"')) ?>
+
+ <?= $this->form->label(t('Email'), 'email') ?>
+ <?= $this->form->email('email', $values, $errors, array('maxlength="255"', 'tabindex="2"')) ?>
+ <p class="form-help"><?= t('The project email is optional and could be used by several plugins.') ?></p>
+
+ <?= $this->form->label(t('Identifier'), 'identifier') ?>
+ <?= $this->form->text('identifier', $values, $errors, array('maxlength="50"', 'tabindex="3"')) ?>
+ <p class="form-help"><?= t('The project identifier is optional and must be alphanumeric, example: MYPROJECT.') ?></p>
+
+ <?= $this->form->label(t('Description'), 'description') ?>
+ <?= $this->form->textEditor('description', $values, $errors, array('tabindex' => 4)) ?>
+ </fieldset>
+
+ <fieldset>
+ <legend><?= t('Permissions and ownership') ?></legend>
+
+ <?php if ($this->user->hasProjectAccess('ProjectCreationController', 'create', $project['id'])): ?>
+ <?= $this->form->checkbox('is_private', t('Private project'), 1, $project['is_private'] == 1) ?>
+ <p class="form-help"><?= t('Private projects do not have users and groups management.') ?></p>
+ <?php endif ?>
+
+ <div class="form-inline">
+ <?= $this->form->label(t('Project owner'), 'owner_id') ?>
+ <?= $this->form->select('owner_id', $owners, $values, $errors, array('tabindex="5"')) ?>
+ </div>
+ </fieldset>
+
+ <fieldset>
+ <legend><?= t('Dates') ?></legend>
+
+ <?= $this->form->date(t('Start date'), 'start_date', $values, $errors, array('tabindex="6"')) ?>
+ <?= $this->form->date(t('End date'), 'end_date', $values, $errors, array('tabindex="7"')) ?>
+ </fieldset>
+
+ <fieldset>
+ <legend><?= t('Priorities') ?></legend>
+
+ <?= $this->form->label(t('Default priority'), 'priority_default') ?>
+ <?= $this->form->number('priority_default', $values, $errors, array('tabindex="8"')) ?>
+
+ <?= $this->form->label(t('Lowest priority'), 'priority_start') ?>
+ <?= $this->form->number('priority_start', $values, $errors, array('tabindex="9"')) ?>
+
+ <?= $this->form->label(t('Highest priority'), 'priority_end') ?>
+ <?= $this->form->number('priority_end', $values, $errors, array('tabindex="10"')) ?>
+ <p class="form-help"><?= t('If you put zero to the low and high priority, this feature will be disabled.') ?></p>
+ </fieldset>
+
+ <?= $this->modal->submitButtons(array('tabindex' => 11)) ?>
+</form>
diff --git a/app/Template/project_edit/task_priority.php b/app/Template/project_edit/task_priority.php
deleted file mode 100644
index 3ef4b3cb..00000000
--- a/app/Template/project_edit/task_priority.php
+++ /dev/null
@@ -1,29 +0,0 @@
-<div class="page-header">
- <h2><?= t('Edit project') ?></h2>
- <ul>
- <li ><?= $this->url->link(t('General'), 'ProjectEditController', 'edit', array('project_id' => $project['id']), false, 'popover-link') ?></li>
- <li><?= $this->url->link(t('Dates'), 'ProjectEditController', 'dates', array('project_id' => $project['id']), false, 'popover-link') ?></li>
- <li><?= $this->url->link(t('Description'), 'ProjectEditController', 'description', array('project_id' => $project['id']), false, 'popover-link') ?></li>
- <li class="active"><?= $this->url->link(t('Task priority'), 'ProjectEditController', 'priority', array('project_id' => $project['id']), false, 'popover-link') ?></li>
- </ul>
-</div>
-<form method="post" class="popover-form" action="<?= $this->url->href('ProjectEditController', 'update', array('project_id' => $project['id'], 'redirect' => 'priority')) ?>" autocomplete="off">
- <?= $this->form->csrf() ?>
- <?= $this->form->hidden('id', $values) ?>
- <?= $this->form->hidden('name', $values) ?>
-
- <?= $this->form->label(t('Default priority'), 'priority_default') ?>
- <?= $this->form->number('priority_default', $values, $errors) ?>
-
- <?= $this->form->label(t('Lowest priority'), 'priority_start') ?>
- <?= $this->form->number('priority_start', $values, $errors) ?>
-
- <?= $this->form->label(t('Highest priority'), 'priority_end') ?>
- <?= $this->form->number('priority_end', $values, $errors) ?>
-
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- </div>
-</form>
-
-<p class="alert alert-info"><?= t('If you put zero to the low and high priority, this feature will be disabled.') ?></p>
diff --git a/app/Template/project_file/create.php b/app/Template/project_file/create.php
index e262799b..de35f87c 100644
--- a/app/Template/project_file/create.php
+++ b/app/Template/project_file/create.php
@@ -1,33 +1,20 @@
<div class="page-header">
<h2><?= t('Attach a document') ?></h2>
</div>
-<div id="file-done" style="display:none">
- <p class="alert alert-success">
- <?= t('All files have been uploaded successfully.') ?>
- <?= $this->url->link(t('View uploaded files'), 'ProjectOverviewController', 'show', array('project_id' => $project['id'])) ?>
- </p>
-</div>
-
-<div id="file-error-max-size" style="display:none">
- <p class="alert alert-error">
- <?= t('The maximum allowed file size is %sB.', $this->text->bytes($max_size)) ?>
- <a href="#" id="file-browser"><?= t('Choose files again') ?></a>
- </p>
-</div>
-<div
- id="file-dropzone"
- data-max-size="<?= $max_size ?>"
- data-url="<?= $this->url->href('ProjectFileController', 'save', array('project_id' => $project['id'])) ?>">
- <div id="file-dropzone-inner">
- <?= t('Drag and drop your files here') ?> <?= t('or') ?> <a href="#" id="file-browser"><?= t('choose files') ?></a>
- </div>
-</div>
-
-<input type="file" name="files[]" multiple style="display:none" id="file-form-element">
+<?= $this->app->component('file-upload', array(
+ 'maxSize' => $max_size,
+ 'url' => $this->url->to('ProjectFileController', 'save', array('project_id' => $project['id'])),
+ 'labelDropzone' => t('Drag and drop your files here'),
+ 'labelOr' => t('or'),
+ 'labelChooseFiles' => t('choose files'),
+ 'labelOversize' => t('The maximum allowed file size is %sB.', $this->text->bytes($max_size)),
+ 'labelSuccess' => t('All files have been uploaded successfully.'),
+ 'labelCloseSuccess' => t('Close this window'),
+ 'labelUploadError' => t('Unable to upload this file.'),
+)) ?>
-<div class="form-actions">
- <input type="submit" value="<?= t('Upload files') ?>" class="btn btn-blue" id="file-upload-button" disabled>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'ProjectOverviewController', 'show', array('project_id' => $project['id']), false, 'close-popover') ?>
-</div>
+<?= $this->modal->submitButtons(array(
+ 'submitLabel' => t('Upload files'),
+ 'disabled' => true,
+)) ?>
diff --git a/app/Template/project_file/remove.php b/app/Template/project_file/remove.php
index 0517a9e7..043b8fc8 100644
--- a/app/Template/project_file/remove.php
+++ b/app/Template/project_file/remove.php
@@ -7,9 +7,9 @@
<?= t('Do you really want to remove this file: "%s"?', $this->text->e($file['name'])) ?>
</p>
- <div class="form-actions">
- <?= $this->url->link(t('Yes'), 'ProjectFileController', 'remove', array('project_id' => $project['id'], 'file_id' => $file['id']), true, 'btn btn-red') ?>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'ProjectOverviewController', 'show', array('project_id' => $project['id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->confirmButtons(
+ 'ProjectFileController',
+ 'remove',
+ array('project_id' => $project['id'], 'file_id' => $file['id'])
+ ) ?>
</div>
diff --git a/app/Template/project_gantt/show.php b/app/Template/project_gantt/show.php
index af22a6ed..725f348d 100644
--- a/app/Template/project_gantt/show.php
+++ b/app/Template/project_gantt/show.php
@@ -1,11 +1,23 @@
<section id="main">
<div class="page-header">
<ul>
+ <?php if ($this->user->hasAccess('ProjectCreationController', 'create')): ?>
+ <li>
+ <?= $this->modal->medium('plus', t('New project'), 'ProjectCreationController', 'create') ?>
+ </li>
+ <?php endif ?>
+ <?php if ($this->app->config('disable_private_project', 0) == 0): ?>
+ <li>
+ <?= $this->modal->medium('lock', t('New private project'), 'ProjectCreationController', 'createPrivate') ?>
+ </li>
+ <?php endif ?>
<li>
- <i class="fa fa-folder fa-fw"></i><?= $this->url->link(t('Projects list'), 'ProjectListController', 'show') ?>
+ <?= $this->url->icon('folder', t('Projects list'), 'ProjectListController', 'show') ?>
</li>
<?php if ($this->user->hasAccess('ProjectUserOverviewController', 'managers')): ?>
- <li><i class="fa fa-user fa-fw"></i><?= $this->url->link(t('Users overview'), 'ProjectUserOverviewController', 'managers') ?></li>
+ <li>
+ <?= $this->url->icon('user', t('Users overview'), 'ProjectUserOverviewController', 'managers') ?>
+ </li>
<?php endif ?>
</ul>
</div>
diff --git a/app/Template/project_header/dropdown.php b/app/Template/project_header/dropdown.php
index baf4cc16..83c2b97f 100644
--- a/app/Template/project_header/dropdown.php
+++ b/app/Template/project_header/dropdown.php
@@ -4,12 +4,10 @@
<?php if ($board_view): ?>
<li>
<span class="filter-display-mode" <?= $this->board->isCollapsed($project['id']) ? '' : 'style="display: none;"' ?>>
- <i class="fa fa-expand fa-fw"></i>
- <?= $this->url->link(t('Expand tasks'), 'BoardAjaxController', 'expand', array('project_id' => $project['id']), false, 'board-display-mode', t('Keyboard shortcut: "%s"', 's')) ?>
+ <?= $this->url->icon('expand', t('Expand tasks'), 'BoardAjaxController', 'expand', array('project_id' => $project['id']), false, 'board-display-mode', t('Keyboard shortcut: "%s"', 's')) ?>
</span>
<span class="filter-display-mode" <?= $this->board->isCollapsed($project['id']) ? 'style="display: none;"' : '' ?>>
- <i class="fa fa-compress fa-fw"></i>
- <?= $this->url->link(t('Collapse tasks'), 'BoardAjaxController', 'collapse', array('project_id' => $project['id']), false, 'board-display-mode', t('Keyboard shortcut: "%s"', 's')) ?>
+ <?= $this->url->icon('compress', t('Collapse tasks'), 'BoardAjaxController', 'collapse', array('project_id' => $project['id']), false, 'board-display-mode', t('Keyboard shortcut: "%s"', 's')) ?>
</span>
</li>
<li>
@@ -24,27 +22,23 @@
<?php if ($this->user->hasProjectAccess('TaskCreationController', 'show', $project['id'])): ?>
<li>
- <i class="fa fa-plus fa-fw"></i>
- <?= $this->url->link(t('Add a new task'), 'TaskCreationController', 'show', array('project_id' => $project['id']), false, 'popover') ?>
+ <?= $this->modal->large('plus', t('Add a new task'), 'TaskCreationController', 'show', array('project_id' => $project['id'])) ?>
</li>
<?php endif ?>
<li>
- <i class="fa fa-dashboard fa-fw"></i>
- <?= $this->url->link(t('Activity'), 'ActivityController', 'project', array('project_id' => $project['id'])) ?>
+ <?= $this->modal->medium('dashboard', t('Activity'), 'ActivityController', 'project', array('project_id' => $project['id'])) ?>
</li>
<?php if ($this->user->hasProjectAccess('CustomFilterController', 'index', $project['id'])): ?>
<li>
- <i class="fa fa-filter fa-fw"></i>
- <?= $this->url->link(t('Custom filters'), 'CustomFilterController', 'index', array('project_id' => $project['id'])) ?>
+ <?= $this->modal->medium('filter', t('Add custom filters'), 'CustomFilterController', 'create', array('project_id' => $project['id'])) ?>
</li>
<?php endif ?>
<?php if ($project['is_public']): ?>
<li>
- <i class="fa fa-share-alt fa-fw"></i>
- <?= $this->url->link(t('Public link'), 'BoardViewController', 'readonly', array('token' => $project['token']), false, '', '', true) ?>
+ <?= $this->url->icon('share-alt', t('Public link'), 'BoardViewController', 'readonly', array('token' => $project['token']), false, '', '', true) ?>
</li>
<?php endif ?>
@@ -52,35 +46,30 @@
<?php if ($this->user->hasProjectAccess('AnalyticController', 'taskDistribution', $project['id'])): ?>
<li>
- <i class="fa fa-line-chart fa-fw"></i>
- <?= $this->url->link(t('Analytics'), 'AnalyticController', 'taskDistribution', array('project_id' => $project['id'])) ?>
+ <?= $this->modal->large('line-chart', t('Analytics'), 'AnalyticController', 'taskDistribution', array('project_id' => $project['id'])) ?>
</li>
<?php endif ?>
<?php if ($this->user->hasProjectAccess('ExportController', 'tasks', $project['id'])): ?>
<li>
- <i class="fa fa-upload fa-fw"></i>
- <?= $this->url->link(t('Exports'), 'ExportController', 'tasks', array('project_id' => $project['id'])) ?>
+ <?= $this->modal->medium('upload', t('Exports'), 'ExportController', 'tasks', array('project_id' => $project['id'])) ?>
</li>
<?php endif ?>
<?php if ($this->user->hasProjectAccess('TaskImportController', 'tasks', $project['id'])): ?>
<li>
- <i class="fa fa-download fa-fw"></i>
- <?= $this->url->link(t('Imports'), 'TaskImportController', 'show', array('project_id' => $project['id'])) ?>
+ <?= $this->modal->medium('download', t('Import tasks'), 'TaskImportController', 'show', array('project_id' => $project['id'])) ?>
</li>
<?php endif ?>
- <?php if ($this->user->hasProjectAccess('ProjectEditController', 'edit', $project['id'])): ?>
+ <?php if ($this->user->hasProjectAccess('ProjectEditController', 'show', $project['id'])): ?>
<li>
- <i class="fa fa-cog fa-fw"></i>
- <?= $this->url->link(t('Settings'), 'ProjectViewController', 'show', array('project_id' => $project['id'])) ?>
+ <?= $this->url->icon('cog', t('Settings'), 'ProjectViewController', 'show', array('project_id' => $project['id'])) ?>
</li>
<?php endif ?>
<li>
- <i class="fa fa-folder fa-fw" aria-hidden="true"></i>
- <?= $this->url->link(t('Manage projects'), 'ProjectListController', 'show') ?>
+ <?= $this->url->icon('folder', t('Manage projects'), 'ProjectListController', 'show') ?>
</li>
</ul>
</div>
diff --git a/app/Template/project_header/views.php b/app/Template/project_header/views.php
index f8a5b39b..0328a051 100644
--- a/app/Template/project_header/views.php
+++ b/app/Template/project_header/views.php
@@ -1,24 +1,19 @@
<ul class="views">
<li <?= $this->app->checkMenuSelection('ProjectOverviewController') ?>>
- <i class="fa fa-eye fa-fw"></i>
- <?= $this->url->link(t('Overview'), 'ProjectOverviewController', 'show', array('project_id' => $project['id'], 'search' => $filters['search']), false, 'view-overview', t('Keyboard shortcut: "%s"', 'v o')) ?>
+ <?= $this->url->icon('eye', t('Overview'), 'ProjectOverviewController', 'show', array('project_id' => $project['id'], 'search' => $filters['search']), false, 'view-overview', t('Keyboard shortcut: "%s"', 'v o')) ?>
</li>
<li <?= $this->app->checkMenuSelection('BoardViewController') ?>>
- <i class="fa fa-th fa-fw"></i>
- <?= $this->url->link(t('Board'), 'BoardViewController', 'show', array('project_id' => $project['id'], 'search' => $filters['search']), false, 'view-board', t('Keyboard shortcut: "%s"', 'v b')) ?>
+ <?= $this->url->icon('th', t('Board'), 'BoardViewController', 'show', array('project_id' => $project['id'], 'search' => $filters['search']), false, 'view-board', t('Keyboard shortcut: "%s"', 'v b')) ?>
</li>
<li <?= $this->app->checkMenuSelection('CalendarController') ?>>
- <i class="fa fa-calendar fa-fw"></i>
- <?= $this->url->link(t('Calendar'), 'CalendarController', 'show', array('project_id' => $project['id'], 'search' => $filters['search']), false, 'view-calendar', t('Keyboard shortcut: "%s"', 'v c')) ?>
+ <?= $this->url->icon('calendar', t('Calendar'), 'CalendarController', 'show', array('project_id' => $project['id'], 'search' => $filters['search']), false, 'view-calendar', t('Keyboard shortcut: "%s"', 'v c')) ?>
</li>
<li <?= $this->app->checkMenuSelection('TaskListController') ?>>
- <i class="fa fa-list fa-fw"></i>
- <?= $this->url->link(t('List'), 'TaskListController', 'show', array('project_id' => $project['id'], 'search' => $filters['search']), false, 'view-listing', t('Keyboard shortcut: "%s"', 'v l')) ?>
+ <?= $this->url->icon('list', t('List'), 'TaskListController', 'show', array('project_id' => $project['id'], 'search' => $filters['search']), false, 'view-listing', t('Keyboard shortcut: "%s"', 'v l')) ?>
</li>
<?php if ($this->user->hasProjectAccess('TaskGanttController', 'show', $project['id'])): ?>
<li <?= $this->app->checkMenuSelection('TaskGanttController') ?>>
- <i class="fa fa-sliders fa-fw"></i>
- <?= $this->url->link(t('Gantt'), 'TaskGanttController', 'show', array('project_id' => $project['id'], 'search' => $filters['search']), false, 'view-gantt', t('Keyboard shortcut: "%s"', 'v g')) ?>
+ <?= $this->url->icon('sliders', t('Gantt'), 'TaskGanttController', 'show', array('project_id' => $project['id'], 'search' => $filters['search']), false, 'view-gantt', t('Keyboard shortcut: "%s"', 'v g')) ?>
</li>
<?php endif ?>
</ul>
diff --git a/app/Template/project_list/show.php b/app/Template/project_list/show.php
index f8f5862c..a6364585 100644
--- a/app/Template/project_list/show.php
+++ b/app/Template/project_list/show.php
@@ -2,12 +2,26 @@
<div class="page-header">
<ul>
<?= $this->hook->render('template:project-list:menu:before') ?>
+
+ <?php if ($this->user->hasAccess('ProjectCreationController', 'create')): ?>
+ <li>
+ <?= $this->modal->medium('plus', t('New project'), 'ProjectCreationController', 'create') ?>
+ </li>
+ <?php endif ?>
+ <?php if ($this->app->config('disable_private_project', 0) == 0): ?>
+ <li>
+ <?= $this->modal->medium('lock', t('New private project'), 'ProjectCreationController', 'createPrivate') ?>
+ </li>
+ <?php endif ?>
+
<?php if ($this->user->hasAccess('ProjectUserOverviewController', 'managers')): ?>
- <li><i class="fa fa-user fa-fw"></i><?= $this->url->link(t('Users overview'), 'ProjectUserOverviewController', 'managers') ?></li>
+ <li><?= $this->url->icon('user', t('Users overview'), 'ProjectUserOverviewController', 'managers') ?></li>
<?php endif ?>
+
<?php if ($this->user->hasAccess('ProjectGanttController', 'show')): ?>
- <li><i class="fa fa-sliders fa-fw"></i><?= $this->url->link(t('Projects Gantt chart'), 'ProjectGanttController', 'show') ?></li>
+ <li><?= $this->url->icon('sliders', t('Projects Gantt chart'), 'ProjectGanttController', 'show') ?></li>
<?php endif ?>
+
<?= $this->hook->render('template:project-list:menu:after') ?>
</ul>
</div>
diff --git a/app/Template/project_overview/attachments.php b/app/Template/project_overview/attachments.php
index ab8cf2ad..b8baadd0 100644
--- a/app/Template/project_overview/attachments.php
+++ b/app/Template/project_overview/attachments.php
@@ -5,7 +5,7 @@
<div class="accordion-content">
<?php if ($this->user->hasProjectAccess('ProjectFileController', 'create', $project['id'])): ?>
<div class="buttons-header">
- <?= $this->url->button('fa-plus', t('Upload a file'), 'ProjectFileController', 'create', array('project_id' => $project['id']), 'popover') ?>
+ <?= $this->modal->mediumButton('plus', t('Upload a file'), 'ProjectFileController', 'create', array('project_id' => $project['id'])) ?>
</div>
<?php endif ?>
diff --git a/app/Template/project_overview/description.php b/app/Template/project_overview/description.php
index 0c2027ed..80b93efe 100644
--- a/app/Template/project_overview/description.php
+++ b/app/Template/project_overview/description.php
@@ -3,9 +3,9 @@
<h3><a href="#" class="fa accordion-toggle"></a> <?= t('Description') ?></h3>
</div>
<div class="accordion-content">
- <?php if ($this->user->hasProjectAccess('ProjectEditController', 'description', $project['id'])): ?>
+ <?php if ($this->user->hasProjectAccess('ProjectEditController', 'show', $project['id'])): ?>
<div class="buttons-header">
- <?= $this->url->button('fa-edit', t('Edit description'), 'ProjectEditController', 'description', array('project_id' => $project['id']), 'popover') ?>
+ <?= $this->modal->mediumButton('edit', t('Edit description'), 'ProjectEditController', 'show', array('project_id' => $project['id'])) ?>
</div>
<?php endif ?>
<article class="markdown">
diff --git a/app/Template/project_overview/files.php b/app/Template/project_overview/files.php
index 826e6325..85de52f7 100644
--- a/app/Template/project_overview/files.php
+++ b/app/Template/project_overview/files.php
@@ -15,18 +15,19 @@
<ul>
<?php if ($this->file->getPreviewType($file['name']) !== null): ?>
<li>
- <i class="fa fa-eye fa-fw"></i>
- <?= $this->url->link(t('View file'), 'FileViewerController', 'show', array('project_id' => $project['id'], 'file_id' => $file['id']), false, 'popover') ?>
+ <?= $this->modal->large('eye', t('View file'), 'FileViewerController', 'show', array('project_id' => $project['id'], 'file_id' => $file['id'])) ?>
+ </li>
+ <?php elseif ($this->file->getBrowserViewType($file['name']) !== null): ?>
+ <li>
+ <?= $this->url->icon('eye', t('View file'), 'FileViewerController', 'browser', array('project_id' => $project['id'], 'file_id' => $file['id']), false, '', '', true) ?>
</li>
<?php endif ?>
<li>
- <i class="fa fa-download fa-fw"></i>
- <?= $this->url->link(t('Download'), 'FileViewerController', 'download', array('project_id' => $project['id'], 'file_id' => $file['id'])) ?>
+ <?= $this->url->icon('download', t('Download'), 'FileViewerController', 'download', array('project_id' => $project['id'], 'file_id' => $file['id'])) ?>
</li>
<?php if ($this->user->hasProjectAccess('ProjectFileController', 'remove', $project['id'])): ?>
<li>
- <i class="fa fa-trash fa-fw"></i>
- <?= $this->url->link(t('Remove'), 'ProjectFileController', 'confirm', array('project_id' => $project['id'], 'file_id' => $file['id']), false, 'popover') ?>
+ <?= $this->modal->confirm('trash-o', t('Remove'), 'ProjectFileController', 'confirm', array('project_id' => $project['id'], 'file_id' => $file['id'])) ?>
</li>
<?php endif ?>
</ul>
diff --git a/app/Template/project_overview/images.php b/app/Template/project_overview/images.php
index 7f38e2b1..482ef551 100644
--- a/app/Template/project_overview/images.php
+++ b/app/Template/project_overview/images.php
@@ -2,20 +2,28 @@
<div class="file-thumbnails">
<?php foreach ($images as $file): ?>
<div class="file-thumbnail">
- <a href="<?= $this->url->href('FileViewerController', 'show', array('project_id' => $project['id'], 'file_id' => $file['id'])) ?>" class="popover"><img src="<?= $this->url->href('FileViewerController', 'thumbnail', array('file_id' => $file['id'], 'project_id' => $project['id'])) ?>" title="<?= $this->text->e($file['name']) ?>" alt="<?= $this->text->e($file['name']) ?>"></a>
+ <?= $this->app->component('image-slideshow', array(
+ 'images' => $images,
+ 'image' => $file,
+ 'regex' => 'FILE_ID',
+ 'url' => array(
+ 'image' => $this->url->to('FileViewerController', 'image', array('file_id' => 'FILE_ID', 'project_id' => $project['id'])),
+ 'thumbnail' => $this->url->to('FileViewerController', 'thumbnail', array('file_id' => 'FILE_ID', 'project_id' => $project['id'])),
+ 'download' => $this->url->to('FileViewerController', 'download', array('file_id' => 'FILE_ID', 'project_id' => $project['id'])),
+ )
+ )) ?>
+
<div class="file-thumbnail-content">
<div class="file-thumbnail-title">
<div class="dropdown">
<a href="#" class="dropdown-menu dropdown-menu-link-text"><?= $this->text->e($file['name']) ?> <i class="fa fa-caret-down"></i></a>
<ul>
<li>
- <i class="fa fa-download fa-fw"></i>
- <?= $this->url->link(t('Download'), 'FileViewerController', 'download', array('project_id' => $project['id'], 'file_id' => $file['id'])) ?>
+ <?= $this->url->icon('download', t('Download'), 'FileViewerController', 'download', array('project_id' => $project['id'], 'file_id' => $file['id'])) ?>
</li>
<?php if ($this->user->hasProjectAccess('ProjectFileController', 'remove', $project['id'])): ?>
<li>
- <i class="fa fa-trash fa-fw"></i>
- <?= $this->url->link(t('Remove'), 'ProjectFileController', 'confirm', array('project_id' => $project['id'], 'file_id' => $file['id']), false, 'popover') ?>
+ <?= $this->modal->confirm('trash-o', t('Remove'), 'ProjectFileController', 'confirm', array('project_id' => $project['id'], 'file_id' => $file['id'])) ?>
</li>
<?php endif ?>
</ul>
@@ -25,7 +33,11 @@
<span class="tooltip" title='<?= t('Uploaded: %s', $this->dt->datetime($file['date'])).'<br>'.t('Size: %s', $this->text->bytes($file['size'])) ?>'>
<i class="fa fa-info-circle"></i>
</span>
- <?= t('Uploaded by %s', $file['user_name'] ?: $file['username']) ?>
+ <?php if (! empty($file['user_id'])): ?>
+ <?= t('Uploaded by %s', $file['user_name'] ?: $file['username']) ?>
+ <?php else: ?>
+ <?= t('Uploaded: %s', $this->dt->datetime($file['date'])) ?>
+ <?php endif ?>
</div>
</div>
</div>
diff --git a/app/Template/project_overview/information.php b/app/Template/project_overview/information.php
index fdf0f753..0fe53e08 100644
--- a/app/Template/project_overview/information.php
+++ b/app/Template/project_overview/information.php
@@ -3,7 +3,7 @@
<h3><a href="#" class="fa accordion-toggle"></a> <?= t('Information') ?></h3>
</div>
<div class="accordion-content">
- <div class="listing">
+ <div class="panel">
<ul>
<?php if ($project['owner_id'] > 0): ?>
<li><?= t('Project owner: ') ?><strong><?= $this->text->e($project['owner_name'] ?: $project['owner_username']) ?></strong></li>
@@ -29,9 +29,9 @@
<?php endif ?>
<?php if ($project['is_public']): ?>
- <li><i class="fa fa-share-alt"></i> <?= $this->url->link(t('Public link'), 'BoardViewController', 'readonly', array('token' => $project['token']), false, '', '', true) ?></li>
- <li><i class="fa fa-rss-square"></i> <?= $this->url->link(t('RSS feed'), 'FeedController', 'project', array('token' => $project['token']), false, '', '', true) ?></li>
- <li><i class="fa fa-calendar"></i> <?= $this->url->link(t('iCal feed'), 'ICalendarController', 'project', array('token' => $project['token'])) ?></li>
+ <li><?= $this->url->icon('share-alt', t('Public link'), 'BoardViewController', 'readonly', array('token' => $project['token']), false, '', '', true) ?></li>
+ <li><?= $this->url->icon('rss-square', t('RSS feed'), 'FeedController', 'project', array('token' => $project['token']), false, '', '', true) ?></li>
+ <li><?= $this->url->icon('calendar', t('iCal feed'), 'ICalendarController', 'project', array('token' => $project['token'])) ?></li>
<?php endif ?>
</ul>
</div>
diff --git a/app/Template/project_overview/show.php b/app/Template/project_overview/show.php
index 6b2bc2cf..d87b2775 100644
--- a/app/Template/project_overview/show.php
+++ b/app/Template/project_overview/show.php
@@ -1,6 +1,7 @@
<section id="main">
<?= $this->projectHeader->render($project, 'ProjectOverviewController', 'show') ?>
<?= $this->render('project_overview/columns', array('project' => $project)) ?>
+ <?= $this->hook->render('template:project-overview:before-description', array('project' => $project)) ?>
<?= $this->render('project_overview/description', array('project' => $project)) ?>
<?= $this->render('project_overview/attachments', array('project' => $project, 'images' => $images, 'files' => $files)) ?>
<?= $this->render('project_overview/information', array('project' => $project, 'users' => $users, 'roles' => $roles)) ?>
diff --git a/app/Template/project_permission/groups.php b/app/Template/project_permission/groups.php
new file mode 100644
index 00000000..c9914344
--- /dev/null
+++ b/app/Template/project_permission/groups.php
@@ -0,0 +1,60 @@
+<div class="page-header">
+ <h2><?= t('Allowed Groups') ?></h2>
+</div>
+
+<?php if (empty($groups)): ?>
+ <div class="alert"><?= t('No group have been allowed specifically.') ?></div>
+<?php else: ?>
+ <table class="table-scrolling">
+ <tr>
+ <th class="column-50"><?= t('Group') ?></th>
+ <th><?= t('Role') ?></th>
+ <?php if ($project['is_private'] == 0): ?>
+ <th class="column-15"><?= t('Actions') ?></th>
+ <?php endif ?>
+ </tr>
+ <?php foreach ($groups as $group): ?>
+ <tr>
+ <td><?= $this->text->e($group['name']) ?></td>
+ <td>
+ <?= $this->app->component('project-select-role', array(
+ 'roles' => $roles,
+ 'role' => $group['role'],
+ 'id' => $group['id'],
+ 'url' => $this->url->to('ProjectPermissionController', 'changeGroupRole', array('project_id' => $project['id'])),
+ )) ?>
+ </td>
+ <td>
+ <?= $this->url->icon('trash-o', t('Remove'), 'ProjectPermissionController', 'removeGroup', array('project_id' => $project['id'], 'group_id' => $group['id']), true) ?>
+ </td>
+ </tr>
+ <?php endforeach ?>
+ </table>
+<?php endif ?>
+
+<?php if ($project['is_private'] == 0): ?>
+ <div class="panel">
+ <form method="post" action="<?= $this->url->href('ProjectPermissionController', 'addGroup', array('project_id' => $project['id'])) ?>" autocomplete="off" class="form-inline">
+ <?= $this->form->csrf() ?>
+ <?= $this->form->hidden('project_id', array('project_id' => $project['id'])) ?>
+ <?= $this->form->hidden('group_id', $values) ?>
+ <?= $this->form->hidden('external_id', $values) ?>
+
+ <?= $this->form->label(t('Group Name'), 'name') ?>
+ <?= $this->form->text('name', $values, $errors, array(
+ 'required',
+ 'placeholder="'.t('Enter group name...').'"',
+ 'title="'.t('Enter group name...').'"',
+ 'data-dst-field="group_id"',
+ 'data-dst-extra-field="external_id"',
+ 'data-search-url="'.$this->url->href('GroupAjaxController', 'autocomplete').'"',
+ ),
+ 'autocomplete') ?>
+
+ <?= $this->form->select('role', $roles, $values, $errors) ?>
+
+ <button type="submit" class="btn btn-blue"><?= t('Add') ?></button>
+ </form>
+ </div>
+<?php endif ?>
+
diff --git a/app/Template/project_permission/index.php b/app/Template/project_permission/index.php
index c7b17782..689966b6 100644
--- a/app/Template/project_permission/index.php
+++ b/app/Template/project_permission/index.php
@@ -5,125 +5,21 @@
<?php if ($project['is_everybody_allowed']): ?>
<div class="alert"><?= t('Everybody have access to this project.') ?></div>
<?php else: ?>
+ <?= $this->render('project_permission/users', array(
+ 'project' => $project,
+ 'roles' => $roles,
+ 'users' => $users,
+ 'errors' => $errors,
+ 'values' => $values,
+ )) ?>
- <?php if (empty($users)): ?>
- <div class="alert"><?= t('No user have been allowed specifically.') ?></div>
- <?php else: ?>
- <table class="table-scrolling">
- <tr>
- <th class="column-50"><?= t('User') ?></th>
- <th><?= t('Role') ?></th>
- <?php if ($project['is_private'] == 0): ?>
- <th class="column-15"><?= t('Actions') ?></th>
- <?php endif ?>
- </tr>
- <?php foreach ($users as $user): ?>
- <tr>
- <td><?= $this->text->e($user['name'] ?: $user['username']) ?></td>
- <td>
- <?= $this->form->select(
- 'role-'.$user['id'],
- $roles,
- array('role-'.$user['id'] => $user['role']),
- array(),
- array('data-url="'.$this->url->href('ProjectPermissionController', 'changeUserRole', array('project_id' => $project['id'])).'"', 'data-id="'.$user['id'].'"'),
- 'project-change-role'
- ) ?>
- </td>
- <td>
- <?= $this->url->link(t('Remove'), 'ProjectPermissionController', 'removeUser', array('project_id' => $project['id'], 'user_id' => $user['id']), true) ?>
- </td>
- </tr>
- <?php endforeach ?>
- </table>
- <?php endif ?>
-
- <?php if ($project['is_private'] == 0): ?>
- <div class="listing">
- <form method="post" action="<?= $this->url->href('ProjectPermissionController', 'addUser', array('project_id' => $project['id'])) ?>" autocomplete="off" class="form-inline">
- <?= $this->form->csrf() ?>
- <?= $this->form->hidden('project_id', array('project_id' => $project['id'])) ?>
- <?= $this->form->hidden('user_id', $values) ?>
-
- <?= $this->form->label(t('Name'), 'name') ?>
- <?= $this->form->text('name', $values, $errors, array(
- 'required',
- 'placeholder="'.t('Enter user name...').'"',
- 'title="'.t('Enter user name...').'"',
- 'data-dst-field="user_id"',
- 'data-search-url="'.$this->url->href('UserAjaxController', 'autocomplete').'"',
- ),
- 'autocomplete') ?>
-
- <?= $this->form->select('role', $roles, $values, $errors) ?>
-
- <button type="submit" class="btn btn-blue"><?= t('Add') ?></button>
- </form>
- </div>
- <?php endif ?>
-
- <div class="page-header">
- <h2><?= t('Allowed Groups') ?></h2>
- </div>
-
- <?php if (empty($groups)): ?>
- <div class="alert"><?= t('No group have been allowed specifically.') ?></div>
- <?php else: ?>
- <table class="table-scrolling">
- <tr>
- <th class="column-50"><?= t('Group') ?></th>
- <th><?= t('Role') ?></th>
- <?php if ($project['is_private'] == 0): ?>
- <th class="column-15"><?= t('Actions') ?></th>
- <?php endif ?>
- </tr>
- <?php foreach ($groups as $group): ?>
- <tr>
- <td><?= $this->text->e($group['name']) ?></td>
- <td>
- <?= $this->form->select(
- 'role-'.$group['id'],
- $roles,
- array('role-'.$group['id'] => $group['role']),
- array(),
- array('data-url="'.$this->url->href('ProjectPermissionController', 'changeGroupRole', array('project_id' => $project['id'])).'"', 'data-id="'.$group['id'].'"'),
- 'project-change-role'
- ) ?>
- </td>
- <td>
- <?= $this->url->link(t('Remove'), 'ProjectPermissionController', 'removeGroup', array('project_id' => $project['id'], 'group_id' => $group['id']), true) ?>
- </td>
- </tr>
- <?php endforeach ?>
- </table>
- <?php endif ?>
-
- <?php if ($project['is_private'] == 0): ?>
- <div class="listing">
- <form method="post" action="<?= $this->url->href('ProjectPermissionController', 'addGroup', array('project_id' => $project['id'])) ?>" autocomplete="off" class="form-inline">
- <?= $this->form->csrf() ?>
- <?= $this->form->hidden('project_id', array('project_id' => $project['id'])) ?>
- <?= $this->form->hidden('group_id', $values) ?>
- <?= $this->form->hidden('external_id', $values) ?>
-
- <?= $this->form->label(t('Group Name'), 'name') ?>
- <?= $this->form->text('name', $values, $errors, array(
- 'required',
- 'placeholder="'.t('Enter group name...').'"',
- 'title="'.t('Enter group name...').'"',
- 'data-dst-field="group_id"',
- 'data-dst-extra-field="external_id"',
- 'data-search-url="'.$this->url->href('GroupAjaxController', 'autocomplete').'"',
- ),
- 'autocomplete') ?>
-
- <?= $this->form->select('role', $roles, $values, $errors) ?>
-
- <button type="submit" class="btn btn-blue"><?= t('Add') ?></button>
- </form>
- </div>
- <?php endif ?>
-
+ <?= $this->render('project_permission/groups', array(
+ 'project' => $project,
+ 'roles' => $roles,
+ 'groups' => $groups,
+ 'errors' => $errors,
+ 'values' => $values,
+ )) ?>
<?php endif ?>
<?php if ($project['is_private'] == 0): ?>
diff --git a/app/Template/project_permission/users.php b/app/Template/project_permission/users.php
new file mode 100644
index 00000000..bc92d060
--- /dev/null
+++ b/app/Template/project_permission/users.php
@@ -0,0 +1,53 @@
+<?php if (empty($users)): ?>
+ <div class="alert"><?= t('No user have been allowed specifically.') ?></div>
+<?php else: ?>
+ <table class="table-scrolling">
+ <tr>
+ <th class="column-50"><?= t('User') ?></th>
+ <th><?= t('Role') ?></th>
+ <?php if ($project['is_private'] == 0): ?>
+ <th class="column-15"><?= t('Actions') ?></th>
+ <?php endif ?>
+ </tr>
+ <?php foreach ($users as $user): ?>
+ <tr>
+ <td><?= $this->text->e($user['name'] ?: $user['username']) ?></td>
+ <td>
+ <?= $this->app->component('project-select-role', array(
+ 'roles' => $roles,
+ 'role' => $user['role'],
+ 'id' => $user['id'],
+ 'url' => $this->url->to('ProjectPermissionController', 'changeUserRole', array('project_id' => $project['id'])),
+ )) ?>
+ </td>
+ <td>
+ <?= $this->url->icon('trash-o', t('Remove'), 'ProjectPermissionController', 'removeUser', array('project_id' => $project['id'], 'user_id' => $user['id']), true) ?>
+ </td>
+ </tr>
+ <?php endforeach ?>
+ </table>
+<?php endif ?>
+
+<?php if ($project['is_private'] == 0): ?>
+ <div class="panel">
+ <form method="post" action="<?= $this->url->href('ProjectPermissionController', 'addUser', array('project_id' => $project['id'])) ?>" autocomplete="off" class="form-inline">
+ <?= $this->form->csrf() ?>
+ <?= $this->form->hidden('project_id', array('project_id' => $project['id'])) ?>
+ <?= $this->form->hidden('user_id', $values) ?>
+
+ <?= $this->form->label(t('Name'), 'name') ?>
+ <?= $this->form->text('name', $values, $errors, array(
+ 'required',
+ 'placeholder="'.t('Enter user name...').'"',
+ 'title="'.t('Enter user name...').'"',
+ 'data-dst-field="user_id"',
+ 'data-search-url="'.$this->url->href('UserAjaxController', 'autocomplete').'"',
+ ),
+ 'autocomplete') ?>
+
+ <?= $this->form->select('role', $roles, $values, $errors) ?>
+
+ <button type="submit" class="btn btn-blue"><?= t('Add') ?></button>
+ </form>
+ </div>
+<?php endif ?>
diff --git a/app/Template/project_role/create.php b/app/Template/project_role/create.php
index d0092243..f554eb17 100644
--- a/app/Template/project_role/create.php
+++ b/app/Template/project_role/create.php
@@ -1,16 +1,12 @@
<div class="page-header">
<h2><?= t('New custom project role') ?></h2>
</div>
-<form class="popover-form" method="post" action="<?= $this->url->href('ProjectRoleController', 'save', array('project_id' => $project['id'])) ?>" autocomplete="off">
+<form method="post" action="<?= $this->url->href('ProjectRoleController', 'save', array('project_id' => $project['id'])) ?>" autocomplete="off">
<?= $this->form->csrf() ?>
<?= $this->form->hidden('project_id', $values) ?>
<?= $this->form->label(t('Role'), 'role') ?>
<?= $this->form->text('role', $values, $errors, array('autofocus', 'required', 'maxlength="50"')) ?>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'ProjectRoleController', 'show', array(), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->submitButtons() ?>
</form>
diff --git a/app/Template/project_role/edit.php b/app/Template/project_role/edit.php
index 3aa9e5cf..740ac0fe 100644
--- a/app/Template/project_role/edit.php
+++ b/app/Template/project_role/edit.php
@@ -1,7 +1,7 @@
<div class="page-header">
<h2><?= t('Edit custom project role') ?></h2>
</div>
-<form class="popover-form" method="post" action="<?= $this->url->href('ProjectRoleController', 'update', array('project_id' => $project['id'], 'role_id' => $role['role_id'])) ?>" autocomplete="off">
+<form method="post" action="<?= $this->url->href('ProjectRoleController', 'update', array('project_id' => $project['id'], 'role_id' => $role['role_id'])) ?>" autocomplete="off">
<?= $this->form->csrf() ?>
<?= $this->form->hidden('project_id', $values) ?>
<?= $this->form->hidden('role_id', $values) ?>
@@ -9,9 +9,5 @@
<?= $this->form->label(t('Role'), 'role') ?>
<?= $this->form->text('role', $values, $errors, array('autofocus', 'required', 'maxlength="50"')) ?>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'ProjectRoleController', 'show', array(), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->submitButtons() ?>
</form>
diff --git a/app/Template/project_role/remove.php b/app/Template/project_role/remove.php
index 25875e3a..44d24eda 100644
--- a/app/Template/project_role/remove.php
+++ b/app/Template/project_role/remove.php
@@ -7,8 +7,9 @@
<?= t('Do you really want to remove this custom role: "%s"? All people assigned to this role will become project member.', $role['role']) ?>
</p>
- <div class="form-actions">
- <?= $this->url->link(t('Yes'), 'ProjectRoleController', 'remove', array('project_id' => $project['id'], 'role_id' => $role['role_id']), true, 'btn btn-red') ?>
- <?= t('or') ?> <?= $this->url->link(t('cancel'), 'ProjectRoleController', 'show', array('project_id' => $project['id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->confirmButtons(
+ 'ProjectRoleController',
+ 'remove',
+ array('project_id' => $project['id'], 'role_id' => $role['role_id'])
+ ) ?>
</div>
diff --git a/app/Template/project_role/show.php b/app/Template/project_role/show.php
index 59200fc9..5377f7bb 100644
--- a/app/Template/project_role/show.php
+++ b/app/Template/project_role/show.php
@@ -2,8 +2,7 @@
<h2><?= t('Custom Project Roles') ?></h2>
<ul>
<li>
- <i class="fa fa-plus fa-fw" aria-hidden="true"></i>
- <?= $this->url->link(t('Add a new custom role'), 'ProjectRoleController', 'create', array('project_id' => $project['id']), false, 'popover') ?>
+ <?= $this->modal->medium('plus', t('Add a new custom role'), 'ProjectRoleController', 'create', array('project_id' => $project['id'])) ?>
</li>
</ul>
</div>
@@ -19,24 +18,19 @@
<a href="#" class="dropdown-menu"><?= t('Restrictions for the role "%s"', $role['role']) ?> <i class="fa fa-caret-down"></i></a>
<ul>
<li>
- <i class="fa fa-plus fa-fw" aria-hidden="true"></i>
- <?= $this->url->link(t('Add a new project restriction'), 'ProjectRoleRestrictionController', 'create', array('project_id' => $project['id'], 'role_id' => $role['role_id']), false, 'popover') ?>
+ <?= $this->modal->medium('plus', t('Add a new project restriction'), 'ProjectRoleRestrictionController', 'create', array('project_id' => $project['id'], 'role_id' => $role['role_id'])) ?>
</li>
<li>
- <i class="fa fa-plus fa-fw" aria-hidden="true"></i>
- <?= $this->url->link(t('Add a new drag and drop restriction'), 'ColumnMoveRestrictionController', 'create', array('project_id' => $project['id'], 'role_id' => $role['role_id']), false, 'popover') ?>
+ <?= $this->modal->medium('plus', t('Add a new drag and drop restriction'), 'ColumnMoveRestrictionController', 'create', array('project_id' => $project['id'], 'role_id' => $role['role_id'])) ?>
</li>
<li>
- <i class="fa fa-plus fa-fw" aria-hidden="true"></i>
- <?= $this->url->link(t('Add a new column restriction'), 'ColumnRestrictionController', 'create', array('project_id' => $project['id'], 'role_id' => $role['role_id']), false, 'popover') ?>
+ <?= $this->modal->medium('plus', t('Add a new column restriction'), 'ColumnRestrictionController', 'create', array('project_id' => $project['id'], 'role_id' => $role['role_id'])) ?>
</li>
<li>
- <i class="fa fa-pencil fa-fw" aria-hidden="true"></i>
- <?= $this->url->link(t('Edit this role'), 'ProjectRoleController', 'edit', array('project_id' => $project['id'], 'role_id' => $role['role_id']), false, 'popover') ?>
+ <?= $this->modal->medium('edit', t('Edit this role'), 'ProjectRoleController', 'edit', array('project_id' => $project['id'], 'role_id' => $role['role_id'])) ?>
</li>
<li>
- <i class="fa fa-trash-o fa-fw" aria-hidden="true"></i>
- <?= $this->url->link(t('Remove this role'), 'ProjectRoleController', 'confirm', array('project_id' => $project['id'], 'role_id' => $role['role_id']), false, 'popover') ?>
+ <?= $this->modal->confirm('trash-o', t('Remove this role'), 'ProjectRoleController', 'confirm', array('project_id' => $project['id'], 'role_id' => $role['role_id'])) ?>
</li>
</ul>
</div>
@@ -59,8 +53,7 @@
<?= $this->text->e($restriction['title']) ?>
</td>
<td>
- <i class="fa fa-trash-o fa-fw" aria-hidden="true"></i>
- <?= $this->url->link(t('Remove'), 'ProjectRoleRestrictionController', 'confirm', array('project_id' => $project['id'], 'restriction_id' => $restriction['restriction_id']), false, 'popover') ?>
+ <?= $this->modal->confirm('trash-o', t('Remove'), 'ProjectRoleRestrictionController', 'confirm', array('project_id' => $project['id'], 'restriction_id' => $restriction['restriction_id'])) ?>
</td>
</tr>
<?php endforeach ?>
@@ -77,8 +70,7 @@
<?= $this->text->e($restriction['title']) ?>
</td>
<td>
- <i class="fa fa-trash-o fa-fw" aria-hidden="true"></i>
- <?= $this->url->link(t('Remove'), 'ColumnRestrictionController', 'confirm', array('project_id' => $project['id'], 'restriction_id' => $restriction['restriction_id']), false, 'popover') ?>
+ <?= $this->modal->confirm('trash-o', t('Remove'), 'ColumnRestrictionController', 'confirm', array('project_id' => $project['id'], 'restriction_id' => $restriction['restriction_id'])) ?>
</td>
</tr>
<?php endforeach ?>
@@ -91,8 +83,7 @@
<?= t('Only moving task between those columns is permitted') ?>
</td>
<td>
- <i class="fa fa-trash-o fa-fw" aria-hidden="true"></i>
- <?= $this->url->link(t('Remove'), 'ColumnMoveRestrictionController', 'confirm', array('project_id' => $project['id'], 'restriction_id' => $restriction['restriction_id']), false, 'popover') ?>
+ <?= $this->modal->confirm('trash-o', t('Remove'), 'ColumnMoveRestrictionController', 'confirm', array('project_id' => $project['id'], 'restriction_id' => $restriction['restriction_id'])) ?>
</td>
</tr>
<?php endforeach ?>
diff --git a/app/Template/project_role_restriction/create.php b/app/Template/project_role_restriction/create.php
index f49eafb3..2b6a61dc 100644
--- a/app/Template/project_role_restriction/create.php
+++ b/app/Template/project_role_restriction/create.php
@@ -2,7 +2,7 @@
<div class="page-header">
<h2><?= t('New project restriction for the role "%s"', $role['role']) ?></h2>
</div>
- <form class="popover-form" method="post" action="<?= $this->url->href('ProjectRoleRestrictionController', 'save', array('project_id' => $project['id'])) ?>" autocomplete="off">
+ <form method="post" action="<?= $this->url->href('ProjectRoleRestrictionController', 'save', array('project_id' => $project['id'])) ?>" autocomplete="off">
<?= $this->form->csrf() ?>
<?= $this->form->hidden('project_id', $values) ?>
<?= $this->form->hidden('role_id', $values) ?>
@@ -10,10 +10,6 @@
<?= $this->form->label(t('Restriction'), 'rule') ?>
<?= $this->form->select('rule', $restrictions, $values, $errors) ?>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'ProjectRoleController', 'show', array(), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->submitButtons() ?>
</form>
</section>
diff --git a/app/Template/project_role_restriction/remove.php b/app/Template/project_role_restriction/remove.php
index db1148e1..1a994199 100644
--- a/app/Template/project_role_restriction/remove.php
+++ b/app/Template/project_role_restriction/remove.php
@@ -7,8 +7,9 @@
<?= t('Do you really want to remove this project restriction: "%s"?', $this->text->in($restriction['rule'], $restrictions)) ?>
</p>
- <div class="form-actions">
- <?= $this->url->link(t('Yes'), 'ProjectRoleRestrictionController', 'remove', array('project_id' => $project['id'], 'restriction_id' => $restriction['restriction_id']), true, 'btn btn-red') ?>
- <?= t('or') ?> <?= $this->url->link(t('cancel'), 'ProjectRoleController', 'show', array('project_id' => $project['id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->confirmButtons(
+ 'ProjectRoleRestrictionController',
+ 'remove',
+ array('project_id' => $project['id'], 'restriction_id' => $restriction['restriction_id'])
+ ) ?>
</div>
diff --git a/app/Template/project_status/disable.php b/app/Template/project_status/disable.php
index d8145d3c..d607cedb 100644
--- a/app/Template/project_status/disable.php
+++ b/app/Template/project_status/disable.php
@@ -7,8 +7,9 @@
<?= t('Do you really want to disable this project: "%s"?', $project['name']) ?>
</p>
- <div class="form-actions">
- <?= $this->url->link(t('Yes'), 'ProjectStatusController', 'disable', array('project_id' => $project['id']), true, 'btn btn-red') ?>
- <?= t('or') ?> <?= $this->url->link(t('cancel'), 'ProjectViewController', 'show', array('project_id' => $project['id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->confirmButtons(
+ 'ProjectStatusController',
+ 'disable',
+ array('project_id' => $project['id'])
+ ) ?>
</div>
diff --git a/app/Template/project_status/enable.php b/app/Template/project_status/enable.php
index 1f76d093..fd8f8c72 100644
--- a/app/Template/project_status/enable.php
+++ b/app/Template/project_status/enable.php
@@ -7,8 +7,9 @@
<?= t('Do you really want to enable this project: "%s"?', $project['name']) ?>
</p>
- <div class="form-actions">
- <?= $this->url->link(t('Yes'), 'ProjectStatusController', 'enable', array('project_id' => $project['id']), true, 'btn btn-red') ?>
- <?= t('or') ?> <?= $this->url->link(t('cancel'), 'ProjectViewController', 'show', array('project_id' => $project['id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->confirmButtons(
+ 'ProjectStatusController',
+ 'enable',
+ array('project_id' => $project['id'])
+ ) ?>
</div>
diff --git a/app/Template/project_status/remove.php b/app/Template/project_status/remove.php
index 8959ef75..27ae2ae0 100644
--- a/app/Template/project_status/remove.php
+++ b/app/Template/project_status/remove.php
@@ -7,8 +7,9 @@
<?= t('Do you really want to remove this project: "%s"?', $project['name']) ?>
</p>
- <div class="form-actions">
- <?= $this->url->link(t('Yes'), 'ProjectStatusController', 'remove', array('project_id' => $project['id']), true, 'btn btn-red') ?>
- <?= t('or') ?> <?= $this->url->link(t('cancel'), 'ProjectViewController', 'show', array('project_id' => $project['id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->confirmButtons(
+ 'ProjectStatusController',
+ 'remove',
+ array('project_id' => $project['id'])
+ ) ?>
</div>
diff --git a/app/Template/project_tag/create.php b/app/Template/project_tag/create.php
index bfd1084a..a0e6243b 100644
--- a/app/Template/project_tag/create.php
+++ b/app/Template/project_tag/create.php
@@ -1,16 +1,12 @@
<div class="page-header">
<h2><?= t('Add new tag') ?></h2>
</div>
-<form method="post" class="popover-form" action="<?= $this->url->href('ProjectTagController', 'save', array('project_id' => $project['id'])) ?>" autocomplete="off">
+<form method="post" action="<?= $this->url->href('ProjectTagController', 'save', array('project_id' => $project['id'])) ?>" autocomplete="off">
<?= $this->form->csrf() ?>
<?= $this->form->hidden('project_id', $values) ?>
<?= $this->form->label(t('Name'), 'name') ?>
<?= $this->form->text('name', $values, $errors, array('autofocus', 'required', 'maxlength="255"')) ?>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'ProjectTagController', 'index', array('project_id' => $project['id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->submitButtons() ?>
</form>
diff --git a/app/Template/project_tag/edit.php b/app/Template/project_tag/edit.php
index 9bf261bd..8cb1e209 100644
--- a/app/Template/project_tag/edit.php
+++ b/app/Template/project_tag/edit.php
@@ -1,7 +1,7 @@
<div class="page-header">
<h2><?= t('Edit a tag') ?></h2>
</div>
-<form method="post" class="popover-form" action="<?= $this->url->href('ProjectTagController', 'update', array('tag_id' => $tag['id'], 'project_id' => $project['id'])) ?>" autocomplete="off">
+<form method="post" action="<?= $this->url->href('ProjectTagController', 'update', array('tag_id' => $tag['id'], 'project_id' => $project['id'])) ?>" autocomplete="off">
<?= $this->form->csrf() ?>
<?= $this->form->hidden('id', $values) ?>
<?= $this->form->hidden('project_id', $values) ?>
@@ -9,9 +9,5 @@
<?= $this->form->label(t('Name'), 'name') ?>
<?= $this->form->text('name', $values, $errors, array('autofocus', 'required', 'maxlength="255"')) ?>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'ProjectTagController', 'index', array(), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->submitButtons() ?>
</form>
diff --git a/app/Template/project_tag/index.php b/app/Template/project_tag/index.php
index f77e21ee..29d7082b 100644
--- a/app/Template/project_tag/index.php
+++ b/app/Template/project_tag/index.php
@@ -2,8 +2,7 @@
<h2><?= t('Project tags') ?></h2>
<ul>
<li>
- <i class="fa fa-plus" aria-hidden="true"></i>
- <?= $this->url->link(t('Add new tag'), 'ProjectTagController', 'create', array('project_id' => $project['id']), false, 'popover') ?>
+ <?= $this->modal->medium('plus', t('Add new tag'), 'ProjectTagController', 'create', array('project_id' => $project['id'])) ?>
</li>
</ul>
</div>
@@ -20,10 +19,8 @@
<tr>
<td><?= $this->text->e($tag['name']) ?></td>
<td>
- <i class="fa fa-times" aria-hidden="true"></i>
- <?= $this->url->link(t('Remove'), 'ProjectTagController', 'confirm', array('tag_id' => $tag['id'], 'project_id' => $project['id']), false, 'popover') ?>
- <i class="fa fa-pencil-square-o" aria-hidden="true"></i>
- <?= $this->url->link(t('Edit'), 'ProjectTagController', 'edit', array('tag_id' => $tag['id'], 'project_id' => $project['id']), false, 'popover') ?>
+ <?= $this->modal->medium('edit', t('Edit'), 'ProjectTagController', 'edit', array('tag_id' => $tag['id'], 'project_id' => $project['id'])) ?>
+ <?= $this->modal->confirm('trash-o', t('Remove'), 'ProjectTagController', 'confirm', array('tag_id' => $tag['id'], 'project_id' => $project['id'])) ?>
</td>
</tr>
<?php endforeach ?>
diff --git a/app/Template/project_tag/remove.php b/app/Template/project_tag/remove.php
index f4aadab1..9f957d10 100644
--- a/app/Template/project_tag/remove.php
+++ b/app/Template/project_tag/remove.php
@@ -7,9 +7,9 @@
<?= t('Do you really want to remove this tag: "%s"?', $tag['name']) ?>
</p>
- <div class="form-actions">
- <?= $this->url->link(t('Yes'), 'ProjectTagController', 'remove', array('tag_id' => $tag['id'], 'project_id' => $project['id']), true, 'btn btn-red popover-link') ?>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'ProjectTagController', 'index', array('project_id' => $project['id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->confirmButtons(
+ 'ProjectTagController',
+ 'remove',
+ array('tag_id' => $tag['id'], 'project_id' => $project['id'])
+ ) ?>
</div>
diff --git a/app/Template/project_user_overview/layout.php b/app/Template/project_user_overview/layout.php
index 19b83436..9115ef3c 100644
--- a/app/Template/project_user_overview/layout.php
+++ b/app/Template/project_user_overview/layout.php
@@ -1,20 +1,27 @@
<section id="main">
<div class="page-header">
<ul>
+ <?php if ($this->user->hasAccess('ProjectCreationController', 'create')): ?>
+ <li>
+ <?= $this->modal->medium('plus', t('New project'), 'ProjectCreationController', 'create') ?>
+ </li>
+ <?php endif ?>
+ <?php if ($this->app->config('disable_private_project', 0) == 0): ?>
+ <li>
+ <?= $this->modal->medium('lock', t('New private project'), 'ProjectCreationController', 'createPrivate') ?>
+ </li>
+ <?php endif ?>
<li>
- <i class="fa fa-folder fa-fw"></i>
- <?= $this->url->link(t('Projects list'), 'ProjectListController', 'show') ?>
+ <?= $this->url->icon('folder', t('Projects list'), 'ProjectListController', 'show') ?>
</li>
<?php if ($this->user->hasAccess('ProjectGanttController', 'show')): ?>
<li>
- <i class="fa fa-sliders fa-fw"></i>
- <?= $this->url->link(t('Projects Gantt chart'), 'ProjectGanttController', 'show') ?>
+ <?= $this->url->icon('sliders', t('Projects Gantt chart'), 'ProjectGanttController', 'show') ?>
</li>
<?php endif ?>
</ul>
</div>
<section class="sidebar-container">
-
<?= $this->render($sidebar_template, array('users' => $users, 'filter' => $filter)) ?>
<div class="sidebar-content">
diff --git a/app/Template/project_user_overview/sidebar.php b/app/Template/project_user_overview/sidebar.php
index ccbf9cab..493f4cbf 100644
--- a/app/Template/project_user_overview/sidebar.php
+++ b/app/Template/project_user_overview/sidebar.php
@@ -1,14 +1,17 @@
<div class="sidebar">
- <?= $this->form->select(
- 'user_id',
- $users,
- $filter,
- array(),
- array('data-redirect-url="'.$this->url->href('ProjectUserOverviewController', $this->app->getRouterAction(), array('user_id' => 'USER_ID')).'"', 'data-redirect-regex="USER_ID"'),
- 'chosen-select select-auto-redirect'
- ) ?>
+ <?= $this->app->component('select-dropdown-autocomplete', array(
+ 'name' => 'user_id',
+ 'items' => $users,
+ 'defaultValue' => $filter['user_id'],
+ 'sortByKeys' => true,
+ 'redirect' => array(
+ 'regex' => 'USER_ID',
+ 'url' => $this->url->to('ProjectUserOverviewController', $this->app->getRouterAction(), array('user_id' => 'USER_ID')),
+ ),
+ )) ?>
+
+ <br>
- <br><br>
<ul>
<li <?= $this->app->checkMenuSelection('ProjectUserOverviewController', 'managers') ?>>
<?= $this->url->link(t('Project managers'), 'ProjectUserOverviewController', 'managers', $filter) ?>
diff --git a/app/Template/project_view/share.php b/app/Template/project_view/share.php
index 409f37e6..87c63916 100644
--- a/app/Template/project_view/share.php
+++ b/app/Template/project_view/share.php
@@ -4,11 +4,11 @@
<?php if ($project['is_public']): ?>
- <div class="listing">
+ <div class="panel">
<ul class="no-bullet">
- <li><strong><i class="fa fa-share-alt"></i> <?= $this->url->link(t('Public link'), 'BoardViewController', 'readonly', array('token' => $project['token']), false, '', '', true) ?></strong></li>
- <li><strong><i class="fa fa-rss-square"></i> <?= $this->url->link(t('RSS feed'), 'FeedController', 'project', array('token' => $project['token']), false, '', '', true) ?></strong></li>
- <li><strong><i class="fa fa-calendar"></i> <?= $this->url->link(t('iCal feed'), 'ICalendarController', 'project', array('token' => $project['token']), false, '', '', true) ?></strong></li>
+ <li><strong><?= $this->url->icon('share-alt', t('Public link'), 'BoardViewController', 'readonly', array('token' => $project['token']), false, '', '', true) ?></strong></li>
+ <li><strong><?= $this->url->icon('rss-square', t('RSS feed'), 'FeedController', 'project', array('token' => $project['token']), false, '', '', true) ?></strong></li>
+ <li><strong><?= $this->url->icon('calendar', t('iCal feed'), 'ICalendarController', 'project', array('token' => $project['token']), false, '', '', true) ?></strong></li>
</ul>
</div>
diff --git a/app/Template/project_view/show.php b/app/Template/project_view/show.php
index afe60384..29d558b1 100644
--- a/app/Template/project_view/show.php
+++ b/app/Template/project_view/show.php
@@ -1,7 +1,7 @@
<div class="page-header">
<h2><?= t('Summary') ?></h2>
</div>
-<ul class="listing">
+<ul class="panel">
<li><strong><?= $project['is_active'] ? t('Active') : t('Inactive') ?></strong></li>
<?php if ($project['owner_id'] > 0): ?>
@@ -13,9 +13,9 @@
<?php endif ?>
<?php if ($project['is_public']): ?>
- <li><i class="fa fa-share-alt"></i> <?= $this->url->link(t('Public link'), 'BoardViewController', 'readonly', array('token' => $project['token']), false, '', '', true) ?></li>
- <li><i class="fa fa-rss-square"></i> <?= $this->url->link(t('RSS feed'), 'FeedController', 'project', array('token' => $project['token']), false, '', '', true) ?></li>
- <li><i class="fa fa-calendar"></i> <?= $this->url->link(t('iCal feed'), 'ICalendarController', 'project', array('token' => $project['token'])) ?></li>
+ <li><?= $this->url->icon('share-alt', t('Public link'), 'BoardViewController', 'readonly', array('token' => $project['token']), false, '', '', true) ?></li>
+ <li><?= $this->url->icon('rss-square', t('RSS feed'), 'FeedController', 'project', array('token' => $project['token']), false, '', '', true) ?></li>
+ <li><?= $this->url->icon('calendar', t('iCal feed'), 'ICalendarController', 'project', array('token' => $project['token'])) ?></li>
<?php else: ?>
<li><?= t('Public access disabled') ?></li>
<?php endif ?>
diff --git a/app/Template/search/activity.php b/app/Template/search/activity.php
index 1dfd9234..2582162b 100644
--- a/app/Template/search/activity.php
+++ b/app/Template/search/activity.php
@@ -2,8 +2,7 @@
<div class="page-header">
<ul>
<li>
- <i class="fa fa-search fa-fw"></i>
- <?= $this->url->link(t('Search tasks'), 'SearchController', 'index') ?>
+ <?= $this->url->icon('search', t('Search tasks'), 'SearchController', 'index') ?>
</li>
</ul>
</div>
@@ -23,7 +22,7 @@
</div>
<?php if (empty($values['search'])): ?>
- <div class="listing">
+ <div class="panel">
<h3><?= t('Advanced search') ?></h3>
<p><?= t('Example of query: ') ?><strong>project:"My project" creator:me</strong></p>
<ul>
diff --git a/app/Template/search/index.php b/app/Template/search/index.php
index c59a5c99..9a5f2931 100644
--- a/app/Template/search/index.php
+++ b/app/Template/search/index.php
@@ -2,8 +2,7 @@
<div class="page-header">
<ul>
<li>
- <i class="fa fa-search fa-fw"></i>
- <?= $this->url->link(t('Activity stream search'), 'SearchController', 'activity') ?>
+ <?= $this->url->icon('search', t('Activity stream search'), 'SearchController', 'activity') ?>
</li>
</ul>
</div>
@@ -23,7 +22,7 @@
</div>
<?php if (empty($values['search'])): ?>
- <div class="listing">
+ <div class="panel">
<h3><?= t('Advanced search') ?></h3>
<p><?= t('Example of query: ') ?><strong>project:"My project" assignee:me due:tomorrow</strong></p>
<ul>
diff --git a/app/Template/subtask/create.php b/app/Template/subtask/create.php
index cc4ccba6..96ad7a46 100644
--- a/app/Template/subtask/create.php
+++ b/app/Template/subtask/create.php
@@ -2,20 +2,17 @@
<h2><?= t('Add a sub-task') ?></h2>
</div>
-<form class="popover-form" method="post" action="<?= $this->url->href('SubtaskController', 'save', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>" autocomplete="off">
+<form method="post" action="<?= $this->url->href('SubtaskController', 'save', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>" autocomplete="off">
<?= $this->form->csrf() ?>
<?= $this->form->hidden('task_id', $values) ?>
- <?= $this->subtask->selectTitle($values, $errors, array('autofocus')) ?>
- <?= $this->subtask->selectAssignee($users_list, $values, $errors) ?>
- <?= $this->subtask->selectTimeEstimated($values, $errors) ?>
+ <?= $this->subtask->renderTitleField($values, $errors, array('autofocus')) ?>
+ <?= $this->subtask->renderAssigneeField($users_list, $values, $errors) ?>
+ <?= $this->subtask->renderTimeEstimatedField($values, $errors) ?>
+
<?= $this->hook->render('template:subtask:form:create', array('values' => $values, 'errors' => $errors)) ?>
<?= $this->form->checkbox('another_subtask', t('Create another sub-task'), 1, isset($values['another_subtask']) && $values['another_subtask'] == 1) ?>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->submitButtons() ?>
</form>
diff --git a/app/Template/subtask/edit.php b/app/Template/subtask/edit.php
index 07419f79..7c0266a8 100644
--- a/app/Template/subtask/edit.php
+++ b/app/Template/subtask/edit.php
@@ -2,20 +2,17 @@
<h2><?= t('Edit a sub-task') ?></h2>
</div>
-<form class="popover-form" method="post" action="<?= $this->url->href('SubtaskController', 'update', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'subtask_id' => $subtask['id'])) ?>" autocomplete="off">
-
+<form method="post" action="<?= $this->url->href('SubtaskController', 'update', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'subtask_id' => $subtask['id'])) ?>" autocomplete="off">
<?= $this->form->csrf() ?>
<?= $this->form->hidden('id', $values) ?>
<?= $this->form->hidden('task_id', $values) ?>
- <?= $this->subtask->selectTitle($values, $errors, array('autofocus')) ?>
- <?= $this->subtask->selectAssignee($users_list, $values, $errors) ?>
- <?= $this->subtask->selectTimeEstimated($values, $errors) ?>
- <?= $this->subtask->selectTimeSpent($values, $errors) ?>
+
+ <?= $this->subtask->renderTitleField($values, $errors, array('autofocus')) ?>
+ <?= $this->subtask->renderAssigneeField($users_list, $values, $errors) ?>
+ <?= $this->subtask->renderTimeEstimatedField($values, $errors) ?>
+ <?= $this->subtask->renderTimeSpentField($values, $errors) ?>
+
<?= $this->hook->render('template:subtask:form:edit', array('values' => $values, 'errors' => $errors)) ?>
-
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?>
- </div>
+
+ <?= $this->modal->submitButtons() ?>
</form>
diff --git a/app/Template/subtask/menu.php b/app/Template/subtask/menu.php
index d5d1bf85..a0743a70 100644
--- a/app/Template/subtask/menu.php
+++ b/app/Template/subtask/menu.php
@@ -2,16 +2,13 @@
<a href="#" class="dropdown-menu dropdown-menu-link-icon"><i class="fa fa-cog fa-fw"></i><i class="fa fa-caret-down"></i></a>
<ul>
<li>
- <i class="fa fa-pencil-square-o" aria-hidden="true"></i>
- <?= $this->url->link(t('Edit'), 'SubtaskController', 'edit', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'subtask_id' => $subtask['id']), false, 'popover') ?>
+ <?= $this->modal->medium('edit', t('Edit'), 'SubtaskController', 'edit', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'subtask_id' => $subtask['id'])) ?>
</li>
<li>
- <i class="fa fa-trash-o" aria-hidden="true"></i>
- <?= $this->url->link(t('Remove'), 'SubtaskController', 'confirm', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'subtask_id' => $subtask['id']), false, 'popover') ?>
+ <?= $this->modal->confirm('trash-o', t('Remove'), 'SubtaskController', 'confirm', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'subtask_id' => $subtask['id'])) ?>
</li>
<li>
- <i class="fa fa-clone" aria-hidden="true"></i>
- <?= $this->url->link(t('Convert to task'), 'SubtaskConverterController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'subtask_id' => $subtask['id']), false, 'popover') ?>
+ <?= $this->modal->confirm('clone', t('Convert to task'), 'SubtaskConverterController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'subtask_id' => $subtask['id'])) ?>
</li>
</ul>
</div>
diff --git a/app/Template/subtask/remove.php b/app/Template/subtask/remove.php
index 426c1a93..cf9bbc35 100644
--- a/app/Template/subtask/remove.php
+++ b/app/Template/subtask/remove.php
@@ -12,9 +12,9 @@
</ul>
</div>
- <div class="form-actions">
- <?= $this->url->link(t('Yes'), 'SubtaskController', 'remove', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'subtask_id' => $subtask['id']), true, 'btn btn-red') ?>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->confirmButtons(
+ 'SubtaskController',
+ 'remove',
+ array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'subtask_id' => $subtask['id'])
+ ) ?>
</div>
diff --git a/app/Template/subtask/table.php b/app/Template/subtask/table.php
index bea49aed..156e08c1 100644
--- a/app/Template/subtask/table.php
+++ b/app/Template/subtask/table.php
@@ -45,12 +45,10 @@
<?php if ($editable && $subtask['user_id'] == $this->user->getId()): ?>
<li>
<?php if ($subtask['is_timer_started']): ?>
- <i class="fa fa-pause"></i>
- <?= $this->url->link(t('Stop timer'), 'SubtaskStatusController', 'timer', array('timer' => 'stop', 'project_id' => $task['project_id'], 'task_id' => $subtask['task_id'], 'subtask_id' => $subtask['id']), false, 'subtask-toggle-timer') ?>
+ <?= $this->url->icon('pause', t('Stop timer'), 'SubtaskStatusController', 'timer', array('timer' => 'stop', 'project_id' => $task['project_id'], 'task_id' => $subtask['task_id'], 'subtask_id' => $subtask['id']), false, 'subtask-toggle-timer') ?>
(<?= $this->dt->age($subtask['timer_start_date']) ?>)
<?php else: ?>
- <i class="fa fa-play-circle-o"></i>
- <?= $this->url->link(t('Start timer'), 'SubtaskStatusController', 'timer', array('timer' => 'start', 'project_id' => $task['project_id'], 'task_id' => $subtask['task_id'], 'subtask_id' => $subtask['id']), false, 'subtask-toggle-timer') ?>
+ <?= $this->url->icon('play-circle-o', t('Start timer'), 'SubtaskStatusController', 'timer', array('timer' => 'start', 'project_id' => $task['project_id'], 'task_id' => $subtask['task_id'], 'subtask_id' => $subtask['id']), false, 'subtask-toggle-timer') ?>
<?php endif ?>
</li>
<?php endif ?>
diff --git a/app/Template/subtask_converter/show.php b/app/Template/subtask_converter/show.php
index 63f45482..9ecc70c8 100644
--- a/app/Template/subtask_converter/show.php
+++ b/app/Template/subtask_converter/show.php
@@ -12,9 +12,9 @@
</ul>
</div>
- <div class="form-actions">
- <?= $this->url->link(t('Yes'), 'SubtaskConverterController', 'save', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'subtask_id' => $subtask['id']), true, 'btn btn-red') ?>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->confirmButtons(
+ 'SubtaskConverterController',
+ 'save',
+ array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'subtask_id' => $subtask['id'])
+ ) ?>
</div>
diff --git a/app/Template/subtask_restriction/show.php b/app/Template/subtask_restriction/show.php
index ec8b8d5b..b6c56a12 100644
--- a/app/Template/subtask_restriction/show.php
+++ b/app/Template/subtask_restriction/show.php
@@ -1,7 +1,7 @@
<div class="page-header">
<h2><?= t('You already have one subtask in progress') ?></h2>
</div>
-<form class="popover-form" action="<?= $this->url->href('SubtaskRestrictionController', 'save', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'subtask_id' => $subtask['id'])) ?>" method="post">
+<form action="<?= $this->url->href('SubtaskRestrictionController', 'save', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'subtask_id' => $subtask['id'])) ?>" method="post">
<?= $this->form->csrf() ?>
@@ -9,9 +9,5 @@
<?= $this->form->radios('status', $status_list) ?>
<?= $this->form->hidden('id', $subtask_inprogress) ?>
- <div class="form-actions">
- <button type="submit" class="btn btn-red"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->submitButtons() ?>
</form>
diff --git a/app/Template/swimlane/create.php b/app/Template/swimlane/create.php
index f5aa1591..7d05e731 100644
--- a/app/Template/swimlane/create.php
+++ b/app/Template/swimlane/create.php
@@ -1,20 +1,16 @@
<div class="page-header">
<h2><?= t('Add a new swimlane') ?></h2>
</div>
-<form class="popover-form" method="post" action="<?= $this->url->href('SwimlaneController', 'save', array('project_id' => $project['id'])) ?>" autocomplete="off">
+<form method="post" action="<?= $this->url->href('SwimlaneController', 'save', array('project_id' => $project['id'])) ?>" autocomplete="off">
<?= $this->form->csrf() ?>
<?= $this->form->hidden('project_id', $values) ?>
<?= $this->form->label(t('Name'), 'name') ?>
- <?= $this->form->text('name', $values, $errors, array('autofocus', 'required', 'maxlength="50"')) ?>
+ <?= $this->form->text('name', $values, $errors, array('autofocus', 'required', 'maxlength="50"', 'tabindex="1"')) ?>
<?= $this->form->label(t('Description'), 'description') ?>
- <?= $this->form->textarea('description', $values, $errors, array(), 'markdown-editor') ?>
+ <?= $this->form->textEditor('description', $values, $errors, array('tabindex' => 2)) ?>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'SwimlaneController', 'index', array('project_id' => $project['id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->submitButtons() ?>
</form>
diff --git a/app/Template/swimlane/edit.php b/app/Template/swimlane/edit.php
index b10cdd52..c1c41196 100644
--- a/app/Template/swimlane/edit.php
+++ b/app/Template/swimlane/edit.php
@@ -2,7 +2,7 @@
<h2><?= t('Swimlane modification for the project "%s"', $project['name']) ?></h2>
</div>
-<form class="popover-form" method="post" action="<?= $this->url->href('SwimlaneController', 'update', array('project_id' => $project['id'], 'swimlane_id' => $values['id'])) ?>" autocomplete="off">
+<form method="post" action="<?= $this->url->href('SwimlaneController', 'update', array('project_id' => $project['id'], 'swimlane_id' => $values['id'])) ?>" autocomplete="off">
<?= $this->form->csrf() ?>
@@ -10,14 +10,10 @@
<?= $this->form->hidden('project_id', $values) ?>
<?= $this->form->label(t('Name'), 'name') ?>
- <?= $this->form->text('name', $values, $errors, array('autofocus', 'required', 'maxlength="50"')) ?>
+ <?= $this->form->text('name', $values, $errors, array('autofocus', 'required', 'maxlength="50"', 'tabindex="1"')) ?>
<?= $this->form->label(t('Description'), 'description') ?>
- <?= $this->form->textarea('description', $values, $errors, array(), 'markdown-editor') ?>
+ <?= $this->form->textEditor('description', $values, $errors, array('tabindex' => 2)) ?>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'SwimlaneController', 'index', array('project_id' => $project['id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->submitButtons() ?>
</form>
diff --git a/app/Template/swimlane/edit_default.php b/app/Template/swimlane/edit_default.php
index f271c513..a2c3ee73 100644
--- a/app/Template/swimlane/edit_default.php
+++ b/app/Template/swimlane/edit_default.php
@@ -1,18 +1,14 @@
<div class="page-header">
<h2><?= t('Change default swimlane') ?></h2>
</div>
-<form class="popover-form" method="post" action="<?= $this->url->href('SwimlaneController', 'updateDefault', array('project_id' => $project['id'])) ?>" autocomplete="off">
+<form method="post" action="<?= $this->url->href('SwimlaneController', 'updateDefault', array('project_id' => $project['id'])) ?>" autocomplete="off">
<?= $this->form->csrf() ?>
<?= $this->form->hidden('id', $values) ?>
<?= $this->form->label(t('Name'), 'default_swimlane') ?>
- <?= $this->form->text('default_swimlane', $values, $errors, array('required', 'maxlength="50"')) ?>
+ <?= $this->form->text('default_swimlane', $values, $errors, array('autofocus', 'required', 'maxlength="50"')) ?>
<?= $this->form->checkbox('show_default_swimlane', t('Show default swimlane'), 1, $values['show_default_swimlane'] == 1) ?>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'SwimlaneController', 'index', array('project_id' => $project['id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->submitButtons() ?>
</form>
diff --git a/app/Template/swimlane/index.php b/app/Template/swimlane/index.php
index 4f78a405..e05b9088 100644
--- a/app/Template/swimlane/index.php
+++ b/app/Template/swimlane/index.php
@@ -2,8 +2,7 @@
<h2><?= t('Swimlanes') ?></h2>
<ul>
<li>
- <i class="fa fa-plus fa-fw"></i>
- <?= $this->url->link(t('Add a new swimlane'), 'SwimlaneController', 'create', array('project_id' => $project['id']), false, 'popover') ?>
+ <?= $this->modal->medium('plus', t('Add a new swimlane'), 'SwimlaneController', 'create', array('project_id' => $project['id'])) ?>
</li>
</ul>
</div>
diff --git a/app/Template/swimlane/remove.php b/app/Template/swimlane/remove.php
index f16b778c..02d1e322 100644
--- a/app/Template/swimlane/remove.php
+++ b/app/Template/swimlane/remove.php
@@ -1,17 +1,15 @@
-<section id="main">
- <div class="page-header">
- <h2><?= t('Remove a swimlane') ?></h2>
- </div>
+<div class="page-header">
+ <h2><?= t('Remove a swimlane') ?></h2>
+</div>
- <div class="confirm">
- <p class="alert alert-info">
- <?= t('Do you really want to remove this swimlane: "%s"?', $swimlane['name']) ?>
- </p>
+<div class="confirm">
+ <p class="alert alert-info">
+ <?= t('Do you really want to remove this swimlane: "%s"?', $swimlane['name']) ?>
+ </p>
- <div class="form-actions">
- <?= $this->url->link(t('Yes'), 'SwimlaneController', 'remove', array('project_id' => $project['id'], 'swimlane_id' => $swimlane['id']), true, 'btn btn-red') ?>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'SwimlaneController', 'index', array('project_id' => $project['id']), false, 'close-popover') ?>
- </div>
- </div>
-</section>
+ <?= $this->modal->confirmButtons(
+ 'SwimlaneController',
+ 'remove',
+ array('project_id' => $project['id'], 'swimlane_id' => $swimlane['id'])
+ ) ?>
+</div>
diff --git a/app/Template/swimlane/table.php b/app/Template/swimlane/table.php
index cefef9de..2d783a00 100644
--- a/app/Template/swimlane/table.php
+++ b/app/Template/swimlane/table.php
@@ -20,13 +20,13 @@
<a href="#" class="dropdown-menu dropdown-menu-link-icon"><i class="fa fa-cog fa-fw"></i><i class="fa fa-caret-down"></i></a>
<ul>
<li>
- <?= $this->url->link(t('Edit'), 'SwimlaneController', 'editDefault', array('project_id' => $project['id']), false, 'popover') ?>
+ <?= $this->modal->medium('edit', t('Edit'), 'SwimlaneController', 'editDefault', array('project_id' => $project['id'])) ?>
</li>
<li>
<?php if ($default_swimlane['show_default_swimlane'] == 1): ?>
- <?= $this->url->link(t('Disable'), 'SwimlaneController', 'disableDefault', array('project_id' => $project['id']), true) ?>
+ <?= $this->url->icon('toggle-off', t('Disable'), 'SwimlaneController', 'disableDefault', array('project_id' => $project['id']), true) ?>
<?php else: ?>
- <?= $this->url->link(t('Enable'), 'SwimlaneController', 'enableDefault', array('project_id' => $project['id']), true) ?>
+ <?= $this->url->icon('toggle-on', t('Enable'), 'SwimlaneController', 'enableDefault', array('project_id' => $project['id']), true) ?>
<?php endif ?>
</li>
</ul>
@@ -55,17 +55,17 @@
<a href="#" class="dropdown-menu dropdown-menu-link-icon"><i class="fa fa-cog fa-fw"></i><i class="fa fa-caret-down"></i></a>
<ul>
<li>
- <?= $this->url->link(t('Edit'), 'SwimlaneController', 'edit', array('project_id' => $project['id'], 'swimlane_id' => $swimlane['id']), false, 'popover') ?>
+ <?= $this->modal->medium('edit', t('Edit'), 'SwimlaneController', 'edit', array('project_id' => $project['id'], 'swimlane_id' => $swimlane['id'])) ?>
</li>
<li>
<?php if ($swimlane['is_active']): ?>
- <?= $this->url->link(t('Disable'), 'SwimlaneController', 'disable', array('project_id' => $project['id'], 'swimlane_id' => $swimlane['id']), true) ?>
+ <?= $this->url->icon('toggle-off', t('Disable'), 'SwimlaneController', 'disable', array('project_id' => $project['id'], 'swimlane_id' => $swimlane['id']), true) ?>
<?php else: ?>
- <?= $this->url->link(t('Enable'), 'SwimlaneController', 'enable', array('project_id' => $project['id'], 'swimlane_id' => $swimlane['id']), true) ?>
+ <?= $this->url->icon('toggle-on', t('Enable'), 'SwimlaneController', 'enable', array('project_id' => $project['id'], 'swimlane_id' => $swimlane['id']), true) ?>
<?php endif ?>
</li>
<li>
- <?= $this->url->link(t('Remove'), 'SwimlaneController', 'confirm', array('project_id' => $project['id'], 'swimlane_id' => $swimlane['id']), false, 'popover') ?>
+ <?= $this->modal->confirm('trash-o', t('Remove'), 'SwimlaneController', 'confirm', array('project_id' => $project['id'], 'swimlane_id' => $swimlane['id'])) ?>
</li>
</ul>
</div>
diff --git a/app/Template/tag/create.php b/app/Template/tag/create.php
index 9b32bc46..752a63e5 100644
--- a/app/Template/tag/create.php
+++ b/app/Template/tag/create.php
@@ -1,16 +1,12 @@
<div class="page-header">
<h2><?= t('Add new tag') ?></h2>
</div>
-<form method="post" class="popover-form" action="<?= $this->url->href('TagController', 'save') ?>" autocomplete="off">
+<form method="post" action="<?= $this->url->href('TagController', 'save') ?>" autocomplete="off">
<?= $this->form->csrf() ?>
<?= $this->form->hidden('project_id', $values) ?>
<?= $this->form->label(t('Name'), 'name') ?>
<?= $this->form->text('name', $values, $errors, array('autofocus', 'required', 'maxlength="255"')) ?>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'TagController', 'index', array(), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->submitButtons() ?>
</form>
diff --git a/app/Template/tag/edit.php b/app/Template/tag/edit.php
index f751ff49..adef3568 100644
--- a/app/Template/tag/edit.php
+++ b/app/Template/tag/edit.php
@@ -1,7 +1,7 @@
<div class="page-header">
<h2><?= t('Edit a tag') ?></h2>
</div>
-<form method="post" class="popover-form" action="<?= $this->url->href('TagController', 'update', array('tag_id' => $tag['id'])) ?>" autocomplete="off">
+<form method="post" action="<?= $this->url->href('TagController', 'update', array('tag_id' => $tag['id'])) ?>" autocomplete="off">
<?= $this->form->csrf() ?>
<?= $this->form->hidden('id', $values) ?>
<?= $this->form->hidden('project_id', $values) ?>
@@ -9,9 +9,5 @@
<?= $this->form->label(t('Name'), 'name') ?>
<?= $this->form->text('name', $values, $errors, array('autofocus', 'required', 'maxlength="255"')) ?>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'TagController', 'index', array(), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->submitButtons() ?>
</form>
diff --git a/app/Template/tag/index.php b/app/Template/tag/index.php
index 8e0c9a06..834e8e7c 100644
--- a/app/Template/tag/index.php
+++ b/app/Template/tag/index.php
@@ -2,8 +2,7 @@
<h2><?= t('Global tags') ?></h2>
<ul>
<li>
- <i class="fa fa-plus" aria-hidden="true"></i>
- <?= $this->url->link(t('Add new tag'), 'TagController', 'create', array(), false, 'popover') ?>
+ <?= $this->modal->medium('plus', t('Add new tag'), 'TagController', 'create') ?>
</li>
</ul>
</div>
@@ -20,10 +19,8 @@
<tr>
<td><?= $this->text->e($tag['name']) ?></td>
<td>
- <i class="fa fa-times" aria-hidden="true"></i>
- <?= $this->url->link(t('Remove'), 'TagController', 'confirm', array('tag_id' => $tag['id']), false, 'popover') ?>
- <i class="fa fa-pencil-square-o" aria-hidden="true"></i>
- <?= $this->url->link(t('Edit'), 'TagController', 'edit', array('tag_id' => $tag['id']), false, 'popover') ?>
+ <?= $this->modal->medium('edit', t('Edit'), 'TagController', 'edit', array('tag_id' => $tag['id'])) ?>
+ <?= $this->modal->confirm('trash-o', t('Remove'), 'TagController', 'confirm', array('tag_id' => $tag['id'])) ?>
</td>
</tr>
<?php endforeach ?>
diff --git a/app/Template/tag/remove.php b/app/Template/tag/remove.php
index 46ea3f99..47ba8d3d 100644
--- a/app/Template/tag/remove.php
+++ b/app/Template/tag/remove.php
@@ -7,9 +7,9 @@
<?= t('Do you really want to remove this tag: "%s"?', $tag['name']) ?>
</p>
- <div class="form-actions">
- <?= $this->url->link(t('Yes'), 'TagController', 'remove', array('tag_id' => $tag['id']), true, 'btn btn-red popover-link') ?>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'TagController', 'index', array(), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->confirmButtons(
+ 'TagController',
+ 'remove',
+ array('tag_id' => $tag['id'])
+ ) ?>
</div>
diff --git a/app/Template/task/analytics.php b/app/Template/task/analytics.php
index 071f24a7..2d968188 100644
--- a/app/Template/task/analytics.php
+++ b/app/Template/task/analytics.php
@@ -9,15 +9,20 @@
<h2><?= t('Analytics') ?></h2>
</div>
-<div class="listing">
+<div class="panel">
<ul>
<li><?= t('Lead time: ').'<strong>'.$this->dt->duration($lead_time) ?></strong></li>
<li><?= t('Cycle time: ').'<strong>'.$this->dt->duration($cycle_time) ?></strong></li>
</ul>
</div>
-<h3 id="analytic-task-time-column"><?= t('Time spent into each column') ?></h3>
-<div id="chart" data-metrics='<?= json_encode($time_spent_columns, JSON_HEX_APOS) ?>' data-label="<?= t('Time spent') ?>"></div>
+<h3><?= t('Time spent into each column') ?></h3>
+
+<?= $this->app->component('chart-task-time-column', array(
+ 'metrics' => $time_spent_columns,
+ 'label' => t('Time spent'),
+)) ?>
+
<table class="table-striped">
<tr>
<th><?= t('Column') ?></th>
diff --git a/app/Template/task/changes.php b/app/Template/task/changes.php
index 9d36f09f..2c2bf267 100644
--- a/app/Template/task/changes.php
+++ b/app/Template/task/changes.php
@@ -69,6 +69,10 @@
<?php if (! empty($changes['description'])): ?>
<p><strong><?= t('The description has been modified:') ?></strong></p>
- <div class="markdown"><?= $this->text->markdown($task['description']) ?></div>
+ <?php if (isset($public)): ?>
+ <div class="markdown"><?= $this->text->markdown($task['description'], true) ?></div>
+ <?php else: ?>
+ <div class="markdown"><?= $this->text->markdown($task['description']) ?></div>
+ <?php endif ?>
<?php endif ?>
<?php endif ?> \ No newline at end of file
diff --git a/app/Template/task/details.php b/app/Template/task/details.php
index a39c1bab..24099a3c 100644
--- a/app/Template/task/details.php
+++ b/app/Template/task/details.php
@@ -33,16 +33,14 @@
<?php if ($project['is_public']): ?>
<li>
<small>
- <i class="fa fa-external-link fa-fw"></i>
- <?= $this->url->link(t('Public link'), 'TaskViewController', 'readonly', array('task_id' => $task['id'], 'token' => $project['token']), false, '', '', true) ?>
+ <?= $this->url->icon('external-link', t('Public link'), 'TaskViewController', 'readonly', array('task_id' => $task['id'], 'token' => $project['token']), false, '', '', true) ?>
</small>
</li>
<?php endif ?>
<?php if ($project['is_public'] && !$editable): ?>
<li>
<small>
- <i class="fa fa-th fa-fw"></i>
- <?= $this->url->link(t('Back to the board'), 'BoardViewController', 'readonly', array('token' => $project['token'])) ?>
+ <?= $this->url->icon('th', t('Back to the board'), 'BoardViewController', 'readonly', array('token' => $project['token'])) ?>
</small>
</li>
<?php endif ?>
@@ -160,9 +158,15 @@
<?php endif ?>
</div>
+ <?php if (! empty($task['external_uri']) && ! empty($task['external_provider'])): ?>
+ <?= $this->app->component('external-task-view', array(
+ 'url' => $this->url->href('ExternalTaskViewController', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id'])),
+ )) ?>
+ <?php endif ?>
+
<?php if ($editable && empty($task['date_started'])): ?>
<div class="buttons-header">
- <?= $this->url->button('fa-play', t('Set start date'), 'TaskModificationController', 'start', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
+ <?= $this->url->button('play', t('Set start date'), 'TaskModificationController', 'start', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</div>
<?php endif ?>
diff --git a/app/Template/task/dropdown.php b/app/Template/task/dropdown.php
index 86428059..1daf8896 100644
--- a/app/Template/task/dropdown.php
+++ b/app/Template/task/dropdown.php
@@ -3,60 +3,47 @@
<ul>
<?php if (array_key_exists('date_started', $task) && empty($task['date_started'])): ?>
<li>
- <i class="fa fa-play fa-fw"></i>
- <?= $this->url->link(t('Set automatically the start date'), 'TaskModificationController', 'start', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
+ <?= $this->url->icon('play', t('Set automatically the start date'), 'TaskModificationController', 'start', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
<?php endif ?>
<li>
- <i class="fa fa-pencil-square-o fa-fw"></i>
- <?= $this->url->link(t('Edit the task'), 'TaskModificationController', 'edit', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'popover') ?>
+ <?= $this->modal->large('edit', t('Edit the task'), 'TaskModificationController', 'edit', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
<li>
- <i class="fa fa-plus fa-fw"></i>
- <?= $this->url->link(t('Add a sub-task'), 'SubtaskController', 'create', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'popover') ?>
+ <?= $this->modal->medium('plus', t('Add a sub-task'), 'SubtaskController', 'create', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
<li>
- <i class="fa fa-code-fork fa-fw"></i>
- <?= $this->url->link(t('Add internal link'), 'TaskInternalLinkController', 'create', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'popover') ?>
+ <?= $this->modal->medium('code-fork', t('Add internal link'), 'TaskInternalLinkController', 'create', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
<li>
- <i class="fa fa-external-link fa-fw"></i>
- <?= $this->url->link(t('Add external link'), 'TaskExternalLinkController', 'find', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'popover') ?>
+ <?= $this->modal->medium('external-link', t('Add external link'), 'TaskExternalLinkController', 'find', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
<li>
- <i class="fa fa-comment-o fa-fw"></i>
- <?= $this->url->link(t('Add a comment'), 'CommentController', 'create', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'popover') ?>
+ <?= $this->modal->small('comment-o', t('Add a comment'), 'CommentController', 'create', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
<li>
- <i class="fa fa-camera fa-fw"></i>
- <?= $this->url->link(t('Add a screenshot'), 'TaskPopoverController', 'screenshot', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'popover') ?>
+ <?= $this->modal->medium('camera', t('Add a screenshot'), 'TaskPopoverController', 'screenshot', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
<li>
- <i class="fa fa-files-o fa-fw"></i>
- <?= $this->url->link(t('Duplicate'), 'TaskDuplicationController', 'duplicate', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'popover') ?>
+ <?= $this->modal->small('files-o', t('Duplicate'), 'TaskDuplicationController', 'duplicate', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
<li>
- <i class="fa fa-clipboard fa-fw"></i>
- <?= $this->url->link(t('Duplicate to another project'), 'TaskDuplicationController', 'copy', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'popover') ?>
+ <?= $this->modal->small('clipboard', t('Duplicate to another project'), 'TaskDuplicationController', 'copy', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
<li>
- <i class="fa fa-clone fa-fw"></i>
- <?= $this->url->link(t('Move to another project'), 'TaskDuplicationController', 'move', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'popover') ?>
+ <?= $this->modal->small('clone', t('Move to another project'), 'TaskDuplicationController', 'move', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
<?php if ($this->projectRole->canRemoveTask($task)): ?>
<li>
- <i class="fa fa-trash-o fa-fw"></i>
- <?= $this->url->link(t('Remove'), 'TaskSuppressionController', 'confirm', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'popover') ?>
+ <?= $this->modal->confirm('trash-o', t('Remove'), 'TaskSuppressionController', 'confirm', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
<?php endif ?>
<?php if (isset($task['is_active']) && $this->projectRole->canChangeTaskStatusInColumn($task['project_id'], $task['column_id'])): ?>
<li>
<?php if ($task['is_active'] == 1): ?>
- <i class="fa fa-times fa-fw"></i>
- <?= $this->url->link(t('Close this task'), 'TaskStatusController', 'close', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'popover') ?>
+ <?= $this->modal->confirm('times', t('Close this task'), 'TaskStatusController', 'close', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
<?php else: ?>
- <i class="fa fa-check-square-o fa-fw"></i>
- <?= $this->url->link(t('Open this task'), 'TaskStatusController', 'open', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'popover') ?>
+ <?= $this->modal->confirm('check-square-o', t('Open this task'), 'TaskStatusController', 'open', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
<?php endif ?>
</li>
<?php endif ?>
diff --git a/app/Template/task/sidebar.php b/app/Template/task/sidebar.php
index 640423f4..f8f1ebde 100644
--- a/app/Template/task/sidebar.php
+++ b/app/Template/task/sidebar.php
@@ -4,25 +4,20 @@
</div>
<ul>
<li <?= $this->app->checkMenuSelection('TaskViewController', 'show') ?>>
- <i class="fa fa-newspaper-o fa-fw"></i>
- <?= $this->url->link(t('Summary'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
+ <?= $this->url->icon('newspaper-o', t('Summary'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
<li <?= $this->app->checkMenuSelection('ActivityController', 'task') ?>>
- <i class="fa fa-dashboard fa-fw"></i>
- <?= $this->url->link(t('Activity stream'), 'ActivityController', 'task', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
+ <?= $this->url->icon('dashboard', t('Activity stream'), 'ActivityController', 'task', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
<li <?= $this->app->checkMenuSelection('TaskViewController', 'transitions') ?>>
- <i class="fa fa-arrows-h fa-fw"></i>
- <?= $this->url->link(t('Transitions'), 'TaskViewController', 'transitions', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
+ <?= $this->url->icon('arrows-h', t('Transitions'), 'TaskViewController', 'transitions', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
<li <?= $this->app->checkMenuSelection('TaskViewController', 'analytics') ?>>
- <i class="fa fa-bar-chart fa-fw"></i>
- <?= $this->url->link(t('Analytics'), 'TaskViewController', 'analytics', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
+ <?= $this->url->icon('bar-chart', t('Analytics'), 'TaskViewController', 'analytics', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
<?php if ($task['time_estimated'] > 0 || $task['time_spent'] > 0): ?>
<li <?= $this->app->checkMenuSelection('TaskViewController', 'timetracking') ?>>
- <i class="fa fa-clock-o fa-fw"></i>
- <?= $this->url->link(t('Time tracking'), 'TaskViewController', 'timetracking', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
+ <?= $this->url->icon('clock-o', t('Time tracking'), 'TaskViewController', 'timetracking', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
<?php endif ?>
@@ -35,70 +30,57 @@
</div>
<ul>
<li>
- <i class="fa fa-pencil-square-o fa-fw"></i>
- <?= $this->url->link(t('Edit the task'), 'TaskModificationController', 'edit', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'popover') ?>
+ <?= $this->modal->large('edit', t('Edit the task'), 'TaskModificationController', 'edit', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
<li>
- <i class="fa fa-refresh fa-rotate-90 fa-fw"></i>
- <?= $this->url->link(t('Edit recurrence'), 'TaskRecurrenceController', 'edit', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'popover') ?>
+ <?= $this->modal->medium('refresh fa-rotate-90', t('Edit recurrence'), 'TaskRecurrenceController', 'edit', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
<li>
- <i class="fa fa-plus fa-fw"></i>
- <?= $this->url->link(t('Add a sub-task'), 'SubtaskController', 'create', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'popover') ?>
+ <?= $this->modal->medium('plus', t('Add a sub-task'), 'SubtaskController', 'create', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
<li>
- <i class="fa fa-code-fork fa-fw"></i>
- <?= $this->url->link(t('Add internal link'), 'TaskInternalLinkController', 'create', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'popover') ?>
+ <?= $this->modal->medium('code-fork', t('Add internal link'), 'TaskInternalLinkController', 'create', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
<li>
- <i class="fa fa-external-link fa-fw"></i>
- <?= $this->url->link(t('Add external link'), 'TaskExternalLinkController', 'find', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'popover') ?>
+ <?= $this->modal->medium('external-link', t('Add external link'), 'TaskExternalLinkController', 'find', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
<li>
- <i class="fa fa-comment-o fa-fw"></i>
- <?= $this->url->link(t('Add a comment'), 'CommentController', 'create', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'popover') ?>
+ <?= $this->modal->small('comment-o', t('Add a comment'), 'CommentController', 'create', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
<li>
- <i class="fa fa-file fa-fw"></i>
- <?= $this->url->link(t('Attach a document'), 'TaskFileController', 'create', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'popover') ?>
+ <?= $this->modal->medium('file', t('Attach a document'), 'TaskFileController', 'create', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
<li>
- <i class="fa fa-camera fa-fw"></i>
- <?= $this->url->link(t('Add a screenshot'), 'TaskFileController', 'screenshot', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'popover') ?>
+ <?= $this->modal->medium('camera', t('Add a screenshot'), 'TaskFileController', 'screenshot', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
<li>
- <i class="fa fa-files-o fa-fw"></i>
- <?= $this->url->link(t('Duplicate'), 'TaskDuplicationController', 'duplicate', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'popover') ?>
+ <?= $this->modal->small('files-o', t('Duplicate'), 'TaskDuplicationController', 'duplicate', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
<li>
- <i class="fa fa-clipboard fa-fw"></i>
- <?= $this->url->link(t('Duplicate to another project'), 'TaskDuplicationController', 'copy', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'popover') ?>
+ <?= $this->modal->small('clipboard', t('Duplicate to another project'), 'TaskDuplicationController', 'copy', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
<li>
- <i class="fa fa-clone fa-fw"></i>
- <?= $this->url->link(t('Move to another project'), 'TaskDuplicationController', 'move', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'popover') ?>
+ <?= $this->modal->small('clone', t('Move to another project'), 'TaskDuplicationController', 'move', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
+ <?php if ($task['is_active'] == 1 && $this->projectRole->isSortableColumn($task['project_id'], $task['column_id'])): ?>
+ <li>
+ <?= $this->modal->small('arrows', t('Move position'), 'TaskMovePositionController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
+ </li>
+ <?php endif ?>
<?php if ($this->projectRole->canChangeTaskStatusInColumn($task['project_id'], $task['column_id'])): ?>
<?php if ($task['is_active'] == 1): ?>
<li>
- <i class="fa fa-arrows fa-fw"></i>
- <?= $this->url->link(t('Move position'), 'TaskMovePositionController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'popover') ?>
- </li>
- <li>
- <i class="fa fa-times fa-fw"></i>
- <?= $this->url->link(t('Close this task'), 'TaskStatusController', 'close', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'popover') ?>
+ <?= $this->modal->confirm('times', t('Close this task'), 'TaskStatusController', 'close', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
<?php else: ?>
<li>
- <i class="fa fa-check-square-o fa-fw"></i>
- <?= $this->url->link(t('Open this task'), 'TaskStatusController', 'open', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'popover') ?>
+ <?= $this->modal->confirm('check-square-o', t('Open this task'), 'TaskStatusController', 'open', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
<?php endif ?>
<?php endif ?>
<?php if ($this->projectRole->canRemoveTask($task)): ?>
<li>
- <i class="fa fa-trash-o fa-fw"></i>
- <?= $this->url->link(t('Remove'), 'TaskSuppressionController', 'confirm', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'redirect' => 'board'), false, 'popover') ?>
+ <?= $this->modal->confirm('trash-o', t('Remove'), 'TaskSuppressionController', 'confirm', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'redirect' => 'board')) ?>
</li>
<?php endif ?>
diff --git a/app/Template/task/time_tracking_summary.php b/app/Template/task/time_tracking_summary.php
index 9886ccfa..63de733a 100644
--- a/app/Template/task/time_tracking_summary.php
+++ b/app/Template/task/time_tracking_summary.php
@@ -1,13 +1,13 @@
<?php if ($task['time_estimated'] > 0 || $task['time_spent'] > 0): ?>
+ <div class="page-header">
+ <h2><?= t('Time tracking') ?></h2>
+ </div>
-<div class="page-header">
- <h2><?= t('Time tracking') ?></h2>
-</div>
-
-<ul class="listing">
- <li><?= t('Estimate:') ?> <strong><?= $this->text->e($task['time_estimated']) ?></strong> <?= t('hours') ?></li>
- <li><?= t('Spent:') ?> <strong><?= $this->text->e($task['time_spent']) ?></strong> <?= t('hours') ?></li>
- <li><?= t('Remaining:') ?> <strong><?= $this->text->e($task['time_estimated'] - $task['time_spent']) ?></strong> <?= t('hours') ?></li>
-</ul>
-
+ <div class="panel">
+ <ul>
+ <li><?= t('Estimate:') ?> <strong><?= $this->text->e($task['time_estimated']) ?></strong> <?= t('hours') ?></li>
+ <li><?= t('Spent:') ?> <strong><?= $this->text->e($task['time_spent']) ?></strong> <?= t('hours') ?></li>
+ <li><?= t('Remaining:') ?> <strong><?= $this->text->e($task['time_estimated'] - $task['time_spent']) ?></strong> <?= t('hours') ?></li>
+ </ul>
+ </div>
<?php endif ?> \ No newline at end of file
diff --git a/app/Template/task_bulk/show.php b/app/Template/task_bulk/show.php
index 11ddea31..acf80d8c 100644
--- a/app/Template/task_bulk/show.php
+++ b/app/Template/task_bulk/show.php
@@ -2,23 +2,20 @@
<h2><?= $this->text->e($project['name']) ?> &gt; <?= t('Create tasks in bulk') ?></h2>
</div>
-<form class="popover-form" method="post" action="<?= $this->url->href('TaskBulkController', 'save', array('project_id' => $project['id'])) ?>" autocomplete="off">
+<form method="post" action="<?= $this->url->href('TaskBulkController', 'save', array('project_id' => $project['id'])) ?>" autocomplete="off">
<?= $this->form->csrf() ?>
<?= $this->form->hidden('column_id', $values) ?>
<?= $this->form->hidden('swimlane_id', $values) ?>
<?= $this->form->hidden('project_id', $values) ?>
- <?= $this->task->selectColor($values) ?>
- <?= $this->task->selectAssignee($users_list, $values, $errors) ?>
- <?= $this->task->selectCategory($categories_list, $values, $errors) ?>
+ <?= $this->task->renderColorField($values) ?>
+ <?= $this->task->renderAssigneeField($users_list, $values, $errors) ?>
+ <?= $this->task->renderCategoryField($categories_list, $values, $errors) ?>
<?= $this->form->label(t('Tasks'), 'tasks') ?>
<?= $this->form->textarea('tasks', $values, $errors, array('placeholder="'.t('My task title').'"')) ?>
<p class="form-help"><?= t('Enter one task by line.') ?></p>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- <?= t('or') ?> <?= $this->url->link(t('cancel'), 'BoardViewController', 'show', array('project_id' => $project['id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->submitButtons() ?>
</form>
diff --git a/app/Template/task_creation/duplicate_projects.php b/app/Template/task_creation/duplicate_projects.php
index dc0fa105..202b3ffe 100644
--- a/app/Template/task_creation/duplicate_projects.php
+++ b/app/Template/task_creation/duplicate_projects.php
@@ -5,10 +5,10 @@
<?php if (empty($projects_list)): ?>
<p class="alert"><?= t('There is no destination project available.') ?></p>
<div class="form-actions">
- <?= $this->url->link(t('cancel'), 'BoardViewController', 'show', array('project_id' => $task['project_id']), false, 'close-popover btn') ?>
+ <?= $this->url->link(t('cancel'), 'BoardViewController', 'show', array('project_id' => $task['project_id']), false, 'js-modal-close btn') ?>
</div>
<?php else: ?>
- <form class="popover-form" method="post" action="<?= $this->url->href('TaskCreationController', 'duplicateProjects', array('project_id' => $task['project_id'])) ?>" autocomplete="off">
+ <form method="post" action="<?= $this->url->href('TaskCreationController', 'duplicateProjects', array('project_id' => $task['project_id'])) ?>" autocomplete="off">
<?= $this->form->csrf() ?>
<?= $this->form->hidden('task_id', $values) ?>
@@ -20,9 +20,6 @@
array('multiple')
) ?>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Duplicate') ?></button>
- <?= t('or') ?> <?= $this->url->link(t('cancel'), 'BoardViewController', 'show', array('project_id' => $task['project_id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->submitButtons() ?>
</form>
<?php endif ?>
diff --git a/app/Template/task_creation/show.php b/app/Template/task_creation/show.php
index 0c267aff..e957087f 100644
--- a/app/Template/task_creation/show.php
+++ b/app/Template/task_creation/show.php
@@ -1,51 +1,48 @@
<div class="page-header">
- <h2><?= $this->text->e($project['name']) ?> &gt; <?= t('New task') ?></h2>
+ <h2><?= $this->text->e($project['name']) ?> &gt; <?= t('New task') ?><?= $this->task->getNewTaskDropdown($project['id'], $values['swimlane_id'], $values['column_id']) ?></h2>
</div>
-
-<form class="popover-form" method="post" action="<?= $this->url->href('TaskCreationController', 'save', array('project_id' => $values['project_id'])) ?>" autocomplete="off">
+<form method="post" action="<?= $this->url->href('TaskCreationController', 'save', array('project_id' => $project['id'])) ?>" autocomplete="off">
<?= $this->form->csrf() ?>
+ <?= $this->form->hidden('project_id', $values) ?>
- <div class="form-columns">
- <div class="form-column">
- <?= $this->task->selectTitle($values, $errors) ?>
- <?= $this->task->selectDescription($values, $errors) ?>
- <?= $this->task->selectTags($project) ?>
-
- <?= $this->hook->render('template:task:form:first-column', array('values' => $values, 'errors' => $errors)) ?>
-
- <?php if (! isset($duplicate)): ?>
- <?= $this->form->checkbox('another_task', t('Create another task'), 1, isset($values['another_task']) && $values['another_task'] == 1) ?>
- <?= $this->form->checkbox('duplicate_multiple_projects', t('Duplicate to multiple projects'), 1) ?>
- <?php endif ?>
+ <div class="task-form-container">
+ <div class="task-form-main-column">
+ <?= $this->task->renderTitleField($values, $errors) ?>
+ <?= $this->task->renderDescriptionField($values, $errors) ?>
+ <?= $this->task->renderTagField($project) ?>
+ <?= $this->hook->render('template:task:form:first-column', array('values' => $values, 'errors' => $errors)) ?>
</div>
- <div class="form-column">
- <?= $this->form->hidden('project_id', $values) ?>
- <?= $this->task->selectColor($values) ?>
- <?= $this->task->selectAssignee($users_list, $values, $errors) ?>
- <?= $this->task->selectCategory($categories_list, $values, $errors) ?>
- <?= $this->task->selectSwimlane($swimlanes_list, $values, $errors) ?>
- <?= $this->task->selectColumn($columns_list, $values, $errors) ?>
- <?= $this->task->selectPriority($project, $values) ?>
- <?= $this->task->selectScore($values, $errors) ?>
- <?= $this->task->selectReference($values, $errors) ?>
+ <div class="task-form-secondary-column">
+ <?= $this->task->renderColorField($values) ?>
+ <?= $this->task->renderAssigneeField($users_list, $values, $errors) ?>
+ <?= $this->task->renderCategoryField($categories_list, $values, $errors) ?>
+ <?= $this->task->renderSwimlaneField($swimlanes_list, $values, $errors) ?>
+ <?= $this->task->renderColumnField($columns_list, $values, $errors) ?>
+ <?= $this->task->renderPriorityField($project, $values) ?>
<?= $this->hook->render('template:task:form:second-column', array('values' => $values, 'errors' => $errors)) ?>
</div>
- <div class="form-column">
- <?= $this->task->selectTimeEstimated($values, $errors) ?>
- <?= $this->task->selectTimeSpent($values, $errors) ?>
- <?= $this->task->selectStartDate($values, $errors) ?>
- <?= $this->task->selectDueDate($values, $errors) ?>
+ <div class="task-form-secondary-column">
+ <?= $this->task->renderDueDateField($values, $errors) ?>
+ <?= $this->task->renderStartDateField($values, $errors) ?>
+ <?= $this->task->renderTimeEstimatedField($values, $errors) ?>
+ <?= $this->task->renderTimeSpentField($values, $errors) ?>
+ <?= $this->task->renderScoreField($values, $errors) ?>
+ <?= $this->task->renderReferenceField($values, $errors) ?>
<?= $this->hook->render('template:task:form:third-column', array('values' => $values, 'errors' => $errors)) ?>
</div>
- </div>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue" tabindex="15"><?= t('Save') ?></button>
- <?= t('or') ?> <?= $this->url->link(t('cancel'), 'BoardViewController', 'show', array('project_id' => $values['project_id']), false, 'close-popover') ?>
+ <div class="task-form-bottom">
+ <?php if (! isset($duplicate)): ?>
+ <?= $this->form->checkbox('another_task', t('Create another task'), 1, isset($values['another_task']) && $values['another_task'] == 1) ?>
+ <?= $this->form->checkbox('duplicate_multiple_projects', t('Duplicate to multiple projects'), 1) ?>
+ <?php endif ?>
+
+ <?= $this->modal->submitButtons() ?>
+ </div>
</div>
</form>
diff --git a/app/Template/task_duplication/copy.php b/app/Template/task_duplication/copy.php
index 65cfe4d6..d96960fc 100644
--- a/app/Template/task_duplication/copy.php
+++ b/app/Template/task_duplication/copy.php
@@ -5,25 +5,25 @@
<?php if (empty($projects_list)): ?>
<p class="alert"><?= t('There is no destination project available.') ?></p>
<div class="form-actions">
- <?= $this->url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover btn') ?>
+ <?= $this->url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'js-modal-close btn') ?>
</div>
<?php else: ?>
- <form class="popover-form" method="post" action="<?= $this->url->href('TaskDuplicationController', 'copy', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>" autocomplete="off">
-
+ <form method="post" action="<?= $this->url->href('TaskDuplicationController', 'copy', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>" autocomplete="off">
<?= $this->form->csrf() ?>
<?= $this->form->hidden('id', $values) ?>
<?= $this->form->label(t('Project'), 'project_id') ?>
- <?= $this->form->select(
- 'project_id',
- $projects_list,
- $values,
- array(),
- array('data-redirect="'.$this->url->href('TaskDuplicationController', 'copy', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'dst_project_id' => 'PROJECT_ID')).'"'),
- 'task-reload-project-destination'
- ) ?>
- <span class="loading-icon" style="display: none">&nbsp;<i class="fa fa-spinner fa-spin"></i></span>
+ <?= $this->app->component('select-dropdown-autocomplete', array(
+ 'name' => 'project_id',
+ 'items' => $projects_list,
+ 'defaultValue' => isset($values['project_id']) ? $values['project_id'] : null,
+ 'placeholder' => t('Choose a project'),
+ 'replace' => array(
+ 'regex' => 'PROJECT_ID',
+ 'url' => $this->url->href('TaskDuplicationController', 'copy', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'dst_project_id' => 'PROJECT_ID')),
+ )
+ )) ?>
<?= $this->form->label(t('Swimlane'), 'swimlane_id') ?>
<?= $this->form->select('swimlane_id', $swimlanes_list, $values) ?>
@@ -41,10 +41,6 @@
<?= $this->form->select('owner_id', $users_list, $values) ?>
<p class="form-help"><?= t('Current assignee: %s', ($task['assignee_name'] ?: $task['assignee_username']) ?: e('not assigned')) ?></p>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->submitButtons() ?>
</form>
<?php endif ?>
diff --git a/app/Template/task_duplication/duplicate.php b/app/Template/task_duplication/duplicate.php
index c0baf94e..aa02b78c 100644
--- a/app/Template/task_duplication/duplicate.php
+++ b/app/Template/task_duplication/duplicate.php
@@ -7,9 +7,9 @@
<?= t('Do you really want to duplicate this task?') ?>
</p>
- <div class="form-actions">
- <?= $this->url->link(t('Yes'), 'TaskDuplicationController', 'duplicate', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'confirmation' => 'yes'), true, 'btn btn-red') ?>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->confirmButtons(
+ 'TaskDuplicationController',
+ 'duplicate',
+ array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'confirmation' => 'yes')
+ ) ?>
</div>
diff --git a/app/Template/task_duplication/move.php b/app/Template/task_duplication/move.php
index 717d15e9..16ce2464 100644
--- a/app/Template/task_duplication/move.php
+++ b/app/Template/task_duplication/move.php
@@ -5,25 +5,26 @@
<?php if (empty($projects_list)): ?>
<p class="alert"><?= t('There is no destination project available.') ?></p>
<div class="form-actions">
- <?= $this->url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover btn') ?>
+ <?= $this->url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'js-modal-close btn') ?>
</div>
<?php else: ?>
- <form class="popover-form" method="post" action="<?= $this->url->href('TaskDuplicationController', 'move', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>" autocomplete="off">
+ <form method="post" action="<?= $this->url->href('TaskDuplicationController', 'move', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>" autocomplete="off">
<?= $this->form->csrf() ?>
<?= $this->form->hidden('id', $values) ?>
<?= $this->form->label(t('Project'), 'project_id') ?>
- <?= $this->form->select(
- 'project_id',
- $projects_list,
- $values,
- array(),
- array('data-redirect="'.$this->url->href('TaskDuplicationController', 'move', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'dst_project_id' => 'PROJECT_ID')).'"'),
- 'task-reload-project-destination'
- ) ?>
- <span class="loading-icon" style="display: none">&nbsp;<i class="fa fa-spinner fa-spin"></i></span>
+ <?= $this->app->component('select-dropdown-autocomplete', array(
+ 'name' => 'project_id',
+ 'items' => $projects_list,
+ 'defaultValue' => isset($values['project_id']) ? $values['project_id'] : null,
+ 'placeholder' => t('Choose a project'),
+ 'replace' => array(
+ 'regex' => 'PROJECT_ID',
+ 'url' => $this->url->href('TaskDuplicationController', 'move', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'dst_project_id' => 'PROJECT_ID')),
+ )
+ )) ?>
<?= $this->form->label(t('Swimlane'), 'swimlane_id') ?>
<?= $this->form->select('swimlane_id', $swimlanes_list, $values) ?>
@@ -41,11 +42,7 @@
<?= $this->form->select('owner_id', $users_list, $values) ?>
<p class="form-help"><?= t('Current assignee: %s', ($task['assignee_name'] ?: $task['assignee_username']) ?: e('not assigned')) ?></p>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->submitButtons() ?>
</form>
<?php endif ?>
diff --git a/app/Template/task_external_link/create.php b/app/Template/task_external_link/create.php
index beddfc90..04d9bed0 100644
--- a/app/Template/task_external_link/create.php
+++ b/app/Template/task_external_link/create.php
@@ -2,12 +2,7 @@
<h2><?= t('Add a new external link') ?></h2>
</div>
-<form class="popover-form" action="<?= $this->url->href('TaskExternalLinkController', 'save', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>" method="post" autocomplete="off">
+<form action="<?= $this->url->href('TaskExternalLinkController', 'save', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>" method="post" autocomplete="off">
<?= $this->render('task_external_link/form', array('task' => $task, 'dependencies' => $dependencies, 'values' => $values, 'errors' => $errors)) ?>
-
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'TaskExternalLinkController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->submitButtons() ?>
</form>
diff --git a/app/Template/task_external_link/edit.php b/app/Template/task_external_link/edit.php
index 917a28b9..df10d444 100644
--- a/app/Template/task_external_link/edit.php
+++ b/app/Template/task_external_link/edit.php
@@ -2,12 +2,7 @@
<h2><?= t('Edit external link') ?></h2>
</div>
-<form class="popover-form" action="<?= $this->url->href('TaskExternalLinkController', 'update', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>" method="post" autocomplete="off">
+<form action="<?= $this->url->href('TaskExternalLinkController', 'update', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>" method="post" autocomplete="off">
<?= $this->render('task_external_link/form', array('task' => $task, 'dependencies' => $dependencies, 'values' => $values, 'errors' => $errors)) ?>
-
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'TaskExternalLinkController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->submitButtons() ?>
</form>
diff --git a/app/Template/task_external_link/find.php b/app/Template/task_external_link/find.php
index a88b29ce..a3665c0d 100644
--- a/app/Template/task_external_link/find.php
+++ b/app/Template/task_external_link/find.php
@@ -2,7 +2,7 @@
<h2><?= t('Add a new external link') ?></h2>
</div>
-<form class="popover-form" action="<?= $this->url->href('TaskExternalLinkController', 'create', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>" method="post" autocomplete="off">
+<form action="<?= $this->url->href('TaskExternalLinkController', 'create', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>" method="post" autocomplete="off">
<?= $this->form->csrf() ?>
<?= $this->form->hidden('task_id', array('task_id' => $task['id'])) ?>
@@ -20,9 +20,5 @@
<?= $this->form->label(t('Link type'), 'type') ?>
<?= $this->form->select('type', $types, $values) ?>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Next') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->submitButtons() ?>
</form>
diff --git a/app/Template/task_external_link/remove.php b/app/Template/task_external_link/remove.php
index 2a888a60..ed8ad15f 100644
--- a/app/Template/task_external_link/remove.php
+++ b/app/Template/task_external_link/remove.php
@@ -7,9 +7,9 @@
<?= t('Do you really want to remove this link: "%s"?', $link['title']) ?>
</p>
- <div class="form-actions">
- <?= $this->url->link(t('Yes'), 'TaskExternalLinkController', 'remove', array('link_id' => $link['id'], 'task_id' => $task['id'], 'project_id' => $task['project_id']), true, 'btn btn-red') ?>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'TaskExternalLinkController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->confirmButtons(
+ 'TaskExternalLinkController',
+ 'remove',
+ array('link_id' => $link['id'], 'task_id' => $task['id'], 'project_id' => $task['project_id'])
+ ) ?>
</div>
diff --git a/app/Template/task_external_link/table.php b/app/Template/task_external_link/table.php
index a5fc7a33..aaa234bb 100644
--- a/app/Template/task_external_link/table.php
+++ b/app/Template/task_external_link/table.php
@@ -33,12 +33,10 @@
<a href="#" class="dropdown-menu dropdown-menu-link-icon"><i class="fa fa-cog fa-fw"></i><i class="fa fa-caret-down"></i></a>
<ul>
<li>
- <i class="fa fa-edit fa-fw"></i>
- <?= $this->url->link(t('Edit'), 'TaskExternalLinkController', 'edit', array('link_id' => $link['id'], 'task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'popover') ?>
+ <?= $this->modal->medium('edit', t('Edit'), 'TaskExternalLinkController', 'edit', array('link_id' => $link['id'], 'task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
<li>
- <i class="fa fa-trash-o fa-fw"></i>
- <?= $this->url->link(t('Remove'), 'TaskExternalLinkController', 'confirm', array('link_id' => $link['id'], 'task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'popover') ?>
+ <?= $this->modal->confirm('trash-o', t('Remove'), 'TaskExternalLinkController', 'confirm', array('link_id' => $link['id'], 'task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
</ul>
</div>
diff --git a/app/Template/task_file/create.php b/app/Template/task_file/create.php
index e05cf829..eebb08eb 100644
--- a/app/Template/task_file/create.php
+++ b/app/Template/task_file/create.php
@@ -1,33 +1,20 @@
<div class="page-header">
<h2><?= t('Attach a document') ?></h2>
</div>
-<div id="file-done" style="display:none">
- <p class="alert alert-success">
- <?= t('All files have been uploaded successfully.') ?>
- <?= $this->url->link(t('View uploaded files'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
- </p>
-</div>
-
-<div id="file-error-max-size" style="display:none">
- <p class="alert alert-error">
- <?= t('The maximum allowed file size is %sB.', $this->text->bytes($max_size)) ?>
- <a href="#" id="file-browser"><?= t('Choose files again') ?></a>
- </p>
-</div>
-<div
- id="file-dropzone"
- data-max-size="<?= $max_size ?>"
- data-url="<?= $this->url->href('TaskFileController', 'save', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>">
- <div id="file-dropzone-inner">
- <?= t('Drag and drop your files here') ?> <?= t('or') ?> <a href="#" id="file-browser"><?= t('choose files') ?></a>
- </div>
-</div>
-
-<input type="file" name="files[]" multiple style="display:none" id="file-form-element">
+<?= $this->app->component('file-upload', array(
+ 'maxSize' => $max_size,
+ 'url' => $this->url->to('TaskFileController', 'save', array('task_id' => $task['id'], 'project_id' => $task['project_id'])),
+ 'labelDropzone' => t('Drag and drop your files here'),
+ 'labelOr' => t('or'),
+ 'labelChooseFiles' => t('choose files'),
+ 'labelOversize' => t('The maximum allowed file size is %sB.', $this->text->bytes($max_size)),
+ 'labelSuccess' => t('All files have been uploaded successfully.'),
+ 'labelCloseSuccess' => t('Close this window'),
+ 'labelUploadError' => t('Unable to upload this file.'),
+)) ?>
-<div class="form-actions">
- <input type="submit" value="<?= t('Upload files') ?>" class="btn btn-blue" id="file-upload-button" disabled>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?>
-</div>
+<?= $this->modal->submitButtons(array(
+ 'submitLabel' => t('Upload files'),
+ 'disabled' => true,
+)) ?>
diff --git a/app/Template/task_file/files.php b/app/Template/task_file/files.php
index 94c26f73..28633dc4 100644
--- a/app/Template/task_file/files.php
+++ b/app/Template/task_file/files.php
@@ -15,18 +15,20 @@
<ul>
<?php if ($this->file->getPreviewType($file['name']) !== null): ?>
<li>
+ <?= $this->modal->large('eye', t('View file'), 'FileViewerController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id'])) ?>
+ </li>
+ <?php elseif ($this->file->getBrowserViewType($file['name']) !== null): ?>
+ <li>
<i class="fa fa-eye fa-fw"></i>
- <?= $this->url->link(t('View file'), 'FileViewerController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id']), false, 'popover') ?>
+ <?= $this->url->link(t('View file'), 'FileViewerController', 'browser', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id']), false, '', '', true) ?>
</li>
<?php endif ?>
<li>
- <i class="fa fa-download fa-fw"></i>
- <?= $this->url->link(t('Download'), 'FileViewerController', 'download', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id'])) ?>
+ <?= $this->url->icon('download', t('Download'), 'FileViewerController', 'download', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id'])) ?>
</li>
<?php if ($this->user->hasProjectAccess('TaskFileController', 'remove', $task['project_id'])): ?>
<li>
- <i class="fa fa-trash fa-fw"></i>
- <?= $this->url->link(t('Remove'), 'TaskFileController', 'confirm', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id']), false, 'popover') ?>
+ <?= $this->modal->confirm('trash-o', t('Remove'), 'TaskFileController', 'confirm', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id'])) ?>
</li>
<?php endif ?>
</ul>
diff --git a/app/Template/task_file/images.php b/app/Template/task_file/images.php
index 81c33151..9d20dea0 100644
--- a/app/Template/task_file/images.php
+++ b/app/Template/task_file/images.php
@@ -2,20 +2,28 @@
<div class="file-thumbnails">
<?php foreach ($images as $file): ?>
<div class="file-thumbnail">
- <a href="<?= $this->url->href('FileViewerController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id'])) ?>" class="popover"><img src="<?= $this->url->href('FileViewerController', 'thumbnail', array('file_id' => $file['id'], 'project_id' => $task['project_id'], 'task_id' => $file['task_id'])) ?>" title="<?= $this->text->e($file['name']) ?>" alt="<?= $this->text->e($file['name']) ?>"></a>
+ <?= $this->app->component('image-slideshow', array(
+ 'images' => $images,
+ 'image' => $file,
+ 'regex' => 'FILE_ID',
+ 'url' => array(
+ 'image' => $this->url->to('FileViewerController', 'image', array('file_id' => 'FILE_ID', 'project_id' => $task['project_id'], 'task_id' => $task['id'])),
+ 'thumbnail' => $this->url->to('FileViewerController', 'thumbnail', array('file_id' => 'FILE_ID', 'project_id' => $task['project_id'], 'task_id' => $task['id'])),
+ 'download' => $this->url->to('FileViewerController', 'download', array('file_id' => 'FILE_ID', 'project_id' => $task['project_id'], 'task_id' => $task['id'])),
+ )
+ )) ?>
+
<div class="file-thumbnail-content">
<div class="file-thumbnail-title">
<div class="dropdown">
- <a href="#" class="dropdown-menu dropdown-menu-link-text"><?= $this->text->e($file['name']) ?> <i class="fa fa-caret-down"></i></a>
+ <a href="#" class="dropdown-menu dropdown-menu-link-text" title="<?= $this->text->e($file['name']) ?>"><?= $this->text->e($file['name']) ?> <i class="fa fa-caret-down"></i></a>
<ul>
<li>
- <i class="fa fa-download fa-fw"></i>
- <?= $this->url->link(t('Download'), 'FileViewerController', 'download', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id'])) ?>
+ <?= $this->url->icon('download', t('Download'), 'FileViewerController', 'download', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id'])) ?>
</li>
<?php if ($this->user->hasProjectAccess('TaskFileController', 'remove', $task['project_id'])): ?>
<li>
- <i class="fa fa-trash fa-fw"></i>
- <?= $this->url->link(t('Remove'), 'TaskFileController', 'confirm', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id']), false, 'popover') ?>
+ <?= $this->modal->confirm('trash-o', t('Remove'), 'TaskFileController', 'confirm', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id'])) ?>
</li>
<?php endif ?>
</ul>
@@ -25,7 +33,11 @@
<span class="tooltip" title='<?= t('Uploaded: %s', $this->dt->datetime($file['date'])).'<br>'.t('Size: %s', $this->text->bytes($file['size'])) ?>'>
<i class="fa fa-info-circle"></i>
</span>
- <?= t('Uploaded by %s', $file['user_name'] ?: $file['username']) ?>
+ <?php if (! empty($file['user_id'])): ?>
+ <?= t('Uploaded by %s', $file['user_name'] ?: $file['username']) ?>
+ <?php else: ?>
+ <?= t('Uploaded: %s', $this->dt->datetime($file['date'])) ?>
+ <?php endif ?>
</div>
</div>
</div>
diff --git a/app/Template/task_file/remove.php b/app/Template/task_file/remove.php
index 42894f05..e7ffe560 100644
--- a/app/Template/task_file/remove.php
+++ b/app/Template/task_file/remove.php
@@ -7,9 +7,9 @@
<?= t('Do you really want to remove this file: "%s"?', $this->text->e($file['name'])) ?>
</p>
- <div class="form-actions">
- <?= $this->url->link(t('Yes'), 'TaskFileController', 'remove', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id']), true, 'btn btn-red') ?>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->confirmButtons(
+ 'TaskFileController',
+ 'remove',
+ array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id'])
+ ) ?>
</div>
diff --git a/app/Template/task_file/screenshot.php b/app/Template/task_file/screenshot.php
index 6300159f..dad8c233 100644
--- a/app/Template/task_file/screenshot.php
+++ b/app/Template/task_file/screenshot.php
@@ -6,14 +6,10 @@
<p id="screenshot-inner"><?= t('Take a screenshot and press CTRL+V or ⌘+V to paste here.') ?></p>
</div>
-<form class="popover-form" action="<?= $this->url->href('TaskFileController', 'screenshot', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>" method="post">
- <input type="hidden" name="screenshot"/>
+<form action="<?= $this->url->href('TaskFileController', 'screenshot', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>" method="post">
<?= $this->form->csrf() ?>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?>
- </div>
+ <?= $this->app->component('screenshot') ?>
+ <?= $this->modal->submitButtons() ?>
</form>
<p class="alert alert-info"><?= t('This feature does not work with all browsers.') ?></p>
diff --git a/app/Template/task_gantt/show.php b/app/Template/task_gantt/show.php
index c5d338fb..61a476b7 100644
--- a/app/Template/task_gantt/show.php
+++ b/app/Template/task_gantt/show.php
@@ -3,16 +3,13 @@
<div class="menu-inline">
<ul>
<li <?= $sorting === 'board' ? 'class="active"' : '' ?>>
- <i class="fa fa-sort-numeric-asc fa-fw"></i>
- <?= $this->url->link(t('Sort by position'), 'TaskGanttController', 'show', array('project_id' => $project['id'], 'sorting' => 'board')) ?>
+ <?= $this->url->icon('sort-numeric-asc', t('Sort by position'), 'TaskGanttController', 'show', array('project_id' => $project['id'], 'sorting' => 'board')) ?>
</li>
<li <?= $sorting === 'date' ? 'class="active"' : '' ?>>
- <i class="fa fa-sort-amount-asc fa-fw"></i>
- <?= $this->url->link(t('Sort by date'), 'TaskGanttController', 'show', array('project_id' => $project['id'], 'sorting' => 'date')) ?>
+ <?= $this->url->icon('sort-amount-asc', t('Sort by date'), 'TaskGanttController', 'show', array('project_id' => $project['id'], 'sorting' => 'date')) ?>
</li>
<li>
- <i class="fa fa-plus fa-fw"></i>
- <?= $this->url->link(t('Add task'), 'TaskGanttCreationController', 'show', array('project_id' => $project['id']), false, 'popover') ?>
+ <?= $this->modal->large('plus', t('Add task'), 'TaskCreationController', 'show', array('project_id' => $project['id'])) ?>
</li>
</ul>
</div>
diff --git a/app/Template/task_gantt_creation/show.php b/app/Template/task_gantt_creation/show.php
deleted file mode 100644
index 7906c39a..00000000
--- a/app/Template/task_gantt_creation/show.php
+++ /dev/null
@@ -1,46 +0,0 @@
-<div class="page-header">
- <h2><?= $this->text->e($project['name']) ?> &gt; <?= t('New task') ?></h2>
-</div>
-<form class="popover-form" method="post" action="<?= $this->url->href('TaskGanttCreationController', 'save', array('project_id' => $values['project_id'])) ?>" autocomplete="off">
- <?= $this->form->csrf() ?>
- <?= $this->form->hidden('project_id', $values) ?>
- <?= $this->form->hidden('column_id', $values) ?>
- <?= $this->form->hidden('position', $values) ?>
-
- <div class="form-columns">
- <div class="form-column">
- <?= $this->task->selectTitle($values, $errors) ?>
- <?= $this->task->selectDescription($values, $errors) ?>
- <?= $this->task->selectTags($project) ?>
-
- <?= $this->hook->render('template:task:form:first-column', array('values' => $values, 'errors' => $errors)) ?>
- </div>
-
- <div class="form-column">
- <?= $this->task->selectColor($values) ?>
- <?= $this->task->selectAssignee($users_list, $values, $errors) ?>
- <?= $this->task->selectCategory($categories_list, $values, $errors) ?>
- <?= $this->task->selectSwimlane($swimlanes_list, $values, $errors) ?>
- <?= $this->task->selectPriority($project, $values) ?>
- <?= $this->task->selectScore($values, $errors) ?>
- <?= $this->task->selectReference($values, $errors) ?>
-
- <?= $this->hook->render('template:task:form:second-column', array('values' => $values, 'errors' => $errors)) ?>
- </div>
-
- <div class="form-column">
- <?= $this->task->selectTimeEstimated($values, $errors) ?>
- <?= $this->task->selectTimeSpent($values, $errors) ?>
- <?= $this->task->selectStartDate($values, $errors) ?>
- <?= $this->task->selectDueDate($values, $errors) ?>
-
- <?= $this->hook->render('template:task:form:third-column', array('values' => $values, 'errors' => $errors)) ?>
- </div>
- </div>
-
- <div class="form-actions">
- <button type="submit" class="btn btn-blue" tabindex="15"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'TaskGanttController', 'show', array('project_id' => $values['project_id']), false, 'close-popover') ?>
- </div>
-</form>
diff --git a/app/Template/task_import/show.php b/app/Template/task_import/show.php
index cc6a7b3a..20b020d3 100644
--- a/app/Template/task_import/show.php
+++ b/app/Template/task_import/show.php
@@ -15,14 +15,11 @@
<p class="form-help"><?= t('Maximum size: ') ?><?= is_integer($max_size) ? $this->text->bytes($max_size) : $max_size ?></p>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Import') ?></button>
- </div>
+ <?= $this->modal->submitButtons(array('submitLabel' => t('Import'))) ?>
</form>
-<div class="page-header">
- <h2><?= t('Instructions') ?></h2>
-</div>
-<div class="alert">
+
+<div class="panel">
+ <h3><?= t('Instructions') ?></h3>
<ul>
<li><?= t('Your file must use the predefined CSV format') ?></li>
<li><?= t('Your file must be encoded in UTF-8') ?></li>
@@ -30,5 +27,7 @@
<li><?= t('Duplicates are not verified for you') ?></li>
<li><?= t('The due date must use the ISO format: YYYY-MM-DD') ?></li>
</ul>
+ <p class="margin-top">
+ <?= $this->url->icon('download', t('Download CSV template'), 'TaskImportController', 'template', array('project_id' => $project['id'])) ?>
+ </p>
</div>
-<p><i class="fa fa-download fa-fw"></i><?= $this->url->link(t('Download CSV template'), 'TaskImportController', 'template', array('project_id' => $project['id'])) ?></p>
diff --git a/app/Template/task_import/sidebar.php b/app/Template/task_import/sidebar.php
deleted file mode 100644
index 04896948..00000000
--- a/app/Template/task_import/sidebar.php
+++ /dev/null
@@ -1,8 +0,0 @@
-<div class="sidebar">
- <ul>
- <li <?= $this->app->checkMenuSelection('TaskImportController', 'show') ?>>
- <?= $this->url->link(t('Tasks').' (CSV)', 'TaskImportController', 'show', array('project_id' => $project['id'])) ?>
- </li>
- <?= $this->hook->render('template:task-import:sidebar') ?>
- </ul>
-</div>
diff --git a/app/Template/task_internal_link/create.php b/app/Template/task_internal_link/create.php
index fed29605..3c39b87c 100644
--- a/app/Template/task_internal_link/create.php
+++ b/app/Template/task_internal_link/create.php
@@ -2,7 +2,7 @@
<h2><?= t('Add a new link') ?></h2>
</div>
-<form class="popover-form" action="<?= $this->url->href('TaskInternalLinkController', 'save', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>" method="post" autocomplete="off">
+<form action="<?= $this->url->href('TaskInternalLinkController', 'save', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>" method="post" autocomplete="off">
<?= $this->form->csrf() ?>
<?= $this->form->hidden('task_id', array('task_id' => $task['id'])) ?>
@@ -25,9 +25,5 @@
),
'autocomplete') ?>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->submitButtons() ?>
</form>
diff --git a/app/Template/task_internal_link/edit.php b/app/Template/task_internal_link/edit.php
index f4df57bd..5abf7b65 100644
--- a/app/Template/task_internal_link/edit.php
+++ b/app/Template/task_internal_link/edit.php
@@ -26,9 +26,5 @@
),
'autocomplete') ?>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->submitButtons() ?>
</form>
diff --git a/app/Template/task_internal_link/remove.php b/app/Template/task_internal_link/remove.php
index 966ad116..f8d91a81 100644
--- a/app/Template/task_internal_link/remove.php
+++ b/app/Template/task_internal_link/remove.php
@@ -7,9 +7,9 @@
<?= t('Do you really want to remove this link with task #%d?', $link['opposite_task_id']) ?>
</p>
- <div class="form-actions">
- <?= $this->url->link(t('Yes'), 'TaskInternalLinkController', 'remove', array('link_id' => $link['id'], 'task_id' => $task['id'], 'project_id' => $task['project_id']), true, 'btn btn-red') ?>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->confirmButtons(
+ 'TaskInternalLinkController',
+ 'remove',
+ array('link_id' => $link['id'], 'task_id' => $task['id'], 'project_id' => $task['project_id'])
+ ) ?>
</div>
diff --git a/app/Template/task_internal_link/table.php b/app/Template/task_internal_link/table.php
index 3a3a2b88..255ecc97 100644
--- a/app/Template/task_internal_link/table.php
+++ b/app/Template/task_internal_link/table.php
@@ -73,12 +73,10 @@
<a href="#" class="dropdown-menu dropdown-menu-link-icon"><i class="fa fa-cog fa-fw"></i><i class="fa fa-caret-down"></i></a>
<ul>
<li>
- <i class="fa fa-edit fa-fw"></i>
- <?= $this->url->link(t('Edit'), 'TaskInternalLinkController', 'edit', array('link_id' => $link['id'], 'task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'popover') ?>
+ <?= $this->modal->medium('edit', t('Edit'), 'TaskInternalLinkController', 'edit', array('link_id' => $link['id'], 'task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
<li>
- <i class="fa fa-trash-o fa-fw"></i>
- <?= $this->url->link(t('Remove'), 'TaskInternalLinkController', 'confirm', array('link_id' => $link['id'], 'task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'popover') ?>
+ <?= $this->modal->confirm('trash-o', t('Remove'), 'TaskInternalLinkController', 'confirm', array('link_id' => $link['id'], 'task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
</ul>
</div>
diff --git a/app/Template/task_modification/show.php b/app/Template/task_modification/show.php
index 734b247a..710abedf 100644
--- a/app/Template/task_modification/show.php
+++ b/app/Template/task_modification/show.php
@@ -1,44 +1,42 @@
<div class="page-header">
<h2><?= $this->text->e($project['name']) ?> &gt; <?= $this->text->e($task['title']) ?></h2>
</div>
-<form class="popover-form" method="post" action="<?= $this->url->href('TaskModificationController', 'update', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>" autocomplete="off">
+<form method="post" action="<?= $this->url->href('TaskModificationController', 'update', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>" autocomplete="off">
<?= $this->form->csrf() ?>
<?= $this->form->hidden('id', $values) ?>
<?= $this->form->hidden('project_id', $values) ?>
- <div class="form-columns">
- <div class="form-column">
- <?= $this->task->selectTitle($values, $errors) ?>
- <?= $this->task->selectDescription($values, $errors) ?>
- <?= $this->task->selectTags($project, $tags) ?>
+ <div class="task-form-container">
+ <div class="task-form-main-column">
+ <?= $this->task->renderTitleField($values, $errors) ?>
+ <?= $this->task->renderDescriptionField($values, $errors) ?>
+ <?= $this->task->renderTagField($project, $tags) ?>
<?= $this->hook->render('template:task:form:first-column', array('values' => $values, 'errors' => $errors)) ?>
</div>
- <div class="form-column">
- <?= $this->task->selectColor($values) ?>
- <?= $this->task->selectAssignee($users_list, $values, $errors) ?>
- <?= $this->task->selectCategory($categories_list, $values, $errors) ?>
- <?= $this->task->selectPriority($project, $values) ?>
- <?= $this->task->selectScore($values, $errors) ?>
- <?= $this->task->selectReference($values, $errors) ?>
+ <div class="task-form-secondary-column">
+ <?= $this->task->renderColorField($values) ?>
+ <?= $this->task->renderAssigneeField($users_list, $values, $errors) ?>
+ <?= $this->task->renderCategoryField($categories_list, $values, $errors) ?>
+ <?= $this->task->renderPriorityField($project, $values) ?>
<?= $this->hook->render('template:task:form:second-column', array('values' => $values, 'errors' => $errors)) ?>
</div>
- <div class="form-column">
- <?= $this->task->selectTimeEstimated($values, $errors) ?>
- <?= $this->task->selectTimeSpent($values, $errors) ?>
- <?= $this->task->selectStartDate($values, $errors) ?>
- <?= $this->task->selectDueDate($values, $errors) ?>
+ <div class="task-form-secondary-column">
+ <?= $this->task->renderDueDateField($values, $errors) ?>
+ <?= $this->task->renderStartDateField($values, $errors) ?>
+ <?= $this->task->renderTimeEstimatedField($values, $errors) ?>
+ <?= $this->task->renderTimeSpentField($values, $errors) ?>
+ <?= $this->task->renderScoreField($values, $errors) ?>
+ <?= $this->task->renderReferenceField($values, $errors) ?>
<?= $this->hook->render('template:task:form:third-column', array('values' => $values, 'errors' => $errors)) ?>
</div>
- </div>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue" tabindex="15"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?>
+ <div class="task-form-bottom">
+ <?= $this->modal->submitButtons() ?>
+ </div>
</div>
</form>
diff --git a/app/Template/task_move_position/show.php b/app/Template/task_move_position/show.php
index 5fadff09..a73be785 100644
--- a/app/Template/task_move_position/show.php
+++ b/app/Template/task_move_position/show.php
@@ -2,41 +2,18 @@
<h2><?= t('Move task to another position on the board') ?></h2>
</div>
-<script type="x/template" id="template-task-move-position">
- <?= $this->form->label(t('Swimlane'), 'swimlane') ?>
- <select v-model="swimlaneId" @change="onChangeSwimlane()" id="form-swimlane">
- <option v-for="swimlane in board" v-bind:value="swimlane.id">
- {{ swimlane.name }}
- </option>
- </select>
+<form>
- <div v-if="columns.length > 0">
- <?= $this->form->label(t('Column'), 'column') ?>
- <select v-model="columnId" @change="onChangeColumn()" id="form-column">
- <option v-for="column in columns" v-bind:value="column.id">
- {{ column.title }}
- </option>
- </select>
- </div>
+<?= $this->app->component('task-move-position', array(
+ 'saveUrl' => $this->url->href('TaskMovePositionController', 'save', array('task_id' => $task['id'], 'project_id' => $task['project_id'])),
+ 'board' => $board,
+ 'swimlaneLabel' => t('Swimlane'),
+ 'columnLabel' => t('Column'),
+ 'positionLabel' => t('Position'),
+ 'beforeLabel' => t('Insert before this task'),
+ 'afterLabel' => t('Insert after this task'),
+)) ?>
- <div v-if="tasks.length > 0">
- <?= $this->form->label(t('Position'), 'position') ?>
- <select v-model="position" id="form-position">
- <option v-for="task in tasks" v-bind:value="task.position">#{{ task.id }} - {{ task.title }}</option>
- </select>
- <label><input type="radio" value="before" v-model="positionChoice"><?= t('Insert before this task') ?></label>
- <label><input type="radio" value="after" v-model="positionChoice"><?= t('Insert after this task') ?></label>
- </div>
+<?= $this->modal->submitButtons() ?>
- <submit-cancel
- label-button="<?= t('Save') ?>"
- label-or="<?= t('or') ?>"
- label-cancel="<?= t('cancel') ?>"
- :callback="onSubmit">
- </submit-cancel>
-</script>
-
-<task-move-position
- save-url="<?= $this->url->href('TaskMovePositionController', 'save', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>"
- :board='<?= json_encode($board, JSON_HEX_APOS) ?>'
-></task-move-position>
+</form>
diff --git a/app/Template/task_recurrence/edit.php b/app/Template/task_recurrence/edit.php
index 09d14826..0db27d46 100644
--- a/app/Template/task_recurrence/edit.php
+++ b/app/Template/task_recurrence/edit.php
@@ -3,7 +3,7 @@
</div>
<?php if ($task['recurrence_status'] != \Kanboard\Model\TaskModel::RECURRING_STATUS_NONE): ?>
-<div class="listing">
+<div class="panel">
<?= $this->render('task_recurrence/info', array(
'task' => $task,
'recurrence_trigger_list' => $recurrence_trigger_list,
@@ -15,7 +15,7 @@
<?php if ($task['recurrence_status'] != \Kanboard\Model\TaskModel::RECURRING_STATUS_PROCESSED): ?>
- <form class="popover-form" method="post" action="<?= $this->url->href('TaskRecurrenceController', 'update', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>" autocomplete="off">
+ <form method="post" action="<?= $this->url->href('TaskRecurrenceController', 'update', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>" autocomplete="off">
<?= $this->form->csrf() ?>
@@ -37,11 +37,7 @@
<?= $this->form->label(t('Base date to calculate new due date'), 'recurrence_basedate') ?>
<?= $this->form->select('recurrence_basedate', $recurrence_basedate_list, $values, $errors) ?>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->submitButtons() ?>
</form>
<?php endif ?>
diff --git a/app/Template/task_status/close.php b/app/Template/task_status/close.php
index 2d7b0ce5..0bf3c8e3 100644
--- a/app/Template/task_status/close.php
+++ b/app/Template/task_status/close.php
@@ -7,9 +7,9 @@
<?= t('Do you really want to close the task "%s" as well as all subtasks?', $task['title']) ?>
</p>
- <div class="form-actions">
- <?= $this->url->link(t('Yes'), 'TaskStatusController', 'close', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'confirmation' => 'yes'), true, 'btn btn-red popover-link') ?>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->confirmButtons(
+ 'TaskStatusController',
+ 'close',
+ array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'confirmation' => 'yes')
+ ) ?>
</div>
diff --git a/app/Template/task_status/open.php b/app/Template/task_status/open.php
index 242b5db5..42765e34 100644
--- a/app/Template/task_status/open.php
+++ b/app/Template/task_status/open.php
@@ -7,9 +7,9 @@
<?= t('Do you really want to open this task: "%s"?', $task['title']) ?>
</p>
- <div class="form-actions">
- <?= $this->url->link(t('Yes'), 'TaskStatusController', 'open', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'confirmation' => 'yes'), true, 'btn btn-red popover-link') ?>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->confirmButtons(
+ 'TaskStatusController',
+ 'open',
+ array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'confirmation' => 'yes')
+ ) ?>
</div>
diff --git a/app/Template/task_suppression/remove.php b/app/Template/task_suppression/remove.php
index 5d0f7720..4b0666d8 100644
--- a/app/Template/task_suppression/remove.php
+++ b/app/Template/task_suppression/remove.php
@@ -7,9 +7,9 @@
<?= t('Do you really want to remove this task: "%s"?', $this->text->e($task['title'])) ?>
</p>
- <div class="form-actions">
- <?= $this->url->link(t('Yes'), 'TaskSuppressionController', 'remove', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'redirect' => $redirect), true, 'btn btn-red popover-link') ?>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->confirmButtons(
+ 'TaskSuppressionController',
+ 'remove',
+ array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'redirect' => $redirect)
+ ) ?>
</div>
diff --git a/app/Template/twofactor/disable.php b/app/Template/twofactor/disable.php
index bc419181..c44c450f 100644
--- a/app/Template/twofactor/disable.php
+++ b/app/Template/twofactor/disable.php
@@ -7,8 +7,9 @@
<?= t('Do you really want to disable the two factor authentication for this user: "%s"?', $user['name'] ?: $user['username']) ?>
</p>
- <div class="form-actions">
- <?= $this->url->link(t('Yes'), 'TwoFactorController', 'disable', array('user_id' => $user['id'], 'disable' => 'yes'), true, 'btn btn-red') ?>
- <?= t('or') ?> <?= $this->url->link(t('cancel'), 'UserViewController', 'show', array('user_id' => $user['id'])) ?>
- </div>
+ <?= $this->modal->confirmButtons(
+ 'TwoFactorController',
+ 'disable',
+ array('user_id' => $user['id'], 'disable' => 'yes')
+ ) ?>
</div>
diff --git a/app/Template/twofactor/show.php b/app/Template/twofactor/show.php
index 0aeef427..a5bdeccb 100644
--- a/app/Template/twofactor/show.php
+++ b/app/Template/twofactor/show.php
@@ -3,7 +3,7 @@
</div>
<?php if (! empty($secret) || ! empty($qrcode_url) || ! empty($key_url)): ?>
-<div class="listing">
+<div class="panel">
<?php if (! empty($secret)): ?>
<p><?= t('Secret key: ') ?><strong><?= $this->text->e($secret) ?></strong></p>
<?php endif ?>
diff --git a/app/Template/user_api_access/show.php b/app/Template/user_api_access/show.php
new file mode 100644
index 00000000..3d58e0d5
--- /dev/null
+++ b/app/Template/user_api_access/show.php
@@ -0,0 +1,17 @@
+<div class="page-header">
+ <h2><?= t('API User Access') ?></h2>
+</div>
+
+<p class="alert">
+ <?php if (empty($user['api_access_token'])): ?>
+ <?= t('No personal API access token registered.') ?>
+ <?php else: ?>
+ <?= t('Your personal API access token is "%s"', $user['api_access_token']) ?>
+ <?php endif ?>
+</p>
+
+<?php if (! empty($user['api_access_token'])): ?>
+ <?= $this->url->link(t('Remove your token'), 'UserApiAccessController', 'remove', array('user_id' => $user['id']), true, 'btn btn-red') ?>
+<?php endif ?>
+
+<?= $this->url->link(t('Generate a new token'), 'UserApiAccessController', 'generate', array('user_id' => $user['id']), true, 'btn btn-blue') ?>
diff --git a/app/Template/user_creation/remote.php b/app/Template/user_creation/remote.php
deleted file mode 100644
index 41d0d3c7..00000000
--- a/app/Template/user_creation/remote.php
+++ /dev/null
@@ -1,51 +0,0 @@
-<div class="page-header">
- <h2><?= t('New remote user') ?></h2>
-</div>
-<form class="popover-form" method="post" action="<?= $this->url->href('UserCreationController', 'save') ?>" autocomplete="off">
- <?= $this->form->csrf() ?>
- <?= $this->form->hidden('is_ldap_user', array('is_ldap_user' => 1)) ?>
-
- <div class="form-columns">
- <div class="form-column">
- <?= $this->form->label(t('Username'), 'username') ?>
- <?= $this->form->text('username', $values, $errors, array('autofocus', 'required', 'maxlength="50"')) ?>
-
- <?= $this->form->label(t('Name'), 'name') ?>
- <?= $this->form->text('name', $values, $errors) ?>
-
- <?= $this->form->label(t('Email'), 'email') ?>
- <?= $this->form->email('email', $values, $errors) ?>
-
- <?= $this->hook->render('template:user:create-remote:form', array('values' => $values, 'errors' => $errors)) ?>
- </div>
-
- <div class="form-column">
- <?= $this->form->label(t('Add project member'), 'project_id') ?>
- <?= $this->form->select('project_id', $projects, $values, $errors) ?>
-
- <?= $this->form->label(t('Timezone'), 'timezone') ?>
- <?= $this->form->select('timezone', $timezones, $values, $errors) ?>
-
- <?= $this->form->label(t('Language'), 'language') ?>
- <?= $this->form->select('language', $languages, $values, $errors) ?>
-
- <?= $this->form->label(t('Role'), 'role') ?>
- <?= $this->form->select('role', $roles, $values, $errors) ?>
-
- <?= $this->form->checkbox('notifications_enabled', t('Enable email notifications'), 1, isset($values['notifications_enabled']) && $values['notifications_enabled'] == 1 ? true : false) ?>
- <?= $this->form->checkbox('disable_login_form', t('Disallow login form'), 1, isset($values['disable_login_form']) && $values['disable_login_form'] == 1) ?>
- </div>
- </div>
-
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'UserListController', 'show', array(), false, 'close-popover') ?>
- </div>
-</form>
-<div class="alert alert-info">
- <ul>
- <li><?= t('Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.') ?></li>
- <li><?= t('If you check the box "Disallow login form", credentials entered in the login form will be ignored.') ?></li>
- </ul>
-</div>
diff --git a/app/Template/user_creation/show.php b/app/Template/user_creation/show.php
new file mode 100644
index 00000000..597dce55
--- /dev/null
+++ b/app/Template/user_creation/show.php
@@ -0,0 +1,67 @@
+<div class="page-header">
+ <h2><?= t('New User') ?></h2>
+</div>
+<form method="post" action="<?= $this->url->href('UserCreationController', 'save') ?>" autocomplete="off">
+ <?= $this->form->csrf() ?>
+
+ <div class="form-columns">
+ <div class="form-column">
+ <fieldset>
+ <legend><?= t('Profile') ?></legend>
+
+ <?= $this->form->label(t('Username'), 'username') ?>
+ <?= $this->form->text('username', $values, $errors, array('autofocus', 'required', 'maxlength="50"')) ?>
+
+ <?= $this->form->label(t('Name'), 'name') ?>
+ <?= $this->form->text('name', $values, $errors) ?>
+
+ <?= $this->form->label(t('Email'), 'email') ?>
+ <?= $this->form->email('email', $values, $errors) ?>
+ </fieldset>
+
+ <fieldset>
+ <legend><?= t('Authentication') ?></legend>
+ <?= $this->form->checkbox('is_ldap_user', t('Remote user'), 1, isset($values['is_ldap_user']) && $values['is_ldap_user'] == 1) ?>
+ <p class="form-help"><?= t('If checked, this user will use a third-party system for authentication.') ?></p>
+
+ <?= $this->form->label(t('Password'), 'password') ?>
+ <?= $this->form->password('password', $values, $errors) ?>
+ <p class="form-help"><?= t('The password is necessary only for local users.') ?></p>
+
+ <?= $this->form->label(t('Confirmation'), 'confirmation') ?>
+ <?= $this->form->password('confirmation', $values, $errors) ?>
+ </fieldset>
+ </div>
+
+ <div class="form-column">
+ <fieldset>
+ <legend><?= t('Security') ?></legend>
+
+ <?= $this->form->label(t('Role'), 'role') ?>
+ <?= $this->form->select('role', $roles, $values, $errors) ?>
+
+ <?= $this->form->checkbox('disable_login_form', t('Disallow login form'), 1, isset($values['disable_login_form']) && $values['disable_login_form'] == 1) ?>
+ </fieldset>
+
+ <fieldset>
+ <legend><?= t('Preferences') ?></legend>
+ <?= $this->form->label(t('Timezone'), 'timezone') ?>
+ <?= $this->form->select('timezone', $timezones, $values, $errors) ?>
+
+ <?= $this->form->label(t('Language'), 'language') ?>
+ <?= $this->form->select('language', $languages, $values, $errors) ?>
+
+ <?= $this->form->checkbox('notifications_enabled', t('Enable email notifications'), 1, isset($values['notifications_enabled']) && $values['notifications_enabled'] == 1 ? true : false) ?>
+ </fieldset>
+
+ <fieldset>
+ <legend><?= t('Projects') ?></legend>
+
+ <?= $this->form->label(t('Add this person to this project'), 'project_id') ?>
+ <?= $this->form->select('project_id', $projects, $values, $errors) ?>
+ </fieldset>
+ </div>
+ </div>
+
+ <?= $this->modal->submitButtons() ?>
+</form>
diff --git a/app/Template/user_credential/authentication.php b/app/Template/user_credential/authentication.php
index fbe2e915..98c0d758 100644
--- a/app/Template/user_credential/authentication.php
+++ b/app/Template/user_credential/authentication.php
@@ -4,13 +4,15 @@
<form method="post" action="<?= $this->url->href('UserCredentialController', 'saveAuthentication', array('user_id' => $user['id'])) ?>" autocomplete="off">
<?= $this->form->csrf() ?>
- <?= $this->form->hidden('id', $values) ?>
- <?= $this->form->hidden('username', $values) ?>
+ <fieldset>
+ <?= $this->form->hidden('id', $values) ?>
+ <?= $this->form->hidden('username', $values) ?>
- <?= $this->hook->render('template:user:authentication:form', array('values' => $values, 'errors' => $errors, 'user' => $user)) ?>
+ <?= $this->hook->render('template:user:authentication:form', array('values' => $values, 'errors' => $errors, 'user' => $user)) ?>
- <?= $this->form->checkbox('is_ldap_user', t('Remote user'), 1, isset($values['is_ldap_user']) && $values['is_ldap_user'] == 1) ?>
- <?= $this->form->checkbox('disable_login_form', t('Disallow login form'), 1, isset($values['disable_login_form']) && $values['disable_login_form'] == 1) ?>
+ <?= $this->form->checkbox('is_ldap_user', t('Remote user'), 1, isset($values['is_ldap_user']) && $values['is_ldap_user'] == 1) ?>
+ <?= $this->form->checkbox('disable_login_form', t('Disallow login form'), 1, isset($values['disable_login_form']) && $values['disable_login_form'] == 1) ?>
+ </fieldset>
<div class="form-actions">
<button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
diff --git a/app/Template/user_credential/password.php b/app/Template/user_credential/password.php
index 5a6e4403..bd7a47da 100644
--- a/app/Template/user_credential/password.php
+++ b/app/Template/user_credential/password.php
@@ -6,14 +6,16 @@
<?= $this->form->hidden('id', $values) ?>
<?= $this->form->csrf() ?>
- <?= $this->form->label(t('Current password for the user "%s"', $this->user->getFullname()), 'current_password') ?>
- <?= $this->form->password('current_password', $values, $errors) ?>
+ <fieldset>
+ <?= $this->form->label(t('Current password for the user "%s"', $this->user->getFullname()), 'current_password') ?>
+ <?= $this->form->password('current_password', $values, $errors) ?>
- <?= $this->form->label(t('New password for the user "%s"', $this->user->getFullname($user)), 'password') ?>
- <?= $this->form->password('password', $values, $errors) ?>
+ <?= $this->form->label(t('New password for the user "%s"', $this->user->getFullname($user)), 'password') ?>
+ <?= $this->form->password('password', $values, $errors) ?>
- <?= $this->form->label(t('Confirmation'), 'confirmation') ?>
- <?= $this->form->password('confirmation', $values, $errors) ?>
+ <?= $this->form->label(t('Confirmation'), 'confirmation') ?>
+ <?= $this->form->password('confirmation', $values, $errors) ?>
+ </fieldset>
<div class="form-actions">
<button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
diff --git a/app/Template/user_import/show.php b/app/Template/user_import/show.php
index 663f107e..3b0e599c 100644
--- a/app/Template/user_import/show.php
+++ b/app/Template/user_import/show.php
@@ -2,8 +2,7 @@
<h2><?= t('Import users from CSV file') ?></h2>
<ul>
<li>
- <i class="fa fa-download fa-fw"></i>
- <?= $this->url->link(t('Download CSV template'), 'UserImportController', 'template') ?>
+ <?= $this->url->icon('download', t('Download CSV template'), 'UserImportController', 'template') ?>
</li>
</ul>
</div>
@@ -33,9 +32,5 @@
<p class="form-help"><?= t('Maximum size: ') ?><?= is_integer($max_size) ? $this->text->bytes($max_size) : $max_size ?></p>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Import') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'UserListController', 'show', array(), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->submitButtons(array('submitLabel' => t('Import'))) ?>
</form>
diff --git a/app/Template/user_invite/email.php b/app/Template/user_invite/email.php
new file mode 100644
index 00000000..674e4a84
--- /dev/null
+++ b/app/Template/user_invite/email.php
@@ -0,0 +1,12 @@
+<p>
+ <?= t('You have been invited to register on Kanboard.') ?>
+</p>
+
+<p>
+ <?= $this->url->absoluteLink(t('Click here to join your team'), 'UserInviteController', 'signup', array('token' => $token)) ?>
+</p>
+
+<?php if ($this->app->config('application_url')): ?>
+ <hr>
+ <a href="<?= $this->app->config('application_url') ?>">Kanboard</a>
+<?php endif ?>
diff --git a/app/Template/user_invite/show.php b/app/Template/user_invite/show.php
new file mode 100644
index 00000000..9d822248
--- /dev/null
+++ b/app/Template/user_invite/show.php
@@ -0,0 +1,15 @@
+<div class="page-header">
+ <h2><?= t('Invite people') ?></h2>
+</div>
+<form method="post" action="<?= $this->url->href('UserInviteController', 'save') ?>" autocomplete="off">
+ <?= $this->form->csrf() ?>
+
+ <?= $this->form->label(t('Emails'), 'emails') ?>
+ <?= $this->form->textarea('emails', $values, $errors, array('required', 'autofocus')) ?>
+ <p class="form-help"><?= t('Enter one email address by line.') ?></p>
+
+ <?= $this->form->label(t('Add these people to this project'), 'project_id') ?>
+ <?= $this->form->select('project_id', $projects, $values, $errors) ?>
+
+ <?= $this->modal->submitButtons() ?>
+</form>
diff --git a/app/Template/user_creation/local.php b/app/Template/user_invite/signup.php
index 059a0114..51edbab7 100644
--- a/app/Template/user_creation/local.php
+++ b/app/Template/user_invite/signup.php
@@ -1,11 +1,13 @@
-<div class="page-header">
- <h2><?= t('New local user') ?></h2>
-</div>
-<form class="popover-form" method="post" action="<?= $this->url->href('UserCreationController', 'save') ?>" autocomplete="off">
- <?= $this->form->csrf() ?>
+<div class="form-login">
+ <div class="page-header">
+ <h2><?= t('Sign-up') ?></h2>
+ </div>
+ <form method="post" action="<?= $this->url->href('UserInviteController', 'register', array('token' => $token)) ?>" autocomplete="off">
+ <?= $this->form->csrf() ?>
+
+ <fieldset>
+ <legend><?= t('Profile') ?></legend>
- <div class="form-columns">
- <div class="form-column">
<?= $this->form->label(t('Username'), 'username') ?>
<?= $this->form->text('username', $values, $errors, array('autofocus', 'required', 'maxlength="50"')) ?>
@@ -13,18 +15,20 @@
<?= $this->form->text('name', $values, $errors) ?>
<?= $this->form->label(t('Email'), 'email') ?>
- <?= $this->form->email('email', $values, $errors) ?>
+ <?= $this->form->email('email', $values, $errors, array('required')) ?>
+ </fieldset>
+ <fieldset>
+ <legend><?= t('Credentials') ?></legend>
<?= $this->form->label(t('Password'), 'password') ?>
<?= $this->form->password('password', $values, $errors, array('required')) ?>
<?= $this->form->label(t('Confirmation'), 'confirmation') ?>
<?= $this->form->password('confirmation', $values, $errors, array('required')) ?>
- </div>
+ </fieldset>
- <div class="form-column">
- <?= $this->form->label(t('Add project member'), 'project_id') ?>
- <?= $this->form->select('project_id', $projects, $values, $errors) ?>
+ <fieldset>
+ <legend><?= t('Preferences') ?></legend>
<?= $this->form->label(t('Timezone'), 'timezone') ?>
<?= $this->form->select('timezone', $timezones, $values, $errors) ?>
@@ -32,16 +36,11 @@
<?= $this->form->label(t('Language'), 'language') ?>
<?= $this->form->select('language', $languages, $values, $errors) ?>
- <?= $this->form->label(t('Role'), 'role') ?>
- <?= $this->form->select('role', $roles, $values, $errors) ?>
-
<?= $this->form->checkbox('notifications_enabled', t('Enable email notifications'), 1, isset($values['notifications_enabled']) && $values['notifications_enabled'] == 1 ? true : false) ?>
- </div>
- </div>
+ </fieldset>
- <div class="form-actions">
- <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'UserListController', 'show', array(), false, 'close-popover') ?>
- </div>
-</form>
+ <div class="form-actions">
+ <button class="btn btn-blue"><?= t('Sign-up') ?></button>
+ </div>
+ </form>
+</div> \ No newline at end of file
diff --git a/app/Template/user_list/dropdown.php b/app/Template/user_list/dropdown.php
index 9e90c230..d18f20aa 100644
--- a/app/Template/user_list/dropdown.php
+++ b/app/Template/user_list/dropdown.php
@@ -2,25 +2,21 @@
<a href="#" class="dropdown-menu dropdown-menu-link-icon"><i class="fa fa-cog fa-fw"></i><i class="fa fa-caret-down"></i></a>
<ul>
<li>
- <i class="fa fa-user fa-fw"></i>
- <?= $this->url->link(t('View profile'), 'UserViewController', 'show', array('user_id' => $user['id'])) ?>
+ <?= $this->url->icon('user', t('View profile'), 'UserViewController', 'show', array('user_id' => $user['id'])) ?>
</li>
<?php if ($user['is_active'] == 1 && $this->user->hasAccess('UserStatusController', 'disable') && ! $this->user->isCurrentUser($user['id'])): ?>
<li>
- <i class="fa fa-times fa-fw"></i>
- <?= $this->url->link(t('Disable'), 'UserStatusController', 'confirmDisable', array('user_id' => $user['id']), false, 'popover') ?>
+ <?= $this->modal->confirm('times', t('Disable'), 'UserStatusController', 'confirmDisable', array('user_id' => $user['id'])) ?>
</li>
<?php endif ?>
<?php if ($user['is_active'] == 0 && $this->user->hasAccess('UserStatusController', 'enable') && ! $this->user->isCurrentUser($user['id'])): ?>
<li>
- <i class="fa fa-check-square-o fa-fw"></i>
- <?= $this->url->link(t('Enable'), 'UserStatusController', 'confirmEnable', array('user_id' => $user['id']), false, 'popover') ?>
+ <?= $this->modal->confirm('check-square-o', t('Enable'), 'UserStatusController', 'confirmEnable', array('user_id' => $user['id'])) ?>
</li>
<?php endif ?>
<?php if ($this->user->hasAccess('UserStatusController', 'remove') && ! $this->user->isCurrentUser($user['id'])): ?>
<li>
- <i class="fa fa-trash-o fa-fw"></i>
- <?= $this->url->link(t('Remove'), 'UserStatusController', 'confirmRemove', array('user_id' => $user['id']), false, 'popover') ?>
+ <?= $this->modal->confirm('trash-o', t('Remove'), 'UserStatusController', 'confirmRemove', array('user_id' => $user['id'])) ?>
</li>
<?php endif ?>
</ul>
diff --git a/app/Template/user_list/show.php b/app/Template/user_list/show.php
index 5e285c89..e83895ea 100644
--- a/app/Template/user_list/show.php
+++ b/app/Template/user_list/show.php
@@ -2,10 +2,18 @@
<div class="page-header">
<?php if ($this->user->hasAccess('UserCreationController', 'show')): ?>
<ul>
- <li><i class="fa fa-plus fa-fw"></i><?= $this->url->link(t('New local user'), 'UserCreationController', 'show', array(), false, 'popover') ?></li>
- <li><i class="fa fa-plus fa-fw"></i><?= $this->url->link(t('New remote user'), 'UserCreationController', 'show', array('remote' => 1), false, 'popover') ?></li>
- <li><i class="fa fa-upload fa-fw"></i><?= $this->url->link(t('Import'), 'UserImportController', 'show', array(), false, 'popover') ?></li>
- <li><i class="fa fa-users fa-fw"></i><?= $this->url->link(t('View all groups'), 'GroupListController', 'index') ?></li>
+ <li>
+ <?= $this->modal->medium('plus', t('New user'), 'UserCreationController', 'show') ?>
+ </li>
+ <li>
+ <?= $this->modal->medium('paper-plane', t('Invite people'), 'UserInviteController', 'show') ?>
+ </li>
+ <li>
+ <?= $this->modal->medium('upload', t('Import'), 'UserImportController', 'show') ?>
+ </li>
+ <li>
+ <?= $this->url->icon('users', t('View all groups'), 'GroupListController', 'index') ?>
+ </li>
</ul>
<?php endif ?>
</div>
diff --git a/app/Template/user_modification/show.php b/app/Template/user_modification/show.php
index 506c9161..d3f3e0cc 100644
--- a/app/Template/user_modification/show.php
+++ b/app/Template/user_modification/show.php
@@ -2,29 +2,36 @@
<h2><?= t('Edit user') ?></h2>
</div>
<form method="post" action="<?= $this->url->href('UserModificationController', 'save', array('user_id' => $user['id'])) ?>" autocomplete="off">
-
<?= $this->form->csrf() ?>
-
<?= $this->form->hidden('id', $values) ?>
- <?= $this->form->label(t('Username'), 'username') ?>
- <?= $this->form->text('username', $values, $errors, array('required', isset($values['is_ldap_user']) && $values['is_ldap_user'] == 1 ? 'readonly' : '', 'maxlength="50"')) ?>
+ <fieldset>
+ <legend><?= t('Profile') ?></legend>
+ <?= $this->form->label(t('Username'), 'username') ?>
+ <?= $this->form->text('username', $values, $errors, array('required', isset($values['is_ldap_user']) && $values['is_ldap_user'] == 1 ? 'readonly' : '', 'maxlength="50"')) ?>
- <?= $this->form->label(t('Name'), 'name') ?>
- <?= $this->form->text('name', $values, $errors, array($this->user->hasAccess('UserModificationController', 'show/edit_name') ? '' : 'readonly')) ?>
+ <?= $this->form->label(t('Name'), 'name') ?>
+ <?= $this->form->text('name', $values, $errors, array($this->user->hasAccess('UserModificationController', 'show/edit_name') ? '' : 'readonly')) ?>
- <?= $this->form->label(t('Email'), 'email') ?>
- <?= $this->form->email('email', $values, $errors, array($this->user->hasAccess('UserModificationController', 'show/edit_email') ? '' : 'readonly')) ?>
+ <?= $this->form->label(t('Email'), 'email') ?>
+ <?= $this->form->email('email', $values, $errors, array($this->user->hasAccess('UserModificationController', 'show/edit_email') ? '' : 'readonly')) ?>
+ </fieldset>
- <?= $this->form->label(t('Timezone'), 'timezone') ?>
- <?= $this->form->select('timezone', $timezones, $values, $errors, array($this->user->hasAccess('UserModificationController', 'show/edit_timezone') ? '' : 'disabled')) ?>
+ <fieldset>
+ <legend><?= t('Preferences') ?></legend>
+ <?= $this->form->label(t('Timezone'), 'timezone') ?>
+ <?= $this->form->select('timezone', $timezones, $values, $errors, array($this->user->hasAccess('UserModificationController', 'show/edit_timezone') ? '' : 'disabled')) ?>
- <?= $this->form->label(t('Language'), 'language') ?>
- <?= $this->form->select('language', $languages, $values, $errors, array($this->user->hasAccess('UserModificationController', 'show/edit_language') ? '' : 'disabled')) ?>
+ <?= $this->form->label(t('Language'), 'language') ?>
+ <?= $this->form->select('language', $languages, $values, $errors, array($this->user->hasAccess('UserModificationController', 'show/edit_language') ? '' : 'disabled')) ?>
+ </fieldset>
<?php if ($this->user->isAdmin()): ?>
- <?= $this->form->label(t('Role'), 'role') ?>
+ <fieldset>
+ <legend><?= t('Security') ?></legend>
+ <?= $this->form->label(t('Application role'), 'role') ?>
<?= $this->form->select('role', $roles, $values, $errors) ?>
+ </fieldset>
<?php endif ?>
<div class="form-actions">
diff --git a/app/Template/user_status/disable.php b/app/Template/user_status/disable.php
index d30b0c20..1309b080 100644
--- a/app/Template/user_status/disable.php
+++ b/app/Template/user_status/disable.php
@@ -5,9 +5,9 @@
<div class="confirm">
<p class="alert alert-info"><?= t('Do you really want to disable this user: "%s"?', $user['name'] ?: $user['username']) ?></p>
- <div class="form-actions">
- <?= $this->url->link(t('Yes'), 'UserStatusController', 'disable', array('user_id' => $user['id']), true, 'btn btn-red') ?>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'UserListController', 'show', array(), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->confirmButtons(
+ 'UserStatusController',
+ 'disable',
+ array('user_id' => $user['id'])
+ ) ?>
</div>
diff --git a/app/Template/user_status/enable.php b/app/Template/user_status/enable.php
index 29d25eee..2413739e 100644
--- a/app/Template/user_status/enable.php
+++ b/app/Template/user_status/enable.php
@@ -5,9 +5,9 @@
<div class="confirm">
<p class="alert alert-info"><?= t('Do you really want to enable this user: "%s"?', $user['name'] ?: $user['username']) ?></p>
- <div class="form-actions">
- <?= $this->url->link(t('Yes'), 'UserStatusController', 'enable', array('user_id' => $user['id']), true, 'btn btn-red') ?>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'UserListController', 'show', array(), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->confirmButtons(
+ 'UserStatusController',
+ 'enable',
+ array('user_id' => $user['id'])
+ ) ?>
</div>
diff --git a/app/Template/user_status/remove.php b/app/Template/user_status/remove.php
index 2b8f2df5..6cd3f63a 100644
--- a/app/Template/user_status/remove.php
+++ b/app/Template/user_status/remove.php
@@ -5,9 +5,9 @@
<div class="confirm">
<p class="alert alert-info"><?= t('Do you really want to remove this user: "%s"?', $user['name'] ?: $user['username']) ?></p>
- <div class="form-actions">
- <?= $this->url->link(t('Yes'), 'UserStatusController', 'remove', array('user_id' => $user['id']), true, 'btn btn-red') ?>
- <?= t('or') ?>
- <?= $this->url->link(t('cancel'), 'UserListController', 'show', array(), false, 'close-popover') ?>
- </div>
+ <?= $this->modal->confirmButtons(
+ 'UserStatusController',
+ 'remove',
+ array('user_id' => $user['id'])
+ ) ?>
</div>
diff --git a/app/Template/user_view/layout.php b/app/Template/user_view/layout.php
index c3604b99..8f24adcc 100644
--- a/app/Template/user_view/layout.php
+++ b/app/Template/user_view/layout.php
@@ -2,11 +2,18 @@
<div class="page-header">
<?php if ($this->user->hasAccess('UserCreationController', 'show')): ?>
<ul>
- <li><i class="fa fa-user fa-fw"></i><?= $this->url->link(t('All users'), 'UserListController', 'show') ?></li>
- <li><i class="fa fa-plus fa-fw"></i><?= $this->url->link(t('New local user'), 'UserCreationController', 'show', array(), false, 'popover') ?></li>
- <li><i class="fa fa-plus fa-fw"></i><?= $this->url->link(t('New remote user'), 'UserCreationController', 'show', array('remote' => 1), false, 'popover') ?></li>
- <li><i class="fa fa-upload fa-fw"></i><?= $this->url->link(t('Import'), 'UserImportController', 'show', array(), false, 'popover') ?></li>
- <li><i class="fa fa-users fa-fw"></i><?= $this->url->link(t('View all groups'), 'GroupListController', 'index') ?></li>
+ <li>
+ <?= $this->url->icon('user', t('All users'), 'UserListController', 'show') ?>
+ </li>
+ <li>
+ <?= $this->modal->medium('plus', t('New user'), 'UserCreationController', 'show') ?>
+ </li>
+ <li>
+ <?= $this->modal->medium('upload', t('Import'), 'UserImportController', 'show') ?>
+ </li>
+ <li>
+ <?= $this->url->icon('users', t('View all groups'), 'GroupListController', 'index') ?>
+ </li>
</ul>
<?php endif ?>
</div>
diff --git a/app/Template/user_view/profile.php b/app/Template/user_view/profile.php
index 9c9d3282..486ca428 100644
--- a/app/Template/user_view/profile.php
+++ b/app/Template/user_view/profile.php
@@ -1,9 +1,11 @@
<section id="main">
<br>
<?= $this->avatar->render($user['id'], $user['username'], $user['name'], $user['email'], $user['avatar_path']) ?>
- <ul class="listing">
- <li><?= t('Username:') ?> <strong><?= $this->text->e($user['username']) ?></strong></li>
- <li><?= t('Name:') ?> <strong><?= $this->text->e($user['name']) ?: t('None') ?></strong></li>
- <li><?= t('Email:') ?> <strong><?= $this->text->e($user['email']) ?: t('None') ?></strong></li>
- </ul>
-</section> \ No newline at end of file
+ <div class="panel">
+ <ul>
+ <li><?= t('Login:') ?> <strong><?= $this->text->e($user['username']) ?></strong></li>
+ <li><?= t('Full Name:') ?> <strong><?= $this->text->e($user['name']) ?: t('None') ?></strong></li>
+ <li><?= t('Email:') ?> <strong><?= $this->text->e($user['email']) ?: t('None') ?></strong></li>
+ </ul>
+ </div>
+</section>
diff --git a/app/Template/user_view/share.php b/app/Template/user_view/share.php
index 570b766e..318d98ea 100644
--- a/app/Template/user_view/share.php
+++ b/app/Template/user_view/share.php
@@ -3,10 +3,10 @@
</div>
<?php if (! empty($user['token'])): ?>
- <div class="listing">
+ <div class="panel">
<ul class="no-bullet">
- <li><strong><i class="fa fa-rss-square"></i> <?= $this->url->link(t('RSS feed'), 'FeedController', 'user', array('token' => $user['token']), false, '', '', true) ?></strong></li>
- <li><strong><i class="fa fa-calendar"></i> <?= $this->url->link(t('iCal feed'), 'ICalendarController', 'user', array('token' => $user['token']), false, '', '', true) ?></strong></li>
+ <li><strong><?= $this->url->icon('rss-square', t('RSS feed'), 'FeedController', 'user', array('token' => $user['token']), false, '', '', true) ?></strong></li>
+ <li><strong><?= $this->url->icon('calendar', t('iCal feed'), 'ICalendarController', 'user', array('token' => $user['token']), false, '', '', true) ?></strong></li>
</ul>
</div>
<?= $this->url->link(t('Disable public access'), 'UserViewController', 'share', array('user_id' => $user['id'], 'switch' => 'disable'), true, 'btn btn-red') ?>
diff --git a/app/Template/user_view/show.php b/app/Template/user_view/show.php
index 2f5a73af..e57fd4cd 100644
--- a/app/Template/user_view/show.php
+++ b/app/Template/user_view/show.php
@@ -1,9 +1,9 @@
<div class="page-header">
<h2><?= t('Summary') ?></h2>
</div>
-<ul class="listing">
- <li><?= t('Username:') ?> <strong><?= $this->text->e($user['username']) ?></strong></li>
- <li><?= t('Name:') ?> <strong><?= $this->text->e($user['name']) ?: t('None') ?></strong></li>
+<ul class="panel">
+ <li><?= t('Login:') ?> <strong><?= $this->text->e($user['username']) ?></strong></li>
+ <li><?= t('Full Name:') ?> <strong><?= $this->text->e($user['name']) ?: t('None') ?></strong></li>
<li><?= t('Email:') ?> <strong><?= $this->text->e($user['email']) ?: t('None') ?></strong></li>
<li><?= t('Status:') ?> <strong><?= $user['is_active'] ? t('Active') : t('Inactive') ?></strong></li>
</ul>
@@ -11,7 +11,7 @@
<div class="page-header">
<h2><?= t('Security') ?></h2>
</div>
-<ul class="listing">
+<ul class="panel">
<li><?= t('Role:') ?> <strong><?= $this->user->getRoleName($user['role']) ?></strong></li>
<li><?= t('Account type:') ?> <strong><?= $user['is_ldap_user'] ? t('Remote') : t('Local') ?></strong></li>
<li><?= $user['twofactor_activated'] == 1 ? t('Two factor authentication enabled') : t('Two factor authentication disabled') ?></li>
@@ -29,7 +29,7 @@
<div class="page-header">
<h2><?= t('Preferences') ?></h2>
</div>
-<ul class="listing">
+<ul class="panel">
<li><?= t('Timezone:') ?> <strong><?= $this->text->in($user['timezone'], $timezones) ?></strong></li>
<li><?= t('Language:') ?> <strong><?= $this->text->in($user['language'], $languages) ?></strong></li>
<li><?= t('Notifications:') ?> <strong><?= $user['notifications_enabled'] == 1 ? t('Enabled') : t('Disabled') ?></strong></li>
@@ -40,10 +40,10 @@
<h2><?= t('Public access') ?></h2>
</div>
- <div class="listing">
+ <div class="panel">
<ul class="no-bullet">
- <li><strong><i class="fa fa-rss-square"></i> <?= $this->url->link(t('RSS feed'), 'FeedController', 'user', array('token' => $user['token']), false, '', '', true) ?></strong></li>
- <li><strong><i class="fa fa-calendar"></i> <?= $this->url->link(t('iCal feed'), 'ICalendarController', 'user', array('token' => $user['token']), false, '', '', true) ?></strong></li>
+ <li><strong><?= $this->url->icon('rss-square', t('RSS feed'), 'FeedController', 'user', array('token' => $user['token']), false, '', '', true) ?></strong></li>
+ <li><strong><?= $this->url->icon('calendar', t('iCal feed'), 'ICalendarController', 'user', array('token' => $user['token']), false, '', '', true) ?></strong></li>
</ul>
</div>
<?php endif ?>
diff --git a/app/Template/user_view/sidebar.php b/app/Template/user_view/sidebar.php
index a80daefa..ef494e42 100644
--- a/app/Template/user_view/sidebar.php
+++ b/app/Template/user_view/sidebar.php
@@ -90,6 +90,11 @@
<?= $this->url->link(t('Integrations'), 'UserViewController', 'integrations', array('user_id' => $user['id'])) ?>
</li>
<?php endif ?>
+ <?php if ($this->user->hasAccess('UserApiAccessController', 'show')): ?>
+ <li <?= $this->app->checkMenuSelection('UserApiAccessController', 'show') ?>>
+ <?= $this->url->link(t('API'), 'UserApiAccessController', 'show', array('user_id' => $user['id'])) ?>
+ </li>
+ <?php endif ?>
<?php endif ?>
<?php if ($this->user->hasAccess('UserCredentialController', 'changeAuthentication')): ?>
diff --git a/app/Validator/ProjectValidator.php b/app/Validator/ProjectValidator.php
index 8c6117a4..8d8053a3 100644
--- a/app/Validator/ProjectValidator.php
+++ b/app/Validator/ProjectValidator.php
@@ -28,13 +28,14 @@ class ProjectValidator extends BaseValidator
new Validators\Integer('priority_start', t('This value must be an integer')),
new Validators\Integer('priority_end', t('This value must be an integer')),
new Validators\Integer('is_active', t('This value must be an integer')),
- new Validators\NotEmpty('name', t('This field cannot be empty')),
new Validators\MaxLength('name', t('The maximum length is %d characters', 50), 50),
new Validators\MaxLength('identifier', t('The maximum length is %d characters', 50), 50),
new Validators\MaxLength('start_date', t('The maximum length is %d characters', 10), 10),
new Validators\MaxLength('end_date', t('The maximum length is %d characters', 10), 10),
new Validators\AlphaNumeric('identifier', t('This value must be alphanumeric')) ,
new Validators\Unique('identifier', t('The identifier must be unique'), $this->db->getConnection(), ProjectModel::TABLE),
+ new Validators\Email('email', t('Email address invalid')) ,
+ new Validators\Unique('email', t('The email project must be unique across all projects'), $this->db->getConnection(), ProjectModel::TABLE),
);
}
@@ -47,15 +48,15 @@ class ProjectValidator extends BaseValidator
*/
public function validateCreation(array $values)
{
- $rules = array(
- new Validators\Required('name', t('The project name is required')),
- );
-
if (! empty($values['identifier'])) {
$values['identifier'] = strtoupper($values['identifier']);
}
- $v = new Validator($values, array_merge($this->commonValidationRules(), $rules));
+ $rules = array(
+ new Validators\Required('name', t('The project name is required')),
+ );
+
+ $v = new Validator($values, array_merge($rules, $this->commonValidationRules()));
return array(
$v->execute(),
@@ -77,6 +78,7 @@ class ProjectValidator extends BaseValidator
}
$rules = array(
+ new Validators\NotEmpty('name', t('This field cannot be empty')),
new Validators\Required('id', t('This value is required')),
);
diff --git a/app/Validator/TaskValidator.php b/app/Validator/TaskValidator.php
index e3b0eded..e824dc05 100644
--- a/app/Validator/TaskValidator.php
+++ b/app/Validator/TaskValidator.php
@@ -42,7 +42,7 @@ class TaskValidator extends BaseValidator
new Validators\MaxLength('title', t('The maximum length is %d characters', 200), 200),
new Validators\MaxLength('reference', t('The maximum length is %d characters', 50), 50),
new Validators\Date('date_due', t('Invalid date'), $this->dateParser->getParserFormats()),
- new Validators\Date('date_started', t('Invalid date'), $this->dateParser->getParserFormats()),
+ new Validators\Date('date_started', t('Invalid date'), array($this->dateParser->getUserDateTimeFormat())),
new Validators\Numeric('time_spent', t('This value must be numeric')),
new Validators\Numeric('time_estimated', t('This value must be numeric')),
);
diff --git a/app/Validator/UserValidator.php b/app/Validator/UserValidator.php
index 9911de50..fe402c47 100644
--- a/app/Validator/UserValidator.php
+++ b/app/Validator/UserValidator.php
@@ -25,7 +25,7 @@ class UserValidator extends BaseValidator
return array(
new Validators\MaxLength('role', t('The maximum length is %d characters', 25), 25),
new Validators\MaxLength('username', t('The maximum length is %d characters', 50), 50),
- new Validators\Unique('username', t('The username must be unique'), $this->db->getConnection(), UserModel::TABLE, 'id'),
+ new Validators\Unique('username', t('This username is already taken'), $this->db->getConnection(), UserModel::TABLE, 'id'),
new Validators\Email('email', t('Email address invalid')),
new Validators\Integer('is_ldap_user', t('This value must be an integer')),
);
diff --git a/app/common.php b/app/common.php
index e5490c11..fd55c0bb 100644
--- a/app/common.php
+++ b/app/common.php
@@ -45,8 +45,10 @@ $container->register(new Kanboard\ServiceProvider\GroupProvider());
$container->register(new Kanboard\ServiceProvider\RouteProvider());
$container->register(new Kanboard\ServiceProvider\ActionProvider());
$container->register(new Kanboard\ServiceProvider\ExternalLinkProvider());
+$container->register(new Kanboard\ServiceProvider\ExternalTaskProvider());
$container->register(new Kanboard\ServiceProvider\AvatarProvider());
$container->register(new Kanboard\ServiceProvider\FilterProvider());
+$container->register(new Kanboard\ServiceProvider\FormatterProvider());
$container->register(new Kanboard\ServiceProvider\JobProvider());
$container->register(new Kanboard\ServiceProvider\QueueProvider());
$container->register(new Kanboard\ServiceProvider\ApiProvider());
diff --git a/app/constants.php b/app/constants.php
index 3adb0835..d62bfd3a 100644
--- a/app/constants.php
+++ b/app/constants.php
@@ -35,6 +35,9 @@ defined('LOG_FILE') or define('LOG_FILE', DATA_DIR.DIRECTORY_SEPARATOR.'debug.lo
// Application version
defined('APP_VERSION') or define('APP_VERSION', build_app_version('$Format:%d$', '$Format:%H$'));
+// Run automatically database migrations
+defined('DB_RUN_MIGRATIONS') or define('DB_RUN_MIGRATIONS', true);
+
// Database driver: sqlite, mysql or postgres
defined('DB_DRIVER') or define('DB_DRIVER', 'sqlite');
@@ -95,6 +98,7 @@ defined('REVERSE_PROXY_DEFAULT_DOMAIN') or define('REVERSE_PROXY_DEFAULT_DOMAIN'
defined('REMEMBER_ME_AUTH') or define('REMEMBER_ME_AUTH', true);
// Mail configuration
+defined('MAIL_CONFIGURATION') or define('MAIL_CONFIGURATION', true);
defined('MAIL_FROM') or define('MAIL_FROM', 'notifications@kanboard.local');
defined('MAIL_TRANSPORT') or define('MAIL_TRANSPORT', 'mail');
defined('MAIL_SMTP_HOSTNAME') or define('MAIL_SMTP_HOSTNAME', '');
diff --git a/app/functions.php b/app/functions.php
index 8f0d482c..7cd59c41 100644
--- a/app/functions.php
+++ b/app/functions.php
@@ -53,6 +53,37 @@ function array_column_index(array &$input, $column)
}
/**
+ * Create indexed array from a list of dict with unique values
+ *
+ * $input = [
+ * ['k1' => 1, 'k2' => 2], ['k1' => 3, 'k2' => 4], ['k1' => 1, 'k2' => 5]
+ * ]
+ *
+ * array_column_index_unique($input, 'k1') will returns:
+ *
+ * [
+ * 1 => ['k1' => 1, 'k2' => 2],
+ * 3 => ['k1' => 3, 'k2' => 4],
+ * ]
+ *
+ * @param array $input
+ * @param string $column
+ * @return array
+ */
+function array_column_index_unique(array &$input, $column)
+{
+ $result = array();
+
+ foreach ($input as &$row) {
+ if (isset($row[$column]) && ! isset($result[$row[$column]])) {
+ $result[$row[$column]] = $row;
+ }
+ }
+
+ return $result;
+}
+
+/**
* Sum all values from a single column in the input array
*
* $input = [
@@ -105,6 +136,27 @@ function build_app_version($ref, $commit_hash)
}
/**
+ * Get upload max size.
+ *
+ * @return string
+ */
+function get_upload_max_size()
+{
+ return min(ini_get('upload_max_filesize'), ini_get('post_max_size'));
+}
+
+/**
+ * Get file extension
+ *
+ * @param $filename
+ * @return string
+ */
+function get_file_extension($filename)
+{
+ return strtolower(pathinfo($filename, PATHINFO_EXTENSION));
+}
+
+/**
* Translate a string
*
* @return string